LCOV - code coverage report
Current view: top level - src/foreign/PHEMlight/V5/cpp - CEP.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 188 236 79.7 %
Date: 2024-04-27 15:34:54 Functions: 18 19 94.7 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2016-2024 German Aerospace Center (DLR) and others.
       4             : // PHEMlight module
       5             : // Copyright (C) 2016-2023 Technische Universitaet Graz, https://www.tugraz.at/
       6             : // This program and the accompanying materials are made available under the
       7             : // terms of the Eclipse Public License 2.0 which is available at
       8             : // https://www.eclipse.org/legal/epl-2.0/
       9             : // This Source Code may also be made available under the following Secondary
      10             : // Licenses when the conditions for such availability set forth in the Eclipse
      11             : // Public License 2.0 are satisfied: GNU General Public License, version 2
      12             : // or later which is available at
      13             : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      14             : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      15             : /****************************************************************************/
      16             : /// @file    CEP.cpp
      17             : /// @author  Martin Dippold
      18             : /// @author  Michael Behrisch
      19             : /// @date    July 2016
      20             : ///
      21             : //
      22             : /****************************************************************************/
      23             : #include <config.h>
      24             : 
      25             : #include "CEP.h"
      26             : #include "CEPHandler.h"
      27             : #include "Constants.h"
      28             : #include "Helpers.h"
      29             : 
      30             : 
      31             : namespace PHEMlightdllV5 {
      32             : 
      33          38 :     CEP::CEP(VEHPHEMLightJSON::VEH* Vehicle, std::vector<std::string>& headerLineFCvalues, std::vector<std::vector<double> >& matrixFCvalues, std::vector<std::string>& headerLinePollutants, std::vector<std::vector<double> >& matrixPollutants, std::vector<double>& idlingFCvalues, std::vector<double>& idlingPollutants) {
      34          38 :         InitializeInstanceFields();
      35          38 :         _resistanceF0 = Vehicle->getRollingResData()->getFr0();
      36          38 :         _resistanceF1 = Vehicle->getRollingResData()->getFr1();
      37          38 :         _resistanceF2 = Vehicle->getRollingResData()->getFr2();
      38          38 :         _resistanceF3 = Vehicle->getRollingResData()->getFr3();
      39          38 :         _resistanceF4 = Vehicle->getRollingResData()->getFr4();
      40          38 :         _cWValue = Vehicle->getVehicleData()->getCw();
      41          38 :         _crossSectionalArea = Vehicle->getVehicleData()->getA();
      42          38 :         _massVehicle = Vehicle->getVehicleData()->getMass();
      43          38 :         _vehicleLoading = Vehicle->getVehicleData()->getLoading();
      44          38 :         _vehicleMassRot = Vehicle->getVehicleData()->getRedMassWheel();
      45          38 :         setCalcType(Vehicle->getVehicleData()->getCalcType());
      46             : //C# TO C++ CONVERTER NOTE: The following 'switch' operated on a string variable and was converted to C++ 'if-else' logic:
      47             : //        switch (CalcType)
      48             : //ORIGINAL LINE: case "Conv":
      49          76 :         if (getCalcType() == "Conv") {
      50          38 :                 setRatedPower(Vehicle->getEngineData()->getICEData()->getPrated());
      51          38 :                 _engineRatedSpeed = Vehicle->getEngineData()->getICEData()->getnrated();
      52          38 :                 _engineIdlingSpeed = Vehicle->getEngineData()->getICEData()->getIdling();
      53             :         }
      54             : //ORIGINAL LINE: case "HEV":
      55           0 :         else if (getCalcType() == "HEV") {
      56             :                 // Power von beiden zusammen Rest bezogen auf ICE
      57           0 :                 setRatedPower(Vehicle->getEngineData()->getICEData()->getPrated() + Vehicle->getEngineData()->getEMData()->getPrated());
      58           0 :                 _engineRatedSpeed = Vehicle->getEngineData()->getICEData()->getnrated();
      59           0 :                 _engineIdlingSpeed = Vehicle->getEngineData()->getICEData()->getIdling();
      60             :         }
      61             : //ORIGINAL LINE: case "BEV":
      62           0 :         else if (getCalcType() == "BEV") {
      63           0 :                 setRatedPower(Vehicle->getEngineData()->getEMData()->getPrated());
      64           0 :                 _engineRatedSpeed = Vehicle->getEngineData()->getEMData()->getnrated();
      65           0 :                 _engineIdlingSpeed = 0;
      66             :         }
      67             : 
      68          38 :         _effectiveWheelDiameter = Vehicle->getVehicleData()->getWheelDiameter();
      69          38 :         privateHeavyVehicle = Vehicle->getVehicleData()->getMassType() == Constants::HeavyVehicle;
      70          38 :         setFuelType(Vehicle->getVehicleData()->getFuelType());
      71          38 :         _axleRatio = Vehicle->getTransmissionData()->getAxelRatio();
      72          38 :         _auxPower = Vehicle->getAuxiliariesData()->getPauxnorm();
      73             : 
      74          38 :         _pNormV0 = Vehicle->getFLDData()->getP_n_max_v0() / 3.6;
      75          38 :         _pNormP0 = Vehicle->getFLDData()->getP_n_max_p0();
      76          38 :         _pNormV1 = Vehicle->getFLDData()->getP_n_max_v1() / 3.6;
      77          38 :         _pNormP1 = Vehicle->getFLDData()->getP_n_max_p1();
      78             : 
      79             :         // Init pollutant identifiers, unit and measures
      80             :         std::vector<std::string> FCvaluesIdentifier;
      81             :         std::vector<std::vector<double> > normalizedFCvaluesMeasures;
      82         152 :         for (int i = 0; i < (int)headerLineFCvalues.size(); i++) {
      83         114 :             FCvaluesIdentifier.push_back(headerLineFCvalues[i]);
      84         114 :             normalizedFCvaluesMeasures.push_back(std::vector<double>());
      85             :         }
      86             : 
      87             :         // Init pollutant identifiers, unit and measures
      88             :         std::vector<std::string> pollutantIdentifier;
      89             :         std::vector<std::vector<double> > normalizedPollutantMeasures;
      90         228 :         for (int i = 0; i < (int)headerLinePollutants.size(); i++) {
      91         190 :             pollutantIdentifier.push_back(headerLinePollutants[i]);
      92         190 :             normalizedPollutantMeasures.push_back(std::vector<double>());
      93             :         }
      94             : 
      95             :         // Assigning values for speed rotational table
      96          38 :         _speedPatternRotational = std::vector<double>();
      97         320 :         for (int i = 0; i < (int)Vehicle->getTransmissionData()->getTransm()["Speed"].size(); i++) {
      98         282 :             _speedPatternRotational.push_back(Vehicle->getTransmissionData()->getTransm()["Speed"][i] / 3.6);
      99             :         }
     100             : 
     101          38 :         _gearTransmissionCurve = Vehicle->getTransmissionData()->getTransm()["GearRatio"];
     102          38 :         _speedCurveRotational = Vehicle->getTransmissionData()->getTransm()["RotMassF"];
     103             : 
     104             :         // Assigning values for drag table
     105          38 :         _nNormTable = Vehicle->getFLDData()->getDragCurve()["n_norm"];
     106          76 :         _dragNormTable = Vehicle->getFLDData()->getDragCurve()["pe_drag_norm"];
     107             : 
     108             :         // Looping through matrix and assigning values for FC values
     109          38 :         _normalizedPowerPatternFCvalues = std::vector<double>();
     110             : 
     111          38 :         int headerFCCount = (int)headerLineFCvalues.size();
     112         532 :         for (int i = 0; i < (int)matrixFCvalues.size(); i++) {
     113        2470 :             for (int j = 0; j < (int)matrixFCvalues[i].size(); j++) {
     114        1976 :                 if ((int)matrixFCvalues[i].size() != headerFCCount + 1) {
     115             :                     return;
     116             :                 }
     117             : 
     118        1976 :                 if (j == 0) {
     119         494 :                     _normalizedPowerPatternFCvalues.push_back(matrixFCvalues[i][j]);
     120             :                 }
     121             :                 else {
     122        1482 :                     normalizedFCvaluesMeasures[j - 1].push_back(matrixFCvalues[i][j]);
     123             :                 }
     124             :             }
     125             :         }
     126             : 
     127          38 :         _idlingValueFCvalues = std::map<std::string, double>();
     128          38 :         _normedCepCurveFCvalues = std::map<std::string, std::vector<double> >();
     129             : 
     130         152 :         for (int i = 0; i < (int)headerLineFCvalues.size(); i++) {
     131         228 :             _normedCepCurveFCvalues.insert(std::make_pair(FCvaluesIdentifier[i], normalizedFCvaluesMeasures[i]));
     132         114 :             _idlingValueFCvalues.insert(std::make_pair(FCvaluesIdentifier[i], idlingFCvalues[i]));
     133             :         }
     134             : 
     135          38 :         _normalizedPowerPatternPollutants = std::vector<double>();
     136          38 :         _cepNormalizedCurvePollutants = std::map<std::string, std::vector<double> >();
     137             : 
     138          38 :         int headerCount = (int)headerLinePollutants.size();
     139        1216 :         for (int i = 0; i < (int)matrixPollutants.size(); i++) {
     140        8246 :             for (int j = 0; j < (int)matrixPollutants[i].size(); j++) {
     141        7068 :                 if ((int)matrixPollutants[i].size() != headerCount + 1) {
     142             :                     return;
     143             :                 }
     144             : 
     145        7068 :                 if (j == 0) {
     146        1178 :                     _normalizedPowerPatternPollutants.push_back(matrixPollutants[i][j]);
     147             :                 }
     148             :                 else {
     149        5890 :                     normalizedPollutantMeasures[j - 1].push_back(matrixPollutants[i][j]);
     150             :                 }
     151             :             }
     152             :         }
     153             : 
     154          38 :         _idlingValuesPollutants = std::map<std::string, double>();
     155             : 
     156         228 :         for (int i = 0; i < (int)headerLinePollutants.size(); i++) {
     157         380 :             _cepNormalizedCurvePollutants.insert(std::make_pair(pollutantIdentifier[i], normalizedPollutantMeasures[i]));
     158         190 :             _idlingValuesPollutants.insert(std::make_pair(pollutantIdentifier[i], idlingPollutants[i]));
     159             :         }
     160             : 
     161          38 :         _FleetMix = std::map<std::string, double>();
     162          38 :         _FleetMix.insert(std::make_pair(Constants::strGasoline, 0));
     163          38 :         _FleetMix.insert(std::make_pair(Constants::strDiesel, 0));
     164          38 :         _FleetMix.insert(std::make_pair(Constants::strCNG, 0));
     165          38 :         _FleetMix.insert(std::make_pair(Constants::strLPG, 0));
     166          38 :     }
     167             : 
     168      218438 :     const bool& CEP::getHeavyVehicle() const {
     169      218438 :         return privateHeavyVehicle;
     170             :     }
     171             : 
     172      178124 :     const std::string& CEP::getFuelType() const {
     173      178124 :         return privateFuelType;
     174             :     }
     175             : 
     176          38 :     void CEP::setFuelType(const std::string& value) {
     177          38 :         privateFuelType = value;
     178          38 :     }
     179             : 
     180      898250 :     const std::string& CEP::getCalcType() const {
     181      898250 :         return privateCalcType;
     182             :     }
     183             : 
     184          38 :     void CEP::setCalcType(const std::string& value) {
     185          38 :         privateCalcType = value;
     186          38 :     }
     187             : 
     188      793344 :     const double& CEP::getRatedPower() const {
     189      793344 :         return privateRatedPower;
     190             :     }
     191             : 
     192          38 :     void CEP::setRatedPower(const double& value) {
     193          38 :         privateRatedPower = value;
     194          38 :     }
     195             : 
     196      142772 :     double CEP::CalcEngPower(double power, const double ratedPower) {
     197      142772 :         if (power < _normalizedPowerPatternFCvalues.front() * ratedPower) {
     198             :             return _normalizedPowerPatternFCvalues.front() * ratedPower;
     199             :         }
     200      139804 :         if (power > _normalizedPowerPatternFCvalues.back() * ratedPower) {
     201        1064 :             return _normalizedPowerPatternFCvalues.back() * ratedPower;
     202             :         }
     203             : 
     204             :         return power;
     205             :     }
     206             : 
     207      141408 :     double CEP::GetEmission(const std::string& pollutant, double power, double speed, Helpers* VehicleClass, const double drivingPower, const double ratedPower) {
     208             :         //Declaration
     209             :         std::vector<double>* emissionCurve = nullptr;
     210             :         std::vector<double>* powerPattern = nullptr;
     211             : 
     212             :         // bisection search to find correct position in power pattern
     213             :         int upperIndex;
     214             :         int lowerIndex;
     215             : 
     216      141408 :         double emissionMultiplier = getHeavyVehicle() ? ratedPower : 1.;
     217      141408 :         if (std::abs(speed) <= Constants::ZERO_SPEED_ACCURACY) {
     218       38752 :             if (_cepNormalizedCurvePollutants.find(pollutant) == _cepNormalizedCurvePollutants.end() && _normedCepCurveFCvalues.find(pollutant) == _normedCepCurveFCvalues.end()) {
     219           0 :                 VehicleClass->setErrMsg(std::string("Emission pollutant or fuel value ") + pollutant + std::string(" not found!"));
     220           0 :                 return 0;
     221             :             }
     222             : 
     223       38752 :             if (_normedCepCurveFCvalues.find(pollutant) != _normedCepCurveFCvalues.end()) {
     224        9688 :                 return _idlingValueFCvalues[pollutant] * ratedPower;
     225             :             }
     226       29064 :             else if (_cepNormalizedCurvePollutants.find(pollutant) != _cepNormalizedCurvePollutants.end()) {
     227       29064 :                 return _idlingValuesPollutants[pollutant] * emissionMultiplier;
     228             :             }
     229             :         }
     230             : 
     231             : 
     232      102656 :         if (_cepNormalizedCurvePollutants.find(pollutant) == _cepNormalizedCurvePollutants.end() && _normedCepCurveFCvalues.find(pollutant) == _normedCepCurveFCvalues.end()) {
     233           0 :             VehicleClass->setErrMsg(std::string("Emission pollutant or fuel value ") + pollutant + std::string(" not found!"));
     234           0 :             return 0;
     235             :         }
     236             : 
     237             :         double normalizingPower = ratedPower;
     238      102656 :         if (_normedCepCurveFCvalues.find(pollutant) != _normedCepCurveFCvalues.end()) {
     239       25664 :             emissionCurve = &_normedCepCurveFCvalues[pollutant];
     240       25664 :             powerPattern = &_normalizedPowerPatternFCvalues;
     241             :             emissionMultiplier = ratedPower;
     242             :         }
     243       76992 :         else if (_cepNormalizedCurvePollutants.find(pollutant) != _cepNormalizedCurvePollutants.end()) {
     244       76992 :             emissionCurve = &_cepNormalizedCurvePollutants[pollutant];
     245       76992 :             powerPattern = &_normalizedPowerPatternPollutants;
     246       76992 :             if (!getHeavyVehicle()) {
     247             :                 normalizingPower = drivingPower;
     248             :             }
     249             :         }
     250             : 
     251      102656 :         if (emissionCurve == nullptr || emissionCurve->empty()) {
     252           0 :             VehicleClass->setErrMsg(std::string("Empty emission curve for ") + pollutant + std::string(" found!"));
     253           0 :             return 0;
     254             :         }
     255      102656 :         if (emissionCurve->size() == 1) {
     256           0 :             return emissionCurve->front() * emissionMultiplier;
     257             :         }
     258             : 
     259             :         // in case that the demanded power is smaller than the first entry (smallest) in the power pattern the first is returned (should never happen)
     260      102656 :         if (power <= powerPattern->front() * normalizingPower) {
     261           0 :             return emissionCurve->front() * emissionMultiplier;
     262             :         }
     263             : 
     264             :         // if power bigger than all entries in power pattern return the last (should never happen)
     265      102656 :         if (power >= powerPattern->back() * normalizingPower) {
     266         304 :             return emissionCurve->back() * emissionMultiplier;
     267             :         }
     268             : 
     269      102352 :         FindLowerUpperInPattern(lowerIndex, upperIndex, *powerPattern, power, normalizingPower);
     270      102352 :         return Interpolate(power, (*powerPattern)[lowerIndex] * normalizingPower, (*powerPattern)[upperIndex] * normalizingPower, (*emissionCurve)[lowerIndex], (*emissionCurve)[upperIndex]) * emissionMultiplier;
     271             :     }
     272             : 
     273       17676 :     double CEP::GetCO2Emission(double _FC, double _CO, double _HC, Helpers* VehicleClass) {
     274             :         //Declaration
     275             :         double fCBr, fCHC, fCCO, fCCO2;
     276             : 
     277       17676 :         fCBr = 0;
     278       17676 :         fCHC = 0;
     279       17676 :         fCCO = 0;
     280       17676 :         fCCO2 = 0;
     281             : 
     282       35352 :         if (getFuelType() != "Mix") {
     283       17676 :             if (!GetfcVals(getFuelType(), fCBr, fCHC, fCCO, fCCO2, VehicleClass)) {
     284             :                 return 0;
     285             :             }
     286             :         }
     287             :         else {
     288           0 :             if (!CalcfCValMix(fCBr, fCHC, fCCO, fCCO2, VehicleClass)) {
     289             :                 return 0;
     290             :             }
     291             :         }
     292             : 
     293       17676 :         return (_FC * fCBr - _CO * fCCO - _HC * fCHC) / fCCO2;
     294             :     }
     295             : 
     296           0 :     bool CEP::CalcfCValMix(double& _fCBr, double& _fCHC, double& _fCCO, double& _fCCO2, Helpers* VehicleClass) {
     297             :         //Declaration
     298             :         double Sum = 0;
     299             :         double sumfCBr, sumfCHC, sumfCCO, sumfCCO2;
     300             : 
     301             :         //Initialise
     302             :         sumfCBr = 0;
     303             :         sumfCHC = 0;
     304             :         sumfCCO = 0;
     305             :         sumfCCO2 = 0;
     306             : 
     307             :         //calculate the sum
     308           0 :         for (std::map<std::string, double>::const_iterator id = _FleetMix.begin(); id != _FleetMix.end(); ++id) {
     309           0 :             Sum += _FleetMix[id->first];
     310             :         }
     311             : 
     312             :         //Calculate the weighted fuel factors
     313           0 :         if (Sum <= 0) {
     314           0 :             VehicleClass->setErrMsg("All propolsion types in the fleetshares file are not known!");
     315           0 :             return false;
     316             :         }
     317             :         else {
     318           0 :             for (std::map<std::string, double>::const_iterator id = _FleetMix.begin(); id != _FleetMix.end(); ++id) {
     319           0 :                 if (!GetfcVals(id->first, _fCBr, _fCHC, _fCCO, _fCCO2, VehicleClass)) {
     320             :                     return false;
     321             :                 }
     322             :                 else {
     323           0 :                     sumfCBr += _fCBr * _FleetMix[id->first] / Sum;
     324           0 :                     sumfCHC += _fCHC * _FleetMix[id->first] / Sum;
     325           0 :                     sumfCCO += _fCCO * _FleetMix[id->first] / Sum;
     326           0 :                     sumfCCO2 += _fCCO2 * _FleetMix[id->first] / Sum;
     327             :                 }
     328             :             }
     329             :         }
     330             :         //Result values
     331           0 :         _fCBr = sumfCBr;
     332           0 :         _fCHC = sumfCHC;
     333           0 :         _fCCO = sumfCCO;
     334           0 :         _fCCO2 = sumfCCO2;
     335           0 :         return true;
     336             :     }
     337             : 
     338       17676 :     bool CEP::GetfcVals(const std::string& _fuelTypex, double& _fCBr, double& _fCHC, double& _fCCO, double& _fCCO2, Helpers* VehicleClass) {
     339       17676 :         _fCHC = 0.866;
     340       17676 :         _fCCO = 0.429;
     341       17676 :         _fCCO2 = 0.273;
     342             : 
     343             : //C# TO C++ CONVERTER NOTE: The following 'switch' operated on a string variable and was converted to C++ 'if-else' logic:
     344             : //        switch (_fuelTypex)
     345             : //ORIGINAL LINE: case Constants.strGasoline:
     346       17676 :         if (_fuelTypex == Constants::strGasoline) {
     347        9232 :                 _fCBr = 0.865;
     348             :         }
     349             : //ORIGINAL LINE: case Constants.strDiesel:
     350        8444 :         else if (_fuelTypex == Constants::strDiesel) {
     351        8444 :                 _fCBr = 0.863;
     352             :         }
     353             : //ORIGINAL LINE: case Constants.strCNG:
     354           0 :         else if (_fuelTypex == Constants::strCNG) {
     355           0 :                 _fCBr = 0.693;
     356           0 :                 _fCHC = 0.803;
     357             :         }
     358             : //ORIGINAL LINE: case Constants.strLPG:
     359           0 :         else if (_fuelTypex == Constants::strLPG) {
     360           0 :                 _fCBr = 0.825;
     361           0 :                 _fCHC = 0.825;
     362             :         }
     363             :         else {
     364           0 :                 VehicleClass->setErrMsg(std::string("The propulsion type is not known! (") + getFuelType() + std::string(")"));
     365           0 :                 return false;
     366             :         }
     367             :         return true;
     368             :     }
     369             : 
     370      161636 :     double CEP::getFMot(const double speed, const double ratedPower, const double wheelRadius) {
     371      161636 :         if (speed < 10e-2) {
     372             :             return 0.;
     373             :         }
     374             :         //Declaration
     375             :         int upperIndex;
     376             :         int lowerIndex;
     377             : 
     378      161636 :         FindLowerUpperInPattern(lowerIndex, upperIndex, _speedPatternRotational, speed);
     379      161636 :         double iGear = Interpolate(speed, _speedPatternRotational[lowerIndex], _speedPatternRotational[upperIndex], _gearTransmissionCurve[lowerIndex], _gearTransmissionCurve[upperIndex]);
     380             : 
     381      161636 :         double iTot = iGear * _axleRatio;
     382             : 
     383      161636 :         double n = (30 * speed * iTot) / (wheelRadius * M_PI);
     384      161636 :         double nNorm = (n - _engineIdlingSpeed) / (_engineRatedSpeed - _engineIdlingSpeed);
     385             : 
     386      161636 :         FindLowerUpperInPattern(lowerIndex, upperIndex, _nNormTable, nNorm);
     387      161636 :         return (-Interpolate(nNorm, _nNormTable[lowerIndex], _nNormTable[upperIndex], _dragNormTable[lowerIndex], _dragNormTable[upperIndex]) * ratedPower * 1000 / speed) / Constants::getDRIVE_TRAIN_EFFICIENCY();
     388             :     }
     389             : 
     390      650572 :     double CEP::GetRotationalCoeffecient(double speed) {
     391             :         //Declaration
     392             :         int upperIndex;
     393             :         int lowerIndex;
     394             : 
     395      650572 :         FindLowerUpperInPattern(lowerIndex, upperIndex, _speedPatternRotational, speed);
     396      650572 :         return Interpolate(speed, _speedPatternRotational[lowerIndex], _speedPatternRotational[upperIndex], _speedCurveRotational[lowerIndex], _speedCurveRotational[upperIndex]);
     397             :     }
     398             : 
     399     1076196 :     void CEP::FindLowerUpperInPattern(int& lowerIndex, int& upperIndex, const std::vector<double>& pattern, double value, double scale) {
     400     1076196 :         lowerIndex = 0;
     401     1076196 :         upperIndex = 0;
     402             : 
     403     1076196 :         if (value <= pattern.front() * scale) {
     404             :             lowerIndex = 0;
     405             :             upperIndex = 0;
     406             :             return;
     407             :         }
     408             : 
     409     1044640 :         if (value >= pattern.back() * scale) {
     410           0 :             lowerIndex = (int)pattern.size() - 1;
     411           0 :             upperIndex = (int)pattern.size() - 1;
     412           0 :             return;
     413             :         }
     414             : 
     415             :         // bisection search to find correct position in power pattern
     416     1044640 :         int middleIndex = ((int)pattern.size() - 1) / 2;
     417     1044640 :         upperIndex = (int)pattern.size() - 1;
     418     1044640 :         lowerIndex = 0;
     419             : 
     420     4317798 :         while (upperIndex - lowerIndex > 1) {
     421     3273158 :             if (pattern[middleIndex] * scale == value) {
     422           0 :                 lowerIndex = middleIndex;
     423           0 :                 upperIndex = middleIndex;
     424           0 :                 return;
     425             :             }
     426     3273158 :             else if (pattern[middleIndex] * scale < value) {
     427     1541592 :                 lowerIndex = middleIndex;
     428     1541592 :                 middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
     429             :             }
     430             :             else {
     431     1731566 :                 upperIndex = middleIndex;
     432     1731566 :                 middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
     433             :             }
     434             :         }
     435             :     }
     436             : 
     437     1105680 :     double CEP::Interpolate(double px, double p1, double p2, double e1, double e2) {
     438     1105680 :         if (p2 == p1) {
     439             :             return e1;
     440             :         }
     441             : 
     442     1074124 :         return e1 + (px - p1) / (p2 - p1) * (e2 - e1);
     443             :     }
     444             : 
     445      111216 :     double CEP::GetPMaxNorm(double speed) {
     446             :         // Linear function between v0 and v1, constant elsewhere
     447      111216 :         if (speed <= _pNormV0) {
     448        5264 :             return _pNormP0;
     449             :         }
     450      105952 :         else if (speed >= _pNormV1) {
     451       76468 :             return _pNormP1;
     452             :         }
     453             :         else {
     454       29484 :             return Interpolate(speed, _pNormV0, _pNormV1, _pNormP0, _pNormP1);
     455             :         }
     456             :     }
     457             : 
     458          38 :     void CEP::InitializeInstanceFields() {
     459          38 :         _massVehicle = 0;
     460          38 :         _vehicleLoading = 0;
     461          38 :         _vehicleMassRot = 0;
     462          38 :         _crossSectionalArea = 0;
     463          38 :         _cWValue = 0;
     464          38 :         _resistanceF0 = 0;
     465          38 :         _resistanceF1 = 0;
     466          38 :         _resistanceF2 = 0;
     467          38 :         _resistanceF3 = 0;
     468          38 :         _resistanceF4 = 0;
     469          38 :         _axleRatio = 0;
     470          38 :         _auxPower = 0;
     471          38 :         _pNormV0 = 0;
     472          38 :         _pNormP0 = 0;
     473          38 :         _pNormV1 = 0;
     474          38 :         _pNormP1 = 0;
     475          38 :         _engineRatedSpeed = 0;
     476          38 :         _engineIdlingSpeed = 0;
     477          38 :         _effectiveWheelDiameter = 0;
     478          38 :     }
     479             : }

Generated by: LCOV version 1.14