LCOV - code coverage report
Current view: top level - EnergyPlus - PollutionModule.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 67.0 % 306 205
Test Date: 2025-06-02 12:03:30 Functions: 100.0 % 9 9

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // ObjexxFCL Headers
      49              : 
      50              : // EnergyPlus Headers
      51              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      52              : #include <EnergyPlus/DataEnvironment.hh>
      53              : #include <EnergyPlus/DataGlobalConstants.hh>
      54              : #include <EnergyPlus/DataHVACGlobals.hh>
      55              : #include <EnergyPlus/DataIPShortCuts.hh>
      56              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      57              : #include <EnergyPlus/OutputProcessor.hh>
      58              : #include <EnergyPlus/PollutionModule.hh>
      59              : #include <EnergyPlus/ScheduleManager.hh>
      60              : #include <EnergyPlus/UtilityRoutines.hh>
      61              : 
      62              : namespace EnergyPlus::Pollution {
      63              : // Module containing the pollution calculation routines
      64              : 
      65              : // MODULE INFORMATION:
      66              : //       AUTHOR         Richard J. Liesen (RJL)
      67              : //       DATE WRITTEN   August 2002
      68              : //       MODIFIED       January 17, 2004 - J Glazer - Added source energy support including schedules for source energy
      69              : //                      January 2008 - L Lawrie - implementing schedule fields for all emission factors.
      70              : //       RE-ENGINEERED  December 2003 RJL
      71              : 
      72              : // PURPOSE OF THIS MODULE:
      73              : // To encapsulate the data and algorithms required to
      74              : // calculate the pollution, and carbon eqiuvalent for the Energy consumed
      75              : 
      76              : // METHODOLOGY EMPLOYED:
      77              : // The methodology employed is to calculate the
      78              : // source pollution from building energy consumption.
      79              : //    PURPOSE:= Takes the Energy from the various sources and
      80              : //               calculates the Environmental Impact Factors.
      81              : //         STEP 1:  We begin with the output expressing the energy
      82              : //         STEP 2:  The energy used by types: must be converted back
      83              : //         to source fuel types (fossil or electricity) via User Input.
      84              : //         STEP 3:  All energy numbers have been converted to units of MJ's or 1x10^6 Joules.
      85              : //         STEP 4:  Environmental Impact Factors are calculated from Coefficients
      86              : 
      87              : // MODULE VARIABLE DECLARATIONS:
      88              : // Total for all of the Pollutants
      89              : // Total Carbon Equivalent Components
      90              : //  !Fuel Types
      91              : // Total Carbon Equivalent Coeffs
      92              : // Purchased Efficiencies
      93              : 
      94              : // Fuel Types used with the Pollution Factors
      95              : // Facility Meter Indexes
      96              : // Facility Meter Values used in Pollution Calcs
      97              : 
      98        19866 : void CalculatePollution(EnergyPlusData &state)
      99              : {
     100              : 
     101              :     // SUBROUTINE INFORMATION:
     102              :     //       AUTHOR         Richard Liesen
     103              :     //       DATE WRITTEN   August 2002
     104              :     //       MODIFIED       na
     105              :     //       RE-ENGINEERED  December 2003 RJL
     106              : 
     107              :     // PURPOSE OF THIS SUBROUTINE:
     108              :     // This subroutine is the main driver for the pollution calculation
     109              : 
     110              :     // METHODOLOGY EMPLOYED:
     111              :     // Uses the status flags to trigger events.
     112              : 
     113        19866 :     if (!state.dataPollution->PollutionReportSetup) {
     114            0 :         return;
     115              :     }
     116              : 
     117              :     //   Call the Routine to Read the Energy Values from the EnergyPlus Meters
     118        19866 :     ReadEnergyMeters(state);
     119              : 
     120              :     //   Call the routine that takes the fuel data and calculates the
     121              :     //     Pollution for each fuel type.
     122        19866 :     CalcPollution(state);
     123              : }
     124              : 
     125              : // Get Input Section of the Module
     126              : //******************************************************************************
     127              : 
     128           73 : void SetupPollutionCalculations(EnergyPlusData &state)
     129              : {
     130              : 
     131              :     // SUBROUTINE INFORMATION:
     132              :     //       AUTHOR         Richard Liesen
     133              :     //       DATE WRITTEN   August 2002
     134              :     //       MODIFIED       na
     135              :     //       RE-ENGINEERED  December 2003 RJL; August 2008 LKL - more standard getinput
     136              : 
     137              :     // PURPOSE OF THIS SUBROUTINE:
     138              :     // This subroutine is the input routines and Get routines
     139              : 
     140              :     // METHODOLOGY EMPLOYED:
     141              :     // Uses the status flags to trigger events.
     142              : 
     143              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     144              :     int NumPolluteRpt;
     145              :     int NumAlphas;
     146              :     int NumNums;
     147              :     int Loop;
     148              :     int IOStat;
     149           73 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     150              : 
     151              :     // First determine if the Pollution reporting has been triggered, and is not exit.
     152           73 :     cCurrentModuleObject = "Output:EnvironmentalImpactFactors";
     153           73 :     NumPolluteRpt = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     154           73 :     state.dataPollution->PollutionReportSetup = true;
     155              : 
     156           73 :     for (Loop = 1; Loop <= NumPolluteRpt; ++Loop) {
     157              : 
     158            0 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     159              :                                                                  cCurrentModuleObject,
     160              :                                                                  Loop,
     161            0 :                                                                  state.dataIPShortCut->cAlphaArgs,
     162              :                                                                  NumAlphas,
     163            0 :                                                                  state.dataIPShortCut->rNumericArgs,
     164              :                                                                  NumNums,
     165              :                                                                  IOStat,
     166            0 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
     167            0 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     168            0 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     169            0 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     170              : 
     171              :         // Call this routine in the Output Processor to setup the correct Facility energy meters that are
     172              :         //  necessary to make sure that the Meter file is opened and written to by the OP so that time stamps
     173              :         //  and the like are happening as expected.
     174            0 :         OutputProcessor::ReportFreq freq = OutputProcessor::ReportFreq::Simulation;
     175              : 
     176            0 :         if (!state.dataIPShortCut->lAlphaFieldBlanks(1) &&
     177              :             (freq = static_cast<OutputProcessor::ReportFreq>(
     178            0 :                  getEnumValue(OutputProcessor::reportFreqNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(1))))) ==
     179              :                 OutputProcessor::ReportFreq::Invalid) {
     180            0 :             ShowSevereError(state, format("Invalid reporting frequency {}", state.dataIPShortCut->cAlphaArgs(1)));
     181            0 :             continue;
     182              :         }
     183              : 
     184            0 :         InitPollutionMeterReporting(state, freq);
     185              :     }
     186           73 : }
     187              : 
     188           78 : void GetPollutionFactorInput(EnergyPlusData &state)
     189              : {
     190              : 
     191              :     // SUBROUTINE INFORMATION:
     192              :     //       AUTHOR         Linda Lawrie
     193              :     //       DATE WRITTEN   August 2008
     194              : 
     195              :     // PURPOSE OF THIS SUBROUTINE:
     196              :     // SetupPollutionCalculation must be called after meters are initialized.  This caused a problem
     197              :     // in runs so have added this routine to allow central get for most inputs.
     198              : 
     199           78 :     constexpr std::string_view routineName = "GetPollutionFactorInput";
     200              : 
     201              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     202              :     int NumAlphas;
     203              :     int NumNums;
     204              :     int IOStat;
     205           78 :     bool ErrorsFound = false;
     206              : 
     207           78 :     auto &ip = state.dataInputProcessing->inputProcessor;
     208           78 :     auto &ipsc = state.dataIPShortCut;
     209           78 :     auto &pm = state.dataPollution;
     210              : 
     211           78 :     if (!pm->GetInputFlagPollution) {
     212            0 :         return; // Input already gotten
     213              :     }
     214           78 :     pm->GetInputFlagPollution = false;
     215              : 
     216           78 :     ipsc->cCurrentModuleObject = "EnvironmentalImpactFactors";
     217           78 :     pm->NumEnvImpactFactors = ip->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
     218              : 
     219           78 :     if (pm->NumEnvImpactFactors > 0) {
     220              :         // Now find and load all of the user inputs and factors.
     221            4 :         ip->getObjectItem(state,
     222            2 :                           ipsc->cCurrentModuleObject,
     223              :                           1,
     224            2 :                           ipsc->cAlphaArgs,
     225              :                           NumAlphas,
     226            2 :                           ipsc->rNumericArgs,
     227              :                           NumNums,
     228              :                           IOStat,
     229            2 :                           ipsc->lNumericFieldBlanks,
     230            2 :                           ipsc->lAlphaFieldBlanks,
     231            2 :                           ipsc->cAlphaFieldNames,
     232            2 :                           ipsc->cNumericFieldNames);
     233           76 :     } else if (pm->PollutionReportSetup) {
     234            0 :         ShowWarningError(state, format("{}: not entered.  Values will be defaulted.", ipsc->cCurrentModuleObject));
     235              :     }
     236              : 
     237           78 :     pm->PurchHeatEffic = 0.3;
     238           78 :     pm->PurchCoolCOP = 3.0;
     239           78 :     pm->SteamConvEffic = 0.25;
     240           78 :     pm->CarbonEquivN2O = 0.0;
     241           78 :     pm->CarbonEquivCH4 = 0.0;
     242           78 :     pm->CarbonEquivCO2 = 0.0;
     243              : 
     244           78 :     if (pm->NumEnvImpactFactors > 0) {
     245              :         // If Heating Efficiency defined by the User is negative or zero then a default of 30% will be assigned.
     246            2 :         if (ipsc->rNumericArgs(1) > 0.0) {
     247            2 :             pm->PurchHeatEffic = ipsc->rNumericArgs(1);
     248              :         }
     249              : 
     250              :         // If COP defined by the User is negative or zero then a default of 3.0 will be assigned.
     251            2 :         if (ipsc->rNumericArgs(2) > 0.0) {
     252            2 :             pm->PurchCoolCOP = ipsc->rNumericArgs(2);
     253              :         }
     254              : 
     255              :         // If Steam Conversion Efficiency defined by the User is negative or zero then a default of 25% will be assigned.
     256            2 :         if (ipsc->rNumericArgs(3) > 0.0) {
     257            2 :             pm->SteamConvEffic = ipsc->rNumericArgs(3);
     258              :         }
     259              : 
     260              :         // Load the Total Carbon Equivalent Pollution Factor coefficients
     261            2 :         pm->CarbonEquivN2O = ipsc->rNumericArgs(4);
     262            2 :         pm->CarbonEquivCH4 = ipsc->rNumericArgs(5);
     263            2 :         pm->CarbonEquivCO2 = ipsc->rNumericArgs(6);
     264              :     }
     265              : 
     266              :     // Compare all of the Fuel Factors and compare to PollutionCalculationFactors List
     267           78 :     ipsc->cCurrentModuleObject = "FuelFactors";
     268           78 :     pm->NumFuelFactors = ip->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
     269              : 
     270           88 :     for (int Loop = 1; Loop <= state.dataPollution->NumFuelFactors; ++Loop) {
     271              :         // Now find and load all of the user inputs and factors.
     272           20 :         ip->getObjectItem(state,
     273           10 :                           ipsc->cCurrentModuleObject,
     274              :                           Loop,
     275           10 :                           ipsc->cAlphaArgs,
     276              :                           NumAlphas,
     277           10 :                           ipsc->rNumericArgs,
     278              :                           NumNums,
     279              :                           IOStat,
     280           10 :                           ipsc->lNumericFieldBlanks,
     281           10 :                           ipsc->lAlphaFieldBlanks,
     282           10 :                           ipsc->cAlphaFieldNames,
     283           10 :                           ipsc->cNumericFieldNames);
     284              : 
     285           10 :         ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
     286              : 
     287           10 :         PollFuel pollFuel = static_cast<PollFuel>(getEnumValue(pollFuelNamesUC, Util::makeUPPER(ipsc->cAlphaArgs(1))));
     288           10 :         if (pollFuel == PollFuel::Invalid) {
     289            0 :             ShowSevereInvalidKey(state, eoh, ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1));
     290            0 :             ErrorsFound = true;
     291            0 :             continue;
     292              :         }
     293              : 
     294           10 :         pm->pollFuelFactorList.push_back(pollFuel);
     295              : 
     296           10 :         auto &pollCoeff = pm->pollCoeffs[(int)pollFuel];
     297           10 :         Constant::eFuel fuel = pollFuel2fuel[(int)pollFuel];
     298              : 
     299           10 :         if (pollCoeff.used) {
     300            0 :             ShowWarningError(
     301            0 :                 state, format("{}: {} already entered. Previous entry will be used.", ipsc->cCurrentModuleObject, Constant::eFuelNames[(int)fuel]));
     302            0 :             continue;
     303              :         }
     304              : 
     305           10 :         pollCoeff.used = true;
     306              : 
     307           10 :         pollCoeff.sourceCoeff = ipsc->rNumericArgs(1);
     308           10 :         if (ipsc->lAlphaFieldBlanks(2)) {
     309            0 :         } else if ((pollCoeff.sourceSched = Sched::GetSchedule(state, ipsc->cAlphaArgs(2))) == nullptr) {
     310            0 :             ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2));
     311            0 :             ErrorsFound = true;
     312            0 :         } else if (!pollCoeff.sourceSched->checkMinVal(state, Clusive::In, 0.0)) {
     313            0 :             Sched::ShowSevereBadMin(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2), Clusive::In, 0.0);
     314            0 :             ErrorsFound = true;
     315              :         }
     316              : 
     317          170 :         for (int iPollutant = 0; iPollutant < (int)Pollutant::Num; ++iPollutant) {
     318          160 :             pollCoeff.pollutantCoeffs[iPollutant] = ipsc->rNumericArgs(iPollutant + 2);
     319          160 :             if (ipsc->lAlphaFieldBlanks(iPollutant + 3)) {
     320            0 :             } else if ((pollCoeff.pollutantScheds[iPollutant] = Sched::GetSchedule(state, ipsc->cAlphaArgs(iPollutant + 3))) == nullptr) {
     321            0 :                 ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(iPollutant + 3), ipsc->cAlphaArgs(iPollutant + 3));
     322            0 :                 ErrorsFound = true;
     323            0 :             } else if (!pollCoeff.pollutantScheds[iPollutant]->checkMinVal(state, Clusive::In, 0.0)) {
     324            0 :                 Sched::ShowSevereBadMin(state, eoh, ipsc->cAlphaFieldNames(iPollutant + 3), ipsc->cAlphaArgs(iPollutant + 3), Clusive::In, 0.0);
     325            0 :                 ErrorsFound = true;
     326              :             }
     327              :         } // for (iPollutant)
     328              : 
     329              :     } // End of the NumEnergyTypes Do Loop
     330              : 
     331           78 :     if (pm->PollutionReportSetup) { // only do this if reporting on the pollution
     332              :         // Need to go through all of the Fuel Types and make sure a Fuel Factor was found for each type of energy being simulated
     333              :         // Check for Electricity
     334            0 :         if (!pm->pollCoeffs[(int)PollFuel::Electricity].used && ((pm->facilityMeterNums[(int)PollFacilityMeter::Electricity] > 0) ||
     335            0 :                                                                  (pm->facilityMeterNums[(int)PollFacilityMeter::ElectricityProduced] > 0) ||
     336            0 :                                                                  (pm->facilityMeterNums[(int)PollFacilityMeter::CoolPurchased] > 0))) {
     337            0 :             ShowSevereError(state,
     338            0 :                             format("{} Not Found or Fuel not specified For Pollution Calculation for ELECTRICITY", ipsc->cCurrentModuleObject));
     339            0 :             ErrorsFound = true;
     340              :         }
     341              : 
     342              :         // Check for Natural Gas
     343            0 :         if (!pm->pollCoeffs[(int)PollFuel::NaturalGas].used &&
     344            0 :             ((pm->facilityMeterNums[(int)PollFacilityMeter::NaturalGas] > 0) || (pm->facilityMeterNums[(int)PollFacilityMeter::HeatPurchased] > 0) ||
     345            0 :              (pm->facilityMeterNums[(int)PollFacilityMeter::Steam] > 0))) {
     346            0 :             ShowSevereError(state,
     347            0 :                             format("{} Not Found or Fuel not specified For Pollution Calculation for NATURAL GAS", ipsc->cCurrentModuleObject));
     348            0 :             ErrorsFound = true;
     349              :         }
     350              :         // Check for FuelOilNo2 (Residual Oil)
     351            0 :         if (!pm->pollCoeffs[(int)PollFuel::FuelOil2].used && (pm->facilityMeterNums[(int)PollFacilityMeter::FuelOil2] > 0)) {
     352            0 :             ShowSevereError(state,
     353            0 :                             format("{} Not Found or Fuel not specified For Pollution Calculation for FUEL OIL #2", ipsc->cCurrentModuleObject));
     354            0 :             ErrorsFound = true;
     355              :         }
     356              :         // Check for FuelOilNo1 (Distillate Oil)
     357            0 :         if (!pm->pollCoeffs[(int)PollFuel::FuelOil1].used && (pm->facilityMeterNums[(int)PollFacilityMeter::FuelOil1] > 0)) {
     358            0 :             ShowSevereError(state,
     359            0 :                             format("{} Not Found or Fuel not specified For Pollution Calculation for FUEL OIL #1", ipsc->cCurrentModuleObject));
     360            0 :             ErrorsFound = true;
     361              :         }
     362              :         // Check for Coal
     363            0 :         if (!pm->pollCoeffs[(int)PollFuel::Coal].used && (pm->facilityMeterNums[(int)PollFacilityMeter::Coal] > 0)) {
     364            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for COAL", ipsc->cCurrentModuleObject));
     365            0 :             ErrorsFound = true;
     366              :         }
     367              :         // Check for Gasoline
     368            0 :         if (!pm->pollCoeffs[(int)PollFuel::Gasoline].used && (pm->facilityMeterNums[(int)PollFacilityMeter::Gasoline] > 0)) {
     369            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for GASOLINE", ipsc->cCurrentModuleObject));
     370            0 :             ErrorsFound = true;
     371              :         }
     372              :         // Check for Propane
     373            0 :         if (!pm->pollCoeffs[(int)PollFuel::Propane].used && (pm->facilityMeterNums[(int)PollFacilityMeter::Propane] > 0)) {
     374            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for PROPANE", ipsc->cCurrentModuleObject));
     375            0 :             ErrorsFound = true;
     376              :         }
     377              :         // Check for Diesel
     378            0 :         if (!pm->pollCoeffs[(int)PollFuel::Diesel].used && (pm->facilityMeterNums[(int)PollFacilityMeter::Diesel] > 0)) {
     379            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for DIESEL", ipsc->cCurrentModuleObject));
     380            0 :             ErrorsFound = true;
     381              :         }
     382              :         // Check for OtherFuel1
     383            0 :         if (!pm->pollCoeffs[(int)PollFuel::OtherFuel1].used && (pm->facilityMeterNums[(int)PollFacilityMeter::OtherFuel1] > 0)) {
     384            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for OTHERFUEL1", ipsc->cCurrentModuleObject));
     385            0 :             ErrorsFound = true;
     386              :         }
     387              :         // Check for OtherFuel2
     388            0 :         if (!pm->pollCoeffs[(int)PollFuel::OtherFuel2].used && (pm->facilityMeterNums[(int)PollFacilityMeter::OtherFuel2] > 0)) {
     389            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for OTHERFUEL2", ipsc->cCurrentModuleObject));
     390            0 :             ErrorsFound = true;
     391              :         }
     392              :     }
     393              : 
     394           78 :     if (ErrorsFound) {
     395            0 :         ShowFatalError(state, "Errors found in getting Pollution Calculation Reporting Input");
     396              :     }
     397              : }
     398              : 
     399           74 : void SetupPollutionMeterReporting(EnergyPlusData &state)
     400              : {
     401              : 
     402              :     // SUBROUTINE INFORMATION:
     403              :     //       AUTHOR         Richard Liesen
     404              :     //       DATE WRITTEN   August 2002
     405              :     //       MODIFIED       na
     406              :     //       RE-ENGINEERED  December 2003 RJL
     407              : 
     408              :     // PURPOSE OF THIS SUBROUTINE:
     409              :     // This subroutine is the input routines and Get routines
     410              : 
     411              :     // METHODOLOGY EMPLOYED:
     412              :     // Uses the status flags to trigger events.
     413              : 
     414              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     415           74 :     auto &pm = state.dataPollution;
     416              : 
     417           74 :     if (pm->GetInputFlagPollution) {
     418           66 :         GetPollutionFactorInput(state);
     419           66 :         pm->GetInputFlagPollution = false;
     420              :     }
     421              : 
     422              :     // We are using this list rather than the enumeration to preserve the order in which meters are created to avoid ordering diffs.
     423           83 :     for (PollFuel pollFuel : pm->pollFuelFactorList) {
     424              : 
     425            9 :         if (!pm->pollCoeffs[(int)pollFuel].used) {
     426            0 :             continue;
     427              :         }
     428              : 
     429            9 :         auto &pollComp = pm->pollComps[(int)pollFuel2pollFuelComponent[(int)pollFuel]];
     430              : 
     431            9 :         Constant::eFuel fuel = pollFuel2fuel[(int)pollFuel];
     432              : 
     433            9 :         constexpr std::array<OutputProcessor::EndUseCat, (int)Constant::eFuel::Num> fuel2sovEndUseCat = {
     434              :             OutputProcessor::EndUseCat::ElectricityEmissions,
     435              :             OutputProcessor::EndUseCat::NaturalGasEmissions,
     436              :             OutputProcessor::EndUseCat::GasolineEmissions,
     437              :             OutputProcessor::EndUseCat::DieselEmissions,
     438              :             OutputProcessor::EndUseCat::CoalEmissions,
     439              :             OutputProcessor::EndUseCat::PropaneEmissions,
     440              :             OutputProcessor::EndUseCat::FuelOilNo1Emissions,
     441              :             OutputProcessor::EndUseCat::FuelOilNo2Emissions,
     442              :             OutputProcessor::EndUseCat::OtherFuel1Emissions,
     443              :             OutputProcessor::EndUseCat::OtherFuel2Emissions,
     444              :             OutputProcessor::EndUseCat::Invalid,
     445              :             OutputProcessor::EndUseCat::Invalid,
     446              :             OutputProcessor::EndUseCat::Invalid,
     447              :             OutputProcessor::EndUseCat::Invalid,
     448              :             OutputProcessor::EndUseCat::Invalid // used for OtherEquipment object
     449              :         };
     450              : 
     451              :         // Need to check whether this fuel is used?
     452           45 :         SetupOutputVariable(state,
     453           18 :                             format("Environmental Impact {} Source Energy", Constant::eFuelNames[(int)fuel]),
     454              :                             Constant::Units::J,
     455            9 :                             pollComp.sourceVal,
     456              :                             OutputProcessor::TimeStepType::System,
     457              :                             OutputProcessor::StoreType::Sum,
     458              :                             "Site",
     459              :                             Constant::eResource::Source,
     460              :                             OutputProcessor::Group::Invalid,
     461            9 :                             fuel2sovEndUseCat[(int)fuel]);
     462              : 
     463          153 :         for (int iPollutant = 0; iPollutant < (int)Pollutant::Num; ++iPollutant) {
     464          720 :             SetupOutputVariable(state,
     465          288 :                                 format("Environmental Impact {} {}", Constant::eFuelNames[(int)fuel], poll2outVarStrs[iPollutant]),
     466          144 :                                 pollUnits[iPollutant],
     467          144 :                                 pollComp.pollutantVals[iPollutant],
     468              :                                 OutputProcessor::TimeStepType::System,
     469              :                                 OutputProcessor::StoreType::Sum,
     470              :                                 "Site",
     471          144 :                                 poll2Resource[iPollutant],
     472              :                                 OutputProcessor::Group::Invalid,
     473          144 :                                 fuel2sovEndUseCat[(int)fuel]);
     474              :         }
     475              : 
     476            9 :         if (fuel == Constant::eFuel::Electricity) {
     477              :             // Setup ElectricityPurchased and ElectricitySold variables
     478              :             // Doing this here as opposed to outside the outer loop to preserve meter order and reduce ordering diffs
     479            4 :             SetupOutputVariable(state,
     480              :                                 "Environmental Impact Purchased Electricity Source Energy",
     481              :                                 Constant::Units::J,
     482            1 :                                 pm->pollComps[(int)PollFuelComponent::ElectricityPurchased].sourceVal,
     483              :                                 OutputProcessor::TimeStepType::System,
     484              :                                 OutputProcessor::StoreType::Sum,
     485              :                                 "Site",
     486              :                                 Constant::eResource::Source,
     487              :                                 OutputProcessor::Group::Invalid,
     488              :                                 OutputProcessor::EndUseCat::PurchasedElectricityEmissions);
     489            4 :             SetupOutputVariable(state,
     490              :                                 "Environmental Impact Surplus Sold Electricity Source",
     491              :                                 Constant::Units::J,
     492            1 :                                 pm->pollComps[(int)PollFuelComponent::ElectricitySurplusSold].sourceVal,
     493              :                                 OutputProcessor::TimeStepType::System,
     494              :                                 OutputProcessor::StoreType::Sum,
     495              :                                 "Site",
     496              :                                 Constant::eResource::Source,
     497              :                                 OutputProcessor::Group::Invalid,
     498              :                                 OutputProcessor::EndUseCat::SoldElectricityEmissions);
     499              :         }
     500              : 
     501           74 :     } // End of the NumEnergyTypes Do Loop
     502              : 
     503              :     // And Total Carbon Equivalent variables
     504          296 :     SetupOutputVariable(state,
     505              :                         "Environmental Impact Total N2O Emissions Carbon Equivalent Mass",
     506              :                         Constant::Units::kg,
     507           74 :                         pm->TotCarbonEquivFromN2O,
     508              :                         OutputProcessor::TimeStepType::System,
     509              :                         OutputProcessor::StoreType::Sum,
     510              :                         "Site",
     511              :                         Constant::eResource::CarbonEquivalent,
     512              :                         OutputProcessor::Group::Invalid,
     513              :                         OutputProcessor::EndUseCat::CarbonEquivalentEmissions);
     514          296 :     SetupOutputVariable(state,
     515              :                         "Environmental Impact Total CH4 Emissions Carbon Equivalent Mass",
     516              :                         Constant::Units::kg,
     517           74 :                         pm->TotCarbonEquivFromCH4,
     518              :                         OutputProcessor::TimeStepType::System,
     519              :                         OutputProcessor::StoreType::Sum,
     520              :                         "Site",
     521              :                         Constant::eResource::CarbonEquivalent,
     522              :                         OutputProcessor::Group::Invalid,
     523              :                         OutputProcessor::EndUseCat::CarbonEquivalentEmissions);
     524          296 :     SetupOutputVariable(state,
     525              :                         "Environmental Impact Total CO2 Emissions Carbon Equivalent Mass",
     526              :                         Constant::Units::kg,
     527           74 :                         pm->TotCarbonEquivFromCO2,
     528              :                         OutputProcessor::TimeStepType::System,
     529              :                         OutputProcessor::StoreType::Sum,
     530              :                         "Site",
     531              :                         Constant::eResource::CarbonEquivalent,
     532              :                         OutputProcessor::Group::Invalid,
     533              :                         OutputProcessor::EndUseCat::CarbonEquivalentEmissions);
     534              : 
     535              :     // Connect pollution meters to energy meters
     536         1258 :     for (int iMeter = 0; iMeter < (int)PollFacilityMeter::Num; ++iMeter) {
     537         1184 :         pm->facilityMeterNums[iMeter] = GetMeterIndex(state, Util::makeUPPER(pollFacilityMeterNames[iMeter]));
     538              :     }
     539           74 : }
     540              : 
     541           73 : void CheckPollutionMeterReporting(EnergyPlusData &state)
     542              : {
     543              : 
     544              :     // SUBROUTINE INFORMATION:
     545              :     //       AUTHOR         Linda Lawrie
     546              :     //       DATE WRITTEN   October 2008
     547              : 
     548              :     // in progress (what is in progress?)
     549              : 
     550           73 :     auto const &pm = state.dataPollution;
     551              : 
     552           73 :     if (pm->NumFuelFactors == 0 || pm->NumEnvImpactFactors == 0) {
     553          219 :         if (ReportingThisVariable(state, "Environmental Impact Total N2O Emissions Carbon Equivalent Mass") ||
     554          219 :             ReportingThisVariable(state, "Environmental Impact Total CH4 Emissions Carbon Equivalent Mass") ||
     555          219 :             ReportingThisVariable(state, "Environmental Impact Total CO2 Emissions Carbon Equivalent Mass") ||
     556          438 :             ReportingThisVariable(state, "Carbon Equivalent:Facility") ||
     557          219 :             ReportingThisVariable(state, "CarbonEquivalentEmissions:Carbon Equivalent")) {
     558            0 :             ShowWarningError(
     559              :                 state, "GetPollutionFactorInput: Requested reporting for Carbon Equivalent Pollution, but insufficient information is entered.");
     560            0 :             ShowContinueError(
     561              :                 state, "Both \"FuelFactors\" and \"EnvironmentalImpactFactors\" must be entered or the displayed carbon pollution will all be zero.");
     562              :         }
     563              :     }
     564           73 : }
     565              : 
     566              : // End of Get Input subroutines for the Pollution Module
     567              : //******************************************************************************
     568              : 
     569        19866 : void CalcPollution(EnergyPlusData &state)
     570              : {
     571              :     // SUBROUTINE INFORMATION:
     572              :     //       AUTHOR         Richard Liesen
     573              :     //       DATE WRITTEN   1998
     574              :     //       MODIFIED       na
     575              :     //       RE-ENGINEERED  December 2003 RJL
     576              : 
     577              :     //       Then the amount of Pollution produced by each fuel type is
     578              :     //       calculated in kgs.
     579              :     //       Input units for the coefficients is not standard and needs to be converted here.
     580              :     //       Most of the units are g/MJ, however water is in L/MJ and low level nuclear water is m3/MJ
     581              :     //       so only the energy has to be converted from J to MJ.
     582              : 
     583              :     //     For each pollution/fuel type, Schedule values are allowed.  Thus, calculations are bundled.
     584        19866 :     auto &pm = state.dataPollution;
     585              : 
     586       337722 :     for (int iPoll = 0; iPoll < (int)Pollutant::Num; ++iPoll) {
     587       317856 :         pm->pollutantVals[iPoll] = 0.0;
     588              : 
     589      3496416 :         for (int iPollFuel = 0; iPollFuel < (int)PollFuel::Num; ++iPollFuel) {
     590      3178560 :             auto &pollCoeff = pm->pollCoeffs[iPollFuel];
     591      3178560 :             PollFuelComponent pollFuelComp = pollFuel2pollFuelComponent[iPollFuel];
     592      3178560 :             auto &pollComp = pm->pollComps[(int)pollFuelComp];
     593              : 
     594      3178560 :             if (pollCoeff.used) {
     595            0 :                 pollComp.pollutantVals[iPoll] = 0.0;
     596            0 :                 Real64 pollutantVal = pollCoeff.pollutantCoeffs[iPoll];
     597              : 
     598              :                 // Why are these two the exceptions?
     599            0 :                 if (iPoll != (int)Pollutant::Water && iPoll != (int)Pollutant::NuclearLow) {
     600            0 :                     pollutantVal *= 0.001;
     601              :                 }
     602              : 
     603            0 :                 if (pollCoeff.pollutantScheds[iPoll] != nullptr) {
     604            0 :                     pollutantVal *= pollCoeff.pollutantScheds[iPoll]->getCurrentVal();
     605              :                 }
     606            0 :                 pollComp.pollutantVals[iPoll] = pm->facilityMeterFuelComponentVals[(int)pollFuelComp] * 1.0e-6 * pollutantVal;
     607              :             }
     608              : 
     609      3178560 :             pm->pollutantVals[iPoll] += pollComp.pollutantVals[iPoll];
     610              :         } // for (iPollFactor)
     611              :     } // for (iPoll)
     612              : 
     613        19866 :     pm->TotCarbonEquivFromN2O = pm->pollutantVals[(int)Pollutant::N2O] * pm->CarbonEquivN2O;
     614        19866 :     pm->TotCarbonEquivFromCH4 = pm->pollutantVals[(int)Pollutant::CH4] * pm->CarbonEquivCH4;
     615        19866 :     pm->TotCarbonEquivFromCO2 = pm->pollutantVals[(int)Pollutant::CO2] * pm->CarbonEquivCO2;
     616              : 
     617        19866 :     auto const &pollCoeffElec = pm->pollCoeffs[(int)PollFuel::Electricity];
     618        19866 :     auto &pollCompElec = pm->pollComps[(int)PollFuelComponent::Electricity];
     619        19866 :     auto &pollCompElecPurchased = pm->pollComps[(int)PollFuelComponent::ElectricityPurchased];
     620        19866 :     auto &pollCompElecSurplusSold = pm->pollComps[(int)PollFuelComponent::ElectricitySurplusSold];
     621              : 
     622        19866 :     pollCompElec.sourceVal = pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Electricity] * pollCoeffElec.sourceCoeff;
     623        19866 :     pollCompElecPurchased.sourceVal = pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::ElectricityPurchased] * pollCoeffElec.sourceCoeff;
     624        19866 :     pollCompElecSurplusSold.sourceVal =
     625        19866 :         pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::ElectricitySurplusSold] * pollCoeffElec.sourceCoeff;
     626              : 
     627        19866 :     if (pollCoeffElec.sourceSched != nullptr) {
     628            0 :         Real64 pollCoeffElecSchedVal = pollCoeffElec.sourceSched->getCurrentVal();
     629            0 :         pollCompElec.sourceVal *= pollCoeffElecSchedVal;
     630            0 :         pollCompElecPurchased.sourceVal *= pollCoeffElecSchedVal;
     631            0 :         pollCompElecSurplusSold.sourceVal *= pollCoeffElecSchedVal;
     632              :     }
     633              : 
     634              :     // does not include district heating or steam
     635        19866 :     auto const &pollCoeffGas = pm->pollCoeffs[(int)PollFuel::NaturalGas];
     636        19866 :     auto &pollCompGas = pm->pollComps[(int)PollFuelComponent::NaturalGas];
     637        19866 :     pollCompGas.sourceVal = pm->facilityMeterVals[(int)PollFacilityMeter::NaturalGas] * pollCoeffGas.sourceCoeff;
     638        19866 :     if (pollCoeffGas.sourceSched != nullptr) {
     639            0 :         pollCompGas.sourceVal *= pollCoeffGas.sourceSched->getCurrentVal();
     640              :     }
     641              : 
     642       178794 :     for (PollFuel pollFuel : {PollFuel::FuelOil1,
     643              :                               PollFuel::FuelOil2,
     644              :                               PollFuel::Diesel,
     645              :                               PollFuel::Gasoline,
     646              :                               PollFuel::Propane,
     647              :                               PollFuel::Coal,
     648              :                               PollFuel::OtherFuel1,
     649       198660 :                               PollFuel::OtherFuel2}) {
     650       158928 :         auto const &pollCoeff = pm->pollCoeffs[(int)pollFuel];
     651       158928 :         PollFuelComponent pollFuelComponent = pollFuel2pollFuelComponent[(int)pollFuel];
     652       158928 :         auto &pollComp = pm->pollComps[(int)pollFuelComponent];
     653              : 
     654       158928 :         pollComp.sourceVal = pm->facilityMeterFuelComponentVals[(int)pollFuelComponent] * pollCoeff.sourceCoeff;
     655       158928 :         if (pollCoeff.sourceSched != nullptr) {
     656            0 :             pollComp.sourceVal *= pollCoeff.sourceSched->getCurrentVal();
     657              :         }
     658              :     } // for (pollFuelComponent)
     659        19866 : } // CalcPollution()
     660              : 
     661        19866 : void ReadEnergyMeters(EnergyPlusData &state)
     662              : {
     663              :     // SUBROUTINE INFORMATION:
     664              :     //       AUTHOR         Richard Liesen
     665              :     //       DATE WRITTEN   1998
     666              :     //       MODIFIED       na
     667              :     //       RE-ENGINEERED  December 2003 RJL
     668              : 
     669              :     // PURPOSE OF THIS SUBROUTINE:
     670              :     //       Read Energy Results from the meters
     671              :     // This routine reads the meters for the energy used
     672              : 
     673              :     // Using/Aliasing
     674        19866 :     Real64 FracTimeStepZone = state.dataHVACGlobal->FracTimeStepZone;
     675        19866 :     auto &pm = state.dataPollution;
     676              : 
     677       337722 :     for (int iMeter = 0; iMeter < (int)PollFacilityMeter::Num; ++iMeter) {
     678       317856 :         pm->facilityMeterVals[iMeter] =
     679       317856 :             GetInstantMeterValue(state, pm->facilityMeterNums[iMeter], OutputProcessor::TimeStepType::Zone) * FracTimeStepZone +
     680       317856 :             GetInstantMeterValue(state, pm->facilityMeterNums[iMeter], OutputProcessor::TimeStepType::System);
     681              :     }
     682              : 
     683              :     // Now these fuel types have to be sorted and summed into categories that we have pollution factors for.
     684              :     // The Off-Site Electricity is the total needed by the facility minus the amount generated on-site.
     685              :     // The on-site pollutants will end up being other fuel types used by the generators.
     686              :     // If the difference between the 2 electric quantities is <0.0 then it will be zero for that time step.
     687              :     // We will also add the District Cooling here with a rough conversion from Energy using the User
     688              :     // defined COP.
     689              : 
     690        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Electricity] =
     691        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::Electricity] - pm->facilityMeterVals[(int)PollFacilityMeter::ElectricityProduced] +
     692        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::CoolPurchased] / pm->PurchCoolCOP;
     693              : 
     694        19866 :     if (pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Electricity] < 0.0) {
     695            0 :         pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Electricity] = 0.0;
     696              :     }
     697              : 
     698              :     // The Natural Gas fuel type will be summed from the meters with the District Heating using an efficiency.
     699        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::NaturalGas] =
     700        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::NaturalGas] +
     701        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::HeatPurchased] / pm->PurchHeatEffic +
     702        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::Steam] / pm->SteamConvEffic;
     703              : 
     704        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::FuelOil1] = pm->facilityMeterVals[(int)PollFacilityMeter::FuelOil1];
     705        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::FuelOil2] = pm->facilityMeterVals[(int)PollFacilityMeter::FuelOil2];
     706        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Gasoline] = pm->facilityMeterVals[(int)PollFacilityMeter::Gasoline];
     707        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Propane] = pm->facilityMeterVals[(int)PollFacilityMeter::Propane];
     708        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Coal] = pm->facilityMeterVals[(int)PollFacilityMeter::Coal];
     709        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Diesel] = pm->facilityMeterVals[(int)PollFacilityMeter::Diesel];
     710        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::OtherFuel1] = pm->facilityMeterVals[(int)PollFacilityMeter::OtherFuel1];
     711        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::OtherFuel2] = pm->facilityMeterVals[(int)PollFacilityMeter::OtherFuel2];
     712        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::ElectricityPurchased] =
     713        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::ElectricityPurchased];
     714        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::ElectricitySurplusSold] =
     715        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::ElectricitySurplusSold];
     716        19866 : }
     717              : 
     718              : // *****************************************************************************
     719              : // Utility Routines to allow access to data inside this module.
     720              : // *****************************************************************************
     721              : 
     722          963 : void GetFuelFactorInfo(EnergyPlusData &state,
     723              :                        Constant::eFuel fuel,         // input fuel name  (standard from Tabular reports)
     724              :                        bool &fuelFactorUsed,         // return value true if user has entered this fuel
     725              :                        Real64 &fuelSourceFactor,     // if used, the source factor
     726              :                        bool &fuelFactorScheduleUsed, // if true, schedules for this fuel are used
     727              :                        Sched::Schedule **ffSched     // if schedules for this fuel are used, return schedule index
     728              : )
     729              : {
     730              : 
     731              :     // SUBROUTINE INFORMATION:
     732              :     //       AUTHOR         Linda Lawrie
     733              :     //       DATE WRITTEN   July 2008
     734              : 
     735              :     // PURPOSE OF THIS SUBROUTINE:
     736              :     // This routine allows access to data inside this module from other modules (specifically the
     737              :     // output tabular reports.
     738          963 :     auto const &pm = state.dataPollution;
     739              : 
     740          963 :     if (pm->GetInputFlagPollution) {
     741           11 :         GetPollutionFactorInput(state);
     742           11 :         pm->GetInputFlagPollution = false;
     743              :     }
     744              : 
     745          963 :     fuelFactorUsed = false;
     746          963 :     fuelSourceFactor = 0.0;
     747          963 :     fuelFactorScheduleUsed = false;
     748          963 :     *ffSched = nullptr;
     749              : 
     750          963 :     PollFuel pollFuel = fuel2pollFuel[(int)fuel];
     751          963 :     auto const &pollCoeff = pm->pollCoeffs[(int)pollFuel];
     752              : 
     753          963 :     if (pollCoeff.used) {
     754            0 :         fuelFactorUsed = true;
     755            0 :         fuelSourceFactor = pollCoeff.sourceCoeff;
     756            0 :         if (pollCoeff.sourceSched == nullptr) {
     757            0 :             fuelFactorScheduleUsed = false;
     758              :         } else {
     759            0 :             fuelFactorScheduleUsed = true;
     760            0 :             *ffSched = pollCoeff.sourceSched;
     761              :         }
     762              :     } else {
     763          963 :         fuelSourceFactor = pollFuelFactors[(int)pollFuel];
     764              :     }
     765              : 
     766          963 :     if (fuel == Constant::eFuel::DistrictHeatingWater) {
     767           74 :         fuelSourceFactor /= pm->PurchHeatEffic;
     768          889 :     } else if (fuel == Constant::eFuel::DistrictCooling) {
     769           74 :         fuelSourceFactor /= pm->PurchCoolCOP;
     770          815 :     } else if (fuel == Constant::eFuel::DistrictHeatingSteam) {
     771           75 :         fuelSourceFactor = 0.3 / pm->SteamConvEffic;
     772              :     }
     773          963 : }
     774              : 
     775           74 : void GetEnvironmentalImpactFactorInfo(EnergyPlusData &state,
     776              :                                       Real64 &efficiencyDistrictHeatingWater,  // if entered, the efficiency of District Heating Water
     777              :                                       Real64 &efficiencyDistrictCooling,       // if entered, the efficiency of District Cooling
     778              :                                       Real64 &sourceFactorDistrictHeatingSteam // if entered, the source factor for Dictrict Heating Steam
     779              : )
     780              : {
     781              : 
     782              :     // SUBROUTINE INFORMATION:
     783              :     //       AUTHOR         Linda Lawrie
     784              :     //       DATE WRITTEN   August 2008
     785              : 
     786              :     // PURPOSE OF THIS SUBROUTINE:
     787              :     // This routine allows access to data inside this module from other modules (specifically the
     788              :     // output tabular reports.
     789              : 
     790           74 :     auto const &pm = state.dataPollution;
     791           74 :     if (pm->GetInputFlagPollution) {
     792            0 :         GetPollutionFactorInput(state);
     793            0 :         pm->GetInputFlagPollution = false;
     794              :     }
     795              : 
     796           74 :     if (pm->NumEnvImpactFactors > 0) {
     797            0 :         efficiencyDistrictHeatingWater = pm->PurchHeatEffic;
     798            0 :         sourceFactorDistrictHeatingSteam = pm->SteamConvEffic;
     799            0 :         efficiencyDistrictCooling = pm->PurchCoolCOP;
     800              :     }
     801           74 : }
     802              : 
     803              : } // namespace EnergyPlus::Pollution
        

Generated by: LCOV version 2.0-1