diff --git a/VectoCommon/VectoCommon/BusAuxiliaries/ISSMDeclarationInputs.cs b/VectoCommon/VectoCommon/BusAuxiliaries/ISSMDeclarationInputs.cs index 48eaa43c81247dd5815f43ce02ac4eb82800e440..f51463013d440f3b3c78a1a90c093846a67dc641 100644 --- a/VectoCommon/VectoCommon/BusAuxiliaries/ISSMDeclarationInputs.cs +++ b/VectoCommon/VectoCommon/BusAuxiliaries/ISSMDeclarationInputs.cs @@ -44,7 +44,7 @@ namespace TUGraz.VectoCommon.BusAuxiliaries BusHVACSystemConfiguration HVACSystemConfiguration { get; } string Source { get; } - + double ElectricWasteHeatToCoolant { get; } } public interface ISSMBusParameters @@ -394,6 +394,7 @@ namespace TUGraz.VectoCommon.BusAuxiliaries double FuelEnergyToHeatToCoolant { get; set; } double CoolantHeatTransferredToAirCabinHeater { get; set; } + double ElectricWasteHeatToCoolant { get; } } } diff --git a/VectoCore/VectoCore/Configuration/Constants.cs b/VectoCore/VectoCore/Configuration/Constants.cs index f4df273aa7cda478f3b1c98790a79b1406fb74c0..8ed1b6607b1ec64b7753b686e3806cf95d394ff4 100644 --- a/VectoCore/VectoCore/Configuration/Constants.cs +++ b/VectoCore/VectoCore/Configuration/Constants.cs @@ -187,6 +187,7 @@ namespace TUGraz.VectoCore.Configuration public static class Heater { public const double CoolantHeatTransferredToAirCabinHeater = 0.75; public const double FuelEnergyToHeatToCoolant = 0.2; + public const double ElectricWasteHeatToCoolant = 0.9; } } diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs index 1525b5866f19209a24b921d98bd82a274bb01905..3ee39476e5e55c3d51cd7d146e5cf6061d1c1a6e 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/SimulationComponents/AuxiliaryDataAdapter.cs @@ -538,6 +538,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen AuxHeaterEfficiency = Constants.BusAuxiliaries.SteadyStateModel.AuxHeaterEfficiency, FuelEnergyToHeatToCoolant = Constants.BusAuxiliaries.Heater.FuelEnergyToHeatToCoolant, CoolantHeatTransferredToAirCabinHeater = Constants.BusAuxiliaries.Heater.CoolantHeatTransferredToAirCabinHeater, + ElectricWasteHeatToCoolant = Constants.BusAuxiliaries.Heater.ElectricWasteHeatToCoolant, GFactor = Constants.BusAuxiliaries.SteadyStateModel.GFactor, VentilationOnDuringHeating = true, diff --git a/VectoCore/VectoCore/Models/BusAuxiliaries/BusAuxiliaries.cs b/VectoCore/VectoCore/Models/BusAuxiliaries/BusAuxiliaries.cs index 6497224abdb578eb915503f2396f8fca2615ef5f..63fb0b35fafa4618ef201c973664d47698ab16b0 100644 --- a/VectoCore/VectoCore/Models/BusAuxiliaries/BusAuxiliaries.cs +++ b/VectoCore/VectoCore/Models/BusAuxiliaries/BusAuxiliaries.cs @@ -160,7 +160,7 @@ namespace TUGraz.VectoCore.Models.BusAuxiliaries ElectricStorage = battery; } - public virtual Joule AuxHeaterDemandCalculation(Second cycleTime, Joule engineWasteHeatTotal) + public virtual HeaterDemandResult AuxHeaterDemandCalculation(Second cycleTime, Joule engineWasteHeatTotal, Joule electricMotorWasteHeatTotal) { if (auxConfig == null) { throw new VectoException("Auxiliary configuration missing!"); @@ -168,11 +168,11 @@ namespace TUGraz.VectoCore.Models.BusAuxiliaries if (auxConfig.SSMInputsHeating is ISSMEngineeringInputs ssmEngineeringInputs) { var M14eng = new M14bImpl(ssmEngineeringInputs); - return M14eng.AuxHeaterDemand(cycleTime, engineWasteHeatTotal); + return M14eng.AuxHeaterDemand(cycleTime, engineWasteHeatTotal, electricMotorWasteHeatTotal); } var M14 = new M14aImpl(new SSMTOOL(auxConfig.SSMInputsHeating)); - return M14.AuxHeaterDemand(cycleTime, engineWasteHeatTotal); + return M14.AuxHeaterDemand(cycleTime, engineWasteHeatTotal, electricMotorWasteHeatTotal); } public virtual void Initialise(IAuxiliaryConfig auxCfg) diff --git a/VectoCore/VectoCore/Models/BusAuxiliaries/DownstreamModules/Impl/HVAC/SSMInputs.cs b/VectoCore/VectoCore/Models/BusAuxiliaries/DownstreamModules/Impl/HVAC/SSMInputs.cs index 72c5553d500a67cc8e553b9256ff681fb7477691..fc747bb3e8d8c969bab019eead8a86033b0faaf5 100644 --- a/VectoCore/VectoCore/Models/BusAuxiliaries/DownstreamModules/Impl/HVAC/SSMInputs.cs +++ b/VectoCore/VectoCore/Models/BusAuxiliaries/DownstreamModules/Impl/HVAC/SSMInputs.cs @@ -140,6 +140,7 @@ namespace TUGraz.VectoCore.Models.BusAuxiliaries.DownstreamModules.Impl.HVAC public double CoolantHeatTransferredToAirCabinHeater { get; set; } + public double ElectricWasteHeatToCoolant { get; set; } #region Implementation of ISSMInputs @@ -233,6 +234,7 @@ namespace TUGraz.VectoCore.Models.BusAuxiliaries.DownstreamModules.Impl.HVAC public double FuelEnergyToHeatToCoolant { get; set; } public double CoolantHeatTransferredToAirCabinHeater { get; set; } + public double ElectricWasteHeatToCoolant { get; set; } #endregion } diff --git a/VectoCore/VectoCore/Models/BusAuxiliaries/DownstreamModules/Impl/M14Impl.cs b/VectoCore/VectoCore/Models/BusAuxiliaries/DownstreamModules/Impl/M14Impl.cs index 2093670fd0377f62ca0eadcfc38d34831f39756a..760b1679de8ee9344a379405eebbbcfaf6550c17 100644 --- a/VectoCore/VectoCore/Models/BusAuxiliaries/DownstreamModules/Impl/M14Impl.cs +++ b/VectoCore/VectoCore/Models/BusAuxiliaries/DownstreamModules/Impl/M14Impl.cs @@ -3,6 +3,7 @@ using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.BusAuxiliaries.DownstreamModules.Impl.HVAC; using TUGraz.VectoCore.Models.BusAuxiliaries.Interfaces; using TUGraz.VectoCore.Models.BusAuxiliaries.Interfaces.DownstreamModules; +using TUGraz.VectoCore.Models.BusAuxiliaries.Interfaces.DownstreamModules.HVAC; using TUGraz.VectoCore.Models.Declaration; namespace TUGraz.VectoCore.Models.BusAuxiliaries.DownstreamModules.Impl @@ -66,13 +67,18 @@ namespace TUGraz.VectoCore.Models.BusAuxiliaries.DownstreamModules.Impl _ssmTool = ssmTool; } - public Joule AuxHeaterDemand(Second cycleTime, Joule engineWasteHeat) + public HeaterDemandResult AuxHeaterDemand(Second cycleTime, Joule engineWasteHeat, + Joule electricMotorWasteHeatTotal) { var averageEngineWasteHeatPwr = engineWasteHeat / cycleTime; - var averageUsableEngineWasteHeat = averageEngineWasteHeatPwr * - _ssmTool.SSMInputs.AuxHeater.FuelEnergyToHeatToCoolant * - _ssmTool.SSMInputs.AuxHeater.CoolantHeatTransferredToAirCabinHeater; - return _ssmTool.AverageHeaterPower(averageUsableEngineWasteHeat).AuxHeaterPower * cycleTime; + var iceUsableWasteHeat = averageEngineWasteHeatPwr * + _ssmTool.SSMInputs.AuxHeater.FuelEnergyToHeatToCoolant * + _ssmTool.SSMInputs.AuxHeater.CoolantHeatTransferredToAirCabinHeater; + var emUsableWasteHeat = electricMotorWasteHeatTotal / cycleTime * + _ssmTool.SSMInputs.ElectricWasteHeatToCoolant * + _ssmTool.SSMInputs.AuxHeater.CoolantHeatTransferredToAirCabinHeater; + var averageUsableEngineWasteHeat = iceUsableWasteHeat + emUsableWasteHeat; + return new HeaterDemandResult(_ssmTool.AverageHeaterPower(averageUsableEngineWasteHeat), cycleTime); } } @@ -86,17 +92,28 @@ namespace TUGraz.VectoCore.Models.BusAuxiliaries.DownstreamModules.Impl _auxConfig = auxConfigSsmInputs; } - public Joule AuxHeaterDemand(Second cycleTime, Joule engineWasteHeat) + public HeaterDemandResult AuxHeaterDemand(Second cycleTime, Joule engineWasteHeat, + Joule electricMotorWasteHeatTotal) { var averageEngineWasteHeatPwr = engineWasteHeat; - var averageUsableEngineWasteHeat = averageEngineWasteHeatPwr * - _auxConfig.FuelEnergyToHeatToCoolant * - _auxConfig.CoolantHeatTransferredToAirCabinHeater; + var iceUsableWasteHeat = averageEngineWasteHeatPwr * + _auxConfig.FuelEnergyToHeatToCoolant * + _auxConfig.CoolantHeatTransferredToAirCabinHeater; + var emUsableWasteHeat = electricMotorWasteHeatTotal * + _auxConfig.ElectricWasteHeatToCoolant * + _auxConfig.CoolantHeatTransferredToAirCabinHeater; + var averageUsableEngineWasteHeat = iceUsableWasteHeat + emUsableWasteHeat; var heatingDiff = VectoMath.Max(0.SI<Joule>(), _auxConfig.HeatingDemand - averageUsableEngineWasteHeat); var auxHeaterEnergy = VectoMath.Min(heatingDiff , (_auxConfig.AuxHeaterPower * cycleTime).Cast<Joule>()) / _auxConfig.AuxHeaterEfficiency; - return auxHeaterEnergy; + return new HeaterDemandResult(new HeaterPower() { + AuxHeaterPower = auxHeaterEnergy / cycleTime, + ElectricHeaterPowerEl = 0.SI<Watt>(), + HeatPumpPowerEl = 0.SI<Watt>(), + HeatPumpPowerMech = 0.SI<Watt>(), + RequiredHeatingPower = _auxConfig.HeatingDemand / cycleTime + }, cycleTime); } } } diff --git a/VectoCore/VectoCore/Models/BusAuxiliaries/Interfaces/IBusAuxiliaries.cs b/VectoCore/VectoCore/Models/BusAuxiliaries/Interfaces/IBusAuxiliaries.cs index 92ba48b352ed929c869296745660de18b897c4ee..7c288f190e4c1c910a34c4d69fd98f449200b404 100644 --- a/VectoCore/VectoCore/Models/BusAuxiliaries/Interfaces/IBusAuxiliaries.cs +++ b/VectoCore/VectoCore/Models/BusAuxiliaries/Interfaces/IBusAuxiliaries.cs @@ -12,6 +12,7 @@ using TUGraz.VectoCommon.BusAuxiliaries; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.BusAuxiliaries.Interfaces.DownstreamModules.Electrics; +using TUGraz.VectoCore.Models.BusAuxiliaries.Interfaces.DownstreamModules.HVAC; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent; @@ -107,8 +108,8 @@ namespace TUGraz.VectoCore.Models.BusAuxiliaries.Interfaces Watt PSPowerCompressorDragOnly { get; } Watt HVACMechanicalPowerConsumer { get; } Watt HVACMechanicalPowerGenerated { get; } - - Joule AuxHeaterDemandCalculation(Second cycleTime, Joule engineWasteHeatTotal); + + HeaterDemandResult AuxHeaterDemandCalculation(Second cycleTime, Joule engineWasteHeatTotal, Joule electricMotorWasteHeatTotal); ///// <summary> @@ -157,4 +158,29 @@ namespace TUGraz.VectoCore.Models.BusAuxiliaries.Interfaces void ResetCalculations(); } + + public class HeaterDemandResult + { + public Joule AuxHeater => HeaterPower.AuxHeaterPower * CycleTime; + + public WattSecond HeatPumpElectricEnergy => HeaterPower.HeatPumpPowerEl * CycleTime; + + public WattSecond HeatPumpMechanicalEnergy => HeaterPower.HeatPumpPowerMech * CycleTime; + + public WattSecond ElectricHeaterEnergy => HeaterPower.ElectricHeaterPowerEl * CycleTime; + + public Watt AverageHeatPumpElectricPower => HeaterPower.HeatPumpPowerEl; + public Watt AverageHeatPumpMechanicalPower => HeaterPower.HeatPumpPowerMech; + public Watt AverageElectricHeaterPower => HeaterPower.ElectricHeaterPowerEl; + + protected HeaterPower HeaterPower; + + public HeaterDemandResult(HeaterPower hPwr, Second cycleTime) + { + HeaterPower = hPwr; + CycleTime = cycleTime; + } + + public Second CycleTime { get; } + } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs index a2f3f19d393ab4114d21d2e5db07ddde404363a6..06f6622a12a858583b3eba88011efa513ebf04a5 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs @@ -101,9 +101,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public ISimpleBattery ElectricStorage { get; set; } - public virtual Joule AuxHeaterDemandCalculation(Second cycleTime, Joule engineWasteHeatTotal) + public virtual HeaterDemandResult AuxHeaterDemandCalculation(Second cycleTime, Joule engineWasteHeatTotal, Joule electricMotorWasteHeatTotal) { - return Auxiliaries.AuxHeaterDemandCalculation(cycleTime, engineWasteHeatTotal);} + return Auxiliaries.AuxHeaterDemandCalculation(cycleTime, engineWasteHeatTotal, electricMotorWasteHeatTotal); + } public IAuxPort Port() { diff --git a/VectoCore/VectoCore/OutputData/BatteryElectricPostprocessingCorrection.cs b/VectoCore/VectoCore/OutputData/BatteryElectricPostprocessingCorrection.cs new file mode 100644 index 0000000000000000000000000000000000000000..338596e7156b9851af920d44a1d13b3ce04b3323 --- /dev/null +++ b/VectoCore/VectoCore/OutputData/BatteryElectricPostprocessingCorrection.cs @@ -0,0 +1,16 @@ +using TUGraz.VectoCore.Models.Simulation.Data; + +namespace TUGraz.VectoCore.OutputData +{ + public class BatteryElectricPostprocessingCorrection : IModalDataPostProcessor + { + #region Implementation of IModalDataPostProcessor + + public ICorrectedModalData ApplyCorrection(IModalDataContainer modData, VectoRunData runData) + { + return new NoCorrectionModalData(modData); + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs index 91059a7dabead453ccd42effd1098a4587e27310..8ca87a45055897973497235e06c514ee2c6891c8 100644 --- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs @@ -37,6 +37,7 @@ using TUGraz.VectoCommon.BusAuxiliaries; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.BusAuxiliaries.Interfaces; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.DataBus; @@ -114,13 +115,15 @@ namespace TUGraz.VectoCore.OutputData void FinishSimulation(); string GetColumnName(IFuelProperties fuelData, ModalResultField mrf); + + string GetColumnName(PowertrainPosition pos, ModalResultField mrf); void Reset(); Second Duration { get; } Meter Distance { get; } - Func<Second, Joule, Joule> AuxHeaterDemandCalc { get; set; } + Func<Second, Joule, Joule, HeaterDemandResult> AuxHeaterDemandCalc { get; set; } KilogramPerWattSecond EngineLineCorrectionFactor(IFuelProperties fuel); void CalculateAggregateValues(); @@ -162,6 +165,11 @@ namespace TUGraz.VectoCore.OutputData WattSecond WorkWHR { get; } WattSecond WorkBusAuxPSCorr { get; } WattSecond WorkBusAuxESMech { get; } + WattSecond WorkBusAuxHeatPumpHeatingElMech { get; } + WattSecond WorkBusAuxHeatPumpHeatingMech { get; } + + WattSecond WorkBusAuxElectricHeater { get; } + WattSecond WorkBusAuxCorr { get; } WattSecond EnergyDCDCMissing { get; } Joule AuxHeaterDemand { get; } diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index 5e651491b8a7a92734e095fe247bfdff7789ea08..90dd578326822c392b6b33f7f2c3031f39d16d5d 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -40,6 +40,7 @@ using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.BusAuxiliaries.Interfaces; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; @@ -243,7 +244,7 @@ namespace TUGraz.VectoCore.OutputData public Meter Distance => _distance ?? (_distance = CalcDistance()); - public Func<Second, Joule, Joule> AuxHeaterDemandCalc { get; set; } + public Func<Second, Joule, Joule, HeaterDemandResult> AuxHeaterDemandCalc { get; set; } public KilogramPerWattSecond EngineLineCorrectionFactor(IFuelProperties fuel) { @@ -918,6 +919,11 @@ namespace TUGraz.VectoCore.OutputData } } + public string GetColumnName(PowertrainPosition pos, ModalResultField mrf) + { + return string.Format(mrf.GetCaption(), pos.GetName()); + } + public object this[ModalResultField key, IFuelProperties fuel] { get { @@ -938,8 +944,8 @@ namespace TUGraz.VectoCore.OutputData public object this[ModalResultField key, PowertrainPosition pos] { - get => CurrentRow[string.Format(key.GetCaption(), pos.GetName())]; - set => CurrentRow[string.Format(key.GetCaption(), pos.GetName())] = value; + get => CurrentRow[GetColumnName(pos, key)]; + set => CurrentRow[GetColumnName(pos, key)] = value; } public object this[ModalResultField key, int? idx] diff --git a/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs b/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs index 9fe67fbc2dd5474e809a282cf6b785cf54a5e509..e69cd01447076dbf6187363d6ee72b526c3a1d14 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs @@ -14,88 +14,6 @@ using TUGraz.VectoCore.Models.SimulationComponent.Data; namespace TUGraz.VectoCore.OutputData { - public class SerialHybridModalDataPostprocessingCorrection : ModalDataPostprocessingCorrection - { - - protected override void SetReesCorrectionDemand(IModalDataContainer modData, VectoRunData runData, - CorrectedModalData r) - { - var deltaEReess = modData.TimeIntegral<WattSecond>(ModalResultField.P_reess_int.GetName()); - var startSoc = modData.REESSStartSoC(); - var endSoc = modData.REESSEndSoC(); - var emEff = 0.0; - if (endSoc < startSoc) { - var etaReessChg = modData.WorkREESSChargeInternal().Value() / modData.WorkREESSChargeTerminal().Value(); - emEff = 1.0 / (etaReessChg); - } - if (endSoc > startSoc) { - var etaReessDischg = modData.WorkREESSDischargeTerminal().Value() / modData.WorkREESSDischargeInternal().Value(); - emEff = etaReessDischg; - } - - r.DeltaEReessMech = double.IsNaN(emEff) ? 0.SI<WattSecond>() : -deltaEReess * emEff; - } - - protected override FuelConsumptionCorrection SetFuelConsumptionCorrection(IModalDataContainer modData, VectoRunData runData, - CorrectedModalData r, IFuelProperties fuel) - { - var duration = modData.Duration; - var distance = modData.Distance; - var essParams = runData.DriverData.EngineStopStart; - var engFuel = runData.EngineData.Fuels.First(x => x.FuelData.Equals(fuel)); - - var fcIceIdle = engFuel.ConsumptionMap.GetFuelConsumptionValue( - 0.SI<NewtonMeter>(), - runData.EngineData.IdleSpeed) * - engFuel.FuelConsumptionCorrectionFactor; - - var elPowerGenerated = modData.TimeIntegral<WattSecond>(string.Format(ModalResultField.P_EM_electricMotor_el_.GetCaption(), PowertrainPosition.GEN)); - var fcGenCharging = modData.TotalFuelConsumption(ModalResultField.FCFinal, fuel); - var socCorr = elPowerGenerated.IsEqual(0) - ? (runData.GenSet.GenSetCharacteristics.OptimalPoint.FuelConsumption / - runData.GenSet.GenSetCharacteristics.OptimalPoint.ElectricPower).Cast<KilogramPerWattSecond>() - : (fcGenCharging / elPowerGenerated).Cast<KilogramPerWattSecond>(); - var engLine = modData.EngineLineCorrectionFactor(fuel); - var comp = - runData.BusAuxiliaries?.PneumaticUserInputsConfig.CompressorMap - .Interpolate(runData.EngineData.IdleSpeed); - - var f = new FuelConsumptionCorrection { - Fuel = fuel, - Distance = distance != null && distance.IsGreater(0) ? distance : null, - Duration = duration != null && duration.IsGreater(0) ? duration : null, - EngineLineCorrectionFactor = engLine, - VehicleLine = modData.VehicleLineSlope(fuel), - FcModSum = modData.TotalFuelConsumption(ModalResultField.FCFinal, fuel), - FcESS_EngineStart = engLine * modData.WorkEngineStart(), - - FcESS_AuxStandstill_ICEOff = r.EnergyAuxICEOffStandstill_UF * engLine, - FcESS_AuxStandstill_ICEOn = r.EnergyAuxICEOnStandstill_UF * engLine + - fcIceIdle * r.ICEOffTimeStandstill * (1 - r.UtilityFactorStandstill), - - FcESS_AuxDriving_ICEOff = r.EnergyAuxICEOffDriving_UF * engLine, - FcESS_AuxDriving_ICEOn = r.EnergyAuxICEOnDriving_UF * engLine + - fcIceIdle * r.ICEOffTimeDriving * (1 - r.UtilityFactorDriving), - - FcESS_DCDCMissing = r.EnergyDCDCMissing * engLine, - FcBusAuxPSAirDemand = engLine * r.WorkBusAuxPSCorr, - - FcBusAuxPSDragICEOffStandstill = comp == null - ? 0.SI<Kilogram>() - : comp.PowerOff * r.ICEOffTimeStandstill * engLine * (1 - essParams.UtilityFactorStandstill), - FcBusAuxPSDragICEOffDriving = comp == null - ? 0.SI<Kilogram>() - : comp.PowerOff * r.ICEOffTimeDriving * engLine * (1 - essParams.UtilityFactorDriving), - FcREESSSoc = r.DeltaEReessMech * socCorr, - FcBusAuxEs = engLine * r.WorkBusAuxESMech, - FcWHR = engLine * r.WorkWHR, - FcAuxHtr = 0.SI<Kilogram>() - }; - - return f; - } - } - public class ModalDataPostprocessingCorrection : IModalDataPostProcessor { @@ -108,7 +26,7 @@ namespace TUGraz.VectoCore.OutputData UtilityFactorDriving = essParams.UtilityFactorDriving, UtilityFactorStandstill = essParams.UtilityFactorStandstill }; - var duration = modData.Duration; + //var duration = modData.Duration; var distance = modData.Distance; SetMissingEnergyICEOFf(modData, r); @@ -137,7 +55,7 @@ namespace TUGraz.VectoCore.OutputData SetMissingDCDCEnergy(modData, runData, r); } - SetAuxHeaterDemand(modData, r, duration); + SetAuxHeaterDemand(modData, runData, r); SetReesCorrectionDemand(modData, runData, r); @@ -169,7 +87,7 @@ namespace TUGraz.VectoCore.OutputData var em = runData.ElectricMachinesData?.FirstOrDefault(x => x.Item1 != PowertrainPosition.GEN); if (em != null) { - var deltaEReess = modData.TimeIntegral<WattSecond>(ModalResultField.P_reess_int.GetName()); + var deltaEReess = modData.TimeIntegral<WattSecond>(ModalResultField.P_reess_int); var startSoc = modData.REESSStartSoC(); var endSoc = modData.REESSEndSoC(); var emEff = 0.0; @@ -239,6 +157,9 @@ namespace TUGraz.VectoCore.OutputData : comp.PowerOff * r.ICEOffTimeDriving * engLine * (1 - essParams.UtilityFactorDriving), FcREESSSoc = r.DeltaEReessMech * engLine, FcBusAuxEs = engLine * r.WorkBusAuxESMech, + FcHeatPumpHeatingEl = engLine * r.WorkBusAuxHeatPumpHeatingElMech, + FcHeatPumpHeatingMech = engLine * r.WorkBusAuxHeatPumpHeatingMech, + FcBusAuxEletcricHeater = engLine * r.WorkBusAuxElectricHeater, FcWHR = engLine * r.WorkWHR, FcAuxHtr = 0.SI<Kilogram>() }; @@ -246,15 +167,43 @@ namespace TUGraz.VectoCore.OutputData return f; } - protected virtual void SetAuxHeaterDemand(IModalDataContainer modData, CorrectedModalData r, Second duration) + protected virtual void SetAuxHeaterDemand(IModalDataContainer modData, VectoRunData runData, CorrectedModalData r) { + + if (modData.AuxHeaterDemandCalc == null) { + r.AuxHeaterDemand = 0.SI<Joule>(); + r.WorkBusAuxHeatPumpHeatingMech = 0.SI<WattSecond>(); + r.WorkBusAuxHeatPumpHeatingElMech = 0.SI<WattSecond>(); + r.WorkBusAuxElectricHeater = 0.SI<WattSecond>(); + return; + } + var duration = modData.Duration; var engineWasteheatSum = modData.FuelData.Aggregate( 0.SI<Joule>(), (current, fuel) => current + modData.TotalFuelConsumption(ModalResultField.FCFinal, fuel) * fuel.LowerHeatingValueVecto); - r.AuxHeaterDemand = modData.AuxHeaterDemandCalc == null - ? 0.SI<Joule>() - : modData.AuxHeaterDemandCalc(duration, engineWasteheatSum); + var emLossEnergy = 0.SI<Joule>(); + //if (runData.ElectricMachinesData.Count > 0) { + foreach (var em in runData.ElectricMachinesData) { + var emPos = em.Item1; //runData.ElectricMachinesData.First().Item1; + var colName = modData.GetColumnName(emPos, ModalResultField.P_EM_electricMotorLoss_); + if (emPos == PowertrainPosition.IEPC) { + colName = modData.GetColumnName(emPos, ModalResultField.P_IEPC_electricMotorLoss_); + } + emLossEnergy += modData.TimeIntegral<WattSecond>(colName).Cast<Joule>(); + } + + //r.WorkBusAuxHeatPumpHeatingElMech = workBusAuxES / + // runData.BusAuxiliaries.ElectricalUserInputsConfig.AlternatorMap.GetEfficiency(0.RPMtoRad(), 0.SI<Ampere>()) / + // runData.BusAuxiliaries.ElectricalUserInputsConfig.AlternatorGearEfficiency; + var heatingDemand = modData.AuxHeaterDemandCalc(duration, engineWasteheatSum, emLossEnergy); + + r.WorkBusAuxHeatPumpHeatingMech = heatingDemand.HeatPumpMechanicalEnergy; + r.WorkBusAuxHeatPumpHeatingElMech = heatingDemand.HeatPumpElectricEnergy / + runData.BusAuxiliaries.ElectricalUserInputsConfig.AlternatorMap.GetEfficiency(0.RPMtoRad(), 0.SI<Ampere>()) / + runData.BusAuxiliaries.ElectricalUserInputsConfig.AlternatorGearEfficiency; + r.AuxHeaterDemand = heatingDemand.AuxHeater; + r.WorkBusAuxElectricHeater = heatingDemand.ElectricHeaterEnergy; } protected virtual void SetMissingDCDCEnergy(IModalDataContainer modData, VectoRunData runData, CorrectedModalData r) @@ -382,18 +331,6 @@ namespace TUGraz.VectoCore.OutputData } - public class BatteryElectricPostprocessingCorrection : IModalDataPostProcessor - { - #region Implementation of IModalDataPostProcessor - - public ICorrectedModalData ApplyCorrection(IModalDataContainer modData, VectoRunData runData) - { - return new NoCorrectionModalData(modData); - } - - #endregion - } - public class CorrectedModalData : ICorrectedModalData { public SI kAir { get; set; } @@ -418,6 +355,13 @@ namespace TUGraz.VectoCore.OutputData public WattSecond WorkWHR => WorkWHRElMech + WorkWHRMech; public WattSecond WorkBusAuxPSCorr { get; set; } public WattSecond WorkBusAuxESMech { get; set; } + + public WattSecond WorkBusAuxHeatPumpHeatingElMech { get; set; } + public WattSecond WorkBusAuxHeatPumpHeatingMech { get; set; } + + public WattSecond WorkBusAuxElectricHeater { get; set; } + + public WattSecond WorkBusAuxCorr => WorkBusAuxPSCorr + WorkBusAuxESMech; public Joule AuxHeaterDemand { get; set; } @@ -522,11 +466,17 @@ namespace TUGraz.VectoCore.OutputData public Kilogram FcAuxHtr { get; set; } + public Kilogram FcHeatPumpHeatingEl { get; set; } + + public Kilogram FcHeatPumpHeatingMech { get; set; } + + public Kilogram FcBusAuxEletcricHeater { get; set; } public Kilogram FcEssCorr => FcModSum + FcESS; public Kilogram FcBusAuxPsCorr => FcEssCorr + FcBusAuxPs; public Kilogram FcBusAuxEsCorr => FcBusAuxPsCorr + FcBusAuxEs; - public Kilogram FcWHRCorr => FcBusAuxEsCorr + FcWHR; + public Kilogram FcBusAuxHeatingCorr => FcBusAuxEsCorr + FcHeatPumpHeatingEl + FcHeatPumpHeatingMech + FcBusAuxEletcricHeater; + public Kilogram FcWHRCorr => FcBusAuxHeatingCorr + FcWHR; public Kilogram FcREESSSoCCorr => FcWHRCorr + FcREESSSoc; public Kilogram FcAuxHtrCorr => FcREESSSoCCorr + FcAuxHtr; @@ -590,6 +540,9 @@ namespace TUGraz.VectoCore.OutputData public WattSecond WorkWHR => 0.SI<WattSecond>(); public WattSecond WorkBusAuxPSCorr => 0.SI<WattSecond>(); public WattSecond WorkBusAuxESMech => 0.SI<WattSecond>(); + public WattSecond WorkBusAuxHeatPumpHeatingElMech => 0.SI<WattSecond>(); + public WattSecond WorkBusAuxHeatPumpHeatingMech => 0.SI<WattSecond>(); + public WattSecond WorkBusAuxElectricHeater => 0.SI<WattSecond>(); public WattSecond WorkBusAuxCorr => 0.SI<WattSecond>(); public WattSecond EnergyDCDCMissing => 0.SI<WattSecond>(); public Joule AuxHeaterDemand => 0.SI<WattSecond>(); diff --git a/VectoCore/VectoCore/OutputData/ParallelHybridModalDataPostprocessingCorrection.cs b/VectoCore/VectoCore/OutputData/ParallelHybridModalDataPostprocessingCorrection.cs new file mode 100644 index 0000000000000000000000000000000000000000..e6b201e57b5067e6e51cbf7a6060b03c50f9b236 --- /dev/null +++ b/VectoCore/VectoCore/OutputData/ParallelHybridModalDataPostprocessingCorrection.cs @@ -0,0 +1,7 @@ +namespace TUGraz.VectoCore.OutputData +{ + public class ParallelHybridModalDataPostprocessingCorrection : ModalDataPostprocessingCorrection + { + + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/SerialHybridModalDataPostprocessingCorrection.cs b/VectoCore/VectoCore/OutputData/SerialHybridModalDataPostprocessingCorrection.cs new file mode 100644 index 0000000000000000000000000000000000000000..145c0c07e926a804bea018781290076641d85483 --- /dev/null +++ b/VectoCore/VectoCore/OutputData/SerialHybridModalDataPostprocessingCorrection.cs @@ -0,0 +1,90 @@ +using System.Linq; +using TUGraz.VectoCommon.BusAuxiliaries; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Simulation.Data; + +namespace TUGraz.VectoCore.OutputData +{ + public class SerialHybridModalDataPostprocessingCorrection : ModalDataPostprocessingCorrection + { + + protected override void SetReesCorrectionDemand(IModalDataContainer modData, VectoRunData runData, + CorrectedModalData r) + { + var deltaEReess = modData.TimeIntegral<WattSecond>(ModalResultField.P_reess_int.GetName()); + var startSoc = modData.REESSStartSoC(); + var endSoc = modData.REESSEndSoC(); + var emEff = 0.0; + if (endSoc < startSoc) { + var etaReessChg = modData.WorkREESSChargeInternal().Value() / modData.WorkREESSChargeTerminal().Value(); + emEff = 1.0 / (etaReessChg); + } + if (endSoc > startSoc) { + var etaReessDischg = modData.WorkREESSDischargeTerminal().Value() / modData.WorkREESSDischargeInternal().Value(); + emEff = etaReessDischg; + } + + r.DeltaEReessMech = double.IsNaN(emEff) ? 0.SI<WattSecond>() : -deltaEReess * emEff; + } + + protected override FuelConsumptionCorrection SetFuelConsumptionCorrection(IModalDataContainer modData, VectoRunData runData, + CorrectedModalData r, IFuelProperties fuel) + { + var duration = modData.Duration; + var distance = modData.Distance; + var essParams = runData.DriverData.EngineStopStart; + var engFuel = runData.EngineData.Fuels.First(x => x.FuelData.Equals(fuel)); + + var fcIceIdle = engFuel.ConsumptionMap.GetFuelConsumptionValue( + 0.SI<NewtonMeter>(), + runData.EngineData.IdleSpeed) * + engFuel.FuelConsumptionCorrectionFactor; + + var elPowerGenerated = modData.TimeIntegral<WattSecond>(string.Format(ModalResultField.P_EM_electricMotor_el_.GetCaption(), PowertrainPosition.GEN)); + var fcGenCharging = modData.TotalFuelConsumption(ModalResultField.FCFinal, fuel); + var socCorr = elPowerGenerated.IsEqual(0) + ? (runData.GenSet.GenSetCharacteristics.OptimalPoint.FuelConsumption / + runData.GenSet.GenSetCharacteristics.OptimalPoint.ElectricPower).Cast<KilogramPerWattSecond>() + : (fcGenCharging / elPowerGenerated).Cast<KilogramPerWattSecond>(); + var engLine = modData.EngineLineCorrectionFactor(fuel); + var comp = + runData.BusAuxiliaries?.PneumaticUserInputsConfig.CompressorMap + .Interpolate(runData.EngineData.IdleSpeed); + + var f = new FuelConsumptionCorrection { + Fuel = fuel, + Distance = distance != null && distance.IsGreater(0) ? distance : null, + Duration = duration != null && duration.IsGreater(0) ? duration : null, + EngineLineCorrectionFactor = engLine, + VehicleLine = modData.VehicleLineSlope(fuel), + FcModSum = modData.TotalFuelConsumption(ModalResultField.FCFinal, fuel), + FcESS_EngineStart = engLine * modData.WorkEngineStart(), + + FcESS_AuxStandstill_ICEOff = r.EnergyAuxICEOffStandstill_UF * engLine, + FcESS_AuxStandstill_ICEOn = r.EnergyAuxICEOnStandstill_UF * engLine + + fcIceIdle * r.ICEOffTimeStandstill * (1 - r.UtilityFactorStandstill), + + FcESS_AuxDriving_ICEOff = r.EnergyAuxICEOffDriving_UF * engLine, + FcESS_AuxDriving_ICEOn = r.EnergyAuxICEOnDriving_UF * engLine + + fcIceIdle * r.ICEOffTimeDriving * (1 - r.UtilityFactorDriving), + + FcESS_DCDCMissing = r.EnergyDCDCMissing * engLine, + FcBusAuxPSAirDemand = engLine * r.WorkBusAuxPSCorr, + + FcBusAuxPSDragICEOffStandstill = comp == null + ? 0.SI<Kilogram>() + : comp.PowerOff * r.ICEOffTimeStandstill * engLine * (1 - essParams.UtilityFactorStandstill), + FcBusAuxPSDragICEOffDriving = comp == null + ? 0.SI<Kilogram>() + : comp.PowerOff * r.ICEOffTimeDriving * engLine * (1 - essParams.UtilityFactorDriving), + FcREESSSoc = r.DeltaEReessMech * socCorr, + FcBusAuxEs = engLine * r.WorkBusAuxESMech, + FcWHR = engLine * r.WorkWHR, + FcAuxHtr = 0.SI<Kilogram>() + }; + + return f; + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Integration/CompletedBus/CompletedBusFactorMethodTest.cs b/VectoCore/VectoCoreTest/Integration/CompletedBus/CompletedBusFactorMethodTest.cs index 4acc6047b4a9dc5a064bde5727c5ac78f3eb0e41..663f48707edf781a99d1496378e4e7763fa9e691 100644 --- a/VectoCore/VectoCoreTest/Integration/CompletedBus/CompletedBusFactorMethodTest.cs +++ b/VectoCore/VectoCoreTest/Integration/CompletedBus/CompletedBusFactorMethodTest.cs @@ -672,8 +672,8 @@ namespace TUGraz.VectoCore.Tests.Integration.CompletedBus Assert.AreEqual(140.865, genericBusParam.BusSurfaceArea.Value(), 1e-3); Assert.AreEqual(134.783, specificBusParam.BusSurfaceArea.Value(), 1e-3); - Assert.AreEqual(81.09, genericBusParam.BusVolume.Value(), 1e-3); - Assert.AreEqual(75.4162, specificBusParam.BusVolume.Value(), 1e-3); + Assert.AreEqual(81.09, genericBusParam.BusVolumeVentilation.Value(), 1e-3); + Assert.AreEqual(75.4162, specificBusParam.BusVolumeVentilation.Value(), 1e-3); } private void AssertPassengerCount(double genericLoading, double specificLoading, int index) @@ -1131,6 +1131,39 @@ namespace TUGraz.VectoCore.Tests.Integration.CompletedBus Assert.IsTrue(jobContainer.Runs.All(r => r.Success), String.Concat(jobContainer.Runs.Select(r => r.ExecException))); } + [TestCase(@"TestData\Integration\Buses\FactorMethod\SingleBus_41-32b.vecto", TestName = "HVAC_Heating RunSingleBusSimulation Group 41/32b"),] + public void TestRunPrimaryOrSingleBusSimulationHVACHeating(string jobName) + { + var relativeJobPath = jobName; + var writer = new FileOutputWriter(relativeJobPath); + var inputData = Path.GetExtension(relativeJobPath) == ".xml" + ? xmlInputReader.CreateDeclaration(relativeJobPath) + : JSONInputDataFactory.ReadJsonJob(relativeJobPath); + + var factory = SimulatorFactory.CreateSimulatorFactory(ExecutionMode.Declaration, inputData, writer, validate: false); + factory.WriteModalResults = true; + //var factory = new SimulatorFactory(ExecutionMode.Declaration, inputData, writer) { + // WriteModalResults = true, + // //ActualModalData = true, + // Validate = false + //}; + var jobContainer = new JobContainer(new SummaryDataContainer(writer)); + + var runs = factory.SimulationRuns().ToArray(); + var runIdx = 0; + runs[runIdx].Run(); + + Assert.IsTrue(runs[runIdx].FinishedWithoutErrors); + + // jobContainer.AddRuns(factory); + + //jobContainer.Execute(); + //jobContainer.WaitFinished(); + var progress = jobContainer.GetProgress(); + Assert.IsTrue(progress.All(r => r.Value.Success), string.Concat(progress.Select(r => r.Value.Error))); + Assert.IsTrue(jobContainer.Runs.All(r => r.Success), String.Concat(jobContainer.Runs.Select(r => r.ExecException))); + } + [TestCase(@"TestData\Integration\Buses\FactorMethod\vecto_vehicle-primary_heavyBus_ESS_electricFanSTP.xml", 13, TestName = "RunBusSimulation electric STP/Fan ESS IU/RL"), TestCase(@"TestData\Integration\Buses\FactorMethod\vecto_vehicle-primary_heavyBus_ESS_electricFanSTP.xml", 17, TestName = "RunBusSimulation electric STP/Fan ESS CO/RL"), diff --git a/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMBusAuxModelParameters.cs b/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMBusAuxModelParameters.cs index 46eaba35fcb741552583fc740629f25689110dd3..afd4dcd1b520181e9cfe62d3830e6f6f8c238a10 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMBusAuxModelParameters.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMBusAuxModelParameters.cs @@ -26,7 +26,8 @@ static internal class SSMBusAuxModelParameters bool airElectricHeater, bool waterElectricHeater, bool otherElectricHeater, BusHVACSystemConfiguration hvacConfig, bool doubleGlazing, bool adjustableAuxHeater, bool separateAirdistributionDicts, bool adjustableCoolantThermostat, bool engineWasteGasHeatExchanger, - string[] steeringpumps, string fanTech, AlternatorType alternatorTech, Meter entranceHeight) + string[] steeringpumps, string fanTech, AlternatorType alternatorTech, Meter entranceHeight, + LoadingType loading = LoadingType.ReferenceLoad) { var dao = new SpecificCompletedBusAuxiliaryDataAdapter(new PrimaryBusAuxiliaryDataAdapter()); @@ -106,7 +107,7 @@ static internal class SSMBusAuxModelParameters var runData = new VectoRunData() { Mission = mission, - Loading = LoadingType.ReferenceLoad, + Loading = loading, VehicleData = new VehicleData() { VehicleClass = vehicleClass, }, diff --git a/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMHeatingPostProcessingCorrection.cs b/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMHeatingPostProcessingCorrection.cs index e4bbe241ccda28c75e64aea23859f19078358be9..cb9bd90786a900e7584d49778a0336599326953b 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMHeatingPostProcessingCorrection.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMHeatingPostProcessingCorrection.cs @@ -1,12 +1,15 @@ using System; +using System.Collections.Generic; using System.Linq; using Moq; using NUnit.Framework; using TUGraz.VectoCommon.BusAuxiliaries; +using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.InputData.Reader.ComponentData; +using TUGraz.VectoCore.InputData.Reader.Impl; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation; using TUGraz.VectoCore.Models.Simulation.Data; @@ -54,35 +57,338 @@ public class SSMHeatingPostProcessingCorrection protected static readonly FuelData.Entry Fuel = FuelData.Diesel; + + [ - TestCase("a", CFG1, HeatPumpNone, HeatPumpNone, 0, AuxHtrPwr0, 0, 0), - TestCase("b", CFG1, HeatPumpNone, HeatPumpNone, 0, AuxHtrPwr30, 6685488.8606, 0.1565688), - TestCase("c", CFG1, HeatPumpNone, HeatPumpNone, 4, AuxHtrPwr30, 205671.4565, 0.0048166), + TestCase("a", CFG1, HeatPumpNone, HeatPumpNone, 0.0, AuxHtrPwr0, 0, 0, 0, 0, 0, 0, 0, 0), + TestCase("b", CFG1, HeatPumpNone, HeatPumpNone, 0.0, AuxHtrPwr30, 0, 0, 0, 0, 0, 0, 9415850.1, 0.2205117), + TestCase("c", CFG1, HeatPumpNone, HeatPumpNone, 4.0, AuxHtrPwr30, 0, 0, 0, 0, 0, 0, 697201.7, 0.0163279), + TestCase("d", CFG1, HeatPumpNone, HeatPumpNone, 10.0, AuxHtrPwr30, 0, 0, 0, 0, 0, 0, 0, 0), + + TestCase("d", CFG2, HeatPump2Stage, HeatPumpNone, 0.0, AuxHtrPwr0, 0.000, 0.000000, 99.712643, 0.001496, 0, 0, 0.0, 0.0000000), + TestCase("e", CFG2, HeatPump2Stage, HeatPumpNone, 0.0, AuxHtrPwr30, 0.000, 0.000000, 81.370822, 0.001221, 0, 0, 8646116.9, 0.2024852), + TestCase("f", CFG2, HeatPump2Stage, HeatPumpNone, 4.0, AuxHtrPwr30, 0.000, 0.000000, 5.211176, 0.000078, 0, 0, 661088.2, 0.0154822), + + TestCase("g", CFG6, HeatPumpNone, HeatPump3Stage, 0.0, AuxHtrPwr0, 0.000, 0.000000, 947.372508, 0.014211, 0, 0, 0.0, 0.0000000), + TestCase("h", CFG6, HeatPumpNone, HeatPump3Stage, 0.0, AuxHtrPwr30, 0.000, 0.000000, 774.516305, 0.011618, 0, 0, 1718517.8, 0.0402463), + TestCase("i", CFG6, HeatPumpNone, HeatPump3Stage, 4.0, AuxHtrPwr30, 0.000, 0.000000, 48.934215, 0.000734, 0, 0, 336067.2, 0.0078704), + TestCase("j", CFG6, HeatPumpNone, HeatPumpCont, 0.0, AuxHtrPwr30, 1038.910, 0.015584, 0.000000, 0.000000, 0, 0, 1718517.8, 0.0402463), + + TestCase("k", CFG7, HeatPump2Stage, HeatPump3Stage, 0.0, AuxHtrPwr0, 0.000, 0.000000, 952.347901, 0.014285, 0, 0, 0.0, 0.0000000), + TestCase("l", CFG7, HeatPump2Stage, HeatPump3Stage, 0.0, AuxHtrPwr30, 0.000, 0.000000, 778.435497, 0.011677, 0, 0, 1718517.8, 0.0402463), + TestCase("m", CFG7, HeatPump2Stage, HeatPump3Stage, 4.0, AuxHtrPwr30, 0.000, 0.000000, 49.251969, 0.000739, 0, 0, 336067.2, 0.0078704), + TestCase("n", CFG7, HeatPumpCont, HeatPumpCont, 4.0, AuxHtrPwr30, 64.408, 0.000966, 0.000000, 0.000000, 0, 0, 336067.2, 0.0078704), ] - public void TestModDataPostprocessing_Conventional(string sort, BusHVACSystemConfiguration cfg, HeatPumpType driverHpHeating, HeatPumpType passengerHpHeating, - double fuelConsumptionKg, double auxhHeaterPwr, double expectedAuxHeatingDemandJ, double expectedFcAuxHeaterKg) + public void TestModDataPostprocessing_Conventional(string sort, BusHVACSystemConfiguration cfg, HeatPumpType driverHpHeating, + HeatPumpType passengerHpHeating, double fuelConsumptionKg, double auxhHeaterPwr, + double expectedHpHeatingElPwrMechW, double expectedFcHPHeatingElKg, double expectedHpHeatingMechPwrW, + double expectedFcHPHeatingMechKg, double expectedElectricHeaterPwrW, + double expectedFcElectricHeaterKg, double expectedAuxHeatingDemandJ, double expectedFcAuxHeaterKg) { - var correction = new ModalDataPostprocessingCorrection(); - var busAux = GetAuxParametersConventionalSingleDeckForTest(cfg, driverHeatPumpHeating: driverHpHeating, passengerHeatPumpHeating: passengerHpHeating, auxHeaterPower: auxhHeaterPwr.SI<Watt>()); + TestModDataPostprocessing(cfg, driverHpHeating, passengerHpHeating, NoElHtr, fuelConsumptionKg, auxhHeaterPwr, + expectedHpHeatingElPwrMechW, expectedFcHPHeatingElKg, expectedHpHeatingMechPwrW, expectedFcHPHeatingMechKg, + expectedElectricHeaterPwrW, expectedFcElectricHeaterKg, expectedAuxHeatingDemandJ, expectedFcAuxHeaterKg, + new ModalDataPostprocessingCorrection()); + } + + // ========================================= + // ========================================= + + // TODO MQ 2022-11-24: Extend Test and assert electric consumption / range + [ + TestCase("a", CFG1, HeatPumpNone, HeatPumpNone,NoElHtr, 0.0, AuxHtrPwr0, 0, 0, 0, 0, 0, 0, 0, 0), + TestCase("b", CFG1, HeatPumpNone, HeatPumpNone,AirElHtr, 0.0, AuxHtrPwr30, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("c", CFG1, HeatPumpNone, HeatPumpNone,WaterElHtr, 4.0, AuxHtrPwr30, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("d", CFG1, HeatPumpNone, HeatPumpNone, OthrElHtr, 10.0, AuxHtrPwr30, 0, 0, 0, 0, 0, 0, 0, 0), + + TestCase("e", CFG2, HeatPumpCont, HeatPumpNone, AirElHtr, 0.0, AuxHtrPwr0, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("f", CFG2, HeatPumpCont, HeatPumpNone, WaterElHtr, 0.0, AuxHtrPwr30, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("g", CFG2, HeatPumpCont, HeatPumpNone, OthrElHtr, 4.0, AuxHtrPwr0, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("h", CFG2, HeatPumpCont, HeatPumpNone, OthrElHtr, 4.0, AuxHtrPwr30, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + + TestCase("i", CFG6, HeatPumpNone, HeatPumpCont, NoElHtr, 0.0, AuxHtrPwr0, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("j", CFG6, HeatPumpNone, HeatPumpCont, AirElHtr, 0.0, AuxHtrPwr30, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("k", CFG6, HeatPumpNone, HeatPumpCont, WaterElHtr, 4.0, AuxHtrPwr30, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("l", CFG6, HeatPumpNone, HeatPumpCont, WaterElHtr, 4.0, AuxHtrPwr0, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + + TestCase("o", CFG7, HeatPumpR744, HeatPumpCont, NoElHtr, 0.0, AuxHtrPwr0 , 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("p", CFG7, HeatPumpR744, HeatPumpCont, AirElHtr, 0.0, AuxHtrPwr30, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("q", CFG7, HeatPumpR744, HeatPumpCont, WaterElHtr, 4.0, AuxHtrPwr0, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("r", CFG7, HeatPumpR744, HeatPumpCont, WaterElHtr, 4.0, AuxHtrPwr30, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("s", CFG7, HeatPumpCont, HeatPumpCont, OthrElHtr, 4.0, AuxHtrPwr0, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + TestCase("t", CFG7, HeatPumpCont, HeatPumpCont, OthrElHtr, 4.0, AuxHtrPwr30, 0.000, 0.0, 0.000, 0.0, 0.000, 0.0, 0.0, 0.0), + ] + public void TestModDataPostprocessing_PEV(string sort, BusHVACSystemConfiguration cfg, HeatPumpType driverHpHeating, + HeatPumpType passengerHpHeating, HeaterType heater, double emLossKwH, double auxhHeaterPwr, + double expectedHpHeatingElPwrMechW, double expectedFcHPHeatingElKg, double expectedHpHeatingMechPwrW, + double expectedFcHPHeatingMechKg, double expectedElectricHeaterPwrW, + double expectedFcElectricHeaterKg, double expectedAuxHeatingDemandJ, double expectedFcAuxHeaterKg) + { + var busAux = GetAuxParametersParallelHybridSingleDeckForTest(cfg, driverHeatPumpHeating: driverHpHeating, + passengerHeatPumpHeating: passengerHpHeating, auxHeaterPower: auxhHeaterPwr.SI<Watt>(), electricHeater: heater); + var runData = GetVectoRunDataBatteryElectric(busAux); + var mockModData = GetMockModData(runData, emLoss: emLossKwH.SI(Unit.SI.Kilo.Watt.Hour).Cast<WattSecond>()); + + var corrected = new BatteryElectricPostprocessingCorrection().ApplyCorrection(mockModData, runData); + + var duration = mockModData.Duration.Value(); + + Assert.NotNull(corrected); + var fcCorr = corrected.FuelConsumptionCorrection(Fuel) as NoFuelConsumptionCorrection; + Assert.NotNull(fcCorr); + + Console.WriteLine(new[] { (corrected.WorkBusAuxHeatPumpHeatingElMech / duration).Value().ToString("F3"), + "0.0", //fcCorr.FcHeatPumpHeatingEl.Value().ToString("F6"), + (corrected.WorkBusAuxHeatPumpHeatingMech.Value() / duration).ToString("F3"), + "0.0",//fcCorr.FcHeatPumpHeatingMech.Value().ToString("F6"), + (corrected.WorkBusAuxElectricHeater / duration).Value().ToString("F3"), + "0.0",//fcCorr.FcBusAuxEletcricHeater.Value().ToString("F6"), + corrected.AuxHeaterDemand.Value().ToString("F1"), + "0.0",//fcCorr.FcAuxHtr.Value().ToString("F6") + }.Join(", ")); + + Assert.AreEqual(expectedHpHeatingElPwrMechW, (corrected.WorkBusAuxHeatPumpHeatingElMech / duration).Value(), 1e-3, "Heatpump Power El Mech"); + Assert.AreEqual(expectedHpHeatingMechPwrW, (corrected.WorkBusAuxHeatPumpHeatingMech / duration).Value(), 1e-3, "Heatpump Power Mech"); + //Assert.AreEqual(expectedFcHPHeatingElKg, fcCorr.FcHeatPumpHeatingEl.Value(), 1e-6, "FC heatpump heating El"); + //Assert.AreEqual(expectedFcHPHeatingMechKg, fcCorr.FcHeatPumpHeatingMech.Value(), 1e-6, "FC heatpump heating Mech"); + Assert.AreEqual(expectedElectricHeaterPwrW, (corrected.WorkBusAuxElectricHeater / duration).Value(), 1e-3, "expectedElectricHeaterDemand"); + //Assert.AreEqual(expectedFcElectricHeaterKg, fcCorr.FcBusAuxEletcricHeater.Value(), 1e-6, "expectedFcElectricHeater"); + Assert.AreEqual(expectedAuxHeatingDemandJ, corrected.AuxHeaterDemand.Value(), 1e-1, "expectedAuxHeatingDemand"); + //Assert.AreEqual(expectedFcAuxHeaterKg, fcCorr.FcAuxHtr.Value(), 1e-6, "expectedFcAuxHeater"); + //Assert.AreEqual(0, fcCorr.FC_FINAL_H.Value()); + } + + // ========================================= + // ========================================= + + + [ + TestCase("a", CFG1, HeatPumpNone, HeatPumpNone, NoElHtr, 0.0, 0.0, 0.0, AuxHtrPwr0, 0, 0, 0, 0, 0, 0, 0, 0), + TestCase("b", CFG1, HeatPumpNone, HeatPumpNone, AirElHtr, 0.0, 0.0, 7.0, AuxHtrPwr0, 0.000, 0.000000, 0.000, 0.000000, 473.748, 0.007106, 0.0, 0.000000), + TestCase("b", CFG1, HeatPumpNone, HeatPumpNone, AirElHtr, 1.0, 2.0, 7.0, AuxHtrPwr0, 0.000, 0.000000, 0.000, 0.000000, 96.890, 0.001453, 0.0, 0.000000), + + TestCase("c", CFG1, HeatPumpNone, HeatPumpNone, NoElHtr, 0.0, 0.0, 0.0, AuxHtrPwr30, 0.000, 0.000000, 0.000, 0.000000, 0.000, 0.000000, 9415850.1, 0.220512), + TestCase("d", CFG1, HeatPumpNone, HeatPumpNone, AirElHtr, 0.0, 0.0, 7.0, AuxHtrPwr30, 0.000, 0.000000, 0.000, 0.000000, 11.390, 0.000171, 1934969.0, 0.045315), + TestCase("e", CFG1, HeatPumpNone, HeatPumpNone, AirElHtr, 1.0, 2.0, 7.0, AuxHtrPwr30, 0.000, 0.000000, 0.000, 0.000000, 7.823, 0.000117, 372742.4, 0.008729), + + TestCase("f", CFG6, HeatPumpNone, HeatPump3Stage, NoElHtr, 0.0, 0.0, 0.0, AuxHtrPwr0, 0.000, 0.000000, 947.372508, 0.014211, 0, 0, 0.0, 0.0000000), + TestCase("g", CFG6, HeatPumpNone, HeatPump3Stage, NoElHtr, 0.0, 0.0, 7.0, AuxHtrPwr0, 0.000, 0.000000, 226.281, 0.003394, 0.000, 0.000000, 0.0, 0.000000), + TestCase("h", CFG6, HeatPumpNone, HeatPump3Stage, NoElHtr, 1.0, 2.0, 7.0, AuxHtrPwr0, 0.000, 0.000000, 32.761, 0.000491, 0.000, 0.000000, 0.0, 0.000000), + + TestCase("i", CFG6, HeatPumpNone, HeatPump3Stage, NoElHtr, 0.0, 0.0, 0.0, AuxHtrPwr30, 0.000, 0.000000, 774.516, 0.011618, 0.000, 0.000000, 1718517.8, 0.040246), + TestCase("j", CFG6, HeatPumpNone, HeatPump3Stage, NoElHtr, 0.0, 0.0, 7.0, AuxHtrPwr30, 0.000, 0.000000, 161.988, 0.002430, 0.000, 0.000000, 727685.3, 0.017042), + TestCase("k", CFG6, HeatPumpNone, HeatPump3Stage, NoElHtr, 1.0, 2.0, 7.0, AuxHtrPwr30, 0.000, 0.000000, 22.933, 0.000344, 0.000, 0.000000, 236239.2, 0.005533), + + TestCase("l", CFG6, HeatPumpNone, HeatPumpCont, NoElHtr, 0.0, 0.0, 0.0, AuxHtrPwr0, 1267.984, 0.019020, 0.000, 0.000000, 0.000, 0.000000, 0.0, 0.000000), + TestCase("m", CFG6, HeatPumpNone, HeatPumpCont, NoElHtr, 0.0, 0.0, 7.0, AuxHtrPwr0, 299.096, 0.004486, 0.000, 0.000000, 0.000, 0.000000, 0.0, 0.000000), + TestCase("n", CFG6, HeatPumpNone, HeatPumpCont, NoElHtr, 1.0, 2.0, 7.0, AuxHtrPwr0, 43.121, 0.000647, 0.000, 0.000000, 0.000, 0.000000, 0.0, 0.000000), + + TestCase("o", CFG6, HeatPumpNone, HeatPumpCont, OthrElHtr, 0.0, 0.0, 0.0, AuxHtrPwr0, 1267.984, 0.019020, 0.000, 0.000000, 83.878, 0.001258, 0.0, 0.000000), + TestCase("p", CFG6, HeatPumpNone, HeatPumpCont, OthrElHtr, 0.0, 0.0, 7.0, AuxHtrPwr0, 299.096, 0.004486, 0.000, 0.000000, 56.950, 0.000854, 0.0, 0.000000), + TestCase("q", CFG6, HeatPumpNone, HeatPumpCont, OthrElHtr, 1.0, 2.0, 7.0, AuxHtrPwr0, 43.121, 0.000647, 0.000, 0.000000, 39.117, 0.000587, 0.0, 0.000000), + + TestCase("r", CFG6, HeatPumpNone, HeatPumpCont, OthrElHtr, 0.0, 0.0, 0.0, AuxHtrPwr30, 1038.910, 0.015584, 0.000, 0.000000, 16.776, 0.000252, 1648312.3, 0.038602), + TestCase("s", CFG6, HeatPumpNone, HeatPumpCont, OthrElHtr, 0.0, 0.0, 7.0, AuxHtrPwr30, 214.221, 0.003213, 0.000, 0.000000, 11.390, 0.000171, 680018.0, 0.015925), + TestCase("t", CFG6, HeatPumpNone, HeatPumpCont, OthrElHtr, 1.0, 2.0, 7.0, AuxHtrPwr30, 30.184, 0.000453, 0.000, 0.000000, 7.823, 0.000117, 203498.0, 0.004766), + + //TestCase("o", CFG7, HeatPump2Stage, HeatPump3Stage, NoElHtr, 0.0, AuxHtrPwr0, 0.000, 0.000000, 952.347901, 0.014285, 0, 0, 0.0, 0.0000000), + //TestCase("p", CFG7, HeatPump2Stage, HeatPump3Stage, AirElHtr, 0.0, AuxHtrPwr30, 0.000, 0.000000, 778.435497, 0.011677, 0, 0, 1718517.8, 0.0402463), + //TestCase("q", CFG7, HeatPump2Stage, HeatPump3Stage, WaterElHtr, 4.0, AuxHtrPwr0, 0.000, 0.000000, 49.251969, 0.000739, 0, 0, 336067.2, 0.0078704), + //TestCase("r", CFG7, HeatPump2Stage, HeatPump3Stage, WaterElHtr, 4.0, AuxHtrPwr30, 0.000, 0.000000, 49.251969, 0.000739, 0, 0, 336067.2, 0.0078704), + //TestCase("s", CFG7, HeatPumpCont, HeatPumpCont, OthrElHtr, 4.0, AuxHtrPwr0, 64.408, 0.000966, 0.000000, 0.000000, 0, 0, 336067.2, 0.0078704), + //TestCase("t", CFG7, HeatPumpCont, HeatPumpCont, OthrElHtr, 4.0, AuxHtrPwr30, 64.408, 0.000966, 0.000000, 0.000000, 0, 0, 336067.2, 0.0078704), + ] + public void TestModDataPostprocessing_HEV_S(string sort, BusHVACSystemConfiguration cfg, HeatPumpType driverHpHeating, + HeatPumpType passengerHpHeating, HeaterType heater, double fuelConsumptionKg, double genLoss, double emLossKwH, double auxhHeaterPwr, + double expectedHpHeatingElPwrMechW, double expectedFcHPHeatingElKg, double expectedHpHeatingMechPwrW, + double expectedFcHPHeatingMechKg, double expectedElectricHeaterPwrW, + double expectedFcElectricHeaterKg, double expectedAuxHeatingDemandJ, double expectedFcAuxHeaterKg) + { + var busAux = GetAuxParametersParallelHybridSingleDeckForTest(cfg, driverHeatPumpHeating: driverHpHeating, + passengerHeatPumpHeating: passengerHpHeating, auxHeaterPower: auxhHeaterPwr.SI<Watt>(), electricHeater: heater); + var runData = GetVectoRunDataSerialHybrid(busAux); + var mockModData = GetMockModData(runData, fuelConsumptionKg.SI<Kilogram>(), emLoss: emLossKwH.SI(Unit.SI.Kilo.Watt.Hour).Cast<WattSecond>(), + genLoss: genLoss.SI(Unit.SI.Kilo.Watt.Hour).Cast<WattSecond>()); + + var corrected = new ParallelHybridModalDataPostprocessingCorrection().ApplyCorrection(mockModData, runData); + + var duration = mockModData.Duration.Value(); + + Assert.NotNull(corrected); + var fcCorr = corrected.FuelConsumptionCorrection(Fuel) as FuelConsumptionCorrection; + Assert.NotNull(fcCorr); + + Console.WriteLine(new[] { (corrected.WorkBusAuxHeatPumpHeatingElMech / duration).Value().ToString("F3"), + fcCorr.FcHeatPumpHeatingEl.Value().ToString("F6"), + (corrected.WorkBusAuxHeatPumpHeatingMech.Value() / duration).ToString("F3"), + fcCorr.FcHeatPumpHeatingMech.Value().ToString("F6"), + (corrected.WorkBusAuxElectricHeater / duration).Value().ToString("F3"), + fcCorr.FcBusAuxEletcricHeater.Value().ToString("F6"), + corrected.AuxHeaterDemand.Value().ToString("F1"), + fcCorr.FcAuxHtr.Value().ToString("F6") + }.Join(", ")); + + Assert.AreEqual(expectedHpHeatingElPwrMechW, (corrected.WorkBusAuxHeatPumpHeatingElMech / duration).Value(), 1e-3, "Heatpump Power El Mech"); + Assert.AreEqual(expectedHpHeatingMechPwrW, (corrected.WorkBusAuxHeatPumpHeatingMech / duration).Value(), 1e-3, "Heatpump Power Mech"); + Assert.AreEqual(expectedFcHPHeatingElKg, fcCorr.FcHeatPumpHeatingEl.Value(), 1e-6, "FC heatpump heating El"); + Assert.AreEqual(expectedFcHPHeatingMechKg, fcCorr.FcHeatPumpHeatingMech.Value(), 1e-6, "FC heatpump heating Mech"); + Assert.AreEqual(expectedElectricHeaterPwrW, (corrected.WorkBusAuxElectricHeater / duration).Value(), 1e-3, "expectedElectricHeaterDemand"); + Assert.AreEqual(expectedFcElectricHeaterKg, fcCorr.FcBusAuxEletcricHeater.Value(), 1e-6, "expectedFcElectricHeater"); + Assert.AreEqual(expectedAuxHeatingDemandJ, corrected.AuxHeaterDemand.Value(), 1e-1, "expectedAuxHeatingDemand"); + Assert.AreEqual(expectedFcAuxHeaterKg, fcCorr.FcAuxHtr.Value(), 1e-6, "expectedFcAuxHeater"); + + var expectedFc = fuelConsumptionKg + expectedFcHPHeatingElKg + expectedFcHPHeatingMechKg + + expectedFcElectricHeaterKg + expectedFcAuxHeaterKg; + Assert.AreEqual(expectedFc, fcCorr.TotalFuelConsumptionCorrected.Value(), 1e-6, "TotalFuelConsumptionCorrected"); + } + + // ========================================= + // ========================================= + + + [ + TestCase("aa", CFG1, HeatPumpNone, HeatPumpNone, NoElHtr, 0.0, 0.0, AuxHtrPwr0, 0, 0, 0, 0, 0, 0, 0, 0), + TestCase("ab", CFG1, HeatPumpNone, HeatPumpNone, AirElHtr, 0.0, 0.0, AuxHtrPwr30, 0.000, 0.000000, 0.000, 0.000000, 16.776, 0.000252, 9345644.6, 0.218868), + TestCase("ac", CFG1, HeatPumpNone, HeatPumpNone, AirElHtr, 0.0, 1.0, AuxHtrPwr30, 0.000, 0.000000, 0.000, 0.000000, 16.006, 0.000240, 7707580.1, 0.180505), + TestCase("ad", CFG1, HeatPumpNone, HeatPumpNone, WaterElHtr, 4.0, 0.0, AuxHtrPwr30, 0.000, 0.000000, 0.000, 0.000000, 8.664, 0.000130, 660942.6, 0.015479), + TestCase("ae", CFG1, HeatPumpNone, HeatPumpNone, WaterElHtr, 4.0, 1.0, AuxHtrPwr30, 0.000, 0.000000, 0.000, 0.000000, 7.895, 0.000118, 397166.1, 0.009301), + + TestCase("af", CFG2, HeatPump2Stage, HeatPumpNone, AirElHtr, 0.0, 0.0, AuxHtrPwr0, 0.000, 0.000000, 99.713, 0.001496, 2033.302, 0.030500, 0.0, 0.00000), + TestCase("ag", CFG2, HeatPump2Stage, HeatPumpNone, AirElHtr, 0.0, 1.0, AuxHtrPwr0, 0.000, 0.000000, 84.563, 0.001268, 1679.953, 0.025199, 0.0, 0.000000), + TestCase("ah", CFG2, HeatPump2Stage, HeatPumpNone, WaterElHtr, 0.0, 0.0, AuxHtrPwr30, 0.000, 0.000000, 81.371, 0.001221, 16.776, 0.000252, 8575911.3, 0.200841), + TestCase("ai", CFG2, HeatPump2Stage, HeatPumpNone, WaterElHtr, 0.0, 1.0, AuxHtrPwr30, 0.000, 0.000000, 67.865, 0.001018, 16.006, 0.000240, 7087820.6, 0.165991), + TestCase("aj", CFG2, HeatPump2Stage, HeatPumpNone, OthrElHtr, 4.0, 0.0, AuxHtrPwr0, 0.000, 0.000000, 7.445, 0.000112, 154.268, 0.002314, 0.0, 0.000000), + TestCase("ak", CFG2, HeatPump2Stage, HeatPumpNone, OthrElHtr, 4.0, 1.0, AuxHtrPwr0, 0.000, 0.000000, 3.824, 0.000057, 96.465, 0.001447, 0.0, 0.000000), + TestCase("al", CFG2, HeatPump2Stage, HeatPumpNone, OthrElHtr, 4.0, 0.0, AuxHtrPwr30, 0.000, 0.000000, 5.211, 0.000078, 8.664, 0.000130, 624829.2, 0.014633), + TestCase("am", CFG2, HeatPump2Stage, HeatPumpNone, OthrElHtr, 4.0, 1.0, AuxHtrPwr30, 0.000, 0.000000, 2.677, 0.000040, 7.895, 0.000118, 378615.5, 0.008867), + + TestCase("ao", CFG6, HeatPumpNone, HeatPump3Stage, NoElHtr, 0.0, 0.0, AuxHtrPwr0, 0.000, 0.000000, 947.372508, 0.014211, 0, 0, 0.0, 0.0000000), + TestCase("ao1", CFG6, HeatPumpNone, HeatPump3Stage, NoElHtr, 0.0, 0.0, AuxHtrPwr30, 0.000, 0.000000, 774.516, 0.011618, 0.000, 0.000000, 1718517.8, 0.040246), + TestCase("ap", CFG6, HeatPumpNone, HeatPump3Stage, NoElHtr, 0.0, 1.0, AuxHtrPwr0, 0.000, 0.000000, 802.389, 0.012036, 0.000, 0.000000, 0.0, 0.000000), + TestCase("ap1", CFG6, HeatPumpNone, HeatPump3Stage, NoElHtr, 0.0, 1.0, AuxHtrPwr30, 0.000, 0.000000, 645.042, 0.009676, 0.000, 0.000000, 1576970.3, 0.036931), + TestCase("aq", CFG6, HeatPumpNone, HeatPump3Stage, AirElHtr, 0.0, 0.0, AuxHtrPwr30, 0.000, 0.000000, 774.516, 0.011618, 16.776, 0.000252, 1648312.3, 0.038602), + TestCase("ar", CFG6, HeatPumpNone, HeatPump3Stage, AirElHtr, 0.0, 1.0, AuxHtrPwr30, 0.000, 0.000000, 645.042, 0.009676, 16.006, 0.000240, 1509984.5, 0.035363), + TestCase("as", CFG6, HeatPumpNone, HeatPump3Stage, WaterElHtr, 4.0, 0.0, AuxHtrPwr30, 0.000, 0.000000, 48.934, 0.000734, 8.664, 0.000130, 299808.1, 0.007021), + TestCase("at", CFG6, HeatPumpNone, HeatPump3Stage, WaterElHtr, 4.0, 1.0, AuxHtrPwr30, 0.000, 0.000000, 25.136, 0.000377, 7.895, 0.000118, 211659.9, 0.004957), + TestCase("au", CFG6, HeatPumpNone, HeatPump3Stage, WaterElHtr, 4.0, 0.0, AuxHtrPwr0, 0.000, 0.000000, 69.906, 0.001049, 43.320, 0.000650, 0.0, 0.000000), + TestCase("av", CFG6, HeatPumpNone, HeatPump3Stage, WaterElHtr, 4.0, 1.0, AuxHtrPwr0, 0.000, 0.000000, 35.909, 0.000539, 39.473, 0.000592, 0.0, 0.000000), + TestCase("aw", CFG6, HeatPumpNone, HeatPumpCont, OthrElHtr, 0.0, 0.0, AuxHtrPwr30, 1038.910, 0.015584, 0.000, 0.000000, 16.776, 0.000252, 1648312.3, 0.038602), + TestCase("ax", CFG6, HeatPumpNone, HeatPumpCont, OthrElHtr, 0.0, 1.0, AuxHtrPwr30, 863.938, 0.012959, 0.000, 0.000000, 16.006, 0.000240, 1509984.5, 0.035363), + TestCase("ay", CFG6, HeatPumpNone, HeatPumpCont, OthrElHtr, 0.0, 0.0, AuxHtrPwr0, 1267.984, 0.019020, 0.000, 0.000000, 83.878, 0.001258, 0.0, 0.000000), + TestCase("az", CFG6, HeatPumpNone, HeatPumpCont, OthrElHtr, 0.0, 1.0, AuxHtrPwr0, 1072.412, 0.016086, 0.000, 0.000000, 80.031, 0.001200, 0.0, 0.000000), + + TestCase("ba", CFG7, HeatPump2Stage, HeatPump3Stage, NoElHtr, 0.0, 0.0, AuxHtrPwr0, 0.000, 0.000000, 952.348, 0.014285, 0.000, 0.000000, 0.0, 0.000000), + TestCase("bb", CFG7, HeatPump2Stage, HeatPump3Stage, NoElHtr, 0.0, 1.0, AuxHtrPwr0, 0.000, 0.000000, 806.713, 0.012101, 0.000, 0.000000, 0.0, 0.000000), + TestCase("bc", CFG7, HeatPump2Stage, HeatPump3Stage, AirElHtr, 0.0, 0.0, AuxHtrPwr30, 0.000, 0.000000, 778.435, 0.011677, 16.776, 0.000252, 1648312.3, 0.038602), + TestCase("bd", CFG7, HeatPump2Stage, HeatPump3Stage, AirElHtr, 0.0, 1.0, AuxHtrPwr30, 0.000, 0.000000, 648.403, 0.009726, 16.006, 0.000240, 1509984.5, 0.035363), + TestCase("be", CFG7, HeatPump2Stage, HeatPump3Stage, WaterElHtr, 4.0, 0.0, AuxHtrPwr0, 0.000, 0.000000, 70.360, 0.001055, 43.320, 0.000650, 0.0, 0.000000), + TestCase("bf", CFG7, HeatPump2Stage, HeatPump3Stage, WaterElHtr, 4.0, 1.0, AuxHtrPwr0, 0.000, 0.000000, 36.142, 0.000542, 39.473, 0.000592, 0.0, 0.000000), + TestCase("bg", CFG7, HeatPump2Stage, HeatPump3Stage, WaterElHtr, 4.0, 0.0, AuxHtrPwr30, 0.000, 0.000000, 49.252, 0.000739, 8.664, 0.000130, 299808.1, 0.007021), + TestCase("bh", CFG7, HeatPump2Stage, HeatPump3Stage, WaterElHtr, 4.0, 1.0, AuxHtrPwr30, 0.000, 0.000000, 25.300, 0.000379, 7.895, 0.000118, 211659.9, 0.004957), + TestCase("bi", CFG7, HeatPumpCont, HeatPumpCont, OthrElHtr, 4.0, 0.0, AuxHtrPwr0, 92.011, 0.001380, 0.000, 0.000000, 43.320, 0.000650, 0.0, 0.000000), + TestCase("bj", CFG7, HeatPumpCont, HeatPumpCont, OthrElHtr, 4.0, 1.0, AuxHtrPwr0, 47.264, 0.000709, 0.000, 0.000000, 39.473, 0.000592, 0.0, 0.000000), + TestCase("bk", CFG7, HeatPumpCont, HeatPumpCont, OthrElHtr, 4.0, 0.0, AuxHtrPwr30, 64.408, 0.000966, 0.000, 0.000000, 8.664, 0.000130, 299808.1, 0.007021), + TestCase("bl", CFG7, HeatPumpCont, HeatPumpCont, OthrElHtr, 4.0, 1.0, AuxHtrPwr30, 33.085, 0.000496, 0.000, 0.000000, 7.895, 0.000118, 211659.9, 0.004957), + ] + public void TestModDataPostprocessing_HEV_P(string sort, BusHVACSystemConfiguration cfg, HeatPumpType driverHpHeating, + HeatPumpType passengerHpHeating, HeaterType heater, double fuelConsumptionKg, double emLossKwH, double auxhHeaterPwr, + double expectedHpHeatingElPwrMechW, double expectedFcHPHeatingElKg, double expectedHpHeatingMechPwrW, + double expectedFcHPHeatingMechKg, double expectedElectricHeaterPwrW, + double expectedFcElectricHeaterKg, double expectedAuxHeatingDemandJ, double expectedFcAuxHeaterKg) + { + var busAux = GetAuxParametersParallelHybridSingleDeckForTest(cfg, driverHeatPumpHeating: driverHpHeating, + passengerHeatPumpHeating: passengerHpHeating, auxHeaterPower: auxhHeaterPwr.SI<Watt>(), electricHeater: heater); + var runData = GetVectoRunDataParallelHybrid(busAux); + var mockModData = GetMockModData(runData, fuelConsumptionKg.SI<Kilogram>(), emLossKwH.SI(Unit.SI.Kilo.Watt.Hour).Cast<WattSecond>()); + + var corrected = new ParallelHybridModalDataPostprocessingCorrection().ApplyCorrection(mockModData, runData); + + var duration = mockModData.Duration.Value(); + + Assert.NotNull(corrected); + var fcCorr = corrected.FuelConsumptionCorrection(Fuel) as FuelConsumptionCorrection; + Assert.NotNull(fcCorr); + + Console.WriteLine(new[] { (corrected.WorkBusAuxHeatPumpHeatingElMech / duration).Value().ToString("F3"), + fcCorr.FcHeatPumpHeatingEl.Value().ToString("F6"), + (corrected.WorkBusAuxHeatPumpHeatingMech.Value() / duration).ToString("F3"), + fcCorr.FcHeatPumpHeatingMech.Value().ToString("F6"), + (corrected.WorkBusAuxElectricHeater / duration).Value().ToString("F3"), + fcCorr.FcBusAuxEletcricHeater.Value().ToString("F6"), + corrected.AuxHeaterDemand.Value().ToString("F1"), + fcCorr.FcAuxHtr.Value().ToString("F6") + }.Join(", ")); + + Assert.AreEqual(expectedHpHeatingElPwrMechW, (corrected.WorkBusAuxHeatPumpHeatingElMech / duration).Value(), 1e-3, "Heatpump Power El Mech"); + Assert.AreEqual(expectedHpHeatingMechPwrW, (corrected.WorkBusAuxHeatPumpHeatingMech / duration).Value(), 1e-3, "Heatpump Power Mech"); + Assert.AreEqual(expectedFcHPHeatingElKg, fcCorr.FcHeatPumpHeatingEl.Value(), 1e-6, "FC heatpump heating El"); + Assert.AreEqual(expectedFcHPHeatingMechKg, fcCorr.FcHeatPumpHeatingMech.Value(), 1e-6, "FC heatpump heating Mech"); + Assert.AreEqual(expectedElectricHeaterPwrW, (corrected.WorkBusAuxElectricHeater / duration).Value(), 1e-3, "expectedElectricHeaterDemand"); + Assert.AreEqual(expectedFcElectricHeaterKg, fcCorr.FcBusAuxEletcricHeater.Value(), 1e-6, "expectedFcElectricHeater"); + Assert.AreEqual(expectedAuxHeatingDemandJ, corrected.AuxHeaterDemand.Value(), 1e-1, "expectedAuxHeatingDemand"); + Assert.AreEqual(expectedFcAuxHeaterKg, fcCorr.FcAuxHtr.Value(), 1e-6, "expectedFcAuxHeater"); + + var expectedFc = fuelConsumptionKg + expectedFcHPHeatingElKg + expectedFcHPHeatingMechKg + + expectedFcElectricHeaterKg + expectedFcAuxHeaterKg; + Assert.AreEqual(expectedFc, fcCorr.TotalFuelConsumptionCorrected.Value(), 1e-6, "TotalFuelConsumptionCorrected"); + } + + // ========================================= + // ========================================= + + public void TestModDataPostprocessing(BusHVACSystemConfiguration cfg, HeatPumpType driverHpHeating, + HeatPumpType passengerHpHeating, HeaterType heater, double fuelConsumptionKg, double auxhHeaterPwr, + double expectedHpHeatingElPwrMechW, double expectedFcHPHeatingElKg, double expectedHpHeatingMechPwrW, + double expectedFcHPHeatingMechKg, + double expectedElectricHeaterPwrW, double expectedFcElectricHeaterKg, double expectedAuxHeatingDemandJ, + double expectedFcAuxHeaterKg, IModalDataPostProcessor correction) + { + + var busAux = GetAuxParametersConventionalSingleDeckForTest(cfg, driverHeatPumpHeating: driverHpHeating, + passengerHeatPumpHeating: passengerHpHeating, auxHeaterPower: auxhHeaterPwr.SI<Watt>(), electricHeater:heater); var runData = GetVectoRunDataConventional(busAux); - var mockModData = GetConventionalMockModData(runData, fuelConsumptionKg.SI<Kilogram>()); + var mockModData = GetMockModData(runData, fuelConsumptionKg.SI<Kilogram>()); var corrected = correction.ApplyCorrection(mockModData, runData); + var duration = mockModData.Duration.Value(); Assert.NotNull(corrected); var fcCorr = corrected.FuelConsumptionCorrection(Fuel) as FuelConsumptionCorrection; Assert.NotNull(fcCorr); - Console.WriteLine($"{corrected.AuxHeaterDemand.Value()}, {fcCorr.FcAuxHtr.Value()}"); + Console.WriteLine(new[] { (corrected.WorkBusAuxHeatPumpHeatingElMech / duration).Value().ToString("F3"), + fcCorr.FcHeatPumpHeatingEl.Value().ToString("F6"), + (corrected.WorkBusAuxHeatPumpHeatingMech.Value() / duration).ToString("F3"), + fcCorr.FcHeatPumpHeatingMech.Value().ToString("F6"), + (corrected.WorkBusAuxElectricHeater / duration).Value().ToString("F3"), + fcCorr.FcBusAuxEletcricHeater.Value().ToString("F6"), + corrected.AuxHeaterDemand.Value().ToString("F1"), + fcCorr.FcAuxHtr.Value().ToString("F6") + }.Join(", ")); - Assert.AreEqual(expectedAuxHeatingDemandJ, corrected.AuxHeaterDemand.Value(), 1e-3, "expectedAuxHeatingDemand"); + Assert.AreEqual(expectedHpHeatingElPwrMechW, (corrected.WorkBusAuxHeatPumpHeatingElMech / duration).Value(), 1e-3, "Heatpump Power El Mech"); + Assert.AreEqual(expectedHpHeatingMechPwrW, (corrected.WorkBusAuxHeatPumpHeatingMech / duration).Value(), 1e-3, "Heatpump Power Mech"); + Assert.AreEqual(expectedFcHPHeatingElKg, fcCorr.FcHeatPumpHeatingEl.Value(), 1e-6, "FC heatpump heating El"); + Assert.AreEqual(expectedFcHPHeatingMechKg, fcCorr.FcHeatPumpHeatingMech.Value(), 1e-6, "FC heatpump heating Mech"); + Assert.AreEqual(expectedElectricHeaterPwrW, (corrected.WorkBusAuxElectricHeater / duration).Value(), 1e-3, "expectedElectricHeaterDemand"); + Assert.AreEqual(expectedFcElectricHeaterKg, fcCorr.FcBusAuxEletcricHeater.Value(), 1e-6, "expectedFcElectricHeater"); + Assert.AreEqual(expectedAuxHeatingDemandJ, corrected.AuxHeaterDemand.Value(), 1e-1, "expectedAuxHeatingDemand"); Assert.AreEqual(expectedFcAuxHeaterKg, fcCorr.FcAuxHtr.Value(), 1e-6, "expectedFcAuxHeater"); + + var expectedFc = fuelConsumptionKg + expectedFcHPHeatingElKg + expectedFcHPHeatingMechKg + + expectedFcElectricHeaterKg + expectedFcAuxHeaterKg; + Assert.AreEqual(expectedFc, fcCorr.TotalFuelConsumptionCorrected.Value(), 1e-6, "TotalFuelConsumptionCorrected"); } + protected VectoRunData GetVectoRunDataConventional(IAuxiliaryConfig busAux) { var runData = new VectoRunData() { + SimulationType = SimulationType.DistanceCycle, + ExecutionMode = ExecutionMode.Declaration, + Exempted = false, + JobType = VectoSimulationJobType.ConventionalVehicle, DriverData = new DriverData() { EngineStopStart = new DriverData.EngineStopStartData() { UtilityFactorDriving = 0.8, @@ -97,45 +403,205 @@ public class SSMHeatingPostProcessingCorrection ConsumptionMap = FuelConsumptionMapReader.ReadFromStream(FuelMap.ToStream()), }}.ToList(), }, + ElectricMachinesData = new List<Tuple<PowertrainPosition, ElectricMotorData>>(), BusAuxiliaries = busAux }; return runData; } - protected IModalDataContainer GetConventionalMockModData(VectoRunData runData, Kilogram totalFuelConsumption) + protected VectoRunData GetVectoRunDataParallelHybrid(IAuxiliaryConfig busAux) + { + var emData = new Mock<ElectricMotorData>(); + + + var runData = new VectoRunData() { + SimulationType = SimulationType.DistanceCycle, + ExecutionMode = ExecutionMode.Declaration, + Exempted = false, + JobType = VectoSimulationJobType.ParallelHybridVehicle, + DriverData = new DriverData() { + EngineStopStart = new DriverData.EngineStopStartData() { + UtilityFactorDriving = 0.8, + UtilityFactorStandstill = 0.8 + } + }, + EngineData = new CombustionEngineData() { + WHRType = WHRType.None, + IdleSpeed = 600.RPMtoRad(), + Fuels = new[] { new CombustionEngineFuelData() { + FuelData =Fuel, + ConsumptionMap = FuelConsumptionMapReader.ReadFromStream(FuelMap.ToStream()), + }}.ToList(), + }, + ElectricMachinesData = new List<Tuple<PowertrainPosition, ElectricMotorData>>() { + Tuple.Create(PowertrainPosition.HybridP2, emData.Object) + }, + BusAuxiliaries = busAux + }; + return runData; + } + + protected VectoRunData GetVectoRunDataSerialHybrid(IAuxiliaryConfig busAux) + { + var emData = new Mock<ElectricMotorData>(); + var genData = new Mock<ElectricMotorData>(); + + + var runData = new VectoRunData() { + SimulationType = SimulationType.DistanceCycle, + ExecutionMode = ExecutionMode.Declaration, + Exempted = false, + JobType = VectoSimulationJobType.SerialHybridVehicle, + DriverData = new DriverData() { + EngineStopStart = new DriverData.EngineStopStartData() { + UtilityFactorDriving = 0.8, + UtilityFactorStandstill = 0.8 + } + }, + EngineData = new CombustionEngineData() { + WHRType = WHRType.None, + IdleSpeed = 600.RPMtoRad(), + Fuels = new[] { new CombustionEngineFuelData() { + FuelData =Fuel, + ConsumptionMap = FuelConsumptionMapReader.ReadFromStream(FuelMap.ToStream()), + }}.ToList(), + }, + ElectricMachinesData = new List<Tuple<PowertrainPosition, ElectricMotorData>>() { + Tuple.Create(PowertrainPosition.BatteryElectricE2, emData.Object), + Tuple.Create(PowertrainPosition.GEN, genData.Object), + }, + BusAuxiliaries = busAux + }; + return runData; + } + + protected VectoRunData GetVectoRunDataBatteryElectric(IAuxiliaryConfig busAux) + { + var emData = new Mock<ElectricMotorData>(); + + var runData = new VectoRunData() { + SimulationType = SimulationType.DistanceCycle, + ExecutionMode = ExecutionMode.Declaration, + Exempted = false, + JobType = VectoSimulationJobType.BatteryElectricVehicle, + DriverData = new DriverData() { + EngineStopStart = new DriverData.EngineStopStartData() { + UtilityFactorDriving = 0.8, + UtilityFactorStandstill = 0.8 + } + }, + //EngineData = new CombustionEngineData() { + // WHRType = WHRType.None, + // IdleSpeed = 600.RPMtoRad(), + // Fuels = new[] { new CombustionEngineFuelData() { + // FuelData =Fuel, + // ConsumptionMap = FuelConsumptionMapReader.ReadFromStream(FuelMap.ToStream()), + // }}.ToList(), + //}, + ElectricMachinesData = new List<Tuple<PowertrainPosition, ElectricMotorData>>() { + Tuple.Create(PowertrainPosition.BatteryElectricE2, emData.Object), + }, + BusAuxiliaries = busAux + }; + return runData; + } + + protected IModalDataContainer GetMockModData(VectoRunData runData, Kilogram totalFuelConsumption = null, WattSecond emLoss = null, WattSecond genLoss = null) { var mockContainer = new Mock<IVehicleContainer>(); - var eng = new Mock<IEngineInfo>(); - eng.Setup(e => e.EngineIdleSpeed).Returns(runData.EngineData.IdleSpeed); + if (runData.JobType != VectoSimulationJobType.BatteryElectricVehicle) { + var eng = new Mock<IEngineInfo>(); + eng.Setup(e => e.EngineIdleSpeed).Returns(runData.EngineData.IdleSpeed); + mockContainer.Setup(c => c.EngineInfo).Returns(eng.Object); + } else { + var eng = new Mock<IEngineInfo>(); + eng.Setup(e => e.EngineIdleSpeed).Returns(100.RPMtoRad()); + mockContainer.Setup(c => c.EngineInfo).Returns(eng.Object); + } - //mockContainer.Setup(c => c.ModalData).Returns(m.Object); - mockContainer.Setup(c => c.EngineInfo).Returns(eng.Object); var busAux = new BusAuxiliariesAdapter(mockContainer.Object, runData.BusAuxiliaries); var m = new Mock<IModalDataContainer>(); m.Setup(x => x.Duration).Returns(3600.SI<Second>()); m.Setup(x => x.Distance).Returns(30000.SI<Meter>()); - m.Setup(x => x.TimeIntegral<WattSecond>(ModalResultField.P_WHR_el_corr, null)).Returns(0.SI<WattSecond>()); - m.Setup(x => x.TimeIntegral<WattSecond>(ModalResultField.P_WHR_mech_corr, null)).Returns(0.SI<WattSecond>()); + if (totalFuelConsumption != null) { + m.Setup(x => x.TimeIntegral<WattSecond>(ModalResultField.P_WHR_el_corr, null)).Returns(0.SI<WattSecond>()); + m.Setup(x => x.TimeIntegral<WattSecond>(ModalResultField.P_WHR_mech_corr, null)).Returns(0.SI<WattSecond>()); + m.Setup(x => x.TimeIntegral<WattSecond>(ModalResultField.P_ice_start, null)).Returns(0.SI<WattSecond>()); + m.Setup(x => x.FuelData).Returns(new IFuelProperties[] { Fuel }); + m.Setup(x => x.TimeIntegral<Kilogram>(It.IsIn(Fuel.FuelType.GetLabel()), null)).Returns<string, Func<SI, bool>>((f,_) => totalFuelConsumption); + m.Setup(x => x.GetColumnName(It.IsNotNull<IFuelProperties>(), It.IsNotNull<ModalResultField>())) + .Returns<IFuelProperties, ModalResultField>((f, m) => f.GetLabel()); + m.Setup(x => x.EngineLineCorrectionFactor(It.IsIn(Fuel))) + .Returns(15.SI(Unit.SI.Gramm.Per.Kilo.Watt.Hour).Cast<KilogramPerWattSecond>()); + } m.Setup(x => x.TimeIntegral<WattSecond>(ModalResultField.P_busAux_ES_consumer_sum, null)) .Returns(0.SI<WattSecond>()); m.Setup(x => x.TimeIntegral<WattSecond>(ModalResultField.P_busAux_ES_generated, null)) .Returns(0.SI<WattSecond>()); - m.Setup(x => x.TimeIntegral<WattSecond>(ModalResultField.P_ice_start, null)).Returns(0.SI<WattSecond>()); m.Setup(x => x.GetValues<NormLiter>(ModalResultField.Nl_busAux_PS_generated)).Returns(new[] { 2470.5180.SI<NormLiter>() }); - m.Setup(x => x.FuelData).Returns(new IFuelProperties[] { Fuel }); - m.Setup(x => x.TimeIntegral<Kilogram>(It.IsIn(Fuel.FuelType.GetLabel()), null)).Returns<string, Func<SI, bool>>((f,_) => totalFuelConsumption); - m.Setup(x => x.GetColumnName(It.IsNotNull<IFuelProperties>(), It.IsNotNull<ModalResultField>())) - .Returns<IFuelProperties, ModalResultField>((f, m) => f.GetLabel()); - m.Setup(x => x.EngineLineCorrectionFactor(It.IsIn(Fuel))) - .Returns(200.SI(Unit.SI.Kilo.Gramm.Per.Kilo.Watt.Hour).Cast<KilogramPerWattSecond>()); m.Setup(x => x.AuxHeaterDemandCalc).Returns(busAux.AuxHeaterDemandCalculation); + if (!runData.JobType.IsOneOf(VectoSimulationJobType.ConventionalVehicle, + VectoSimulationJobType.EngineOnlySimulation) + && !runData.ElectricMachinesData.Any()) { + throw new VectoException("hybrid vehicle requires electric machine"); + } + + if (runData.ElectricMachinesData.Any(x => x.Item1 != PowertrainPosition.GEN)) { + m.Setup(x => x.GetColumnName(It.IsAny<PowertrainPosition>(), It.IsAny<ModalResultField>())) + .Returns<PowertrainPosition, ModalResultField>((pos, mrf) => + string.Format(mrf.GetCaption(), pos.GetName())); + var emPos = runData.ElectricMachinesData.First(x => x.Item1 != PowertrainPosition.GEN).Item1; + SetupMockEMotorValues(emLoss, m, emPos); + + if (runData.ElectricMachinesData.Any(x => x.Item1 == PowertrainPosition.GEN)) { + SetupMockEMotorValues(genLoss, m, PowertrainPosition.GEN); + } + } + return m.Object; } + private static void SetupMockEMotorValues(WattSecond emLoss, Mock<IModalDataContainer> m, PowertrainPosition emPos) + { + var colName = m.Object.GetColumnName(emPos, ModalResultField.P_EM_electricMotorLoss_); + if (emPos == PowertrainPosition.IEPC) { + colName = m.Object.GetColumnName(emPos, ModalResultField.P_IEPC_electricMotorLoss_); + } + + m.Setup(x => x.TimeIntegral<WattSecond>(It.Is<string>(c => colName.Equals(c)), null)) + .Returns(emLoss ?? 0.SI<WattSecond>()); + m.Setup(x => x.ElectricMotorEfficiencyDrive(emPos)).Returns(0.94); + m.Setup(x => x.ElectricMotorEfficiencyGenerate(emPos)).Returns(0.92); + SetupMockBatteryValues(m); + } + + private static void SetupMockBatteryValues(Mock<IModalDataContainer> m) + { + var batChgEff = 0.95; + var batDischgEff = 0.93; + var batEnergy = 1000.SI<WattSecond>(); + var batteryEntries = new[] { + // internal , terminal + Tuple.Create(batEnergy, batEnergy / batChgEff), + Tuple.Create(-batEnergy, -batEnergy * batDischgEff) + }; + m.Setup(x => x.TimeIntegral<WattSecond>(ModalResultField.P_reess_int, null)) + .Returns(batteryEntries.Select(x => x.Item1).Sum()); + m.Setup(x => x.TimeIntegral<WattSecond>(ModalResultField.P_reess_int, It.IsAny<Func<SI, bool>>())) + .Returns<ModalResultField, Func<SI, bool>>((_, f) => + batteryEntries.Select(x => x.Item1).Where(x => f == null || f(x)).Sum()); + m.Setup(x => x.TimeIntegral<WattSecond>(ModalResultField.P_reess_terminal, It.IsAny<Func<SI, bool>>())) + .Returns<ModalResultField, + Func<SI, bool>>((_, f) => batteryEntries.Select(x => x.Item2).Where(x => f(x)).Sum()); + + m.Setup(x => x.REESSStartSoC()).Returns(0.5); + m.Setup(x => x.REESSEndSoC()).Returns(0.4); + } + protected IAuxiliaryConfig GetAuxParametersConventionalSingleDeckForTest(BusHVACSystemConfiguration hvacConfig, HeatPumpType? driverHeatpumpCooling = null, HeatPumpType? passengerHeatpumpCooling = null, HeatPumpType? driverHeatPumpHeating = null, HeatPumpType? passengerHeatPumpHeating = null, @@ -162,7 +628,46 @@ public class SSMHeatingPostProcessingCorrection airElectricHeater: electricHeater != null && (electricHeater & HeaterType.AirElectricHeater) != 0, waterElectricHeater: electricHeater != null && (electricHeater & HeaterType.WaterElectricHeater) != 0, otherElectricHeater: electricHeater != null && (electricHeater & HeaterType.OtherElectricHeating) != 0, - hvacConfig, + hvacConfig: hvacConfig, + doubleGlazing: false, + adjustableAuxHeater: false, + separateAirdistributionDicts: false, + adjustableCoolantThermostat: false, + engineWasteGasHeatExchanger: false, + steeringpumps: new[] { "Dual displacement" }, + fanTech: "Crankshaft mounted - Discrete step clutch", + alternatorTech: AlternatorType.Conventional, + entranceHeight: 0.3.SI<Meter>(), + loading: LoadingType.LowLoading); + + } + + protected IAuxiliaryConfig GetAuxParametersParallelHybridSingleDeckForTest(BusHVACSystemConfiguration hvacConfig, HeatPumpType? driverHeatpumpCooling = null, + HeatPumpType? passengerHeatpumpCooling = null, HeatPumpType? driverHeatPumpHeating = null, HeatPumpType? passengerHeatPumpHeating = null, + Watt auxHeaterPower = null, HeaterType? electricHeater = null, int passengerCount = 40, double length = 12, double height = 3) + { + return SSMBusAuxModelParameters.CreateBusAuxInputParameters(MissionType.Urban, + VehicleClass.Class31a, + VectoSimulationJobType.ConventionalVehicle, + VehicleCode.CA, + RegistrationClass.II, + AxleConfiguration.AxleConfig_4x2, + articulated: false, + lowEntry: false, + length: length.SI<Meter>(), + height: height.SI<Meter>(), + width: 2.55.SI<Meter>(), + numPassengersLowerdeck: passengerCount, + numPassengersUpperdeck: 0, + hpHeatingDriver: driverHeatPumpHeating ?? HeatPumpType.none, + hpCoolingDriver: driverHeatpumpCooling ?? HeatPumpType.none, + hpHeatingPassenger: passengerHeatPumpHeating ?? HeatPumpType.none, + hpCoolingPassenger: passengerHeatpumpCooling ?? HeatPumpType.none, + auxHeaterPower: auxHeaterPower ?? 0.SI<Watt>(), + airElectricHeater: electricHeater != null && (electricHeater & HeaterType.AirElectricHeater) != 0, + waterElectricHeater: electricHeater != null && (electricHeater & HeaterType.WaterElectricHeater) != 0, + otherElectricHeater: electricHeater != null && (electricHeater & HeaterType.OtherElectricHeating) != 0, + hvacConfig: hvacConfig, doubleGlazing: false, adjustableAuxHeater: false, separateAirdistributionDicts: false, @@ -170,7 +675,9 @@ public class SSMHeatingPostProcessingCorrection engineWasteGasHeatExchanger: false, steeringpumps: new[] { "Dual displacement" }, fanTech: "Crankshaft mounted - Discrete step clutch", - alternatorTech: AlternatorType.Conventional, entranceHeight: 0.3.SI<Meter>()); + alternatorTech: AlternatorType.Conventional, + entranceHeight: 0.3.SI<Meter>(), + loading: LoadingType.LowLoading); } -} \ No newline at end of file +} diff --git a/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMTestHeatingCooling.cs b/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMTestHeatingCooling.cs index 4a892800f96e98288316275524b397d25b3891dd..1322c1c43813cb2cfa794c739b7a6bc4d2d11110 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMTestHeatingCooling.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/BusAux/SSMTestHeatingCooling.cs @@ -1601,7 +1601,7 @@ public class SSMTestHeatingCooling airElectricHeater: electricHeater != null && (electricHeater & HeaterType.AirElectricHeater) != 0, waterElectricHeater: electricHeater != null && (electricHeater & HeaterType.WaterElectricHeater) != 0, otherElectricHeater: electricHeater != null && (electricHeater & HeaterType.OtherElectricHeating) != 0, - hvacConfig, + hvacConfig: hvacConfig, doubleGlazing: false, adjustableAuxHeater: false, separateAirdistributionDicts: false, @@ -1609,7 +1609,9 @@ public class SSMTestHeatingCooling engineWasteGasHeatExchanger: false, steeringpumps: new[] { "Dual displacement" }, fanTech: "Crankshaft mounted - Discrete step clutch", - alternatorTech: AlternatorType.Conventional, entranceHeight: 0.3.SI<Meter>()); + alternatorTech: AlternatorType.Conventional, + entranceHeight: 0.3.SI<Meter>(), + loading: LoadingType.ReferenceLoad); } diff --git a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs index 187ddf2d5b61bfffe6b534423bdeb10bb500ffa5..bb04d8443ca357ede31b98db9e6cc0c454a34267 100644 --- a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs @@ -38,6 +38,7 @@ using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.BusAuxiliaries.Interfaces; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; @@ -231,6 +232,11 @@ namespace TUGraz.VectoCore.Tests.Utils } } + public string GetColumnName(PowertrainPosition pos, ModalResultField mrf) + { + return string.Format(mrf.GetCaption(), pos.GetName()); + } + public void Reset() { @@ -240,7 +246,7 @@ namespace TUGraz.VectoCore.Tests.Utils public Meter Distance => null; - public Func<Second, Joule, Joule> AuxHeaterDemandCalc { get; set; } + public Func<Second, Joule, Joule, HeaterDemandResult> AuxHeaterDemandCalc { get; set; } public KilogramPerWattSecond EngineLineCorrectionFactor(IFuelProperties fuel) { diff --git a/VectoMockup/VectoMockup/MockupModalDataContainer.cs b/VectoMockup/VectoMockup/MockupModalDataContainer.cs index c5ddedd060b2972d1097bbf27746368bb0c35f82..00a0aa8ba8cc70ffa2ac370112bc60df5a14a579 100644 --- a/VectoMockup/VectoMockup/MockupModalDataContainer.cs +++ b/VectoMockup/VectoMockup/MockupModalDataContainer.cs @@ -4,6 +4,7 @@ using System.Data; using TUGraz.VectoCommon.BusAuxiliaries; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.BusAuxiliaries.Interfaces; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; using TUGraz.VectoCore.OutputData; @@ -43,6 +44,7 @@ namespace TUGraz.VectoMockup { private IModalDataContainer _modalDataContainerImplementation; private readonly Action<IModalDataContainer> _addReportResult; + private Func<Second, Joule, Joule, HeaterDemandResult> _auxHeaterDemandCalc; public MockupModalDataContainer(IModalDataContainer modalDataContainer, Action<IModalDataContainer> addReportResult) @@ -57,6 +59,11 @@ namespace TUGraz.VectoMockup public Second Duration => 1.SI(Unit.SI.Hour).Cast<Second>(); public Meter Distance => 100.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + Func<Second, Joule, Joule, HeaterDemandResult> IModalDataContainer.AuxHeaterDemandCalc + { + get => _auxHeaterDemandCalc; + set => _auxHeaterDemandCalc = value; + } #endregion @@ -162,6 +169,11 @@ namespace TUGraz.VectoMockup return _modalDataContainerImplementation.GetColumnName(fuelData, mrf); } + public string GetColumnName(PowertrainPosition pos, ModalResultField mrf) + { + return _modalDataContainerImplementation.GetColumnName(pos, mrf); + } + public void Reset() { _modalDataContainerImplementation.Reset(); @@ -169,7 +181,7 @@ namespace TUGraz.VectoMockup - public Func<Second, Joule, Joule> AuxHeaterDemandCalc + public Func<Second, Joule, Joule, HeaterDemandResult> AuxHeaterDemandCalc { get => _modalDataContainerImplementation.AuxHeaterDemandCalc; set => _modalDataContainerImplementation.AuxHeaterDemandCalc = value;