Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS has been phased out. To see alternatives please check here

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

adding sanity checks for electric components: efficiency must not be greater...

adding sanity checks for electric components: efficiency must not be greater than 1, drag torque must be negative
parent 44db12f3
No related branches found
No related tags found
No related merge requests found
Showing
with 81 additions and 29 deletions
......@@ -28,7 +28,12 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
MotorSpeed = x.ParseDouble(Fields.MotorSpeed).RPMtoRad(), // / ratio,
DragTorque = -x.ParseDouble(Fields.DragTorque).SI<NewtonMeter>() * count, // * ratio / efficiency
}).OrderBy(x => x.MotorSpeed).ToList();
var invalid = entries.Where(x => x.DragTorque.IsSmaller(0)).ToList();
if (invalid.Count > 0) {
throw new VectoException("Drag torque has to be negative in input: {0}",
invalid.Select(x => x.MotorSpeed.AsRPM).Join());
}
var duplicates = entries.GroupBy(x => x.MotorSpeed).Where(g => g.Count() > 1).Select(x => x.Key.AsRPM).ToList();
if (duplicates.Any()) {
throw new VectoException(
......
......@@ -14,12 +14,12 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
public class ElectricMotorMapReader
{
public static EfficiencyMap Create(Stream data, int count)
public static EfficiencyMap Create(Stream data, int count, ExecutionMode mode)
{
return Create(VectoCSVFile.ReadStream(data), count);
return Create(VectoCSVFile.ReadStream(data), count, mode);
}
public static EfficiencyMap Create(DataTable data, int count)
public static EfficiencyMap Create(DataTable data, int count, ExecutionMode mode)
{
var headerValid = HeaderIsValid(data.Columns);
if (!headerValid) {
......@@ -39,6 +39,26 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
if (duplicates.Count > 0) {
throw new VectoException("Duplicate entries in EM power map: {0}", duplicates.Select(x => $"{x.Item1.AsRPM} rpm / {x.Item2}").Join());
}
var highEff = entries.Where(x => !x.Torque.IsEqual(0) && !x.MotorSpeed.IsEqual(0))
.Select(x => Tuple.Create(x,
x.Torque.IsGreater(0)
? x.MotorSpeed * x.Torque / x.PowerElectrical
: x.PowerElectrical / (x.MotorSpeed * x.Torque))).Where(x => x.Item2.IsGreater(1)).ToList();
if (highEff.Any()) {
if (mode == ExecutionMode.Declaration) {
throw new VectoException("Electric power map contains entries with efficiencies > 1! {1} entries: {0}",
highEff.Select(x =>
$"{x.Item1.MotorSpeed.AsRPM} rpm {x.Item1.Torque} => {x.Item1.PowerElectrical}").Join(),
highEff.Count);
}
LogManager.GetLogger(typeof(ElectricMotorMapReader).FullName).Debug(
"Electric power map contains entries with efficiencies > 1! {0}",
highEff.Select(x =>
$"{x.Item1.MotorSpeed.AsRPM} rpm {x.Item1.Torque} => {x.Item1.PowerElectrical}").Join());
}
var entriesZero = GetEntriesAtZeroRpm(entries);
var delaunayMap = new DelaunayMap("ElectricMotorEfficiencyMap Mechanical to Electric");
......
......@@ -28,6 +28,11 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
MotorSpeed = x.ParseDouble(Fields.MotorSpeed).RPMtoRad() * ratio,
DragTorque = -x.ParseDouble(Fields.DragTorque).SI<NewtonMeter>() * count / ratio // / efficiency
}).OrderBy(x => x.MotorSpeed).ToList();
var invalid = entries.Where(x => x.DragTorque.IsSmaller(0)).ToList();
if (invalid.Count > 0) {
throw new VectoException("Drag torque has to be negative in input: {0}",
invalid.Select(x => $"{x.MotorSpeed.AsRPM} rpm").Join());
}
var duplicates = entries.GroupBy(x => x.MotorSpeed).Where(g => g.Count() > 1).Select(x => x.Key.AsRPM / ratio).ToList();
if (duplicates.Any()) {
throw new VectoException(
......
......@@ -19,13 +19,13 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
public class IEPCMapReader
{
public static EfficiencyMap Create(Stream data, int count, double ratio,
ElectricMotorFullLoadCurve fullLoadCurve)
ElectricMotorFullLoadCurve fullLoadCurve, ExecutionMode mode)
{
return Create(VectoCSVFile.ReadStream(data), count, ratio, fullLoadCurve);
return Create(VectoCSVFile.ReadStream(data), count, ratio, fullLoadCurve, mode);
}
public static EfficiencyMap Create(DataTable data, int count, double ratio,
ElectricMotorFullLoadCurve fullLoadCurve)
ElectricMotorFullLoadCurve fullLoadCurve, ExecutionMode mode)
{
if (fullLoadCurve == null) {
throw new ArgumentNullException("Provide fullloadcurve for extrapolation");
......@@ -43,7 +43,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
data.Columns[2].ColumnName = Fields.PowerElectrical;
}
var entries = GetEntries(data, ratio);
var entries = GetEntries(data, ratio, mode);
entries = ExtendEfficiencyMap(entries, fullLoadCurve);
var entriesZero = GetEntriesAtZeroRpm(entries);
......@@ -282,7 +282,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
powerElectrical: row.ParseDouble(Fields.PowerElectrical).SI<Watt>());
}
internal static IList<EfficiencyMap.Entry> GetEntries(DataTable data, double ratio)
internal static IList<EfficiencyMap.Entry> GetEntries(DataTable data, double ratio, ExecutionMode mode)
{
var entries = (from DataRow row in data.Rows select CreateEntry(row, ratio)).OrderBy(x => x.MotorSpeed)
.ThenBy(x => x.Torque).ToList();
......@@ -291,7 +291,25 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
if (duplicates.Count > 0) {
throw new VectoException("Duplicate entries in IEPC power map: {0}", duplicates.Select(x => $"{x.Item1.AsRPM / ratio} rpm / {x.Item2 * ratio}").Join());
}
var highEff = entries.Where(x => !x.Torque.IsEqual(0) && !x.MotorSpeed.IsEqual(0))
.Select(x => Tuple.Create(x,
x.Torque.IsGreater(0)
? x.MotorSpeed * x.Torque / x.PowerElectrical
: x.PowerElectrical / (x.MotorSpeed * x.Torque))).Where(x => x.Item2.IsGreater(1)).ToList();
if (highEff.Any()) {
if (mode == ExecutionMode.Declaration) {
throw new VectoException("Electric power map contains entries with efficiencies > 1! {1} entries: {0}",
highEff.Select(x =>
$"{x.Item1.MotorSpeed.AsRPM} rpm {x.Item1.Torque} => {x.Item1.PowerElectrical}").Join(),
highEff.Count);
}
LogManager.GetLogger(typeof(ElectricMotorMapReader).FullName).Debug(
"Electric power map contains entries with efficiencies > 1! {0}",
highEff.Select(x =>
$"{x.Item1.MotorSpeed.AsRPM} rpm {x.Item1.Torque} => {x.Item1.PowerElectrical}").Join());
}
return entries;
}
......
......@@ -1010,7 +1010,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
}
var effMap = new Dictionary<uint, EfficiencyMap>();
foreach (var gear in gearList) {
effMap.Add(gear.Gear, ElectricMotorMapReader.Create(entry.PowerMap[(int)gear.Gear - 1].PowerMap, count));
effMap.Add(gear.Gear, ElectricMotorMapReader.Create(entry.PowerMap[(int)gear.Gear - 1].PowerMap, count, ExecutionMode.Engineering));
}
return new IEPCVoltageLevelData() {
Voltage = entry.VoltageLevel,
......@@ -1026,7 +1026,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
FullLoadCurve = fullLoadCurveCombined,
// DragCurve = ElectricMotorDragCurveReader.Create(entry.DragCurve, count),
EfficiencyMap = ElectricMotorMapReader.Create(entry.PowerMap.First().PowerMap, count), //PowerMap
EfficiencyMap = ElectricMotorMapReader.Create(entry.PowerMap.First().PowerMap, count, ExecutionMode.Engineering), //PowerMap
};
}
......@@ -1223,7 +1223,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
IEPCFullLoadCurveReader.Create(entry.FullLoadCurve, count, gearRatioUsedForMeasurement.Ratio);
for (var i = 0u; i < entry.PowerMap.Count; i++) {
var ratio = iepc.Gears.First(x => x.GearNumber == i + 1).Ratio;
effMap.Add(i + 1, IEPCMapReader.Create(entry.PowerMap[(int)i].PowerMap, count, ratio, fldCurve));
effMap.Add(i + 1, IEPCMapReader.Create(entry.PowerMap[(int)i].PowerMap, count, ratio, fldCurve, ExecutionMode.Engineering));
//fullLoadCurves.Add(i + 1, IEPCFullLoadCurveReader.Create(entry.FullLoadCurve, count, ratio));
}
voltageLevels.Add(new IEPCVoltageLevelData() {
......
......@@ -101,7 +101,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
} catch (Exception ex) {
throw new VectoException(
$"Could not create Voltage Level data for {entry.VoltageLevel} at position {powertrainPosition}!\n" +
$"{ex.Message}",
$"{ex.Message} {ex.InnerException?.Message?.Substring(0, Math.Min(256, ex.InnerException.Message.Length))}",
ex);
}
}
......@@ -229,7 +229,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
}
var effMap = new Dictionary<uint, EfficiencyMap>();
foreach (var gear in gearList) {
effMap.Add(gear.Gear, ElectricMotorMapReader.Create(entry.PowerMap[(int)gear.Gear - 1].PowerMap, count));
effMap.Add(gear.Gear, ElectricMotorMapReader.Create(entry.PowerMap[(int)gear.Gear - 1].PowerMap, count, ExecutionMode.Declaration));
}
return new IHPCVoltageLevelData() {
Voltage = entry.VoltageLevel,
......@@ -247,7 +247,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
FullLoadCurve = fullLoadCurveCombined,
// DragCurve = ElectricMotorDragCurveReader.Create(entry.DragCurve, count),
EfficiencyMap = ElectricMotorMapReader.Create(entry.PowerMap.First().PowerMap, count), //PowerMap
EfficiencyMap = ElectricMotorMapReader.Create(entry.PowerMap.First().PowerMap, count, ExecutionMode.Declaration), //PowerMap
};
} catch (Exception ex) {
throw new VectoException($"Invalid efficiency map at voltage level {entry.VoltageLevel}", ex);
......@@ -282,7 +282,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter.SimulationComponen
IEPCFullLoadCurveReader.Create(entry.FullLoadCurve, count, gearRatioUsedForMeasurement.Ratio);
for (var i = 0u; i < entry.PowerMap.Count; i++) {
var ratio = iepc.Gears.First(x => x.GearNumber == i + 1).Ratio;
effMap.Add(i + 1, IEPCMapReader.Create(entry.PowerMap[(int)i].PowerMap, count, ratio, fldCurve));
effMap.Add(i + 1, IEPCMapReader.Create(entry.PowerMap[(int)i].PowerMap, count, ratio, fldCurve, ExecutionMode.Declaration));
//fullLoadCurves.Add(i + 1, IEPCFullLoadCurveReader.Create(entry.FullLoadCurve, count, ratio));
}
voltageLevels.Add(new IEPCVoltageLevelData() {
......
......@@ -165,7 +165,7 @@ namespace TUGraz.VectoCore.Models.GenericModelData
var electricMotorVoltageLevel = new ElectricMotorVoltageLevelData {
Voltage = voltageLevel.VoltageLevel,
FullLoadCurve = GetElectricMotorFullLoadCurve(voltageLevel, count, torqueLimits),
EfficiencyMap = ElectricMotorMapReader.Create(efficiencyMap, count)
EfficiencyMap = ElectricMotorMapReader.Create(efficiencyMap, count, ExecutionMode.Declaration)
};
result.Add(electricMotorVoltageLevel);
......
......@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Data;
using System.Linq;
using TUGraz.VectoCommon.InputData;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.InputData.Reader.ComponentData;
using TUGraz.VectoCore.Models.Declaration;
......@@ -120,7 +121,7 @@ namespace TUGraz.VectoCore.Models.GenericModelData
_axleRatio, _gearRatioAtMeasurement.Value, GenericGearEfficiency, _axleEfficiency);
var deNormalizedMap = DeNormalizeData(GetNormalizedEfficiencyMap(electricMachineType), ratedPoint, gearRatio);
result.Add((uint) gearEntry.Key, IEPCMapReader.Create(deNormalizedMap, count, gearRatio, fullLoadCurve));
result.Add((uint) gearEntry.Key, IEPCMapReader.Create(deNormalizedMap, count, gearRatio, fullLoadCurve, ExecutionMode.Declaration));
}
return result;
......
......@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Data;
using System.Linq;
using TUGraz.VectoCommon.InputData;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.InputData.Reader.ComponentData;
using TUGraz.VectoCore.Models.Declaration;
......@@ -84,7 +85,7 @@ namespace TUGraz.VectoCore.Models.GenericModelData
var efficiencyMap = DeNormalizeData(normalizedMap, ratedPoint);
foreach (var gearData in gearboxData.Gears.OrderBy(x => x.Gear)) {
result.Add((uint)gearData.Gear, ElectricMotorMapReader.Create(efficiencyMap, count));
result.Add((uint)gearData.Gear, ElectricMotorMapReader.Create(efficiencyMap, count, ExecutionMode.Declaration));
}
return result;
......
......@@ -74,7 +74,7 @@ namespace TUGraz.VectoCore.Tests.FileIO
Assert.AreEqual("-800", pwr.Rows[0][ElectricMotorMapReader.Fields.Torque]);
Assert.AreEqual("9844.9", pwr.Rows[0][ElectricMotorMapReader.Fields.PowerElectrical]);
var pwrMap = ElectricMotorMapReader.Create(pwr, 1);
var pwrMap = ElectricMotorMapReader.Create(pwr, 1, ExecutionMode.Engineering);
Assert.AreEqual(0, pwrMap.LookupElectricPower(-0.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3);
Assert.AreEqual(-298.4752, pwrMap.LookupElectricPower(1.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3);
......@@ -107,7 +107,7 @@ namespace TUGraz.VectoCore.Tests.FileIO
Assert.AreEqual("-800", pwrLow.Rows[0][ElectricMotorMapReader.Fields.Torque]);
Assert.AreEqual("9844.9", pwrLow.Rows[0][ElectricMotorMapReader.Fields.PowerElectrical]);
var pwrMapLow = ElectricMotorMapReader.Create(pwrLow, 1);
var pwrMapLow = ElectricMotorMapReader.Create(pwrLow, 1, ExecutionMode.Engineering);
Assert.AreEqual(-0, pwrMapLow.LookupElectricPower(-0.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3);
Assert.AreEqual(-298.4752, pwrMapLow.LookupElectricPower(1.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3);
......@@ -132,7 +132,7 @@ namespace TUGraz.VectoCore.Tests.FileIO
Assert.AreEqual("-800", pwrHi.Rows[0][ElectricMotorMapReader.Fields.Torque]);
Assert.AreEqual("8860.41", pwrHi.Rows[0][ElectricMotorMapReader.Fields.PowerElectrical]);
var pwrMap = ElectricMotorMapReader.Create(pwrHi, 1);
var pwrMap = ElectricMotorMapReader.Create(pwrHi, 1, ExecutionMode.Engineering);
Assert.AreEqual(0, pwrMap.LookupElectricPower(-0.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3);
Assert.AreEqual(-268.6277, pwrMap.LookupElectricPower(1.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3);
......@@ -205,7 +205,7 @@ namespace TUGraz.VectoCore.Tests.FileIO
Assert.AreEqual("-800", pwr.Rows[0][ElectricMotorMapReader.Fields.Torque]);
Assert.AreEqual("9844.9", pwr.Rows[0][ElectricMotorMapReader.Fields.PowerElectrical]);
var pwrMap = ElectricMotorMapReader.Create(pwr, 2);
var pwrMap = ElectricMotorMapReader.Create(pwr, 2, ExecutionMode.Engineering);
Assert.AreEqual(0, pwrMap.LookupElectricPower(-0.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3);
Assert.AreEqual(-208.04255, pwrMap.LookupElectricPower(1.RPMtoRad(), -800.SI<NewtonMeter>()).ElectricalPower.Value(), 1e-3);
......
......@@ -14,6 +14,7 @@ using System.Linq;
using System.Reflection;
using NUnit.Framework;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.InputData.Reader.ComponentData;
......@@ -66,10 +67,10 @@ namespace TUGraz.VectoCore.Tests.InputData
powerMapData.Columns[2].ColumnName = IEPCMapReader.Fields.PowerElectrical;
var fld = IEPCFullLoadCurveReader.Create(fullLoadCurveData, 1, fldMeasuredRatio);
var powerMapInput = IEPCMapReader.GetEntries(powerMapData, ratio);
var powerMapInput = IEPCMapReader.GetEntries(powerMapData, ratio, ExecutionMode.Engineering);
var effMap = IEPCMapReader.Create(powerMapData, 1, ratio, fld);
var effMap = IEPCMapReader.Create(powerMapData, 1, ratio, fld, ExecutionMode.Engineering);
#if TRACE
PrintMaps("FLD.png",
new SeriesProperties<ElectricMotorFullLoadCurve.FullLoadEntry>() {
......
......@@ -4,6 +4,7 @@ using System.Data;
using System.IO;
using System.Linq;
using NUnit.Framework;
using TUGraz.VectoCommon.Models;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Configuration;
using TUGraz.VectoCore.InputData.FileIO.JSON;
......@@ -38,7 +39,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData {
var pwr = inputProvider.VoltageLevels.First().PowerMap.First().PowerMap; //ToDo FK: maybe wrong selection
// var pwr = inputProvider.VoltageLevels.First().EfficiencyMap;
var pwrMap = ElectricMotorMapReader.Create(pwr, 1);
var pwrMap = ElectricMotorMapReader.Create(pwr, 1, ExecutionMode.Engineering);
var maxEmPwr = batPwr < 0
? fldMap.FullLoadDriveTorque(emSpeed.RPMtoRad())
......@@ -103,7 +104,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData {
var pwr = inputProvider.VoltageLevels.First().PowerMap.First().PowerMap;//ToDo FK: maybe wrong selection
// var pwr = inputProvider.VoltageLevels.First().EfficiencyMap;
var pwrMap = ElectricMotorMapReader.Create(pwr, 1);
var pwrMap = ElectricMotorMapReader.Create(pwr, 1, ExecutionMode.Engineering);
var maxEmPwr = batPwr < 0
? fldMap.FullLoadDriveTorque(emSpeed.RPMtoRad())
......@@ -120,7 +121,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData {
public void TestInterpolationMethod_PowerMap(string filename, double etaMin, double etaMax)
{
var data = VectoCSVFile.Read(filename).ApplyFactor(ElectricMotorMapReader.Fields.PowerElectrical, 1000.0);
var emMap = ElectricMotorMapReader.Create(data, 1);
var emMap = ElectricMotorMapReader.Create(data, 1, ExecutionMode.Engineering);
var efficiencies = new List<double>();
for (var n = 10.RPMtoRad(); n < 4000.RPMtoRad(); n += 10.RPMtoRad()) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment