diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/EfficiencyMap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/EfficiencyMap.cs index f61e127a710b75925432dd92f6d8a2225e0f8352..54baf78c9eaed6b54f2872f7c35f5d96fdf334f7 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/EfficiencyMap.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/ElectricMotor/EfficiencyMap.cs @@ -150,35 +150,23 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricMotor } try { - var retVal = SearchAlgorithm.Search( - maxEmTorque, elPowerMaxEM.ElectricalPower - batPower, - -maxEmTorque * 0.1 * (maxEmTorque > 0 ? -1 : 1), - getYValue: x => { - var myX = (EfficiencyResult)x; - return myX.ElectricalPower - batPower; - }, - evaluateFunction: x => LookupElectricPower(avgSpeed, x, true), - criterion: x => { - var myX = (EfficiencyResult)x; - return (myX.ElectricalPower - batPower).Value(); - }, - searcher: this); + var retVal = SearchTorqueForElectricPower(batPower, avgSpeed, maxEmTorque, elPowerMaxEM); var tmp = LookupElectricPower(avgSpeed, retVal, true); if (VectoMath.Abs(tmp.ElectricalPower - batPower).IsGreater(Constants.SimulationSettings.InterpolateSearchTolerance)) { // searched operating point is not accurate enough... - retVal = SearchAlgorithm.Search( - maxEmTorque, elPowerMaxEM.ElectricalPower - batPower, - -maxEmTorque * 0.1 * (maxEmTorque > 0 ? -1 : 1), - getYValue: x => { - var myX = (EfficiencyResult)x; - return (myX.ElectricalPower - batPower) * 1e3; - }, - evaluateFunction: x => LookupElectricPower(avgSpeed, x, true), - criterion: x => { - var myX = (EfficiencyResult)x; - return (myX.ElectricalPower - batPower).Value() * 1e3; - }, - searcher: this); + retVal = SearchTorqueForElectricPower(batPower, avgSpeed, maxEmTorque, elPowerMaxEM, 1e3); + } + + if (maxEmTorque < 0) { + // propelling + if (retVal.IsSmaller(maxEmTorque)) { + retVal = SearchTorqueForElectricPower(batPower, avgSpeed, maxEmTorque, elPowerMaxEM, 1e3, true); + } + } else { + // recuperating + if (retVal.IsGreater(maxEmTorque)) { + retVal = SearchTorqueForElectricPower(batPower, avgSpeed, maxEmTorque, elPowerMaxEM, 1e3, true); + } } return retVal; } catch (VectoSearchFailedException vsfe) { @@ -188,6 +176,26 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricMotor return null; } + private NewtonMeter SearchTorqueForElectricPower(Watt batPower, PerSecond avgSpeed, NewtonMeter maxEmTorque, + EfficiencyResult elPowerMaxEM, double factor = 1.0, bool forceLinesearch = false) + { + var retVal = SearchAlgorithm.Search( + maxEmTorque, elPowerMaxEM.ElectricalPower - batPower, + -maxEmTorque * 0.1 * (maxEmTorque > 0 ? -1 : 1), + getYValue: x => { + var myX = (EfficiencyResult)x; + return (myX.ElectricalPower - batPower) * factor; + }, + evaluateFunction: x => LookupElectricPower(avgSpeed, x, true), + criterion: x => { + var myX = (EfficiencyResult)x; + return (myX.ElectricalPower - batPower).Value() * factor; + }, + searcher: this, + forceLineSearch: forceLinesearch); + return retVal; + } + public PerSecond MaxSpeed { get { return _maxSpeed ?? (_maxSpeed = _efficiencyMapMech2El.Entries.Select(x => x.Y).Max().SI<PerSecond>()); }