LCOV - code coverage report
Current view: top level - src/utils/emissions - PollutantsInterface.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 69.6 % 135 94
Test Date: 2024-11-21 15:56:26 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    102638573 : PollutantsInterface::Emissions::Emissions(double co2, double co, double hc, double f, double nox, double pmx, double elec) :
      72    102638573 :     CO2(co2),
      73    102638573 :     CO(co),
      74    102638573 :     HC(hc),
      75    102638573 :     fuel(f),
      76    102638573 :     NOx(nox),
      77    102638573 :     PMx(pmx),
      78    102638573 :     electricity(elec) {
      79    102638573 : }
      80              : 
      81              : 
      82    101197171 : void PollutantsInterface::Emissions::addScaled(const Emissions& a, const double scale) {
      83    101197171 :     CO2 += scale * a.CO2;
      84    101197171 :     CO += scale * a.CO;
      85    101197171 :     HC += scale * a.HC;
      86    101197171 :     fuel += scale * a.fuel;
      87    101197171 :     NOx += scale * a.NOx;
      88    101197171 :     PMx += scale * a.PMx;
      89    101197171 :     electricity += scale * a.electricity;
      90    101197171 : }
      91              : 
      92              : // ---------------------------------------------------------------------------
      93              : // PollutantsInterface::Helper - methods
      94              : // ---------------------------------------------------------------------------
      95              : 
      96       445160 : PollutantsInterface::Helper::Helper(std::string name, const int baseIndex, const int defaultClass) :
      97       445160 :     myName(name),
      98       445160 :     myBaseIndex(baseIndex) {
      99       445160 :     if (defaultClass != -1) {
     100       166935 :         myEmissionClassStrings.insert("default", defaultClass);
     101       333870 :         myEmissionClassStrings.addAlias("unknown", defaultClass);
     102              :     }
     103       445160 : }
     104              : 
     105              : 
     106              : const
     107      3955621 : std::string& PollutantsInterface::Helper::getName() const {
     108      3955621 :     return myName;
     109              : }
     110              : 
     111              : 
     112              : SUMOEmissionClass
     113      1313539 : PollutantsInterface::Helper::getClassByName(const std::string& eClass, const SUMOVehicleClass vc) {
     114              :     UNUSED_PARAMETER(vc);
     115      2621052 :     myVolumetricFuel = OptionsCont::getOptions().exists("emissions.volumetric-fuel") && OptionsCont::getOptions().getBool("emissions.volumetric-fuel");
     116              :     if (myEmissionClassStrings.hasString(eClass)) {
     117      1313539 :         return myEmissionClassStrings.get(eClass);
     118              :     }
     119            0 :     return myEmissionClassStrings.get(StringUtils::to_lower_case(eClass));
     120              : }
     121              : 
     122              : 
     123              : const std::string
     124       977629 : PollutantsInterface::Helper::getClassName(const SUMOEmissionClass c) const {
     125      1955258 :     return myName + "/" + myEmissionClassStrings.getString(c);
     126              : }
     127              : 
     128              : 
     129              : bool
     130       776740 : PollutantsInterface::Helper::isSilent(const SUMOEmissionClass c) {
     131       776740 :     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            9 : PollutantsInterface::Helper::getWeight(const SUMOEmissionClass c) const {
     168              :     UNUSED_PARAMETER(c);
     169            9 :     return -1.;
     170              : }
     171              : 
     172              : 
     173              : double
     174        92610 : 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        92610 :     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    315917043 : 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    315917043 :     if (v < PHEMlightdllV5::Constants::SPEED_DCEL_MIN) {
     199     17270004 :         return v / PHEMlightdllV5::Constants::SPEED_DCEL_MIN * getCoastingDecel(c, PHEMlightdllV5::Constants::SPEED_DCEL_MIN, a, slope, param);
     200              :     }
     201    298647039 :     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    298647039 :     const double mass = param->getDouble(SUMO_ATTR_MASS);
     206    298647039 :     const double area = param->getDouble(SUMO_ATTR_WIDTH) * param->getDouble(SUMO_ATTR_HEIGHT) * M_PI / 4.;
     207    298647039 :     const double incl = area / mass * -9.05337017 + -0.00017774;
     208    298647039 :     const double grad = PHEMlightdllV5::Constants::GRAVITY_CONST * slope / 100.;
     209    298647039 :     return MIN2(0., incl * v + 0.00001066 * mass + -0.38347107 - 20.0 * incl - grad);
     210              : }
     211              : 
     212              : 
     213              : void
     214            0 : PollutantsInterface::Helper::addAllClassesInto(std::vector<SUMOEmissionClass>& list) const {
     215            0 :     myEmissionClassStrings.addKeysInto(list);
     216            0 : }
     217              : 
     218              : 
     219              : bool
     220            0 : PollutantsInterface::Helper::includesClass(const SUMOEmissionClass c) const {
     221            0 :     return (c >> 16) == (myBaseIndex >> 16);
     222              : }
     223              : 
     224              : // ---------------------------------------------------------------------------
     225              : // PollutantsInterface - methods
     226              : // ---------------------------------------------------------------------------
     227              : 
     228              : SUMOEmissionClass
     229      1313699 : PollutantsInterface::getClassByName(const std::string& eClass, const SUMOVehicleClass vc) {
     230              :     const std::string::size_type sep = eClass.find("/");
     231      1313699 :     const std::string model = eClass.substr(0, sep); // this includes the case of no separator
     232      3956717 :     for (int i = 0; i < 8; i++) {
     233      3955621 :         if (myHelpers[i]->getName() == model) {
     234      1312603 :             if (sep != std::string::npos) {
     235      1312376 :                 const std::string subClass = eClass.substr(sep + 1);
     236      1312376 :                 if (subClass == "zero") {
     237       319704 :                     return myZeroHelper.getClassByName("default", vc);
     238              :                 }
     239      1152524 :                 return myHelpers[i]->getClassByName(subClass, vc);
     240              :             }
     241          454 :             return myHelpers[i]->getClassByName("default", vc);
     242              :         }
     243              :     }
     244         1096 :     if (sep == std::string::npos) {
     245         1096 :         if (eClass == "zero") {
     246           28 :             return myZeroHelper.getClassByName("default", vc);
     247              :         }
     248              :         // default HBEFA2
     249         1082 :         return myHBEFA2Helper.getClassByName(eClass, vc);
     250              :     }
     251            0 :     throw InvalidArgument("Unknown emission class '" + eClass + "'.");
     252              : }
     253              : 
     254              : 
     255              : const std::vector<SUMOEmissionClass>
     256            0 : PollutantsInterface::getAllClasses() {
     257              :     std::vector<SUMOEmissionClass> result;
     258            0 :     for (int i = 0; i < 8; i++) {
     259            0 :         myHelpers[i]->addAllClassesInto(result);
     260              :     }
     261            0 :     return result;
     262            0 : }
     263              : 
     264              : 
     265              : const std::vector<std::string>&
     266            0 : PollutantsInterface::getAllClassesStr() {
     267              :     // first check if myAllClassesStr has to be filled
     268            0 :     if (myAllClassesStr.empty()) {
     269              :         // first obtain all emissionClasses
     270              :         std::vector<SUMOEmissionClass> emissionClasses;
     271            0 :         for (int i = 0; i < 8; i++) {
     272            0 :             myHelpers[i]->addAllClassesInto(emissionClasses);
     273              :         }
     274              :         // now write all emissionClasses in myAllClassesStr
     275            0 :         for (const auto& i : emissionClasses) {
     276            0 :             myAllClassesStr.push_back(getName(i));
     277              :         }
     278            0 :     }
     279            0 :     return myAllClassesStr;
     280              : }
     281              : 
     282              : std::string
     283       977629 : PollutantsInterface::getName(const SUMOEmissionClass c) {
     284       977629 :     return myHelpers[c >> 16]->getClassName(c);
     285              : }
     286              : 
     287              : 
     288              : std::string
     289            0 : PollutantsInterface::getPollutantName(const EmissionType e) {
     290            0 :     switch (e) {
     291              :         case CO2:
     292            0 :             return "CO2";
     293              :         case CO:
     294            0 :             return "CO";
     295              :         case HC:
     296            0 :             return "HC";
     297              :         case FUEL:
     298            0 :             return "fuel";
     299              :         case NO_X:
     300            0 :             return "NOx";
     301              :         case PM_X:
     302            0 :             return "PMx";
     303              :         case ELEC:
     304            0 :             return "electricity";
     305            0 :         default:
     306            0 :             throw InvalidArgument("Unknown emission type '" + toString(e) + "'");
     307              :     }
     308              : }
     309              : 
     310              : bool
     311       779973 : PollutantsInterface::isHeavy(const SUMOEmissionClass c) {
     312       779973 :     return (c & HEAVY_BIT) != 0;
     313              : }
     314              : 
     315              : 
     316              : bool
     317       776740 : PollutantsInterface::isSilent(const SUMOEmissionClass c) {
     318       776740 :     return myHelpers[c >> 16]->isSilent(c);
     319              : }
     320              : 
     321              : 
     322              : SUMOEmissionClass
     323            2 : PollutantsInterface::getClass(const SUMOEmissionClass base, const std::string& vClass,
     324              :                               const std::string& fuel, const std::string& eClass, const double weight) {
     325            2 :     return myHelpers[base >> 16]->getClass(base, vClass, fuel, eClass, weight);
     326              : }
     327              : 
     328              : 
     329              : std::string
     330            9 : PollutantsInterface::getAmitranVehicleClass(const SUMOEmissionClass c) {
     331            9 :     return myHelpers[c >> 16]->getAmitranVehicleClass(c);
     332              : }
     333              : 
     334              : 
     335              : std::string
     336         1646 : PollutantsInterface::getFuel(const SUMOEmissionClass c) {
     337         1646 :     return myHelpers[c >> 16]->getFuel(c);
     338              : }
     339              : 
     340              : 
     341              : int
     342            9 : PollutantsInterface::getEuroClass(const SUMOEmissionClass c) {
     343            9 :     return myHelpers[c >> 16]->getEuroClass(c);
     344              : }
     345              : 
     346              : 
     347              : double
     348            9 : PollutantsInterface::getWeight(const SUMOEmissionClass c) {
     349            9 :     return myHelpers[c >> 16]->getWeight(c);
     350              : }
     351              : 
     352              : 
     353              : double
     354       377793 : PollutantsInterface::compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const EnergyParams* param) {
     355       377793 :     return myHelpers[c >> 16]->compute(c, e, v, a, slope, param);
     356              : }
     357              : 
     358              : 
     359              : PollutantsInterface::Emissions
     360    100877277 : PollutantsInterface::computeAll(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) {
     361    100877277 :     const Helper* const h = myHelpers[c >> 16];
     362    302631831 :     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),
     363    302631831 :                      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),
     364    100877277 :                      h->compute(c, ELEC, v, a, slope, param));
     365              : }
     366              : 
     367              : 
     368              : double
     369         7472 : PollutantsInterface::computeDefault(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const double tt, const EnergyParams* param) {
     370         7472 :     const Helper* const h = myHelpers[c >> 16];
     371         7472 :     return (h->compute(c, e, v, 0, slope, param) + h->compute(c, e, v - a, a, slope, param)) * tt / 2.;
     372              : }
     373              : 
     374              : 
     375              : double
     376            0 : PollutantsInterface::getModifiedAccel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) {
     377            0 :     return myHelpers[c >> 16]->getModifiedAccel(c, v, a, slope, param);
     378              : }
     379              : 
     380              : 
     381              : double
     382      1170747 : PollutantsInterface::getCoastingDecel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) {
     383      1170747 :     return myHelpers[c >> 16]->getCoastingDecel(c, v, a, slope, param);
     384              : }
     385              : 
     386              : 
     387              : const HelpersEnergy&
     388         1722 : PollutantsInterface::getEnergyHelper() {
     389         1722 :     return myEnergyHelper;
     390              : }
     391              : 
     392              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1