From baf362832c5ff85106c1fa468fd8c7eab3b80715 Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <Markus.Quaritsch@tugraz.at>
Date: Thu, 26 Mar 2020 11:15:11 +0100
Subject: [PATCH] hybrid controller works on simple cycle with gearshifting

---
 .../VectoCommon/Models/PowertrainPosition.cs  |  5 ++
 .../Simulation/Data/ModalResultField.cs       | 26 +++----
 .../IHybridControlStrategy.cs                 |  1 +
 .../Impl/HybridController.cs                  |  7 +-
 .../DelegateParallelHybridStrategy.cs         |  7 ++
 .../Strategies/HybridStrategy.cs              |  5 ++
 .../OutputData/ModalDataContainer.cs          | 75 ++++++++++++-------
 .../Integration/Hybrid/ParallelHybridTest.cs  | 42 +++++++++--
 8 files changed, 121 insertions(+), 47 deletions(-)

diff --git a/VectoCommon/VectoCommon/Models/PowertrainPosition.cs b/VectoCommon/VectoCommon/Models/PowertrainPosition.cs
index de65b8ae9c..1d5f6fb91a 100644
--- a/VectoCommon/VectoCommon/Models/PowertrainPosition.cs
+++ b/VectoCommon/VectoCommon/Models/PowertrainPosition.cs
@@ -18,5 +18,10 @@ namespace TUGraz.VectoCommon.InputData {
 		{
 			return (Prefix + pos).ParseEnum<PowertrainPosition>();
 		}
+
+		public static string GetName(this PowertrainPosition pos)
+		{
+			return pos.ToString().Replace(Prefix, "");
+		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs
index 10a6ce6264..ec8244206d 100644
--- a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs
@@ -374,19 +374,19 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
 		[ModalResultField(typeof(SI), "P_WHR_mech [kW]", outputFactor: 1e-3)] P_WHR_mech_map,
 		[ModalResultField(typeof(SI), "P_WHR_mech_corr [kW]", outputFactor: 1e-3)] P_WHR_mech_corr,
 
-		[ModalResultField(typeof(SI), caption: "n_em{0}_avg [1/min]", outputFactor: 60 / (2 * Math.PI))] n_electricMotor_,
-		[ModalResultField(typeof(SI), caption: "T_em{0} [Nm]")] T_electricMotor_,
-		[ModalResultField(typeof(SI), caption: "T_em{0}_full [Nm]")] T_electricMotor_full_,
-		[ModalResultField(typeof(SI), caption: "T_em{0}_drag [Nm]")] T_electricMotor_drag_,
-		[ModalResultField(typeof(SI), caption: "P_em{0}_in [kW]", outputFactor: 1e-3)] P_electricMotor_in_,
-		[ModalResultField(typeof(SI), caption: "P_em{0}_out [kW]", outputFactor: 1e-3)] P_electricMotor_out_,
-		[ModalResultField(typeof(SI), caption: "P_em{0}_mech [kW]", outputFactor: 1e-3)] P_electricMotor_mech_,
-		[ModalResultField(typeof(SI), caption: "P_em{0}_el [kW]", outputFactor: 1e-3)] P_electricMotor_el_,
-		[ModalResultField(typeof(SI), caption: "P_em{0}_drag_max_ [kW]", outputFactor: 1e-3)] P_electricMotor_drag_max_,
-		[ModalResultField(typeof(SI), caption: "P_em{0}_drive_max [kW]", outputFactor: 1e-3)] P_electricMotor_drive_max_,
-		[ModalResultField(typeof(SI), caption: "P_em{0}_brake [kW]", outputFactor: 1e-3)] P_electricMotor_brake_,
-		[ModalResultField(typeof(SI), caption: "P_em{0}_loss [kW]", outputFactor: 1e-3)] P_electricMotorLoss_,
-		[ModalResultField(typeof(SI), caption: "P_em{0}_inertia_loss [kW]", outputFactor: 1e-3)] P_electricMotorInertiaLoss_,
+		[ModalResultField(typeof(SI), caption: "n_em-{0}_avg [1/min]", outputFactor: 60 / (2 * Math.PI))] n_electricMotor_,
+		[ModalResultField(typeof(SI), caption: "T_em-{0} [Nm]")] T_electricMotor_,
+		[ModalResultField(typeof(SI), caption: "T_em-{0}_full [Nm]")] T_electricMotor_full_,
+		[ModalResultField(typeof(SI), caption: "T_em-{0}_drag [Nm]")] T_electricMotor_drag_,
+		[ModalResultField(typeof(SI), caption: "P_em-{0}_in [kW]", outputFactor: 1e-3)] P_electricMotor_in_,
+		[ModalResultField(typeof(SI), caption: "P_em-{0}_out [kW]", outputFactor: 1e-3)] P_electricMotor_out_,
+		[ModalResultField(typeof(SI), caption: "P_em-{0}_mech [kW]", outputFactor: 1e-3)] P_electricMotor_mech_,
+		[ModalResultField(typeof(SI), caption: "P_em-{0}_el [kW]", outputFactor: 1e-3)] P_electricMotor_el_,
+		[ModalResultField(typeof(SI), caption: "P_em-{0}_drag_max_ [kW]", outputFactor: 1e-3)] P_electricMotor_drag_max_,
+		[ModalResultField(typeof(SI), caption: "P_em-{0}_drive_max [kW]", outputFactor: 1e-3)] P_electricMotor_drive_max_,
+		[ModalResultField(typeof(SI), caption: "P_em-{0}_brake [kW]", outputFactor: 1e-3)] P_electricMotor_brake_,
+		[ModalResultField(typeof(SI), caption: "P_em-{0}_loss [kW]", outputFactor: 1e-3)] P_electricMotorLoss_,
+		[ModalResultField(typeof(SI), caption: "P_em-{0}_inertia_loss [kW]", outputFactor: 1e-3)] P_electricMotorInertiaLoss_,
 
 		[ModalResultField(typeof(SI), caption: "P_bat_T [kW]", outputFactor: 1e-3)] P_battery_terminal,
 		[ModalResultField(typeof(SI), caption: "P_bat_int [kW]", outputFactor: 1e-3)] P_battery_int,
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs
index 9955b9e13c..8193d17a1e 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/IHybridControlStrategy.cs
@@ -16,5 +16,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 	{
 		HybridStrategyResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, bool dryRun);
 		HybridStrategyResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity);
+		void CommitSimulationStep();
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
index 84c166dbcf..091c127416 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
@@ -63,7 +63,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			bool dryRun = false)
 		{
 			CurrentState.StrategyResponse = Strategy.Request(absTime, dt, outTorque, outAngularVelocity, dryRun);
-			return NextComponent.Request(absTime, dt, outTorque, outAngularVelocity);
+			return NextComponent.Request(absTime, dt, outTorque, outAngularVelocity, dryRun);
 		}
 
 		public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
@@ -72,6 +72,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			return NextComponent.Initialize(outTorque, outAngularVelocity);
 		}
 
+		protected override void DoCommitSimulationStep()
+		{
+			base.DoCommitSimulationStep();
+			Strategy.CommitSimulationStep();
+		}
 
 		protected override void DoWriteModalResults(Second time, Second simulationInterval,
 			IModalDataContainer container) { }
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/DelegateParallelHybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/DelegateParallelHybridStrategy.cs
index 1af43d6db2..b4cd9ff212 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/DelegateParallelHybridStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/DelegateParallelHybridStrategy.cs
@@ -10,6 +10,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 		public Func<NewtonMeter, PerSecond, HybridStrategyResponse> InitializeFunc { get; set; }
 		public Func<Second, Second, NewtonMeter, PerSecond, bool, HybridStrategyResponse> RequestFunc { get; set; }
 
+		public Action CommitFunc { get; set; }
+
 		public HybridStrategyResponse Request(Second absTime, Second dt, NewtonMeter outTorque,
 			PerSecond outAngularVelocity, bool dryRun)
 		{
@@ -21,5 +23,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 		{
 			return InitializeFunc(outTorque, outAngularVelocity);
 		}
+
+		public void CommitSimulationStep()
+		{
+			CommitFunc();
+		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
index 6b3b76c7cc..40a2c1452c 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Strategies/HybridStrategy.cs
@@ -25,6 +25,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Strategies
 			return new HybridStrategyResponse()
 				{ MechanicalAssistPower = new Dictionary<PowertrainPosition, NewtonMeter>() };
 		}
+
+		public void CommitSimulationStep()
+		{
+			
+		}
 	}
 
 	
diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs
index 1f3fb55d89..f4a75d388d 100644
--- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs
+++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs
@@ -43,6 +43,7 @@ using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Models.Declaration;
 using TUGraz.VectoCore.Models.Simulation.Data;
 using TUGraz.VectoCore.Models.Simulation.Impl;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl;
 
 namespace TUGraz.VectoCore.OutputData
 {
@@ -62,6 +63,16 @@ namespace TUGraz.VectoCore.OutputData
 		private Second _duration;
 		private Meter _distance;
 
+		private readonly ModalResultField[] _electricMotorColumns = new[] {
+			ModalResultField.n_electricMotor_, ModalResultField.T_electricMotor_,
+			ModalResultField.T_electricMotor_full_, ModalResultField.T_electricMotor_drag_,
+			ModalResultField.P_electricMotor_in_, ModalResultField.P_electricMotor_out_,
+			ModalResultField.P_electricMotor_mech_, ModalResultField.P_electricMotor_el_,
+			ModalResultField.P_electricMotorLoss_, ModalResultField.P_electricMotorInertiaLoss_,
+			ModalResultField.P_electricMotor_brake_, ModalResultField.P_electricMotor_drive_max_,
+			ModalResultField.P_electricMotor_drag_max_
+		};
+
 		public static readonly IList<ModalResultField> FuelConsumptionSignals = new[] {
 			ModalResultField.FCMap, ModalResultField.FCNCVc, ModalResultField.FCWHTCc, // ModalResultField.FCAAUX,
 			ModalResultField.FCICEStopStart,  ModalResultField.FCFinal
@@ -69,6 +80,7 @@ namespace TUGraz.VectoCore.OutputData
 
 		private readonly Dictionary<String, SI> _timeIntegrals = new Dictionary<string, SI>();
 		private readonly Dictionary<FuelType, KilogramPerWattSecond> _vehicleLine = new Dictionary<FuelType, KilogramPerWattSecond>();
+		private List<PowertrainPosition> ElectricMotors = new List<PowertrainPosition>();
 
 		public int JobRunId { get; }
 		public string RunName { get; }
@@ -231,18 +243,9 @@ namespace TUGraz.VectoCore.OutputData
 
 		public void AddElectricMotor(PowertrainPosition pos)
 		{
-			var electricMotorColumns = new[] {
-				ModalResultField.n_electricMotor_, ModalResultField.T_electricMotor_,
-				ModalResultField.T_electricMotor_full_, ModalResultField.T_electricMotor_drag_,
-				ModalResultField.P_electricMotor_in_, ModalResultField.P_electricMotor_out_,
-				ModalResultField.P_electricMotor_mech_, ModalResultField.P_electricMotor_el_,
-				ModalResultField.P_electricMotorLoss_, ModalResultField.P_electricMotorInertiaLoss_,
-				ModalResultField.P_electricMotor_brake_, ModalResultField.P_electricMotor_drive_max_,
-				ModalResultField.P_electricMotor_drag_max_
-			};
-			foreach (var entry in electricMotorColumns)
-			{
-				var col = Data.Columns.Add(string.Format(entry.GetAttribute().Caption, pos.ToString()), typeof(SI));
+			ElectricMotors.Add(pos);
+			foreach (var entry in _electricMotorColumns)  {
+				var col = Data.Columns.Add(string.Format(entry.GetAttribute().Caption, pos.GetName()), typeof(SI));
 				col.ExtendedProperties[ModalResults.ExtendedPropertyNames.Decimals] =
 					entry.GetAttribute().Decimals;
 				col.ExtendedProperties[ModalResults.ExtendedPropertyNames.OutputFactor] =
@@ -308,8 +311,7 @@ namespace TUGraz.VectoCore.OutputData
 
 			var dataColumns = GetOutputColumns();
 
-			var strCols = dataColumns.Select(x => x.GetName())
-									.Concat(Auxiliaries.Values.Select(c => c.ColumnName))
+			var strCols = dataColumns.Concat(Auxiliaries.Values.Select(c => c.ColumnName))
 									.Concat(
 										new[] {
 											ModalResultField.P_WHR_el_map, ModalResultField.P_WHR_el_corr, ModalResultField.P_WHR_mech_map, ModalResultField.P_WHR_mech_corr, ModalResultField.P_aux_ice_off,
@@ -342,9 +344,9 @@ namespace TUGraz.VectoCore.OutputData
 			_addReportResult(this);
 		}
 
-		private IList<ModalResultField> GetOutputColumns()
+		private IList<string> GetOutputColumns()
 		{
-			var dataColumns = new List<ModalResultField> { ModalResultField.time };
+			var dataColumns = new List<string> { ModalResultField.time.GetName() };
 
 			if (!_writeEngineOnly) {
 				dataColumns.AddRange(
@@ -356,15 +358,15 @@ namespace TUGraz.VectoCore.OutputData
 						ModalResultField.acc,
 						ModalResultField.grad,
 						ModalResultField.altitude
-			});
+			}.Select(x => x.GetName()));
 			}
 			if (!_writeEngineOnly) {
 				dataColumns.AddRange(
 					new[] {
 						ModalResultField.Gear,
-					});
+					}.Select(x => x.GetName()));
 				if (HasTorqueConverter) {
-					dataColumns.AddRange(new[] { ModalResultField.TC_Locked });
+					dataColumns.AddRange(new[] { ModalResultField.TC_Locked }.Select(x => x.GetName()));
 				}
 			}
 			dataColumns.AddRange(
@@ -379,25 +381,42 @@ namespace TUGraz.VectoCore.OutputData
 					ModalResultField.P_ice_drag,
 					ModalResultField.P_ice_inertia,
 					ModalResultField.P_ice_out,
-				});
+				}.Select(x => x.GetName()));
+			if (ElectricMotors.Count > 0) {
+				dataColumns.AddRange(new[] {
+					ModalResultField.P_battery_terminal,
+					ModalResultField.P_battery_int,
+					ModalResultField.P_battery_loss,
+					ModalResultField.P_battery_charge_max,
+					ModalResultField.P_battery_discharge_max,
+					ModalResultField.BatteryStateOfCharge,
+					ModalResultField.U_bat_terminal,
+					ModalResultField.U0_bat,
+					ModalResultField.I_bat
+				}.Select(x => x.GetName()));
+				foreach (var em in ElectricMotors.OrderBy(x => x).Reverse()) {
+					dataColumns.AddRange(_electricMotorColumns.Select(emCol =>
+						string.Format(emCol.GetAttribute().Caption, em.GetName())));
+				}
+			}
 			if (HasTorqueConverter) {
 				dataColumns.AddRange(
 					new[] {
 						ModalResultField.P_gbx_shift_loss,
 						ModalResultField.P_TC_loss,
 						ModalResultField.P_TC_out,
-					});
+					}.Select(x => x.GetName()));
 			} else {
 				dataColumns.AddRange(
 					new[] {
 						ModalResultField.P_clutch_loss,
 						ModalResultField.P_clutch_out,
-					});
+					}.Select(x => x.GetName()));
 			}
 			dataColumns.AddRange(
 				new[] {
 					ModalResultField.P_aux_mech
-				});
+				}.Select(x => x.GetName()));
 
 			if (!_writeEngineOnly) {
 				dataColumns.AddRange(
@@ -422,7 +441,7 @@ namespace TUGraz.VectoCore.OutputData
 						ModalResultField.P_veh_inertia,
 						ModalResultField.n_gbx_out_avg,
 						ModalResultField.T_gbx_out
-					});
+					}.Select(x => x.GetName()));
 				if (WriteAdvancedAux) {
 					dataColumns.AddRange(
 						new[] {
@@ -441,7 +460,7 @@ namespace TUGraz.VectoCore.OutputData
 							ModalResultField.P_busAux_PS_generated,
 							ModalResultField.P_busAux_PS_generated_alwaysOn,
 							ModalResultField.P_busAux_PS_generated_dragOnly,
-						});
+						}.Select(x => x.GetName()));
 				}
 				if (HasTorqueConverter) {
 					dataColumns.AddRange(
@@ -452,7 +471,7 @@ namespace TUGraz.VectoCore.OutputData
 							ModalResultField.TC_angularSpeedOut,
 							ModalResultField.TC_TorqueIn,
 							ModalResultField.TC_angularSpeedIn,
-						});
+						}.Select(x => x.GetName()));
 				}
 			}
 			//if (!_writeEngineOnly && WriteAdvancedAux) {
@@ -546,8 +565,8 @@ namespace TUGraz.VectoCore.OutputData
 
 		public object this[ModalResultField key, PowertrainPosition pos]
 		{
-			get { return CurrentRow[string.Format(key.GetCaption(), pos.ToString())]; }
-			set { CurrentRow[string.Format(key.GetCaption(), pos)] = value; }
+			get { return CurrentRow[string.Format(key.GetCaption(), pos.GetName())]; }
+			set { CurrentRow[string.Format(key.GetCaption(), pos.GetName())] = value; }
 		}
 
 		public object this[string auxId]
diff --git a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
index 5614fe85c3..7723974f97 100644
--- a/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
+++ b/VectoCore/VectoCoreTest/Integration/Hybrid/ParallelHybridTest.cs
@@ -52,7 +52,11 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 				@"   0,   0, 0,    3
 				   700, {0}, 0,    0", vmax);
 			var cycle = SimpleDrivingCycles.CreateCycleData(cycleData);
+			RunHybridSimulation(vmax, initialSoC, electricTorque, cycle);
+		}
 
+		public void RunHybridSimulation(double vmax, double initialSoC, double electricTorque, DrivingCycleData cycle) 
+		{
 			const bool largeMotor = true;
 			var run = CreateEngineeringRun(
 				cycle, string.Format("SimpleParallelHybrid_acc_{0}_{2}-{1}.vmod", vmax, initialSoC, electricTorque), initialSoC,
@@ -65,16 +69,37 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 
 			var modData = ((ModalDataContainer)((VehicleContainer)run.GetContainer()).ModData).Data;
 
-			strategy.RequestFunc = (a, b, c, d, e) => new HybridStrategyResponse {
-				MechanicalAssistPower = new Dictionary<PowertrainPosition, NewtonMeter>()
-					{ { PowertrainPosition.HybridP2, 0.SI<NewtonMeter>() } },
-				ShiftRequired = run.GetContainer().EngineSpeed > 1600.RPMtoRad() || run.GetContainer().EngineSpeed < 680.RPMtoRad(),
-				NextGear = (uint)(run.GetContainer().Gear + (run.GetContainer().EngineSpeed > 1600.RPMtoRad() ?  1 : (run.GetContainer().EngineSpeed < 680.RPMtoRad() ? -1 : 0)))
+			var nextState = new StrategyState();
+			var currentState = new StrategyState();
+			strategy.RequestFunc = (absTime, b, c, d, dryRun) => {
+				var shiftAllowed =  absTime > currentState.lastGearShift + 2.SI<Second>();
+				var triggerGearshift = shiftAllowed && ( run.GetContainer().EngineSpeed > 1600.RPMtoRad() ||
+										run.GetContainer().EngineSpeed < 625.RPMtoRad());
+				//var nextGear = run.GetContainer().Gear;
+				if (!dryRun && triggerGearshift) {
+					nextState.lastGearShift = absTime;
+					nextState.nextGear = (uint)(run.GetContainer().Gear + (run.GetContainer().EngineSpeed > 1600.RPMtoRad()
+						? 1
+						: (run.GetContainer().EngineSpeed < 625.RPMtoRad() ? -1 : 0)));
+				}
+				return new HybridStrategyResponse {
+					MechanicalAssistPower = new Dictionary<PowertrainPosition, NewtonMeter>()
+						{ { PowertrainPosition.HybridP2, 0.SI<NewtonMeter>() } },
+					ShiftRequired = triggerGearshift,
+					NextGear = nextState.nextGear
+				};
 			};
 			strategy.InitializeFunc = (a, b) => new HybridStrategyResponse {
 				MechanicalAssistPower = new Dictionary<PowertrainPosition, NewtonMeter>()
 					{ { PowertrainPosition.HybridP2, 0.SI<NewtonMeter>() } }
 			};
+			strategy.CommitFunc = () => {
+				currentState = nextState;
+				nextState = new StrategyState() {
+					lastGearShift = currentState.lastGearShift,
+					nextGear = currentState.nextGear,
+				};
+			};
 
 			run.Run();
 			Assert.IsTrue(run.FinishedWithoutErrors);
@@ -82,6 +107,13 @@ namespace TUGraz.VectoCore.Tests.Integration.Hybrid
 			Assert.IsTrue(modData.Rows.Count > 0);
 		}
 
+		public class StrategyState
+		{
+			public Second lastGearShift = -double.MaxValue.SI<Second>();
+			public Second requestTstmp = -double.MaxValue.SI<Second>();
+			public uint nextGear = 0u;
+		}
+
 		// =================================================
 
 		public static VectoRun CreateEngineeringRun(DrivingCycleData cycleData, string modFileName, double initialSoc, IHybridControlStrategy hybridStrategy, PowertrainPosition pos, bool largeMotor = false, SummaryDataContainer sumData = null, double pAuxEl = 0)
-- 
GitLab