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

            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           33 :     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           33 :         InitializeInstanceFields();
      35           33 :         _resistanceF0 = Vehicle->getRollingResData()->getFr0();
      36           33 :         _resistanceF1 = Vehicle->getRollingResData()->getFr1();
      37           33 :         _resistanceF2 = Vehicle->getRollingResData()->getFr2();
      38           33 :         _resistanceF3 = Vehicle->getRollingResData()->getFr3();
      39           33 :         _resistanceF4 = Vehicle->getRollingResData()->getFr4();
      40           33 :         _cWValue = Vehicle->getVehicleData()->getCw();
      41           33 :         _crossSectionalArea = Vehicle->getVehicleData()->getA();
      42           33 :         _massVehicle = Vehicle->getVehicleData()->getMass();
      43           33 :         _vehicleLoading = Vehicle->getVehicleData()->getLoading();
      44           33 :         _vehicleMassRot = Vehicle->getVehicleData()->getRedMassWheel();
      45           33 :         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           33 :         if (getCalcType() == "Conv") {
      50           33 :                 setRatedPower(Vehicle->getEngineData()->getICEData()->getPrated());
      51           33 :                 _engineRatedSpeed = Vehicle->getEngineData()->getICEData()->getnrated();
      52           33 :                 _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           33 :         _effectiveWheelDiameter = Vehicle->getVehicleData()->getWheelDiameter();
      69           33 :         privateHeavyVehicle = Vehicle->getVehicleData()->getMassType() == Constants::HeavyVehicle;
      70           33 :         setFuelType(Vehicle->getVehicleData()->getFuelType());
      71           33 :         _axleRatio = Vehicle->getTransmissionData()->getAxelRatio();
      72           33 :         _auxPower = Vehicle->getAuxiliariesData()->getPauxnorm();
      73              : 
      74           33 :         _pNormV0 = Vehicle->getFLDData()->getP_n_max_v0() / 3.6;
      75           33 :         _pNormP0 = Vehicle->getFLDData()->getP_n_max_p0();
      76           33 :         _pNormV1 = Vehicle->getFLDData()->getP_n_max_v1() / 3.6;
      77           33 :         _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          132 :         for (int i = 0; i < (int)headerLineFCvalues.size(); i++) {
      83           99 :             FCvaluesIdentifier.push_back(headerLineFCvalues[i]);
      84           99 :             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          198 :         for (int i = 0; i < (int)headerLinePollutants.size(); i++) {
      91          165 :             pollutantIdentifier.push_back(headerLinePollutants[i]);
      92          165 :             normalizedPollutantMeasures.push_back(std::vector<double>());
      93              :         }
      94              : 
      95              :         // Assigning values for speed rotational table
      96           33 :         _speedPatternRotational = std::vector<double>();
      97          275 :         for (int i = 0; i < (int)Vehicle->getTransmissionData()->getTransm()["Speed"].size(); i++) {
      98          484 :             _speedPatternRotational.push_back(Vehicle->getTransmissionData()->getTransm()["Speed"][i] / 3.6);
      99              :         }
     100              : 
     101           33 :         _gearTransmissionCurve = Vehicle->getTransmissionData()->getTransm()["GearRatio"];
     102           33 :         _speedCurveRotational = Vehicle->getTransmissionData()->getTransm()["RotMassF"];
     103              : 
     104              :         // Assigning values for drag table
     105           33 :         _nNormTable = Vehicle->getFLDData()->getDragCurve()["n_norm"];
     106           66 :         _dragNormTable = Vehicle->getFLDData()->getDragCurve()["pe_drag_norm"];
     107              : 
     108              :         // Looping through matrix and assigning values for FC values
     109           33 :         _normalizedPowerPatternFCvalues = std::vector<double>();
     110              : 
     111           33 :         int headerFCCount = (int)headerLineFCvalues.size();
     112          462 :         for (int i = 0; i < (int)matrixFCvalues.size(); i++) {
     113         2145 :             for (int j = 0; j < (int)matrixFCvalues[i].size(); j++) {
     114         1716 :                 if ((int)matrixFCvalues[i].size() != headerFCCount + 1) {
     115              :                     return;
     116              :                 }
     117              : 
     118         1716 :                 if (j == 0) {
     119          429 :                     _normalizedPowerPatternFCvalues.push_back(matrixFCvalues[i][j]);
     120              :                 }
     121              :                 else {
     122         1287 :                     normalizedFCvaluesMeasures[j - 1].push_back(matrixFCvalues[i][j]);
     123              :                 }
     124              :             }
     125              :         }
     126              : 
     127           33 :         _idlingValueFCvalues = std::map<std::string, double>();
     128           33 :         _normedCepCurveFCvalues = std::map<std::string, std::vector<double> >();
     129              : 
     130          132 :         for (int i = 0; i < (int)headerLineFCvalues.size(); i++) {
     131          198 :             _normedCepCurveFCvalues.insert(std::make_pair(FCvaluesIdentifier[i], normalizedFCvaluesMeasures[i]));
     132           99 :             _idlingValueFCvalues.insert(std::make_pair(FCvaluesIdentifier[i], idlingFCvalues[i]));
     133              :         }
     134              : 
     135           33 :         _normalizedPowerPatternPollutants = std::vector<double>();
     136           33 :         _cepNormalizedCurvePollutants = std::map<std::string, std::vector<double> >();
     137              : 
     138           33 :         int headerCount = (int)headerLinePollutants.size();
     139         1056 :         for (int i = 0; i < (int)matrixPollutants.size(); i++) {
     140         7161 :             for (int j = 0; j < (int)matrixPollutants[i].size(); j++) {
     141         6138 :                 if ((int)matrixPollutants[i].size() != headerCount + 1) {
     142              :                     return;
     143              :                 }
     144              : 
     145         6138 :                 if (j == 0) {
     146         1023 :                     _normalizedPowerPatternPollutants.push_back(matrixPollutants[i][j]);
     147              :                 }
     148              :                 else {
     149         5115 :                     normalizedPollutantMeasures[j - 1].push_back(matrixPollutants[i][j]);
     150              :                 }
     151              :             }
     152              :         }
     153              : 
     154           33 :         _idlingValuesPollutants = std::map<std::string, double>();
     155              : 
     156          198 :         for (int i = 0; i < (int)headerLinePollutants.size(); i++) {
     157          330 :             _cepNormalizedCurvePollutants.insert(std::make_pair(pollutantIdentifier[i], normalizedPollutantMeasures[i]));
     158          165 :             _idlingValuesPollutants.insert(std::make_pair(pollutantIdentifier[i], idlingPollutants[i]));
     159              :         }
     160              : 
     161           33 :         _FleetMix = std::map<std::string, double>();
     162           33 :         _FleetMix.insert(std::make_pair(Constants::strGasoline, 0));
     163           33 :         _FleetMix.insert(std::make_pair(Constants::strDiesel, 0));
     164           33 :         _FleetMix.insert(std::make_pair(Constants::strCNG, 0));
     165           33 :         _FleetMix.insert(std::make_pair(Constants::strLPG, 0));
     166           33 :     }
     167              : 
     168       118514 :     const bool& CEP::getHeavyVehicle() const {
     169       118514 :         return privateHeavyVehicle;
     170              :     }
     171              : 
     172        95167 :     const std::string& CEP::getFuelType() const {
     173        95167 :         return privateFuelType;
     174              :     }
     175              : 
     176           33 :     void CEP::setFuelType(const std::string& value) {
     177           33 :         privateFuelType = value;
     178           33 :     }
     179              : 
     180       482858 :     const std::string& CEP::getCalcType() const {
     181       482858 :         return privateCalcType;
     182              :     }
     183              : 
     184           33 :     void CEP::setCalcType(const std::string& value) {
     185           33 :         privateCalcType = value;
     186           33 :     }
     187              : 
     188       425566 :     const double& CEP::getRatedPower() const {
     189       425566 :         return privateRatedPower;
     190              :     }
     191              : 
     192           33 :     void CEP::setRatedPower(const double& value) {
     193           33 :         privateRatedPower = value;
     194           33 :     }
     195              : 
     196        76211 :     double CEP::CalcEngPower(double power, const double ratedPower) {
     197        76211 :         if (power < _normalizedPowerPatternFCvalues.front() * ratedPower) {
     198              :             return _normalizedPowerPatternFCvalues.front() * ratedPower;
     199              :         }
     200        74727 :         if (power > _normalizedPowerPatternFCvalues.back() * ratedPower) {
     201          924 :             return _normalizedPowerPatternFCvalues.back() * ratedPower;
     202              :         }
     203              : 
     204              :         return power;
     205              :     }
     206              : 
     207        76169 :     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        76169 :         double emissionMultiplier = getHeavyVehicle() ? ratedPower : 1.;
     217        76169 :         if (std::abs(speed) <= Constants::ZERO_SPEED_ACCURACY) {
     218        19408 :             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        19408 :             if (_normedCepCurveFCvalues.find(pollutant) != _normedCepCurveFCvalues.end()) {
     224         4852 :                 return _idlingValueFCvalues[pollutant] * ratedPower;
     225              :             }
     226        14556 :             else if (_cepNormalizedCurvePollutants.find(pollutant) != _cepNormalizedCurvePollutants.end()) {
     227        14556 :                 return _idlingValuesPollutants[pollutant] * emissionMultiplier;
     228              :             }
     229              :         }
     230              : 
     231              : 
     232        56761 :         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        56761 :         if (_normedCepCurveFCvalues.find(pollutant) != _normedCepCurveFCvalues.end()) {
     239        14449 :             emissionCurve = &_normedCepCurveFCvalues[pollutant];
     240        14449 :             powerPattern = &_normalizedPowerPatternFCvalues;
     241              :             emissionMultiplier = ratedPower;
     242              :         }
     243        42312 :         else if (_cepNormalizedCurvePollutants.find(pollutant) != _cepNormalizedCurvePollutants.end()) {
     244        42312 :             emissionCurve = &_cepNormalizedCurvePollutants[pollutant];
     245        42312 :             powerPattern = &_normalizedPowerPatternPollutants;
     246        42312 :             if (!getHeavyVehicle()) {
     247              :                 normalizingPower = drivingPower;
     248              :             }
     249              :         }
     250              : 
     251        56761 :         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        56761 :         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        56761 :         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        56761 :         if (power >= powerPattern->back() * normalizingPower) {
     266          264 :             return emissionCurve->back() * emissionMultiplier;
     267              :         }
     268              : 
     269        56497 :         FindLowerUpperInPattern(lowerIndex, upperIndex, *powerPattern, power, normalizingPower);
     270        56497 :         return Interpolate(power, (*powerPattern)[lowerIndex] * normalizingPower, (*powerPattern)[upperIndex] * normalizingPower, (*emissionCurve)[lowerIndex], (*emissionCurve)[upperIndex]) * emissionMultiplier;
     271              :     }
     272              : 
     273         9478 :     double CEP::GetCO2Emission(double _FC, double _CO, double _HC, Helpers* VehicleClass) {
     274              :         //Declaration
     275              :         double fCBr, fCHC, fCCO, fCCO2;
     276              : 
     277         9478 :         fCBr = 0;
     278         9478 :         fCHC = 0;
     279         9478 :         fCCO = 0;
     280         9478 :         fCCO2 = 0;
     281              : 
     282         9478 :         if (getFuelType() != "Mix") {
     283         9478 :             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         9478 :         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         9478 :     bool CEP::GetfcVals(const std::string& _fuelTypex, double& _fCBr, double& _fCHC, double& _fCCO, double& _fCCO2, Helpers* VehicleClass) {
     339         9478 :         _fCHC = 0.866;
     340         9478 :         _fCCO = 0.429;
     341         9478 :         _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         9478 :         if (_fuelTypex == Constants::strGasoline) {
     347         5141 :                 _fCBr = 0.865;
     348              :         }
     349              : //ORIGINAL LINE: case Constants.strDiesel:
     350         4337 :         else if (_fuelTypex == Constants::strDiesel) {
     351         4337 :                 _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        85643 :     double CEP::getFMot(const double speed, const double ratedPower, const double wheelRadius) {
     371        85643 :         if (speed < 10e-2) {
     372              :             return 0.;
     373              :         }
     374              :         //Declaration
     375              :         int upperIndex;
     376              :         int lowerIndex;
     377              : 
     378        85643 :         FindLowerUpperInPattern(lowerIndex, upperIndex, _speedPatternRotational, speed);
     379        85643 :         double iGear = Interpolate(speed, _speedPatternRotational[lowerIndex], _speedPatternRotational[upperIndex], _gearTransmissionCurve[lowerIndex], _gearTransmissionCurve[upperIndex]);
     380              : 
     381        85643 :         double iTot = iGear * _axleRatio;
     382              : 
     383        85643 :         double n = (30 * speed * iTot) / (wheelRadius * M_PI);
     384        85643 :         double nNorm = (n - _engineIdlingSpeed) / (_engineRatedSpeed - _engineIdlingSpeed);
     385              : 
     386        85643 :         FindLowerUpperInPattern(lowerIndex, upperIndex, _nNormTable, nNorm);
     387        85643 :         return (-Interpolate(nNorm, _nNormTable[lowerIndex], _nNormTable[upperIndex], _dragNormTable[lowerIndex], _dragNormTable[upperIndex]) * ratedPower * 1000 / speed) / Constants::getDRIVE_TRAIN_EFFICIENCY();
     388              :     }
     389              : 
     390       349355 :     double CEP::GetRotationalCoeffecient(double speed) {
     391              :         //Declaration
     392              :         int upperIndex;
     393              :         int lowerIndex;
     394              : 
     395       349355 :         FindLowerUpperInPattern(lowerIndex, upperIndex, _speedPatternRotational, speed);
     396       349355 :         return Interpolate(speed, _speedPatternRotational[lowerIndex], _speedPatternRotational[upperIndex], _speedCurveRotational[lowerIndex], _speedCurveRotational[upperIndex]);
     397              :     }
     398              : 
     399       577138 :     void CEP::FindLowerUpperInPattern(int& lowerIndex, int& upperIndex, const std::vector<double>& pattern, double value, double scale) {
     400       577138 :         lowerIndex = 0;
     401       577138 :         upperIndex = 0;
     402              : 
     403       577138 :         if (value <= pattern.front() * scale) {
     404              :             lowerIndex = 0;
     405              :             upperIndex = 0;
     406              :             return;
     407              :         }
     408              : 
     409       561332 :         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       561332 :         int middleIndex = ((int)pattern.size() - 1) / 2;
     417       561332 :         upperIndex = (int)pattern.size() - 1;
     418       561332 :         lowerIndex = 0;
     419              : 
     420      2327243 :         while (upperIndex - lowerIndex > 1) {
     421      1765911 :             if (pattern[middleIndex] * scale == value) {
     422            0 :                 lowerIndex = middleIndex;
     423            0 :                 upperIndex = middleIndex;
     424            0 :                 return;
     425              :             }
     426      1765911 :             else if (pattern[middleIndex] * scale < value) {
     427       851549 :                 lowerIndex = middleIndex;
     428       851549 :                 middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
     429              :             }
     430              :             else {
     431       914362 :                 upperIndex = middleIndex;
     432       914362 :                 middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
     433              :             }
     434              :         }
     435              :     }
     436              : 
     437       592020 :     double CEP::Interpolate(double px, double p1, double p2, double e1, double e2) {
     438       592020 :         if (p2 == p1) {
     439              :             return e1;
     440              :         }
     441              : 
     442       576214 :         return e1 + (px - p1) / (p2 - p1) * (e2 - e1);
     443              :     }
     444              : 
     445        60405 :     double CEP::GetPMaxNorm(double speed) {
     446              :         // Linear function between v0 and v1, constant elsewhere
     447        60405 :         if (speed <= _pNormV0) {
     448         2632 :             return _pNormP0;
     449              :         }
     450        57773 :         else if (speed >= _pNormV1) {
     451        42891 :             return _pNormP1;
     452              :         }
     453              :         else {
     454        14882 :             return Interpolate(speed, _pNormV0, _pNormV1, _pNormP0, _pNormP1);
     455              :         }
     456              :     }
     457              : 
     458           33 :     void CEP::InitializeInstanceFields() {
     459           33 :         _massVehicle = 0;
     460           33 :         _vehicleLoading = 0;
     461           33 :         _vehicleMassRot = 0;
     462           33 :         _crossSectionalArea = 0;
     463           33 :         _cWValue = 0;
     464           33 :         _resistanceF0 = 0;
     465           33 :         _resistanceF1 = 0;
     466           33 :         _resistanceF2 = 0;
     467           33 :         _resistanceF3 = 0;
     468           33 :         _resistanceF4 = 0;
     469           33 :         _axleRatio = 0;
     470           33 :         _auxPower = 0;
     471           33 :         _pNormV0 = 0;
     472           33 :         _pNormP0 = 0;
     473           33 :         _pNormV1 = 0;
     474           33 :         _pNormP1 = 0;
     475           33 :         _engineRatedSpeed = 0;
     476           33 :         _engineIdlingSpeed = 0;
     477           33 :         _effectiveWheelDiameter = 0;
     478           33 :     }
     479              : }
        

Generated by: LCOV version 2.0-1