LCOV - code coverage report
Current view: top level - src/utils/emissions - PollutantsInterface.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 95 134 70.9 %
Date: 2024-05-04 15:27:10 Functions: 25 35 71.4 %

          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   202006317 : PollutantsInterface::Emissions::Emissions(double co2, double co, double hc, double f, double nox, double pmx, double elec) :
      72   202006317 :     CO2(co2),
      73   202006317 :     CO(co),
      74   202006317 :     HC(hc),
      75   202006317 :     fuel(f),
      76   202006317 :     NOx(nox),
      77   202006317 :     PMx(pmx),
      78   202006317 :     electricity(elec) {
      79   202006317 : }
      80             : 
      81             : 
      82   200394339 : void PollutantsInterface::Emissions::addScaled(const Emissions& a, const double scale) {
      83   200394339 :     CO2 += scale * a.CO2;
      84   200394339 :     CO += scale * a.CO;
      85   200394339 :     HC += scale * a.HC;
      86   200394339 :     fuel += scale * a.fuel;
      87   200394339 :     NOx += scale * a.NOx;
      88   200394339 :     PMx += scale * a.PMx;
      89   200394339 :     electricity += scale * a.electricity;
      90   200394339 : }
      91             : 
      92             : // ---------------------------------------------------------------------------
      93             : // PollutantsInterface::Helper - methods
      94             : // ---------------------------------------------------------------------------
      95             : 
      96      366560 : PollutantsInterface::Helper::Helper(std::string name, const int baseIndex, const int defaultClass) :
      97      366560 :     myName(name),
      98      366560 :     myBaseIndex(baseIndex) {
      99      366560 :     if (defaultClass != -1) {
     100      137460 :         myEmissionClassStrings.insert("default", defaultClass);
     101      274920 :         myEmissionClassStrings.addAlias("unknown", defaultClass);
     102             :     }
     103      366560 : }
     104             : 
     105             : 
     106             : const
     107     3294750 : std::string& PollutantsInterface::Helper::getName() const {
     108     3294750 :     return myName;
     109             : }
     110             : 
     111             : 
     112             : SUMOEmissionClass
     113     1090538 : PollutantsInterface::Helper::getClassByName(const std::string& eClass, const SUMOVehicleClass vc) {
     114             :     UNUSED_PARAMETER(vc);
     115     4342676 :     myVolumetricFuel = OptionsCont::getOptions().exists("emissions.volumetric-fuel") && OptionsCont::getOptions().getBool("emissions.volumetric-fuel");
     116     1090538 :     if (myEmissionClassStrings.hasString(eClass)) {
     117     1090538 :         return myEmissionClassStrings.get(eClass);
     118             :     }
     119           0 :     return myEmissionClassStrings.get(StringUtils::to_lower_case(eClass));
     120             : }
     121             : 
     122             : 
     123             : const std::string
     124      845046 : PollutantsInterface::Helper::getClassName(const SUMOEmissionClass c) const {
     125     1690092 :     return myName + "/" + myEmissionClassStrings.getString(c);
     126             : }
     127             : 
     128             : 
     129             : bool
     130      776979 : PollutantsInterface::Helper::isSilent(const SUMOEmissionClass c) {
     131      776979 :     return (c & (int)0xffffffff & ~HEAVY_BIT) == 0;
     132             : }
     133             : 
     134             : 
     135             : SUMOEmissionClass
     136           4 : 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           4 :     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          12 : PollutantsInterface::Helper::getWeight(const SUMOEmissionClass c) const {
     168             :     UNUSED_PARAMETER(c);
     169          12 :     return -1.;
     170             : }
     171             : 
     172             : 
     173             : double
     174      185164 : 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      185164 :     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   628124886 : 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   628124886 :     if (v < PHEMlightdllV5::Constants::SPEED_DCEL_MIN) {
     199    34423738 :         return v / PHEMlightdllV5::Constants::SPEED_DCEL_MIN * getCoastingDecel(c, PHEMlightdllV5::Constants::SPEED_DCEL_MIN, a, slope, param);
     200             :     }
     201   593701148 :     if (param == nullptr) {
     202        7432 :         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   593701148 :     const double mass = param->getDouble(SUMO_ATTR_MASS);
     206   593701148 :     const double area = param->getDouble(SUMO_ATTR_WIDTH) * param->getDouble(SUMO_ATTR_HEIGHT) * M_PI / 4.;
     207   593701148 :     const double incl = area / mass * -9.05337017 + -0.00017774;
     208   593701148 :     const double grad = PHEMlightdllV5::Constants::GRAVITY_CONST * slope / 100.;
     209   593701148 :     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     1090712 : PollutantsInterface::getClassByName(const std::string& eClass, const SUMOVehicleClass vc) {
     230             :     const std::string::size_type sep = eClass.find("/");
     231     1090712 :     const std::string model = eClass.substr(0, sep); // this includes the case of no separator
     232     3295850 :     for (int i = 0; i < 8; i++) {
     233     3294750 :         if (myHelpers[i]->getName() == model) {
     234     1089612 :             if (sep != std::string::npos) {
     235     1089470 :                 const std::string subClass = eClass.substr(sep + 1);
     236     1089470 :                 if (subClass == "zero") {
     237      264902 :                     return myZeroHelper.getClassByName("default", vc);
     238             :                 }
     239      957019 :                 return myHelpers[i]->getClassByName(subClass, vc);
     240             :             }
     241         284 :             return myHelpers[i]->getClassByName("default", vc);
     242             :         }
     243             :     }
     244        1100 :     if (sep == std::string::npos) {
     245        1100 :         if (eClass == "zero") {
     246          32 :             return myZeroHelper.getClassByName("default", vc);
     247             :         }
     248             :         // default HBEFA2
     249        1084 :         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             : }
     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             :     }
     279           0 :     return myAllClassesStr;
     280             : }
     281             : 
     282             : std::string
     283      845046 : PollutantsInterface::getName(const SUMOEmissionClass c) {
     284      845046 :     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      778851 : PollutantsInterface::isHeavy(const SUMOEmissionClass c) {
     312      778851 :     return (c & HEAVY_BIT) != 0;
     313             : }
     314             : 
     315             : 
     316             : bool
     317      776979 : PollutantsInterface::isSilent(const SUMOEmissionClass c) {
     318      776979 :     return myHelpers[c >> 16]->isSilent(c);
     319             : }
     320             : 
     321             : 
     322             : SUMOEmissionClass
     323           4 : PollutantsInterface::getClass(const SUMOEmissionClass base, const std::string& vClass,
     324             :                               const std::string& fuel, const std::string& eClass, const double weight) {
     325           4 :     return myHelpers[base >> 16]->getClass(base, vClass, fuel, eClass, weight);
     326             : }
     327             : 
     328             : 
     329             : std::string
     330          12 : PollutantsInterface::getAmitranVehicleClass(const SUMOEmissionClass c) {
     331          12 :     return myHelpers[c >> 16]->getAmitranVehicleClass(c);
     332             : }
     333             : 
     334             : 
     335             : std::string
     336         932 : PollutantsInterface::getFuel(const SUMOEmissionClass c) {
     337         932 :     return myHelpers[c >> 16]->getFuel(c);
     338             : }
     339             : 
     340             : 
     341             : int
     342          12 : PollutantsInterface::getEuroClass(const SUMOEmissionClass c) {
     343          12 :     return myHelpers[c >> 16]->getEuroClass(c);
     344             : }
     345             : 
     346             : 
     347             : double
     348          12 : PollutantsInterface::getWeight(const SUMOEmissionClass c) {
     349          12 :     return myHelpers[c >> 16]->getWeight(c);
     350             : }
     351             : 
     352             : 
     353             : double
     354      207656 : PollutantsInterface::compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const EnergyParams* param) {
     355      207656 :     return myHelpers[c >> 16]->compute(c, e, v, a, slope, param);
     356             : }
     357             : 
     358             : 
     359             : PollutantsInterface::Emissions
     360   200121199 : PollutantsInterface::computeAll(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) {
     361   200121199 :     const Helper* const h = myHelpers[c >> 16];
     362   600363597 :     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   600363597 :                      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   200121199 :                      h->compute(c, ELEC, v, a, slope, param));
     365             : }
     366             : 
     367             : 
     368             : double
     369        7552 : PollutantsInterface::computeDefault(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const double tt, const EnergyParams* param) {
     370        7552 :     const Helper* const h = myHelpers[c >> 16];
     371        7552 :     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     2341494 : PollutantsInterface::getCoastingDecel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) {
     383     2341494 :     return myHelpers[c >> 16]->getCoastingDecel(c, v, a, slope, param);
     384             : }
     385             : 
     386             : 
     387             : const HelpersEnergy&
     388        1876 : PollutantsInterface::getEnergyHelper() {
     389        1876 :     return myEnergyHelper;
     390             : }
     391             : 
     392             : /****************************************************************************/

Generated by: LCOV version 1.14