LCOV - code coverage report
Current view: top level - EnergyPlus - PollutionModule.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 67.8 % 301 204
Test Date: 2025-05-22 16:09:37 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) return;
     114              : 
     115              :     //   Call the Routine to Read the Energy Values from the EnergyPlus Meters
     116        19866 :     ReadEnergyMeters(state);
     117              : 
     118              :     //   Call the routine that takes the fuel data and calculates the
     119              :     //     Pollution for each fuel type.
     120        19866 :     CalcPollution(state);
     121              : }
     122              : 
     123              : // Get Input Section of the Module
     124              : //******************************************************************************
     125              : 
     126           73 : void SetupPollutionCalculations(EnergyPlusData &state)
     127              : {
     128              : 
     129              :     // SUBROUTINE INFORMATION:
     130              :     //       AUTHOR         Richard Liesen
     131              :     //       DATE WRITTEN   August 2002
     132              :     //       MODIFIED       na
     133              :     //       RE-ENGINEERED  December 2003 RJL; August 2008 LKL - more standard getinput
     134              : 
     135              :     // PURPOSE OF THIS SUBROUTINE:
     136              :     // This subroutine is the input routines and Get routines
     137              : 
     138              :     // METHODOLOGY EMPLOYED:
     139              :     // Uses the status flags to trigger events.
     140              : 
     141              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     142              :     int NumPolluteRpt;
     143              :     int NumAlphas;
     144              :     int NumNums;
     145              :     int Loop;
     146              :     int IOStat;
     147           73 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     148              : 
     149              :     // First determine if the Pollution reporting has been triggered, and is not exit.
     150           73 :     cCurrentModuleObject = "Output:EnvironmentalImpactFactors";
     151           73 :     NumPolluteRpt = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     152           73 :     state.dataPollution->PollutionReportSetup = true;
     153              : 
     154           73 :     for (Loop = 1; Loop <= NumPolluteRpt; ++Loop) {
     155              : 
     156            0 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     157              :                                                                  cCurrentModuleObject,
     158              :                                                                  Loop,
     159            0 :                                                                  state.dataIPShortCut->cAlphaArgs,
     160              :                                                                  NumAlphas,
     161            0 :                                                                  state.dataIPShortCut->rNumericArgs,
     162              :                                                                  NumNums,
     163              :                                                                  IOStat,
     164            0 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
     165            0 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     166            0 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     167            0 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     168              : 
     169              :         // Call this routine in the Output Processor to setup the correct Facility energy meters that are
     170              :         //  necessary to make sure that the Meter file is opened and written to by the OP so that time stamps
     171              :         //  and the like are happening as expected.
     172            0 :         OutputProcessor::ReportFreq freq = OutputProcessor::ReportFreq::Simulation;
     173              : 
     174            0 :         if (!state.dataIPShortCut->lAlphaFieldBlanks(1) &&
     175              :             (freq = static_cast<OutputProcessor::ReportFreq>(
     176            0 :                  getEnumValue(OutputProcessor::reportFreqNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(1))))) ==
     177              :                 OutputProcessor::ReportFreq::Invalid) {
     178            0 :             ShowSevereError(state, format("Invalid reporting frequency {}", state.dataIPShortCut->cAlphaArgs(1)));
     179            0 :             continue;
     180              :         }
     181              : 
     182            0 :         InitPollutionMeterReporting(state, freq);
     183              :     }
     184           73 : }
     185              : 
     186           78 : void GetPollutionFactorInput(EnergyPlusData &state)
     187              : {
     188              : 
     189              :     // SUBROUTINE INFORMATION:
     190              :     //       AUTHOR         Linda Lawrie
     191              :     //       DATE WRITTEN   August 2008
     192              : 
     193              :     // PURPOSE OF THIS SUBROUTINE:
     194              :     // SetupPollutionCalculation must be called after meters are initialized.  This caused a problem
     195              :     // in runs so have added this routine to allow central get for most inputs.
     196              : 
     197           78 :     constexpr std::string_view routineName = "GetPollutionFactorInput";
     198              : 
     199              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     200              :     int NumAlphas;
     201              :     int NumNums;
     202              :     int IOStat;
     203           78 :     bool ErrorsFound = false;
     204              : 
     205           78 :     auto &ip = state.dataInputProcessing->inputProcessor;
     206           78 :     auto &ipsc = state.dataIPShortCut;
     207           78 :     auto &pm = state.dataPollution;
     208              : 
     209           78 :     if (!pm->GetInputFlagPollution) return; // Input already gotten
     210           78 :     pm->GetInputFlagPollution = false;
     211              : 
     212           78 :     ipsc->cCurrentModuleObject = "EnvironmentalImpactFactors";
     213           78 :     pm->NumEnvImpactFactors = ip->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
     214              : 
     215           78 :     if (pm->NumEnvImpactFactors > 0) {
     216              :         // Now find and load all of the user inputs and factors.
     217            4 :         ip->getObjectItem(state,
     218            2 :                           ipsc->cCurrentModuleObject,
     219              :                           1,
     220            2 :                           ipsc->cAlphaArgs,
     221              :                           NumAlphas,
     222            2 :                           ipsc->rNumericArgs,
     223              :                           NumNums,
     224              :                           IOStat,
     225            2 :                           ipsc->lNumericFieldBlanks,
     226            2 :                           ipsc->lAlphaFieldBlanks,
     227            2 :                           ipsc->cAlphaFieldNames,
     228            2 :                           ipsc->cNumericFieldNames);
     229           76 :     } else if (pm->PollutionReportSetup) {
     230            0 :         ShowWarningError(state, format("{}: not entered.  Values will be defaulted.", ipsc->cCurrentModuleObject));
     231              :     }
     232              : 
     233           78 :     pm->PurchHeatEffic = 0.3;
     234           78 :     pm->PurchCoolCOP = 3.0;
     235           78 :     pm->SteamConvEffic = 0.25;
     236           78 :     pm->CarbonEquivN2O = 0.0;
     237           78 :     pm->CarbonEquivCH4 = 0.0;
     238           78 :     pm->CarbonEquivCO2 = 0.0;
     239              : 
     240           78 :     if (pm->NumEnvImpactFactors > 0) {
     241              :         // If Heating Efficiency defined by the User is negative or zero then a default of 30% will be assigned.
     242            2 :         if (ipsc->rNumericArgs(1) > 0.0) {
     243            2 :             pm->PurchHeatEffic = ipsc->rNumericArgs(1);
     244              :         }
     245              : 
     246              :         // If COP defined by the User is negative or zero then a default of 3.0 will be assigned.
     247            2 :         if (ipsc->rNumericArgs(2) > 0.0) {
     248            2 :             pm->PurchCoolCOP = ipsc->rNumericArgs(2);
     249              :         }
     250              : 
     251              :         // If Steam Conversion Efficiency defined by the User is negative or zero then a default of 25% will be assigned.
     252            2 :         if (ipsc->rNumericArgs(3) > 0.0) {
     253            2 :             pm->SteamConvEffic = ipsc->rNumericArgs(3);
     254              :         }
     255              : 
     256              :         // Load the Total Carbon Equivalent Pollution Factor coefficients
     257            2 :         pm->CarbonEquivN2O = ipsc->rNumericArgs(4);
     258            2 :         pm->CarbonEquivCH4 = ipsc->rNumericArgs(5);
     259            2 :         pm->CarbonEquivCO2 = ipsc->rNumericArgs(6);
     260              :     }
     261              : 
     262              :     // Compare all of the Fuel Factors and compare to PollutionCalculationFactors List
     263           78 :     ipsc->cCurrentModuleObject = "FuelFactors";
     264           78 :     pm->NumFuelFactors = ip->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
     265              : 
     266           88 :     for (int Loop = 1; Loop <= state.dataPollution->NumFuelFactors; ++Loop) {
     267              :         // Now find and load all of the user inputs and factors.
     268           20 :         ip->getObjectItem(state,
     269           10 :                           ipsc->cCurrentModuleObject,
     270              :                           Loop,
     271           10 :                           ipsc->cAlphaArgs,
     272              :                           NumAlphas,
     273           10 :                           ipsc->rNumericArgs,
     274              :                           NumNums,
     275              :                           IOStat,
     276           10 :                           ipsc->lNumericFieldBlanks,
     277           10 :                           ipsc->lAlphaFieldBlanks,
     278           10 :                           ipsc->cAlphaFieldNames,
     279           10 :                           ipsc->cNumericFieldNames);
     280              : 
     281           10 :         ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
     282              : 
     283           10 :         PollFuel pollFuel = static_cast<PollFuel>(getEnumValue(pollFuelNamesUC, Util::makeUPPER(ipsc->cAlphaArgs(1))));
     284           10 :         if (pollFuel == PollFuel::Invalid) {
     285            0 :             ShowSevereInvalidKey(state, eoh, ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1));
     286            0 :             ErrorsFound = true;
     287            0 :             continue;
     288              :         }
     289              : 
     290           10 :         pm->pollFuelFactorList.push_back(pollFuel);
     291              : 
     292           10 :         auto &pollCoeff = pm->pollCoeffs[(int)pollFuel];
     293           10 :         Constant::eFuel fuel = pollFuel2fuel[(int)pollFuel];
     294              : 
     295           10 :         if (pollCoeff.used) {
     296            0 :             ShowWarningError(
     297            0 :                 state, format("{}: {} already entered. Previous entry will be used.", ipsc->cCurrentModuleObject, Constant::eFuelNames[(int)fuel]));
     298            0 :             continue;
     299              :         }
     300              : 
     301           10 :         pollCoeff.used = true;
     302              : 
     303           10 :         pollCoeff.sourceCoeff = ipsc->rNumericArgs(1);
     304           10 :         if (ipsc->lAlphaFieldBlanks(2)) {
     305            0 :         } else if ((pollCoeff.sourceSched = Sched::GetSchedule(state, ipsc->cAlphaArgs(2))) == nullptr) {
     306            0 :             ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2));
     307            0 :             ErrorsFound = true;
     308            0 :         } else if (!pollCoeff.sourceSched->checkMinVal(state, Clusive::In, 0.0)) {
     309            0 :             Sched::ShowSevereBadMin(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2), Clusive::In, 0.0);
     310            0 :             ErrorsFound = true;
     311              :         }
     312              : 
     313          170 :         for (int iPollutant = 0; iPollutant < (int)Pollutant::Num; ++iPollutant) {
     314          160 :             pollCoeff.pollutantCoeffs[iPollutant] = ipsc->rNumericArgs(iPollutant + 2);
     315          160 :             if (ipsc->lAlphaFieldBlanks(iPollutant + 3)) {
     316            0 :             } else if ((pollCoeff.pollutantScheds[iPollutant] = Sched::GetSchedule(state, ipsc->cAlphaArgs(iPollutant + 3))) == nullptr) {
     317            0 :                 ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(iPollutant + 3), ipsc->cAlphaArgs(iPollutant + 3));
     318            0 :                 ErrorsFound = true;
     319            0 :             } else if (!pollCoeff.pollutantScheds[iPollutant]->checkMinVal(state, Clusive::In, 0.0)) {
     320            0 :                 Sched::ShowSevereBadMin(state, eoh, ipsc->cAlphaFieldNames(iPollutant + 3), ipsc->cAlphaArgs(iPollutant + 3), Clusive::In, 0.0);
     321            0 :                 ErrorsFound = true;
     322              :             }
     323              :         } // for (iPollutant)
     324              : 
     325              :     } // End of the NumEnergyTypes Do Loop
     326              : 
     327           78 :     if (pm->PollutionReportSetup) { // only do this if reporting on the pollution
     328              :         // Need to go through all of the Fuel Types and make sure a Fuel Factor was found for each type of energy being simulated
     329              :         // Check for Electricity
     330            0 :         if (!pm->pollCoeffs[(int)PollFuel::Electricity].used && ((pm->facilityMeterNums[(int)PollFacilityMeter::Electricity] > 0) ||
     331            0 :                                                                  (pm->facilityMeterNums[(int)PollFacilityMeter::ElectricityProduced] > 0) ||
     332            0 :                                                                  (pm->facilityMeterNums[(int)PollFacilityMeter::CoolPurchased] > 0))) {
     333            0 :             ShowSevereError(state,
     334            0 :                             format("{} Not Found or Fuel not specified For Pollution Calculation for ELECTRICITY", ipsc->cCurrentModuleObject));
     335            0 :             ErrorsFound = true;
     336              :         }
     337              : 
     338              :         // Check for Natural Gas
     339            0 :         if (!pm->pollCoeffs[(int)PollFuel::NaturalGas].used &&
     340            0 :             ((pm->facilityMeterNums[(int)PollFacilityMeter::NaturalGas] > 0) || (pm->facilityMeterNums[(int)PollFacilityMeter::HeatPurchased] > 0) ||
     341            0 :              (pm->facilityMeterNums[(int)PollFacilityMeter::Steam] > 0))) {
     342            0 :             ShowSevereError(state,
     343            0 :                             format("{} Not Found or Fuel not specified For Pollution Calculation for NATURAL GAS", ipsc->cCurrentModuleObject));
     344            0 :             ErrorsFound = true;
     345              :         }
     346              :         // Check for FuelOilNo2 (Residual Oil)
     347            0 :         if (!pm->pollCoeffs[(int)PollFuel::FuelOil2].used && (pm->facilityMeterNums[(int)PollFacilityMeter::FuelOil2] > 0)) {
     348            0 :             ShowSevereError(state,
     349            0 :                             format("{} Not Found or Fuel not specified For Pollution Calculation for FUEL OIL #2", ipsc->cCurrentModuleObject));
     350            0 :             ErrorsFound = true;
     351              :         }
     352              :         // Check for FuelOilNo1 (Distillate Oil)
     353            0 :         if (!pm->pollCoeffs[(int)PollFuel::FuelOil1].used && (pm->facilityMeterNums[(int)PollFacilityMeter::FuelOil1] > 0)) {
     354            0 :             ShowSevereError(state,
     355            0 :                             format("{} Not Found or Fuel not specified For Pollution Calculation for FUEL OIL #1", ipsc->cCurrentModuleObject));
     356            0 :             ErrorsFound = true;
     357              :         }
     358              :         // Check for Coal
     359            0 :         if (!pm->pollCoeffs[(int)PollFuel::Coal].used && (pm->facilityMeterNums[(int)PollFacilityMeter::Coal] > 0)) {
     360            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for COAL", ipsc->cCurrentModuleObject));
     361            0 :             ErrorsFound = true;
     362              :         }
     363              :         // Check for Gasoline
     364            0 :         if (!pm->pollCoeffs[(int)PollFuel::Gasoline].used && (pm->facilityMeterNums[(int)PollFacilityMeter::Gasoline] > 0)) {
     365            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for GASOLINE", ipsc->cCurrentModuleObject));
     366            0 :             ErrorsFound = true;
     367              :         }
     368              :         // Check for Propane
     369            0 :         if (!pm->pollCoeffs[(int)PollFuel::Propane].used && (pm->facilityMeterNums[(int)PollFacilityMeter::Propane] > 0)) {
     370            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for PROPANE", ipsc->cCurrentModuleObject));
     371            0 :             ErrorsFound = true;
     372              :         }
     373              :         // Check for Diesel
     374            0 :         if (!pm->pollCoeffs[(int)PollFuel::Diesel].used && (pm->facilityMeterNums[(int)PollFacilityMeter::Diesel] > 0)) {
     375            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for DIESEL", ipsc->cCurrentModuleObject));
     376            0 :             ErrorsFound = true;
     377              :         }
     378              :         // Check for OtherFuel1
     379            0 :         if (!pm->pollCoeffs[(int)PollFuel::OtherFuel1].used && (pm->facilityMeterNums[(int)PollFacilityMeter::OtherFuel1] > 0)) {
     380            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for OTHERFUEL1", ipsc->cCurrentModuleObject));
     381            0 :             ErrorsFound = true;
     382              :         }
     383              :         // Check for OtherFuel2
     384            0 :         if (!pm->pollCoeffs[(int)PollFuel::OtherFuel2].used && (pm->facilityMeterNums[(int)PollFacilityMeter::OtherFuel2] > 0)) {
     385            0 :             ShowSevereError(state, format("{} Not Found or Fuel not specified For Pollution Calculation for OTHERFUEL2", ipsc->cCurrentModuleObject));
     386            0 :             ErrorsFound = true;
     387              :         }
     388              :     }
     389              : 
     390           78 :     if (ErrorsFound) {
     391            0 :         ShowFatalError(state, "Errors found in getting Pollution Calculation Reporting Input");
     392              :     }
     393              : }
     394              : 
     395           74 : void SetupPollutionMeterReporting(EnergyPlusData &state)
     396              : {
     397              : 
     398              :     // SUBROUTINE INFORMATION:
     399              :     //       AUTHOR         Richard Liesen
     400              :     //       DATE WRITTEN   August 2002
     401              :     //       MODIFIED       na
     402              :     //       RE-ENGINEERED  December 2003 RJL
     403              : 
     404              :     // PURPOSE OF THIS SUBROUTINE:
     405              :     // This subroutine is the input routines and Get routines
     406              : 
     407              :     // METHODOLOGY EMPLOYED:
     408              :     // Uses the status flags to trigger events.
     409              : 
     410              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     411           74 :     auto &pm = state.dataPollution;
     412              : 
     413           74 :     if (pm->GetInputFlagPollution) {
     414           66 :         GetPollutionFactorInput(state);
     415           66 :         pm->GetInputFlagPollution = false;
     416              :     }
     417              : 
     418              :     // We are using this list rather than the enumeration to preserve the order in which meters are created to avoid ordering diffs.
     419           83 :     for (PollFuel pollFuel : pm->pollFuelFactorList) {
     420              : 
     421            9 :         if (!pm->pollCoeffs[(int)pollFuel].used) continue;
     422              : 
     423            9 :         auto &pollComp = pm->pollComps[(int)pollFuel2pollFuelComponent[(int)pollFuel]];
     424              : 
     425            9 :         Constant::eFuel fuel = pollFuel2fuel[(int)pollFuel];
     426              : 
     427            9 :         constexpr std::array<OutputProcessor::EndUseCat, (int)Constant::eFuel::Num> fuel2sovEndUseCat = {
     428              :             OutputProcessor::EndUseCat::ElectricityEmissions,
     429              :             OutputProcessor::EndUseCat::NaturalGasEmissions,
     430              :             OutputProcessor::EndUseCat::GasolineEmissions,
     431              :             OutputProcessor::EndUseCat::DieselEmissions,
     432              :             OutputProcessor::EndUseCat::CoalEmissions,
     433              :             OutputProcessor::EndUseCat::PropaneEmissions,
     434              :             OutputProcessor::EndUseCat::FuelOilNo1Emissions,
     435              :             OutputProcessor::EndUseCat::FuelOilNo2Emissions,
     436              :             OutputProcessor::EndUseCat::OtherFuel1Emissions,
     437              :             OutputProcessor::EndUseCat::OtherFuel2Emissions,
     438              :             OutputProcessor::EndUseCat::Invalid,
     439              :             OutputProcessor::EndUseCat::Invalid,
     440              :             OutputProcessor::EndUseCat::Invalid,
     441              :             OutputProcessor::EndUseCat::Invalid,
     442              :             OutputProcessor::EndUseCat::Invalid // used for OtherEquipment object
     443              :         };
     444              : 
     445              :         // Need to check whether this fuel is used?
     446           45 :         SetupOutputVariable(state,
     447           18 :                             format("Environmental Impact {} Source Energy", Constant::eFuelNames[(int)fuel]),
     448              :                             Constant::Units::J,
     449            9 :                             pollComp.sourceVal,
     450              :                             OutputProcessor::TimeStepType::System,
     451              :                             OutputProcessor::StoreType::Sum,
     452              :                             "Site",
     453              :                             Constant::eResource::Source,
     454              :                             OutputProcessor::Group::Invalid,
     455            9 :                             fuel2sovEndUseCat[(int)fuel]);
     456              : 
     457          153 :         for (int iPollutant = 0; iPollutant < (int)Pollutant::Num; ++iPollutant) {
     458          720 :             SetupOutputVariable(state,
     459          288 :                                 format("Environmental Impact {} {}", Constant::eFuelNames[(int)fuel], poll2outVarStrs[iPollutant]),
     460          144 :                                 pollUnits[iPollutant],
     461          144 :                                 pollComp.pollutantVals[iPollutant],
     462              :                                 OutputProcessor::TimeStepType::System,
     463              :                                 OutputProcessor::StoreType::Sum,
     464              :                                 "Site",
     465          144 :                                 poll2Resource[iPollutant],
     466              :                                 OutputProcessor::Group::Invalid,
     467          144 :                                 fuel2sovEndUseCat[(int)fuel]);
     468              :         }
     469              : 
     470            9 :         if (fuel == Constant::eFuel::Electricity) {
     471              :             // Setup ElectricityPurchased and ElectricitySold variables
     472              :             // Doing this here as opposed to outside the outer loop to preserve meter order and reduce ordering diffs
     473            4 :             SetupOutputVariable(state,
     474              :                                 "Environmental Impact Purchased Electricity Source Energy",
     475              :                                 Constant::Units::J,
     476            1 :                                 pm->pollComps[(int)PollFuelComponent::ElectricityPurchased].sourceVal,
     477              :                                 OutputProcessor::TimeStepType::System,
     478              :                                 OutputProcessor::StoreType::Sum,
     479              :                                 "Site",
     480              :                                 Constant::eResource::Source,
     481              :                                 OutputProcessor::Group::Invalid,
     482              :                                 OutputProcessor::EndUseCat::PurchasedElectricityEmissions);
     483            4 :             SetupOutputVariable(state,
     484              :                                 "Environmental Impact Surplus Sold Electricity Source",
     485              :                                 Constant::Units::J,
     486            1 :                                 pm->pollComps[(int)PollFuelComponent::ElectricitySurplusSold].sourceVal,
     487              :                                 OutputProcessor::TimeStepType::System,
     488              :                                 OutputProcessor::StoreType::Sum,
     489              :                                 "Site",
     490              :                                 Constant::eResource::Source,
     491              :                                 OutputProcessor::Group::Invalid,
     492              :                                 OutputProcessor::EndUseCat::SoldElectricityEmissions);
     493              :         }
     494              : 
     495              :     } // End of the NumEnergyTypes Do Loop
     496              : 
     497              :     // And Total Carbon Equivalent variables
     498          296 :     SetupOutputVariable(state,
     499              :                         "Environmental Impact Total N2O Emissions Carbon Equivalent Mass",
     500              :                         Constant::Units::kg,
     501           74 :                         pm->TotCarbonEquivFromN2O,
     502              :                         OutputProcessor::TimeStepType::System,
     503              :                         OutputProcessor::StoreType::Sum,
     504              :                         "Site",
     505              :                         Constant::eResource::CarbonEquivalent,
     506              :                         OutputProcessor::Group::Invalid,
     507              :                         OutputProcessor::EndUseCat::CarbonEquivalentEmissions);
     508          296 :     SetupOutputVariable(state,
     509              :                         "Environmental Impact Total CH4 Emissions Carbon Equivalent Mass",
     510              :                         Constant::Units::kg,
     511           74 :                         pm->TotCarbonEquivFromCH4,
     512              :                         OutputProcessor::TimeStepType::System,
     513              :                         OutputProcessor::StoreType::Sum,
     514              :                         "Site",
     515              :                         Constant::eResource::CarbonEquivalent,
     516              :                         OutputProcessor::Group::Invalid,
     517              :                         OutputProcessor::EndUseCat::CarbonEquivalentEmissions);
     518          296 :     SetupOutputVariable(state,
     519              :                         "Environmental Impact Total CO2 Emissions Carbon Equivalent Mass",
     520              :                         Constant::Units::kg,
     521           74 :                         pm->TotCarbonEquivFromCO2,
     522              :                         OutputProcessor::TimeStepType::System,
     523              :                         OutputProcessor::StoreType::Sum,
     524              :                         "Site",
     525              :                         Constant::eResource::CarbonEquivalent,
     526              :                         OutputProcessor::Group::Invalid,
     527              :                         OutputProcessor::EndUseCat::CarbonEquivalentEmissions);
     528              : 
     529              :     // Connect pollution meters to energy meters
     530         1258 :     for (int iMeter = 0; iMeter < (int)PollFacilityMeter::Num; ++iMeter) {
     531         1184 :         pm->facilityMeterNums[iMeter] = GetMeterIndex(state, Util::makeUPPER(pollFacilityMeterNames[iMeter]));
     532              :     }
     533           74 : }
     534              : 
     535           73 : void CheckPollutionMeterReporting(EnergyPlusData &state)
     536              : {
     537              : 
     538              :     // SUBROUTINE INFORMATION:
     539              :     //       AUTHOR         Linda Lawrie
     540              :     //       DATE WRITTEN   October 2008
     541              : 
     542              :     // in progress (what is in progress?)
     543              : 
     544           73 :     auto const &pm = state.dataPollution;
     545              : 
     546           73 :     if (pm->NumFuelFactors == 0 || pm->NumEnvImpactFactors == 0) {
     547          219 :         if (ReportingThisVariable(state, "Environmental Impact Total N2O Emissions Carbon Equivalent Mass") ||
     548          219 :             ReportingThisVariable(state, "Environmental Impact Total CH4 Emissions Carbon Equivalent Mass") ||
     549          219 :             ReportingThisVariable(state, "Environmental Impact Total CO2 Emissions Carbon Equivalent Mass") ||
     550          438 :             ReportingThisVariable(state, "Carbon Equivalent:Facility") ||
     551          219 :             ReportingThisVariable(state, "CarbonEquivalentEmissions:Carbon Equivalent")) {
     552            0 :             ShowWarningError(
     553              :                 state, "GetPollutionFactorInput: Requested reporting for Carbon Equivalent Pollution, but insufficient information is entered.");
     554            0 :             ShowContinueError(
     555              :                 state, "Both \"FuelFactors\" and \"EnvironmentalImpactFactors\" must be entered or the displayed carbon pollution will all be zero.");
     556              :         }
     557              :     }
     558           73 : }
     559              : 
     560              : // End of Get Input subroutines for the Pollution Module
     561              : //******************************************************************************
     562              : 
     563        19866 : void CalcPollution(EnergyPlusData &state)
     564              : {
     565              :     // SUBROUTINE INFORMATION:
     566              :     //       AUTHOR         Richard Liesen
     567              :     //       DATE WRITTEN   1998
     568              :     //       MODIFIED       na
     569              :     //       RE-ENGINEERED  December 2003 RJL
     570              : 
     571              :     //       Then the amount of Pollution produced by each fuel type is
     572              :     //       calculated in kgs.
     573              :     //       Input units for the coefficients is not standard and needs to be converted here.
     574              :     //       Most of the units are g/MJ, however water is in L/MJ and low level nuclear water is m3/MJ
     575              :     //       so only the energy has to be converted from J to MJ.
     576              : 
     577              :     //     For each pollution/fuel type, Schedule values are allowed.  Thus, calculations are bundled.
     578        19866 :     auto &pm = state.dataPollution;
     579              : 
     580       337722 :     for (int iPoll = 0; iPoll < (int)Pollutant::Num; ++iPoll) {
     581       317856 :         pm->pollutantVals[iPoll] = 0.0;
     582              : 
     583      3496416 :         for (int iPollFuel = 0; iPollFuel < (int)PollFuel::Num; ++iPollFuel) {
     584      3178560 :             auto &pollCoeff = pm->pollCoeffs[iPollFuel];
     585      3178560 :             PollFuelComponent pollFuelComp = pollFuel2pollFuelComponent[iPollFuel];
     586      3178560 :             auto &pollComp = pm->pollComps[(int)pollFuelComp];
     587              : 
     588      3178560 :             if (pollCoeff.used) {
     589            0 :                 pollComp.pollutantVals[iPoll] = 0.0;
     590            0 :                 Real64 pollutantVal = pollCoeff.pollutantCoeffs[iPoll];
     591              : 
     592              :                 // Why are these two the exceptions?
     593            0 :                 if (iPoll != (int)Pollutant::Water && iPoll != (int)Pollutant::NuclearLow) pollutantVal *= 0.001;
     594              : 
     595            0 :                 if (pollCoeff.pollutantScheds[iPoll] != nullptr) {
     596            0 :                     pollutantVal *= pollCoeff.pollutantScheds[iPoll]->getCurrentVal();
     597              :                 }
     598            0 :                 pollComp.pollutantVals[iPoll] = pm->facilityMeterFuelComponentVals[(int)pollFuelComp] * 1.0e-6 * pollutantVal;
     599              :             }
     600              : 
     601      3178560 :             pm->pollutantVals[iPoll] += pollComp.pollutantVals[iPoll];
     602              :         } // for (iPollFactor)
     603              :     }     // for (iPoll)
     604              : 
     605        19866 :     pm->TotCarbonEquivFromN2O = pm->pollutantVals[(int)Pollutant::N2O] * pm->CarbonEquivN2O;
     606        19866 :     pm->TotCarbonEquivFromCH4 = pm->pollutantVals[(int)Pollutant::CH4] * pm->CarbonEquivCH4;
     607        19866 :     pm->TotCarbonEquivFromCO2 = pm->pollutantVals[(int)Pollutant::CO2] * pm->CarbonEquivCO2;
     608              : 
     609        19866 :     auto const &pollCoeffElec = pm->pollCoeffs[(int)PollFuel::Electricity];
     610        19866 :     auto &pollCompElec = pm->pollComps[(int)PollFuelComponent::Electricity];
     611        19866 :     auto &pollCompElecPurchased = pm->pollComps[(int)PollFuelComponent::ElectricityPurchased];
     612        19866 :     auto &pollCompElecSurplusSold = pm->pollComps[(int)PollFuelComponent::ElectricitySurplusSold];
     613              : 
     614        19866 :     pollCompElec.sourceVal = pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Electricity] * pollCoeffElec.sourceCoeff;
     615        19866 :     pollCompElecPurchased.sourceVal = pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::ElectricityPurchased] * pollCoeffElec.sourceCoeff;
     616        19866 :     pollCompElecSurplusSold.sourceVal =
     617        19866 :         pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::ElectricitySurplusSold] * pollCoeffElec.sourceCoeff;
     618              : 
     619        19866 :     if (pollCoeffElec.sourceSched != nullptr) {
     620            0 :         Real64 pollCoeffElecSchedVal = pollCoeffElec.sourceSched->getCurrentVal();
     621            0 :         pollCompElec.sourceVal *= pollCoeffElecSchedVal;
     622            0 :         pollCompElecPurchased.sourceVal *= pollCoeffElecSchedVal;
     623            0 :         pollCompElecSurplusSold.sourceVal *= pollCoeffElecSchedVal;
     624              :     }
     625              : 
     626              :     // does not include district heating or steam
     627        19866 :     auto const &pollCoeffGas = pm->pollCoeffs[(int)PollFuel::NaturalGas];
     628        19866 :     auto &pollCompGas = pm->pollComps[(int)PollFuelComponent::NaturalGas];
     629        19866 :     pollCompGas.sourceVal = pm->facilityMeterVals[(int)PollFacilityMeter::NaturalGas] * pollCoeffGas.sourceCoeff;
     630        19866 :     if (pollCoeffGas.sourceSched != nullptr) {
     631            0 :         pollCompGas.sourceVal *= pollCoeffGas.sourceSched->getCurrentVal();
     632              :     }
     633              : 
     634       178794 :     for (PollFuel pollFuel : {PollFuel::FuelOil1,
     635              :                               PollFuel::FuelOil2,
     636              :                               PollFuel::Diesel,
     637              :                               PollFuel::Gasoline,
     638              :                               PollFuel::Propane,
     639              :                               PollFuel::Coal,
     640              :                               PollFuel::OtherFuel1,
     641       198660 :                               PollFuel::OtherFuel2}) {
     642       158928 :         auto const &pollCoeff = pm->pollCoeffs[(int)pollFuel];
     643       158928 :         PollFuelComponent pollFuelComponent = pollFuel2pollFuelComponent[(int)pollFuel];
     644       158928 :         auto &pollComp = pm->pollComps[(int)pollFuelComponent];
     645              : 
     646       158928 :         pollComp.sourceVal = pm->facilityMeterFuelComponentVals[(int)pollFuelComponent] * pollCoeff.sourceCoeff;
     647       158928 :         if (pollCoeff.sourceSched != nullptr) {
     648            0 :             pollComp.sourceVal *= pollCoeff.sourceSched->getCurrentVal();
     649              :         }
     650              :     } // for (pollFuelComponent)
     651        19866 : } // CalcPollution()
     652              : 
     653        19866 : void ReadEnergyMeters(EnergyPlusData &state)
     654              : {
     655              :     // SUBROUTINE INFORMATION:
     656              :     //       AUTHOR         Richard Liesen
     657              :     //       DATE WRITTEN   1998
     658              :     //       MODIFIED       na
     659              :     //       RE-ENGINEERED  December 2003 RJL
     660              : 
     661              :     // PURPOSE OF THIS SUBROUTINE:
     662              :     //       Read Energy Results from the meters
     663              :     // This routine reads the meters for the energy used
     664              : 
     665              :     // Using/Aliasing
     666        19866 :     Real64 FracTimeStepZone = state.dataHVACGlobal->FracTimeStepZone;
     667        19866 :     auto &pm = state.dataPollution;
     668              : 
     669       337722 :     for (int iMeter = 0; iMeter < (int)PollFacilityMeter::Num; ++iMeter) {
     670       317856 :         pm->facilityMeterVals[iMeter] =
     671       317856 :             GetInstantMeterValue(state, pm->facilityMeterNums[iMeter], OutputProcessor::TimeStepType::Zone) * FracTimeStepZone +
     672       317856 :             GetInstantMeterValue(state, pm->facilityMeterNums[iMeter], OutputProcessor::TimeStepType::System);
     673              :     }
     674              : 
     675              :     // Now these fuel types have to be sorted and summed into categories that we have pollution factors for.
     676              :     // The Off-Site Electricity is the total needed by the facility minus the amount generated on-site.
     677              :     // The on-site pollutants will end up being other fuel types used by the generators.
     678              :     // If the difference between the 2 electric quantities is <0.0 then it will be zero for that time step.
     679              :     // We will also add the District Cooling here with a rough conversion from Energy using the User
     680              :     // defined COP.
     681              : 
     682        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Electricity] =
     683        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::Electricity] - pm->facilityMeterVals[(int)PollFacilityMeter::ElectricityProduced] +
     684        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::CoolPurchased] / pm->PurchCoolCOP;
     685              : 
     686        19866 :     if (pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Electricity] < 0.0)
     687            0 :         pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Electricity] = 0.0;
     688              : 
     689              :     // The Natural Gas fuel type will be summed from the meters with the District Heating using an efficiency.
     690        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::NaturalGas] =
     691        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::NaturalGas] +
     692        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::HeatPurchased] / pm->PurchHeatEffic +
     693        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::Steam] / pm->SteamConvEffic;
     694              : 
     695        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::FuelOil1] = pm->facilityMeterVals[(int)PollFacilityMeter::FuelOil1];
     696        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::FuelOil2] = pm->facilityMeterVals[(int)PollFacilityMeter::FuelOil2];
     697        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Gasoline] = pm->facilityMeterVals[(int)PollFacilityMeter::Gasoline];
     698        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Propane] = pm->facilityMeterVals[(int)PollFacilityMeter::Propane];
     699        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Coal] = pm->facilityMeterVals[(int)PollFacilityMeter::Coal];
     700        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::Diesel] = pm->facilityMeterVals[(int)PollFacilityMeter::Diesel];
     701        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::OtherFuel1] = pm->facilityMeterVals[(int)PollFacilityMeter::OtherFuel1];
     702        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::OtherFuel2] = pm->facilityMeterVals[(int)PollFacilityMeter::OtherFuel2];
     703        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::ElectricityPurchased] =
     704        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::ElectricityPurchased];
     705        19866 :     pm->facilityMeterFuelComponentVals[(int)PollFuelComponent::ElectricitySurplusSold] =
     706        19866 :         pm->facilityMeterVals[(int)PollFacilityMeter::ElectricitySurplusSold];
     707        19866 : }
     708              : 
     709              : // *****************************************************************************
     710              : // Utility Routines to allow access to data inside this module.
     711              : // *****************************************************************************
     712              : 
     713          963 : void GetFuelFactorInfo(EnergyPlusData &state,
     714              :                        Constant::eFuel fuel,         // input fuel name  (standard from Tabular reports)
     715              :                        bool &fuelFactorUsed,         // return value true if user has entered this fuel
     716              :                        Real64 &fuelSourceFactor,     // if used, the source factor
     717              :                        bool &fuelFactorScheduleUsed, // if true, schedules for this fuel are used
     718              :                        Sched::Schedule **ffSched     // if schedules for this fuel are used, return schedule index
     719              : )
     720              : {
     721              : 
     722              :     // SUBROUTINE INFORMATION:
     723              :     //       AUTHOR         Linda Lawrie
     724              :     //       DATE WRITTEN   July 2008
     725              : 
     726              :     // PURPOSE OF THIS SUBROUTINE:
     727              :     // This routine allows access to data inside this module from other modules (specifically the
     728              :     // output tabular reports.
     729          963 :     auto const &pm = state.dataPollution;
     730              : 
     731          963 :     if (pm->GetInputFlagPollution) {
     732           11 :         GetPollutionFactorInput(state);
     733           11 :         pm->GetInputFlagPollution = false;
     734              :     }
     735              : 
     736          963 :     fuelFactorUsed = false;
     737          963 :     fuelSourceFactor = 0.0;
     738          963 :     fuelFactorScheduleUsed = false;
     739          963 :     *ffSched = nullptr;
     740              : 
     741          963 :     PollFuel pollFuel = fuel2pollFuel[(int)fuel];
     742          963 :     auto const &pollCoeff = pm->pollCoeffs[(int)pollFuel];
     743              : 
     744          963 :     if (pollCoeff.used) {
     745            0 :         fuelFactorUsed = true;
     746            0 :         fuelSourceFactor = pollCoeff.sourceCoeff;
     747            0 :         if (pollCoeff.sourceSched == nullptr) {
     748            0 :             fuelFactorScheduleUsed = false;
     749              :         } else {
     750            0 :             fuelFactorScheduleUsed = true;
     751            0 :             *ffSched = pollCoeff.sourceSched;
     752              :         }
     753              :     } else {
     754          963 :         fuelSourceFactor = pollFuelFactors[(int)pollFuel];
     755              :     }
     756              : 
     757          963 :     if (fuel == Constant::eFuel::DistrictHeatingWater) {
     758           74 :         fuelSourceFactor /= pm->PurchHeatEffic;
     759          889 :     } else if (fuel == Constant::eFuel::DistrictCooling) {
     760           74 :         fuelSourceFactor /= pm->PurchCoolCOP;
     761          815 :     } else if (fuel == Constant::eFuel::DistrictHeatingSteam) {
     762           75 :         fuelSourceFactor = 0.3 / pm->SteamConvEffic;
     763              :     }
     764          963 : }
     765              : 
     766           74 : void GetEnvironmentalImpactFactorInfo(EnergyPlusData &state,
     767              :                                       Real64 &efficiencyDistrictHeatingWater,  // if entered, the efficiency of District Heating Water
     768              :                                       Real64 &efficiencyDistrictCooling,       // if entered, the efficiency of District Cooling
     769              :                                       Real64 &sourceFactorDistrictHeatingSteam // if entered, the source factor for Dictrict Heating Steam
     770              : )
     771              : {
     772              : 
     773              :     // SUBROUTINE INFORMATION:
     774              :     //       AUTHOR         Linda Lawrie
     775              :     //       DATE WRITTEN   August 2008
     776              : 
     777              :     // PURPOSE OF THIS SUBROUTINE:
     778              :     // This routine allows access to data inside this module from other modules (specifically the
     779              :     // output tabular reports.
     780              : 
     781           74 :     auto const &pm = state.dataPollution;
     782           74 :     if (pm->GetInputFlagPollution) {
     783            0 :         GetPollutionFactorInput(state);
     784            0 :         pm->GetInputFlagPollution = false;
     785              :     }
     786              : 
     787           74 :     if (pm->NumEnvImpactFactors > 0) {
     788            0 :         efficiencyDistrictHeatingWater = pm->PurchHeatEffic;
     789            0 :         sourceFactorDistrictHeatingSteam = pm->SteamConvEffic;
     790            0 :         efficiencyDistrictCooling = pm->PurchCoolCOP;
     791              :     }
     792           74 : }
     793              : 
     794              : } // namespace EnergyPlus::Pollution
        

Generated by: LCOV version 2.0-1