LCOV - code coverage report
Current view: top level - EnergyPlus - PollutionModule.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 239 316 75.6 %
Date: 2024-08-24 18:31:18 Functions: 9 9 100.0 %

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

Generated by: LCOV version 1.14