Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit b722903c authored by Markus Quaritsch's avatar Markus Quaritsch
Browse files

writing reess usable and total capacity in MRF and CIF: refactor how this...

writing reess usable and total capacity in MRF and CIF: refactor how this value is calculated. use data adapter to consider all the soc limits, calculate capacity based on stored energy in battery system (initialize batteries to min/max soc)
parent a5c21528
No related branches found
No related tags found
No related merge requests found
Showing
with 99 additions and 41 deletions
...@@ -15,6 +15,10 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData ...@@ -15,6 +15,10 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
{ {
public static InternalResistanceMap Create(DataTable data, bool inputInMiliOhm) public static InternalResistanceMap Create(DataTable data, bool inputInMiliOhm)
{ {
if (data == null) {
// may be null in case it is used to create a temp battery system to calc stored energy
return null;
}
if (!(data.Columns.Count == 2 || data.Columns.Count == 4 || data.Columns.Count == 5)) { if (!(data.Columns.Count == 2 || data.Columns.Count == 4 || data.Columns.Count == 5)) {
throw new VectoException( throw new VectoException(
"Internal Resistance Map data must contain either two, four or five columns: {0}, {1}", "Internal Resistance Map data must contain either two, four or five columns: {0}, {1}",
......
...@@ -52,20 +52,4 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData { ...@@ -52,20 +52,4 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData {
} }
} }
public static class BatteryHelper
{
public static WattSecond TotalUsableCapacityInSimulation(this IBatteryPackDeclarationInputData batteryData)
{
var tmp = BatterySOCReader.Create(batteryData.VoltageCurve);
var voltage = tmp.Lookup(((batteryData.MinSOC ?? 0) + (batteryData.MaxSOC ?? 1)) / 2.0);
return batteryData.Capacity * voltage;
}
public static WattSecond TotalStorageCapacity(this IBatteryPackDeclarationInputData batteryData)
{
var tmp = BatterySOCReader.Create(batteryData.VoltageCurve);
var voltage = tmp.Lookup(((batteryData.MinSOC ?? 0) + (batteryData.MaxSOC ?? 1)) / 2.0);
return batteryData.Capacity * voltage;
}
}
} }
\ No newline at end of file
...@@ -61,6 +61,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen ...@@ -61,6 +61,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
InternalResistance = InternalResistance =
BatteryInternalResistanceReader.Create(b.InternalResistanceCurve, true), BatteryInternalResistanceReader.Create(b.InternalResistanceCurve, true),
SOCMap = BatterySOCReader.Create(b.VoltageCurve), SOCMap = BatterySOCReader.Create(b.VoltageCurve),
InputData = entry
}; };
retVal.Batteries.Add(Tuple.Create(entry.StringId, batteryData)); retVal.Batteries.Add(Tuple.Create(entry.StringId, batteryData));
......
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Exceptions;
using TUGraz.VectoCommon.InputData;
using TUGraz.VectoCommon.Utils; using TUGraz.VectoCommon.Utils;
namespace TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricComponents.Battery { namespace TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricComponents.Battery {
...@@ -60,6 +61,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricComponents.Ba ...@@ -60,6 +61,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricComponents.Ba
public bool ChargeSustainingBattery { get; internal set; } public bool ChargeSustainingBattery { get; internal set; }
public WattSecond UseableStoredEnergy => _useableStoredEnergy ?? (_useableStoredEnergy = CalculateUsableEnergy()); public WattSecond UseableStoredEnergy => _useableStoredEnergy ?? (_useableStoredEnergy = CalculateUsableEnergy());
public IElectricStorageDeclarationInputData InputData { get; internal set; }
protected WattSecond CalculateUsableEnergy() protected WattSecond CalculateUsableEnergy()
{ {
......
...@@ -32,9 +32,9 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport. ...@@ -32,9 +32,9 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport.
{ {
if (inputData is IMultistepBusInputDataProvider multistep) { if (inputData is IMultistepBusInputDataProvider multistep) {
return multistep.JobInputData.PrimaryVehicle.Vehicle; return multistep.JobInputData.PrimaryVehicle.Vehicle;
} else {
return inputData.JobInputData.Vehicle;
} }
return inputData.JobInputData.Vehicle;
} }
} }
......
...@@ -11,6 +11,9 @@ using TUGraz.VectoCommon.Models; ...@@ -11,6 +11,9 @@ using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Resources; using TUGraz.VectoCommon.Resources;
using TUGraz.VectoCommon.Utils; using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.InputData.Reader.ComponentData; using TUGraz.VectoCore.InputData.Reader.ComponentData;
using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents;
using TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricComponents.Battery;
using TUGraz.VectoCore.Models.SimulationComponent.Impl;
using TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport.ManufacturerReport_0_9.ManufacturerReportGroupWriter; using TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport.ManufacturerReport_0_9.ManufacturerReportGroupWriter;
using TUGraz.VectoCore.Utils; using TUGraz.VectoCore.Utils;
...@@ -225,18 +228,32 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation ...@@ -225,18 +228,32 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation
{ {
var vehicle = GetVehicle(inputData); var vehicle = GetVehicle(inputData);
var reess = vehicle.Components.ElectricStorage; var reess = vehicle.Components.ElectricStorage;
var batteries = reess.ElectricStorageElements //var batteries = reess.ElectricStorageElements
.Where(es => es.REESSPack.StorageType == REESSType.Battery) // .Where(es => es.REESSPack.StorageType == REESSType.Battery)
.Select(es => es.REESSPack as IBatteryPackDeclarationInputData).ToArray(); // .Select(es => es.REESSPack as IBatteryPackDeclarationInputData).ToArray();
var batTotalCap = 0.SI<WattSecond>();
var batUsableCap = 0.SI<WattSecond>();
if (reess.ElectricStorageElements.Any(x => x.REESSPack.StorageType == REESSType.Battery)) {
var eletricStorageAdapter = new ElectricStorageAdapter();
var batData = eletricStorageAdapter.CreateBatteryData(reess, vehicle.VehicleType, vehicle.OvcHev);
batUsableCap = GetEnergyStoredInBatterySystem(batData);
foreach (var entry in batData.Batteries) {
entry.Item2.MinSOC = 0;
entry.Item2.MaxSOC = 1;
}
batTotalCap = GetEnergyStoredInBatterySystem(batData);
}
var capacitors = reess.ElectricStorageElements.Where(es => es.REESSPack.StorageType == REESSType.SuperCap) var capacitors = reess.ElectricStorageElements.Where(es => es.REESSPack.StorageType == REESSType.SuperCap)
.Select(es => es.REESSPack as ISuperCapDeclarationInputData).ToArray(); .Select(es => es.REESSPack as ISuperCapDeclarationInputData).ToArray();
var totalStorageCapacity = var totalStorageCapacity =
(batteries.Length > 0 ? batteries.Sum(bp => bp.TotalStorageCapacity()) : 0.SI<WattSecond>()) + batTotalCap +
(capacitors.Length > 0 ? capacitors.Sum(cap => GetStorageCapacity(cap)) : 0.SI<WattSecond>()); (capacitors.Length > 0 ? capacitors.Sum(cap => GetStorageCapacity(cap)) : 0.SI<WattSecond>());
var totalUsableCapacity = (batteries.Length > 0 var totalUsableCapacity = batUsableCap +
? batteries.Sum(bp => bp.TotalUsableCapacityInSimulation())
: 0.SI<WattSecond>()) +
(capacitors.Length > 0 (capacitors.Length > 0
? capacitors.Sum(cap => GetTotalUsableCapacityInSimulation(cap)) ? capacitors.Sum(cap => GetTotalUsableCapacityInSimulation(cap))
: 0.SI<WattSecond>()); : 0.SI<WattSecond>());
...@@ -247,6 +264,24 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation ...@@ -247,6 +264,24 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation
}; };
} }
private static WattSecond GetEnergyStoredInBatterySystem(BatterySystemData batData)
{
var tmpBat = new BatterySystem(null, batData);
// set every single battery to its max SoC - initializing the battery system does
// not work as individual batteries may have different SoC limits
foreach (var battery in tmpBat.Batteries.SelectMany(batteryString => batteryString.Value.Batteries)) {
battery.Initialize(battery.MaxSoC);
}
var energyFull = tmpBat.StoredEnergy;
// set every single battery to its min SoC - initializing the battery system does
// not work as individual batteries may have different SoC limits
foreach (var battery in tmpBat.Batteries.SelectMany(batteryString => batteryString.Value.Batteries)) {
battery.Initialize(battery.MinSoC);
}
var energyEmpty = tmpBat.StoredEnergy;
return energyFull - energyEmpty;
}
private WattSecond GetTotalUsableCapacityInSimulation(ISuperCapDeclarationInputData cap) private WattSecond GetTotalUsableCapacityInSimulation(ISuperCapDeclarationInputData cap)
{ {
return GetStorageCapacity(cap) * 0.8; return GetStorageCapacity(cap) * 0.8;
......
...@@ -14,5 +14,13 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport. ...@@ -14,5 +14,13 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport.
_mrfFactory = mrfFactory; _mrfFactory = mrfFactory;
} }
protected virtual IVehicleDeclarationInputData GetVehicle(IDeclarationInputDataProvider inputData)
{
if (inputData is IMultistepBusInputDataProvider multistep) {
return multistep.JobInputData.PrimaryVehicle.Vehicle;
}
return inputData.JobInputData.Vehicle;
}
} }
} }
...@@ -10,6 +10,9 @@ using TUGraz.VectoCommon.Models; ...@@ -10,6 +10,9 @@ using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Resources; using TUGraz.VectoCommon.Resources;
using TUGraz.VectoCommon.Utils; using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.InputData.Reader.ComponentData; using TUGraz.VectoCore.InputData.Reader.ComponentData;
using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponents;
using TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricComponents.Battery;
using TUGraz.VectoCore.Models.SimulationComponent.Impl;
using TUGraz.VectoCore.Utils; using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport.ManufacturerReport_0_9.ManufacturerReportXMLTypeWriter.Components namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport.ManufacturerReport_0_9.ManufacturerReportXMLTypeWriter.Components
...@@ -22,26 +25,39 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport. ...@@ -22,26 +25,39 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport.
public XElement GetElement(IDeclarationInputDataProvider inputData) public XElement GetElement(IDeclarationInputDataProvider inputData)
{ {
var reessElements = inputData.JobInputData.Vehicle.Components.ElectricStorage.ElectricStorageElements; var vehicle = GetVehicle(inputData);
var reess = inputData.JobInputData.Vehicle.Components.ElectricStorage;
var reessElements = reess.ElectricStorageElements;
var result = new XElement(_mrf + "REESSSpecifications"); var result = new XElement(_mrf + "REESSSpecifications");
foreach (var electricStorage in reessElements.OrderBy((element) => element.StringId)) { if (reessElements.Any(x => x.REESSPack.StorageType == REESSType.Battery)) {
if (electricStorage.REESSPack.StorageType == REESSType.Battery && var eletricStorageAdapter = new ElectricStorageAdapter();
electricStorage.REESSPack is IBatteryPackDeclarationInputData battery) { var batData = eletricStorageAdapter.CreateBatteryData(reess, vehicle.VehicleType, vehicle.OvcHev);
foreach (var entry in batData.Batteries.OrderBy(x => x.Item1)) {
var batteryPackInput = entry.Item2.InputData;
var battery = batteryPackInput.REESSPack as IBatteryPackDeclarationInputData;
var batUsableCap = GetEnergyStoredInBattery(entry);
entry.Item2.MaxSOC = 1;
entry.Item2.MinSOC = 0;
var batTotalCap = GetEnergyStoredInBattery(entry);
result.Add(new XElement(_mrf + XMLNames.ElectricEnergyStorage_Battery, result.Add(new XElement(_mrf + XMLNames.ElectricEnergyStorage_Battery,
new XAttribute("stringId", electricStorage.StringId), new XAttribute("stringId", entry.Item1),
new XElement(_mrf + XMLNames.Component_Model, battery.Model), new XElement(_mrf + XMLNames.Component_Model, battery.Model),
new XElement(_mrf + XMLNames.Component_CertificationNumber, battery.CertificationNumber), new XElement(_mrf + XMLNames.Component_CertificationNumber, battery.CertificationNumber),
new XElement(_mrf + XMLNames.DI_Signature_Reference_DigestValue, battery.DigestValue?.DigestValue ?? ""), new XElement(_mrf + XMLNames.DI_Signature_Reference_DigestValue, battery.DigestValue?.DigestValue ?? ""),
new XElement(_mrf + XMLNames.BusAux_ElectricSystem_NominalVoltage, BatterySOCReader.Create(battery.VoltageCurve).Lookup(0.5).ToXMLFormat(0)), new XElement(_mrf + XMLNames.BusAux_ElectricSystem_NominalVoltage, BatterySOCReader.Create(battery.VoltageCurve).Lookup(0.5).ToXMLFormat(0)),
new XElement(_mrf + "TotalStorageCapacity", battery.TotalStorageCapacity().ValueAsUnit("kWh", 0)), new XElement(_mrf + "TotalStorageCapacity", batTotalCap.ValueAsUnit("kWh", 0)),
new XElement(_mrf + "TotalUsableCapacityInSimulation", battery.TotalUsableCapacityInSimulation().ValueAsUnit("kWh"), 0), new XElement(_mrf + "TotalUsableCapacityInSimulation", batUsableCap.ValueAsUnit("kWh", 0)),
new XElement(_mrf + XMLNames.Component_CertificationMethod, battery.CertificationMethod.ToXMLFormat()) new XElement(_mrf + XMLNames.Component_CertificationMethod, battery.CertificationMethod.ToXMLFormat())
) )
); );
} else if (electricStorage.REESSPack.StorageType == REESSType.SuperCap && }
electricStorage.REESSPack is ISuperCapDeclarationInputData superCap) {
} else {
foreach (var electricStorage in reessElements.Where(x => x.REESSPack.StorageType == REESSType.SuperCap)) {
var superCap = electricStorage.REESSPack as ISuperCapDeclarationInputData;
result.Add(new XElement(_mrf + XMLNames.ElectricEnergyStorage_Capacitor, result.Add(new XElement(_mrf + XMLNames.ElectricEnergyStorage_Capacitor,
new XElement(_mrf + XMLNames.Component_Model, superCap.Model), new XElement(_mrf + XMLNames.Component_Model, superCap.Model),
new XElement(_mrf + XMLNames.Component_CertificationNumber, superCap.CertificationNumber), new XElement(_mrf + XMLNames.Component_CertificationNumber, superCap.CertificationNumber),
...@@ -52,13 +68,21 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport. ...@@ -52,13 +68,21 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.ManufacturerReport.
new XElement(_mrf + XMLNames.Capacitor_MaxVoltage, superCap.MaxVoltage.ToXMLFormat(2)) new XElement(_mrf + XMLNames.Capacitor_MaxVoltage, superCap.MaxVoltage.ToXMLFormat(2))
) )
); );
} else {
throw new VectoException("Invalid REESS type");
} }
} }
return result; return result;
} }
private static WattSecond GetEnergyStoredInBattery(Tuple<int, BatteryData> entry)
{
var tmpBattery = new Battery(null, entry.Item2);
tmpBattery.Initialize(tmpBattery.MaxSoC);
var energyFull = tmpBattery.StoredEnergy;
tmpBattery.Initialize(tmpBattery.MinSoC);
var energyEmpty = tmpBattery.StoredEnergy;
return energyFull - energyEmpty;
}
#endregion #endregion
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment