LCOV - code coverage report
Current view: top level - src/utils/emissions - PollutantsInterface.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 69.4 % 134 93
Test Date: 2024-12-21 15:45:41 Functions: 71.4 % 35 25

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2013-2024 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    PollutantsInterface.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Michael Behrisch
      17              : /// @date    Mon, 19.08.2013
      18              : ///
      19              : // Interface to capsulate different emission models
      20              : /****************************************************************************/
      21              : #include <config.h>
      22              : 
      23              : #include <limits>
      24              : #include <cmath>
      25              : #include <utils/common/SUMOVehicleClass.h>
      26              : #include <utils/common/StringUtils.h>
      27              : #include <utils/common/ToString.h>
      28              : #include <utils/options/OptionsCont.h>
      29              : #include <foreign/PHEMlight/V5/cpp/Constants.h>
      30              : 
      31              : #include "HelpersHBEFA.h"
      32              : #include "HelpersHBEFA3.h"
      33              : #include "HelpersHBEFA4.h"
      34              : #include "HelpersPHEMlight.h"
      35              : #include "HelpersEnergy.h"
      36              : #include "HelpersMMPEVEM.h"
      37              : #include "HelpersPHEMlight5.h"
      38              : #include "PollutantsInterface.h"
      39              : 
      40              : 
      41              : // ===========================================================================
      42              : // static definitions
      43              : // ===========================================================================
      44              : const double PollutantsInterface::Helper::ZERO_SPEED_ACCURACY = .5;
      45              : PollutantsInterface::Helper PollutantsInterface::myZeroHelper("Zero", PollutantsInterface::ZERO_EMISSIONS, PollutantsInterface::ZERO_EMISSIONS);
      46              : HelpersHBEFA PollutantsInterface::myHBEFA2Helper;
      47              : HelpersHBEFA3 PollutantsInterface::myHBEFA3Helper;
      48              : HelpersPHEMlight PollutantsInterface::myPHEMlightHelper;
      49              : HelpersEnergy PollutantsInterface::myEnergyHelper;
      50              : HelpersMMPEVEM PollutantsInterface::myMMPEVEMHelper;
      51              : HelpersPHEMlight5 PollutantsInterface::myPHEMlight5Helper;
      52              : HelpersHBEFA4 PollutantsInterface::myHBEFA4Helper;
      53              : PollutantsInterface::Helper* PollutantsInterface::myHelpers[] = {
      54              :     &PollutantsInterface::myZeroHelper,
      55              :     &PollutantsInterface::myHBEFA2Helper, &PollutantsInterface::myHBEFA3Helper,
      56              :     &PollutantsInterface::myPHEMlightHelper, &PollutantsInterface::myEnergyHelper,
      57              :     &PollutantsInterface::myMMPEVEMHelper, &PollutantsInterface::myPHEMlight5Helper,
      58              :     &PollutantsInterface::myHBEFA4Helper
      59              : };
      60              : std::vector<std::string> PollutantsInterface::myAllClassesStr;
      61              : 
      62              : 
      63              : // ===========================================================================
      64              : // method definitions
      65              : // ===========================================================================
      66              : 
      67              : // ---------------------------------------------------------------------------
      68              : // PollutantsInterface::Emissions - methods
      69              : // ---------------------------------------------------------------------------
      70              : 
      71    102686801 : PollutantsInterface::Emissions::Emissions(double co2, double co, double hc, double f, double nox, double pmx, double elec) :
      72    102686801 :     CO2(co2),
      73    102686801 :     CO(co),
      74    102686801 :     HC(hc),
      75    102686801 :     fuel(f),
      76    102686801 :     NOx(nox),
      77    102686801 :     PMx(pmx),
      78    102686801 :     electricity(elec) {
      79    102686801 : }
      80              : 
      81              : 
      82    101245198 : void PollutantsInterface::Emissions::addScaled(const Emissions& a, const double scale) {
      83    101245198 :     CO2 += scale * a.CO2;
      84    101245198 :     CO += scale * a.CO;
      85    101245198 :     HC += scale * a.HC;
      86    101245198 :     fuel += scale * a.fuel;
      87    101245198 :     NOx += scale * a.NOx;
      88    101245198 :     PMx += scale * a.PMx;
      89    101245198 :     electricity += scale * a.electricity;
      90    101245198 : }
      91              : 
      92              : // ---------------------------------------------------------------------------
      93              : // PollutantsInterface::Helper - methods
      94              : // ---------------------------------------------------------------------------
      95              : 
      96       449424 : PollutantsInterface::Helper::Helper(std::string name, const int baseIndex, const int defaultClass) :
      97       449424 :     myName(name),
      98       449424 :     myBaseIndex(baseIndex) {
      99       449424 :     if (defaultClass != -1) {
     100       168534 :         myEmissionClassStrings.insert("default", defaultClass);
     101       337068 :         myEmissionClassStrings.addAlias("unknown", defaultClass);
     102              :     }
     103       449424 : }
     104              : 
     105              : 
     106              : const
     107      3022433 : std::string& PollutantsInterface::Helper::getName() const {
     108      3022433 :     return myName;
     109              : }
     110              : 
     111              : 
     112              : SUMOEmissionClass
     113      1002425 : PollutantsInterface::Helper::getClassByName(const std::string& eClass, const SUMOVehicleClass vc) {
     114              :     UNUSED_PARAMETER(vc);
     115      1998828 :     myVolumetricFuel = OptionsCont::getOptions().exists("emissions.volumetric-fuel") && OptionsCont::getOptions().getBool("emissions.volumetric-fuel");
     116              :     if (myEmissionClassStrings.hasString(eClass)) {
     117      1002425 :         return myEmissionClassStrings.get(eClass);
     118              :     }
     119            0 :     return myEmissionClassStrings.get(StringUtils::to_lower_case(eClass));
     120              : }
     121              : 
     122              : 
     123              : const std::string
     124       341759 : PollutantsInterface::Helper::getClassName(const SUMOEmissionClass c) const {
     125       683518 :     return myName + "/" + myEmissionClassStrings.getString(c);
     126              : }
     127              : 
     128              : 
     129              : bool
     130       776866 : PollutantsInterface::Helper::isSilent(const SUMOEmissionClass c) {
     131       776866 :     return (c & (int)0xffffffff & ~HEAVY_BIT) == 0;
     132              : }
     133              : 
     134              : 
     135              : SUMOEmissionClass
     136            2 : PollutantsInterface::Helper::getClass(const SUMOEmissionClass base, const std::string& vClass, const std::string& fuel, const std::string& eClass, const double weight) const {
     137              :     UNUSED_PARAMETER(vClass);
     138              :     UNUSED_PARAMETER(fuel);
     139              :     UNUSED_PARAMETER(eClass);
     140              :     UNUSED_PARAMETER(weight);
     141            2 :     return base;
     142              : }
     143              : 
     144              : 
     145              : std::string
     146            0 : PollutantsInterface::Helper::getAmitranVehicleClass(const SUMOEmissionClass c) const {
     147              :     UNUSED_PARAMETER(c);
     148            0 :     return "Passenger";
     149              : }
     150              : 
     151              : 
     152              : std::string
     153            0 : PollutantsInterface::Helper::getFuel(const SUMOEmissionClass c) const {
     154              :     UNUSED_PARAMETER(c);
     155            0 :     return "Gasoline";
     156              : }
     157              : 
     158              : 
     159              : int
     160            0 : PollutantsInterface::Helper::getEuroClass(const SUMOEmissionClass c) const {
     161              :     UNUSED_PARAMETER(c);
     162            0 :     return 0;
     163              : }
     164              : 
     165              : 
     166              : double
     167       320133 : PollutantsInterface::Helper::getWeight(const SUMOEmissionClass c) const {
     168              :     UNUSED_PARAMETER(c);
     169       320133 :     return -1.;
     170              : }
     171              : 
     172              : 
     173              : double
     174        94220 : PollutantsInterface::Helper::compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const EnergyParams* param) const {
     175              :     UNUSED_PARAMETER(c);
     176              :     UNUSED_PARAMETER(e);
     177              :     UNUSED_PARAMETER(v);
     178              :     UNUSED_PARAMETER(a);
     179              :     UNUSED_PARAMETER(slope);
     180              :     UNUSED_PARAMETER(param);
     181        94220 :     return 0.;
     182              : }
     183              : 
     184              : 
     185              : double
     186            0 : PollutantsInterface::Helper::getModifiedAccel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) const {
     187              :     UNUSED_PARAMETER(c);
     188              :     UNUSED_PARAMETER(v);
     189              :     UNUSED_PARAMETER(slope);
     190              :     UNUSED_PARAMETER(param);
     191            0 :     return a;
     192              : }
     193              : 
     194              : 
     195              : double
     196    315920520 : PollutantsInterface::Helper::getCoastingDecel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) const {
     197              :     // the interpolation for small v is basically the same as in PHEMlightdllV5::CEP::GetDecelCoast
     198    315920520 :     if (v < PHEMlightdllV5::Constants::SPEED_DCEL_MIN) {
     199     17271439 :         return v / PHEMlightdllV5::Constants::SPEED_DCEL_MIN * getCoastingDecel(c, PHEMlightdllV5::Constants::SPEED_DCEL_MIN, a, slope, param);
     200              :     }
     201    298649081 :     if (param == nullptr) {
     202         3780 :         param = EnergyParams::getDefault();
     203              :     }
     204              :     // the magic numbers below come from a linear interpolation with http://ts-sim-service-ba/svn/simo/trunk/projects/sumo/data/emissions/linear.py
     205    298649081 :     const double mass = param->getDouble(SUMO_ATTR_MASS);
     206    298649081 :     const double incl = param->getDouble(SUMO_ATTR_FRONTSURFACEAREA) / mass * -9.05337017 + -0.00017774;
     207    298649081 :     const double grad = PHEMlightdllV5::Constants::GRAVITY_CONST * slope / 100.;
     208    298649081 :     return MIN2(0., incl * v + 0.00001066 * mass + -0.38347107 - 20.0 * incl - grad);
     209              : }
     210              : 
     211              : 
     212              : void
     213            0 : PollutantsInterface::Helper::addAllClassesInto(std::vector<SUMOEmissionClass>& list) const {
     214            0 :     myEmissionClassStrings.addKeysInto(list);
     215            0 : }
     216              : 
     217              : 
     218              : bool
     219            0 : PollutantsInterface::Helper::includesClass(const SUMOEmissionClass c) const {
     220            0 :     return (c >> 16) == (myBaseIndex >> 16);
     221              : }
     222              : 
     223              : // ---------------------------------------------------------------------------
     224              : // PollutantsInterface - methods
     225              : // ---------------------------------------------------------------------------
     226              : 
     227              : SUMOEmissionClass
     228      1002595 : PollutantsInterface::getClassByName(const std::string& eClass, const SUMOVehicleClass vc) {
     229              :     const std::string::size_type sep = eClass.find("/");
     230      1002595 :     const std::string model = eClass.substr(0, sep); // this includes the case of no separator
     231      3023529 :     for (int i = 0; i < 8; i++) {
     232      3022433 :         if (myHelpers[i]->getName() == model) {
     233      1001499 :             if (sep != std::string::npos) {
     234      1001253 :                 const std::string subClass = eClass.substr(sep + 1);
     235      1001253 :                 if (subClass == "zero") {
     236       321866 :                     return myZeroHelper.getClassByName("default", vc);
     237              :                 }
     238       840320 :                 return myHelpers[i]->getClassByName(subClass, vc);
     239              :             }
     240          492 :             return myHelpers[i]->getClassByName("default", vc);
     241              :         }
     242              :     }
     243         1096 :     if (sep == std::string::npos) {
     244         1096 :         if (eClass == "zero") {
     245           28 :             return myZeroHelper.getClassByName("default", vc);
     246              :         }
     247              :         // default HBEFA2
     248         1082 :         return myHBEFA2Helper.getClassByName(eClass, vc);
     249              :     }
     250            0 :     throw InvalidArgument("Unknown emission class '" + eClass + "'.");
     251              : }
     252              : 
     253              : 
     254              : const std::vector<SUMOEmissionClass>
     255            0 : PollutantsInterface::getAllClasses() {
     256              :     std::vector<SUMOEmissionClass> result;
     257            0 :     for (int i = 0; i < 8; i++) {
     258            0 :         myHelpers[i]->addAllClassesInto(result);
     259              :     }
     260            0 :     return result;
     261            0 : }
     262              : 
     263              : 
     264              : const std::vector<std::string>&
     265            0 : PollutantsInterface::getAllClassesStr() {
     266              :     // first check if myAllClassesStr has to be filled
     267            0 :     if (myAllClassesStr.empty()) {
     268              :         // first obtain all emissionClasses
     269              :         std::vector<SUMOEmissionClass> emissionClasses;
     270            0 :         for (int i = 0; i < 8; i++) {
     271            0 :             myHelpers[i]->addAllClassesInto(emissionClasses);
     272              :         }
     273              :         // now write all emissionClasses in myAllClassesStr
     274            0 :         for (const auto& i : emissionClasses) {
     275            0 :             myAllClassesStr.push_back(getName(i));
     276              :         }
     277            0 :     }
     278            0 :     return myAllClassesStr;
     279              : }
     280              : 
     281              : std::string
     282       341759 : PollutantsInterface::getName(const SUMOEmissionClass c) {
     283       341759 :     return myHelpers[c >> 16]->getClassName(c);
     284              : }
     285              : 
     286              : 
     287              : std::string
     288            0 : PollutantsInterface::getPollutantName(const EmissionType e) {
     289            0 :     switch (e) {
     290              :         case CO2:
     291            0 :             return "CO2";
     292              :         case CO:
     293            0 :             return "CO";
     294              :         case HC:
     295            0 :             return "HC";
     296              :         case FUEL:
     297            0 :             return "fuel";
     298              :         case NO_X:
     299            0 :             return "NOx";
     300              :         case PM_X:
     301            0 :             return "PMx";
     302              :         case ELEC:
     303            0 :             return "electricity";
     304            0 :         default:
     305            0 :             throw InvalidArgument("Unknown emission type '" + toString(e) + "'");
     306              :     }
     307              : }
     308              : 
     309              : bool
     310       780099 : PollutantsInterface::isHeavy(const SUMOEmissionClass c) {
     311       780099 :     return (c & HEAVY_BIT) != 0;
     312              : }
     313              : 
     314              : 
     315              : bool
     316       776866 : PollutantsInterface::isSilent(const SUMOEmissionClass c) {
     317       776866 :     return myHelpers[c >> 16]->isSilent(c);
     318              : }
     319              : 
     320              : 
     321              : SUMOEmissionClass
     322            2 : PollutantsInterface::getClass(const SUMOEmissionClass base, const std::string& vClass,
     323              :                               const std::string& fuel, const std::string& eClass, const double weight) {
     324            2 :     return myHelpers[base >> 16]->getClass(base, vClass, fuel, eClass, weight);
     325              : }
     326              : 
     327              : 
     328              : std::string
     329            9 : PollutantsInterface::getAmitranVehicleClass(const SUMOEmissionClass c) {
     330            9 :     return myHelpers[c >> 16]->getAmitranVehicleClass(c);
     331              : }
     332              : 
     333              : 
     334              : std::string
     335         1672 : PollutantsInterface::getFuel(const SUMOEmissionClass c) {
     336         1672 :     return myHelpers[c >> 16]->getFuel(c);
     337              : }
     338              : 
     339              : 
     340              : int
     341            9 : PollutantsInterface::getEuroClass(const SUMOEmissionClass c) {
     342            9 :     return myHelpers[c >> 16]->getEuroClass(c);
     343              : }
     344              : 
     345              : 
     346              : double
     347       320351 : PollutantsInterface::getWeight(const SUMOEmissionClass c) {
     348       320351 :     return myHelpers[c >> 16]->getWeight(c);
     349              : }
     350              : 
     351              : 
     352              : double
     353       387787 : PollutantsInterface::compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const EnergyParams* param) {
     354       387787 :     return myHelpers[c >> 16]->compute(c, e, v, a, slope, param);
     355              : }
     356              : 
     357              : 
     358              : PollutantsInterface::Emissions
     359    100925613 : PollutantsInterface::computeAll(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) {
     360    100925613 :     const Helper* const h = myHelpers[c >> 16];
     361    302776839 :     return Emissions(h->compute(c, CO2, v, a, slope, param), h->compute(c, CO, v, a, slope, param), h->compute(c, HC, v, a, slope, param),
     362    302776839 :                      h->compute(c, FUEL, v, a, slope, param), h->compute(c, NO_X, v, a, slope, param), h->compute(c, PM_X, v, a, slope, param),
     363    100925613 :                      h->compute(c, ELEC, v, a, slope, param));
     364              : }
     365              : 
     366              : 
     367              : double
     368         7472 : PollutantsInterface::computeDefault(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const double tt, const EnergyParams* param) {
     369         7472 :     const Helper* const h = myHelpers[c >> 16];
     370         7472 :     return (h->compute(c, e, v, 0, slope, param) + h->compute(c, e, v - a, a, slope, param)) * tt / 2.;
     371              : }
     372              : 
     373              : 
     374              : double
     375            0 : PollutantsInterface::getModifiedAccel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) {
     376            0 :     return myHelpers[c >> 16]->getModifiedAccel(c, v, a, slope, param);
     377              : }
     378              : 
     379              : 
     380              : double
     381      1170747 : PollutantsInterface::getCoastingDecel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) {
     382      1170747 :     return myHelpers[c >> 16]->getCoastingDecel(c, v, a, slope, param);
     383              : }
     384              : 
     385              : 
     386              : const HelpersEnergy&
     387         1720 : PollutantsInterface::getEnergyHelper() {
     388         1720 :     return myEnergyHelper;
     389              : }
     390              : 
     391              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1