From a077c50af0226073a17c11fea23300ebcd12f947 Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Thu, 24 Mar 2022 13:11:28 +0100
Subject: [PATCH] refactor electric system to allow multiple chargers (required
 for serial hybrid in case of electric WHR)

---
 .../InputData/Reader/ComponentData/WHRPowerReader.cs  |  2 +-
 .../Models/Simulation/Impl/PowertrainBuilder.cs       |  2 +-
 .../Models/SimulationComponent/ElectricSystem.cs      | 11 +++++++----
 .../SimulationComponent/Impl/PEVAMTShiftStrategy.cs   |  2 +-
 .../SimulationComponent/Strategies/TestPowertrain.cs  |  2 +-
 .../Integration/Hybrid/SerialHybridTest.cs            |  3 +++
 6 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/WHRPowerReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/WHRPowerReader.cs
index b3d870fe0f..6d4dbc4536 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/WHRPowerReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/WHRPowerReader.cs
@@ -49,7 +49,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 
 			// todo mk-2021-08-26 this check is redundant. Previous code would have thrown exception otherwise.
 			if (!headerValid && (type == WHRType.ElectricalOutput || type == WHRType.MechanicalOutputDrivetrain)) {
-				throw new VectoException("expected column headers: {0}", whrColumn.Join());
+				throw new VectoException("expected column headers: {0}", whrColumn);
 			}
 
 			if (!headerValid) {
diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
index fe43bf9718..edf8100c4b 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
@@ -1079,7 +1079,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 			var aux = new ElectricAuxiliary(container);
 			aux.AddConstant("P_aux_el", data.ElectricAuxDemand ?? 0.SI<Watt>());
 			es.Connect(aux);
-			es.Charger = new SimpleCharger();
+			es.Connect(new SimpleCharger());
 
 			var ctl = new DummyElectricMotorControl();
 			var powertrain = vehicle
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/ElectricSystem.cs b/VectoCore/VectoCore/Models/SimulationComponent/ElectricSystem.cs
index 2e3c4eec48..d4903f8f0b 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/ElectricSystem.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/ElectricSystem.cs
@@ -15,16 +15,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 
 		protected readonly List<IElectricAuxPort> Consumers = new List<IElectricAuxPort>();
 
-		protected internal IElectricChargerPort Charger;
+		public IList<IElectricChargerPort> Charger { get;  }
 
 		protected IElectricEnergyStorage Battery;
 
-		public ElectricSystem(IVehicleContainer container) : base(container) { }
+		public ElectricSystem(IVehicleContainer container) : base(container)
+		{
+			Charger = new List<IElectricChargerPort>();
+		}
 
 		public IElectricSystemResponse Request(Second absTime, Second dt, Watt powerDemand, bool dryRun = false)
 		{
 			var auxDemand = Consumers.Sum(x => x.PowerDemand(absTime, dt, dryRun)).DefaultIfNull(0);
-			var chargePower = Charger == null ? 0.SI<Watt>() : Charger.PowerDemand(absTime, dt, powerDemand, auxDemand, dryRun);
+			var chargePower = Charger.Count == 0 ? 0.SI<Watt>() : Charger.Sum(x => x.PowerDemand(absTime, dt, powerDemand, auxDemand, dryRun));
 			var totalPowerDemand = powerDemand + chargePower - auxDemand;
 
 			var batResponse = Battery.MainBatteryPort.Request(absTime, dt, totalPowerDemand, dryRun);
@@ -77,7 +80,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 
 		public void Connect(IElectricChargerPort charger)
 		{
-			Charger = charger;
+			Charger.Add(charger);
 		}
 
 		#endregion
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs
index f15e669cb1..45f7384055 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs
@@ -108,7 +108,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			TestContainerBattery = TestContainer.BatteryInfo as Battery;
 			TestContainerBatterySystem = TestContainer.BatteryInfo as BatterySystem;
 			TestContainerSuperCap = TestContainer.BatteryInfo as SuperCap;
-			TestContainerElectricSystemCharger = (TestContainer.ElectricSystemInfo as ElectricSystem)?.Charger as SimpleCharger;
+			TestContainerElectricSystemCharger = (TestContainer.ElectricSystemInfo as ElectricSystem)?.Charger.FirstOrDefault(x => x is SimpleCharger) as SimpleCharger ;
 			TestContainerElectricMotor =
 				TestContainer.ElectricMotorInfo(PowertrainPosition.BatteryElectricE2) as ElectricMotor;
 			if (TestContainerGbx == null) {
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs
index 71a9ea6a40..be68a2a1b5 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/TestPowertrain.cs
@@ -73,7 +73,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			Clutch = Container.ClutchInfo as Clutch;
 			CombustionEngine = Container.EngineInfo as StopStartCombustionEngine;
 			ElectricMotor = container.ElectricMotors.FirstOrDefault().Value as ElectricMotor;
-			Charger = (ElectricMotor?.ElectricPower as ElectricSystem)?.Charger as GensetChargerAdapter;
+			Charger = ((ElectricMotor?.ElectricPower as ElectricSystem)?.Charger.FirstOrDefault(x => x is GensetChargerAdapter)) as GensetChargerAdapter;
 			foreach (var pos in container.ElectricMotorPositions) {
 				if (pos == PowertrainPosition.HybridP1 || pos == PowertrainPosition.HybridP2 ||
 					pos == PowertrainPosition.HybridP2_5 || pos == PowertrainPosition.HybridP3) {
diff --git a/VectoCore/VectoCoreTest/Integration/Hybrid/SerialHybridTest.cs b/VectoCore/VectoCoreTest/Integration/Hybrid/SerialHybridTest.cs
index a3c3d2d5a3..b4e83ca35e 100644
--- a/VectoCore/VectoCoreTest/Integration/Hybrid/SerialHybridTest.cs
+++ b/VectoCore/VectoCoreTest/Integration/Hybrid/SerialHybridTest.cs
@@ -87,6 +87,9 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 			TestCase(@"TestData\Hybrids\GenericVehicle_S2_APTN\HEV_S2_Group5LH_rl_APTN.vecto", 6, TestName = "Generic Serial Hybrid S2 APT-N 3speed Job, Interurban"),
 			TestCase(@"TestData\Hybrids\GenericVehicle_S2_APTN\HEV_S2_Group5LH_rl_APTN.vecto", 7, TestName = "Generic Serial Hybrid S2 APT-N 3speed Job, Coach"),
 		]
+		[
+			TestCase(@"TestData\Hybrids\GenericVehicle_S2_Job\SerialHybrid_S2_WHR.vecto", 1, TestName = "Generic Serial Hybrid S2 AMT WHR 12speed Job, RegionalDelivery"),
+		]
 		public void S2SerialHybridJob(string jobFile, int runIdx)
 		{
 			RunHybridJob(jobFile, runIdx);
-- 
GitLab