LCOV - code coverage report
Current view: top level - EnergyPlus/InputProcessing - InputProcessor.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 90.6 % 1471 1333
Test Date: 2025-06-02 12:03:30 Functions: 93.5 % 46 43

            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              : // C++ Headers
      49              : #include <algorithm>
      50              : #include <fstream>
      51              : #include <iostream>
      52              : #include <istream>
      53              : #include <memory>
      54              : #include <unordered_set>
      55              : 
      56              : #include <ObjexxFCL/Array1S.hh>
      57              : 
      58              : // EnergyPlus Headers
      59              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      60              : #include <EnergyPlus/DataIPShortCuts.hh>
      61              : #include <EnergyPlus/DataOutputs.hh>
      62              : #include <EnergyPlus/DataSizing.hh>
      63              : #include <EnergyPlus/DataStringGlobals.hh>
      64              : #include <EnergyPlus/DataSystemVariables.hh>
      65              : #include <EnergyPlus/DisplayRoutines.hh>
      66              : #include <EnergyPlus/FileSystem.hh>
      67              : #include <EnergyPlus/InputProcessing/DataStorage.hh>
      68              : #include <EnergyPlus/InputProcessing/IdfParser.hh>
      69              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      70              : #include <EnergyPlus/InputProcessing/InputValidation.hh>
      71              : #include <EnergyPlus/OutputProcessor.hh>
      72              : #include <EnergyPlus/UtilityRoutines.hh>
      73              : #include <embedded/EmbeddedEpJSONSchema.hh>
      74              : 
      75              : #include <fmt/os.h>
      76              : #include <milo/dtoa.h>
      77              : #include <milo/itoa.h>
      78              : 
      79              : namespace EnergyPlus {
      80              : // Module containing the input processor routines
      81              : 
      82              : // MODULE INFORMATION:
      83              : //       AUTHOR         Linda K. Lawrie
      84              : //       DATE WRITTEN   August 1997
      85              : //       MODIFIED       na
      86              : //       RE-ENGINEERED  Mark Adams 2017
      87              : 
      88              : // PURPOSE OF THIS MODULE:
      89              : // To provide the capabilities of reading the input data dictionary
      90              : // and input file and supplying the simulation routines with the data
      91              : // contained therein.
      92              : 
      93              : // METHODOLOGY EMPLOYED:
      94              : 
      95              : // REFERENCES:
      96              : // The input syntax is designed to allow for future flexibility without
      97              : // necessitating massive (or any) changes to this code.  Two files are
      98              : // used as key elements: (1) the input data dictionary will specify the
      99              : // sections and objects that will be allowed in the actual simulation
     100              : // input file and (2) the simulation input data file will be processed
     101              : // with the data therein being supplied to the actual simulation routines.
     102              : 
     103              : static std::string const BlankString;
     104              : 
     105              : using json = nlohmann::json;
     106              : 
     107        42985 : const json &InputProcessor::schema()
     108              : {
     109              :     // avoid re-parsing embedded JSON schema by making this into a static const singleton
     110              :     // because it is const, we don't have to worry about threading issues for creation or access
     111        42985 :     static const auto json_schema = json::from_cbor(EmbeddedEpJSONSchema::embeddedEpJSONSchema()); // (AUTO_OK_OBJ)
     112        42985 :     return json_schema;
     113              : }
     114              : 
     115         4233 : InputProcessor::InputProcessor() : idf_parser(std::make_unique<IdfParser>()), data(std::make_unique<DataStorage>())
     116              : {
     117         4233 :     const json &loc = schema()["properties"];
     118         4233 :     caseInsensitiveObjectMap.reserve(loc.size());
     119      3598050 :     for (auto it = loc.begin(); it != loc.end(); ++it) {
     120      3593817 :         caseInsensitiveObjectMap.emplace(convertToUpper(it.key()), it.key());
     121         4233 :     }
     122         4233 :     idf_parser = std::make_unique<IdfParser>();
     123         4233 :     data = std::make_unique<DataStorage>();
     124         4233 :     epJSON = json::object();
     125              :     //    objectCacheMap.clear();
     126              :     //    unusedInputs.clear();
     127         4233 :     validation = std::make_unique<Validation>(&schema());
     128         4233 : }
     129              : 
     130         4233 : std::unique_ptr<InputProcessor> InputProcessor::factory()
     131              : {
     132         4233 :     return std::make_unique<InputProcessor>();
     133              : }
     134              : 
     135            0 : json const &InputProcessor::getFields(EnergyPlusData &state, std::string const &objectType, std::string const &objectName)
     136              : {
     137            0 :     auto const it = epJSON.find(objectType);
     138            0 :     if (it == epJSON.end()) {
     139            0 :         ShowFatalError(state, "ObjectType (" + objectType + ") requested was not found in input");
     140              :     }
     141            0 :     auto const &objs = it.value();
     142            0 :     auto const it2 = objs.find(objectName);
     143            0 :     if (it2 == objs.end()) {
     144              :         // HACK: this is not ideal and should be removed once everything is case sensitive internally
     145            0 :         for (auto it3 = objs.begin(); it3 != objs.end(); ++it3) {
     146            0 :             if (Util::makeUPPER(it3.key()) == objectName) {
     147            0 :                 return it3.value();
     148              :             }
     149            0 :         }
     150            0 :         ShowFatalError(state, "Name \"" + objectName + "\" requested was not found in input for ObjectType (" + objectType + ")");
     151              :     }
     152            0 :     return it2.value();
     153            0 : }
     154              : 
     155            0 : json const &InputProcessor::getFields(EnergyPlusData &state, std::string const &objectType)
     156              : {
     157            0 :     static const std::string blankString;
     158            0 :     auto const it = epJSON.find(objectType);
     159            0 :     if (it == epJSON.end()) {
     160            0 :         ShowFatalError(state, "ObjectType (" + objectType + ") requested was not found in input");
     161              :     }
     162            0 :     auto const &objs = it.value();
     163            0 :     auto const it2 = objs.find(blankString);
     164            0 :     if (it2 == objs.end()) {
     165            0 :         ShowFatalError(state, "Name \"\" requested was not found in input for ObjectType (" + objectType + ")");
     166              :     }
     167            0 :     return it2.value();
     168            0 : }
     169              : 
     170        29856 : json const &InputProcessor::getPatternProperties(EnergyPlusData &state, json const &schema_obj)
     171              : {
     172        29856 :     std::string pattern_property;
     173        29856 :     auto const &pattern_properties = schema_obj["patternProperties"];
     174        59712 :     int dot_star_present = pattern_properties.count(".*");
     175        29856 :     int no_whitespace_present = pattern_properties.count(R"(^.*\S.*$)");
     176        29856 :     if (dot_star_present) {
     177         7181 :         pattern_property = ".*";
     178        22675 :     } else if (no_whitespace_present) {
     179        22675 :         pattern_property = R"(^.*\S.*$)";
     180              :     } else {
     181            0 :         ShowFatalError(state, R"(The patternProperties value is not a valid choice (".*", "^.*\S.*$"))");
     182              :     }
     183        29856 :     auto const &schema_obj_props = pattern_properties[pattern_property]["properties"];
     184        29856 :     return schema_obj_props;
     185        29856 : }
     186              : 
     187              : // Functions
     188              : 
     189              : // void InputProcessor::clear_state() {
     190              : //    idf_parser = std::make_unique<IdfParser>();
     191              : //    data = std::make_unique<DataStorage>();
     192              : //    epJSON = json::object();
     193              : //    objectCacheMap.clear();
     194              : //    unusedInputs.clear();
     195              : //    validation = std::make_unique<Validation>(&schema);
     196              : //}
     197              : 
     198            8 : std::vector<std::string> const &InputProcessor::validationErrors()
     199              : {
     200            8 :     return validation->errors();
     201              : }
     202              : 
     203            6 : std::vector<std::string> const &InputProcessor::validationWarnings()
     204              : {
     205            6 :     return validation->warnings();
     206              : }
     207              : 
     208            0 : std::pair<bool, std::string> InputProcessor::convertInsensitiveObjectType(std::string const &objectType)
     209              : {
     210            0 :     auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(objectType));
     211            0 :     if (tmp_umit != caseInsensitiveObjectMap.end()) {
     212            0 :         return std::make_pair(true, tmp_umit->second);
     213              :     }
     214            0 :     return std::make_pair(false, "");
     215            0 : }
     216              : 
     217         1369 : void InputProcessor::initializeMaps()
     218              : {
     219         1369 :     unusedInputs.clear();
     220         1369 :     objectCacheMap.clear();
     221         1369 :     objectCacheMap.reserve(epJSON.size());
     222         2738 :     auto const &schema_properties = schema().at("properties");
     223              : 
     224        17786 :     for (auto epJSON_iter = epJSON.begin(); epJSON_iter != epJSON.end(); ++epJSON_iter) {
     225        16417 :         auto const &objects = epJSON_iter.value();
     226        16417 :         auto const &objectType = epJSON_iter.key();
     227        16417 :         ObjectCache objectCache;
     228        16417 :         objectCache.inputObjectIterators.reserve(objects.size());
     229        52020 :         for (auto epJSON_obj_iter = objects.begin(); epJSON_obj_iter != objects.end(); ++epJSON_obj_iter) {
     230        35603 :             objectCache.inputObjectIterators.emplace_back(epJSON_obj_iter);
     231        35603 :             unusedInputs.emplace(objectType, epJSON_obj_iter.key());
     232        16417 :         }
     233        16417 :         auto const schema_iter = schema_properties.find(objectType);
     234        16417 :         objectCache.schemaIterator = schema_iter;
     235        16417 :         objectCacheMap.emplace(schema_iter.key(), objectCache);
     236        17786 :     }
     237         1369 : }
     238              : 
     239         2567 : void InputProcessor::markObjectAsUsed(const std::string &objectType, const std::string &objectName)
     240              : {
     241         2567 :     auto const find_unused = unusedInputs.find({objectType, objectName});
     242         2567 :     if (find_unused != unusedInputs.end()) {
     243         2548 :         unusedInputs.erase(find_unused);
     244              :     }
     245         2567 : }
     246              : 
     247           10 : void cleanEPJSON(json &epjson)
     248              : {
     249           10 :     if (epjson.type() == json::value_t::object) {
     250           10 :         epjson.erase("idf_order");
     251           10 :         epjson.erase("idf_max_fields");
     252            5 :         epjson.erase("idf_max_extensible_fields");
     253           14 :         for (auto it = epjson.begin(); it != epjson.end(); ++it) {
     254            9 :             cleanEPJSON(epjson[it.key()]);
     255            5 :         }
     256              :     }
     257           10 : }
     258              : 
     259           26 : void InputProcessor::processInput(EnergyPlusData &state)
     260              : {
     261           26 :     if (!FileSystem::fileExists(state.dataStrGlobals->inputFilePath)) {
     262            0 :         ShowFatalError(state, fmt::format("Input file path {} not found", state.dataStrGlobals->inputFilePath));
     263            0 :         return;
     264              :     }
     265              : 
     266              :     try {
     267           26 :         if (!state.dataGlobal->isEpJSON) {
     268           26 :             auto input_file = FileSystem::readFile(state.dataStrGlobals->inputFilePath); // (AUTO_OK_OBJ)
     269              : 
     270           26 :             bool success = true;
     271           26 :             epJSON = idf_parser->decode(input_file, schema(), success);
     272              : 
     273           26 :             if (state.dataGlobal->outputEpJSONConversion || state.dataGlobal->outputEpJSONConversionOnly) {
     274            0 :                 json epJSONClean = epJSON;
     275            0 :                 cleanEPJSON(epJSONClean);
     276              :                 fs::path convertedIDF = FileSystem::makeNativePath(
     277            0 :                     FileSystem::replaceFileExtension(state.dataStrGlobals->outDirPath / state.dataStrGlobals->inputFilePathNameOnly, ".epJSON"));
     278            0 :                 FileSystem::writeFile<FileSystem::FileTypes::EpJSON>(convertedIDF, epJSONClean);
     279            0 :             }
     280           26 :         } else {
     281            0 :             epJSON = FileSystem::readJSON(state.dataStrGlobals->inputFilePath);
     282              :         }
     283            0 :     } catch (const std::exception &e) {
     284            0 :         ShowSevereError(state, e.what());
     285            0 :         ShowFatalError(state, "Errors occurred on processing input file. Preceding condition(s) cause termination.");
     286            0 :     }
     287              : 
     288           26 :     bool is_valid = validation->validate(epJSON);
     289           26 :     bool hasErrors = processErrors(state);
     290           26 :     bool versionMatch = checkVersionMatch(state);
     291           26 :     bool unsupportedFound = checkForUnsupportedObjects(state);
     292              : 
     293           26 :     if (!is_valid || hasErrors || unsupportedFound) {
     294            0 :         ShowFatalError(state, "Errors occurred on processing input file. Preceding condition(s) cause termination.");
     295              :     }
     296              : 
     297           26 :     if (state.dataGlobal->isEpJSON && (state.dataGlobal->outputEpJSONConversion || state.dataGlobal->outputEpJSONConversionOnly)) {
     298            0 :         if (versionMatch) {
     299            0 :             std::string const encoded = idf_parser->encode(epJSON, schema());
     300              :             fs::path convertedEpJSON = FileSystem::makeNativePath(
     301            0 :                 FileSystem::replaceFileExtension(state.dataStrGlobals->outDirPath / state.dataStrGlobals->inputFilePathNameOnly, ".idf"));
     302            0 :             FileSystem::writeFile<FileSystem::FileTypes::IDF>(convertedEpJSON, encoded);
     303            0 :         } else {
     304            0 :             ShowWarningError(state, "Skipping conversion of epJSON to IDF due to mismatched Version.");
     305              :         }
     306              :     }
     307              : 
     308           26 :     initializeMaps();
     309              : 
     310           26 :     int MaxArgs = 0;
     311           26 :     int MaxAlpha = 0;
     312           26 :     int MaxNumeric = 0;
     313           26 :     getMaxSchemaArgs(MaxArgs, MaxAlpha, MaxNumeric);
     314              : 
     315           26 :     state.dataIPShortCut->cAlphaFieldNames.allocate(MaxAlpha);
     316           26 :     state.dataIPShortCut->cAlphaArgs.allocate(MaxAlpha);
     317           26 :     state.dataIPShortCut->lAlphaFieldBlanks.dimension(MaxAlpha, false);
     318           26 :     state.dataIPShortCut->cNumericFieldNames.allocate(MaxNumeric);
     319           26 :     state.dataIPShortCut->rNumericArgs.dimension(MaxNumeric, 0.0);
     320           26 :     state.dataIPShortCut->lNumericFieldBlanks.dimension(MaxNumeric, false);
     321              : 
     322           26 :     reportIDFRecordsStats(state);
     323              : }
     324              : 
     325           26 : bool InputProcessor::checkVersionMatch(EnergyPlusData &state)
     326              : {
     327              :     using DataStringGlobals::MatchVersion;
     328           52 :     auto it = epJSON.find("Version");
     329           26 :     if (it != epJSON.end()) {
     330           49 :         for (auto const &version : it.value()) {
     331           25 :             std::string v = version["version_identifier"].get<std::string>();
     332           25 :             if (v.empty()) {
     333            0 :                 ShowWarningError(state, "Input errors occurred and version ID was left blank, verify file version");
     334              :             } else {
     335           25 :                 std::string::size_type const lenVer(len(MatchVersion));
     336              :                 int Which;
     337           25 :                 if ((lenVer > 0) && (MatchVersion[lenVer - 1] == '0')) {
     338            0 :                     Which = static_cast<int>(index(v.substr(0, lenVer - 2), MatchVersion.substr(0, lenVer - 2)));
     339              :                 } else {
     340           25 :                     Which = static_cast<int>(index(v, MatchVersion));
     341              :                 }
     342           25 :                 if (Which != 0) {
     343            1 :                     ShowWarningError(state, "Version: in IDF=\"" + v + "\" not the same as expected=\"" + MatchVersion + "\"");
     344            1 :                     return false;
     345              :                 }
     346              :             }
     347           51 :         }
     348              :     }
     349           25 :     return true;
     350           26 : }
     351              : 
     352           28 : bool InputProcessor::checkForUnsupportedObjects(EnergyPlusData &state)
     353              : {
     354           28 :     bool errorsFound = false;
     355              :     static constexpr std::array<std::string_view, 32> hvacTemplateObjects = {"HVACTemplate:Thermostat",
     356              :                                                                              "HVACTemplate:Zone:IdealLoadsAirSystem",
     357              :                                                                              "HVACTemplate:Zone:BaseboardHeat",
     358              :                                                                              "HVACTemplate:Zone:FanCoil",
     359              :                                                                              "HVACTemplate:Zone:PTAC",
     360              :                                                                              "HVACTemplate:Zone:PTHP",
     361              :                                                                              "HVACTemplate:Zone:WaterToAirHeatPump",
     362              :                                                                              "HVACTemplate:Zone:VRF",
     363              :                                                                              "HVACTemplate:Zone:Unitary",
     364              :                                                                              "HVACTemplate:Zone:VAV",
     365              :                                                                              "HVACTemplate:Zone:VAV:FanPowered",
     366              :                                                                              "HVACTemplate:Zone:VAV:HeatAndCool",
     367              :                                                                              "HVACTemplate:Zone:ConstantVolume",
     368              :                                                                              "HVACTemplate:Zone:DualDuct",
     369              :                                                                              "HVACTemplate:System:VRF",
     370              :                                                                              "HVACTemplate:System:Unitary",
     371              :                                                                              "HVACTemplate:System:UnitaryHeatPump:AirToAir",
     372              :                                                                              "HVACTemplate:System:UnitarySystem",
     373              :                                                                              "HVACTemplate:System:VAV",
     374              :                                                                              "HVACTemplate:System:PackagedVAV",
     375              :                                                                              "HVACTemplate:System:ConstantVolume",
     376              :                                                                              "HVACTemplate:System:DualDuct",
     377              :                                                                              "HVACTemplate:System:DedicatedOutdoorAir",
     378              :                                                                              "HVACTemplate:Plant:ChilledWaterLoop",
     379              :                                                                              "HVACTemplate:Plant:Chiller",
     380              :                                                                              "HVACTemplate:Plant:Chiller:ObjectReference",
     381              :                                                                              "HVACTemplate:Plant:Tower",
     382              :                                                                              "HVACTemplate:Plant:Tower:ObjectReference",
     383              :                                                                              "HVACTemplate:Plant:HotWaterLoop",
     384              :                                                                              "HVACTemplate:Plant:Boiler",
     385              :                                                                              "HVACTemplate:Plant:Boiler:ObjectReference",
     386              :                                                                              "HVACTemplate:Plant:MixedWaterLoop"};
     387              : 
     388              :     // For EnergyPlus, there is no option to convert or allow these objects
     389           28 :     bool objectFound = false;
     390           28 :     std::string objectType;
     391         1778 :     for (size_t count = 0; count < hvacTemplateObjects.size(); ++count) {
     392          863 :         objectType = hvacTemplateObjects[count];
     393          863 :         auto it = epJSON.find(objectType);
     394          863 :         if (it != epJSON.end()) {
     395            2 :             objectFound = true;
     396            2 :             break;
     397              :         }
     398          863 :     }
     399           28 :     if (objectFound) {
     400            4 :         ShowSevereError(state, "HVACTemplate:* objects found. These objects are not supported directly by EnergyPlus.");
     401            4 :         ShowContinueError(state, "You must run the ExpandObjects program on this input.");
     402            2 :         errorsFound = true;
     403              :     }
     404              : 
     405              :     static constexpr std::array<std::string_view, 26> groundHTObjects = {"GroundHeatTransfer:Control",
     406              :                                                                          "GroundHeatTransfer:Slab:Materials",
     407              :                                                                          "GroundHeatTransfer:Slab:MatlProps",
     408              :                                                                          "GroundHeatTransfer:Slab:BoundConds",
     409              :                                                                          "GroundHeatTransfer:Slab:BldgProps",
     410              :                                                                          "GroundHeatTransfer:Slab:Insulation",
     411              :                                                                          "GroundHeatTransfer:Slab:EquivalentSlab",
     412              :                                                                          "GroundHeatTransfer:Slab:AutoGrid",
     413              :                                                                          "GroundHeatTransfer:Slab:ManualGrid",
     414              :                                                                          "GroundHeatTransfer:Slab:XFACE",
     415              :                                                                          "GroundHeatTransfer:Slab:YFACE",
     416              :                                                                          "GroundHeatTransfer:Slab:ZFACE",
     417              :                                                                          "GroundHeatTransfer:Basement:SimParameters",
     418              :                                                                          "GroundHeatTransfer:Basement:MatlProps",
     419              :                                                                          "GroundHeatTransfer:Basement:Insulation",
     420              :                                                                          "GroundHeatTransfer:Basement:SurfaceProps",
     421              :                                                                          "GroundHeatTransfer:Basement:BldgData",
     422              :                                                                          "GroundHeatTransfer:Basement:Interior",
     423              :                                                                          "GroundHeatTransfer:Basement:ComBldg",
     424              :                                                                          "GroundHeatTransfer:Basement:EquivSlab",
     425              :                                                                          "GroundHeatTransfer:Basement:EquivAutoGrid",
     426              :                                                                          "GroundHeatTransfer:Basement:AutoGrid",
     427              :                                                                          "GroundHeatTransfer:Basement:ManualGrid",
     428              :                                                                          "GroundHeatTransfer:Basement:XFACE",
     429              :                                                                          "GroundHeatTransfer:Basement:YFACE",
     430              :                                                                          "GroundHeatTransfer:Basement:ZFACE"};
     431              : 
     432           28 :     objectFound = false;
     433         1408 :     for (size_t count = 0; count < groundHTObjects.size(); ++count) {
     434          678 :         objectType = groundHTObjects[count];
     435          678 :         auto it = epJSON.find(objectType);
     436          678 :         if (it != epJSON.end()) {
     437            2 :             objectFound = true;
     438            2 :             break;
     439              :         }
     440          678 :     }
     441           28 :     if (objectFound) {
     442            4 :         ShowSevereError(state, "GroundHeatTransfer:* objects found. These objects are not supported directly by EnergyPlus.");
     443            4 :         ShowContinueError(state, "You must run the ExpandObjects program on this input.");
     444            2 :         errorsFound = true;
     445              :     }
     446              : 
     447              :     static constexpr std::array<std::string_view, 4> parametricObjects = {
     448              :         "Parametric:SetValueForRun", "Parametric:Logic", "Parametric:RunControl", "Parametric:FileNameSuffix"};
     449              : 
     450           28 :     objectFound = false;
     451          268 :     for (size_t count = 0; count < parametricObjects.size(); ++count) {
     452          108 :         objectType = parametricObjects[count];
     453          108 :         auto it = epJSON.find(objectType);
     454          108 :         if (it != epJSON.end()) {
     455            2 :             objectFound = true;
     456            2 :             break;
     457              :         }
     458          108 :     }
     459           28 :     if (objectFound) {
     460            4 :         ShowSevereError(state, "Parametric:* objects found. These objects are not supported directly by EnergyPlus.");
     461            4 :         ShowContinueError(state, "You must run the ParametricPreprocesor program on this input.");
     462            2 :         errorsFound = true;
     463              :     }
     464           28 :     return errorsFound;
     465           28 : }
     466              : 
     467         1360 : bool InputProcessor::processErrors(EnergyPlusData &state)
     468              : {
     469         1364 :     for (auto const &error : idf_parser->errors()) {
     470            4 :         ShowSevereError(state, error);
     471         1360 :     }
     472         1360 :     for (auto const &warning : idf_parser->warnings()) {
     473            0 :         ShowWarningError(state, warning);
     474         1360 :     }
     475         1395 :     for (auto const &error : validation->errors()) {
     476           35 :         ShowSevereError(state, error);
     477         1360 :     }
     478         1360 :     for (auto const &warning : validation->warnings()) {
     479            0 :         ShowWarningError(state, warning);
     480         1360 :     }
     481              : 
     482         1360 :     bool has_errors = validation->hasErrors() || idf_parser->hasErrors();
     483              : 
     484         1360 :     return has_errors;
     485              : }
     486              : 
     487         6579 : int InputProcessor::getNumSectionsFound(std::string const &SectionWord)
     488              : {
     489              :     // PURPOSE OF THIS SUBROUTINE:
     490              :     // This function returns the number of a particular section (in input data file)
     491              :     // found in the current run.  If it can't find the section in list
     492              :     // of sections, a -1 will be returned.
     493              : 
     494              :     // METHODOLOGY EMPLOYED:
     495              :     // Look up section in list of sections.  If there, return the
     496              :     // number of sections of that kind found in the current input.  If not, return -1.
     497              : 
     498         6579 :     auto const SectionWord_iter = epJSON.find(SectionWord);
     499         6579 :     if (SectionWord_iter == epJSON.end()) {
     500         6579 :         return -1;
     501              :     }
     502            0 :     return static_cast<int>(SectionWord_iter.value().size());
     503         6579 : }
     504              : 
     505       175750 : int InputProcessor::getNumObjectsFound(EnergyPlusData &state, std::string_view const ObjectWord)
     506              : {
     507              : 
     508              :     // FUNCTION INFORMATION:
     509              :     //       AUTHOR         Linda K. Lawrie
     510              :     //       DATE WRITTEN   September 1997
     511              :     //       MODIFIED       Mark Adams
     512              :     //       RE-ENGINEERED  na
     513              : 
     514              :     // PURPOSE OF THIS SUBROUTINE:
     515              :     // This function returns the number of objects (in input data file)
     516              :     // found in the current run.  If it can't find the object in list
     517              :     // of objects, a 0 will be returned.
     518              : 
     519              :     // METHODOLOGY EMPLOYED:
     520              :     // Look up object in list of objects.  If there, return the
     521              :     // number of objects found in the current input.  If not, return 0.
     522              : 
     523       351500 :     auto const find_obj = epJSON.find(std::string(ObjectWord));
     524              : 
     525       175750 :     if (find_obj == epJSON.end()) {
     526       155681 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(ObjectWord));
     527       155681 :         if (tmp_umit == caseInsensitiveObjectMap.end() || epJSON.find(tmp_umit->second) == epJSON.end()) {
     528       155494 :             return 0;
     529              :         }
     530          187 :         return static_cast<int>(epJSON[tmp_umit->second].size());
     531       155681 :     } else {
     532        20069 :         return static_cast<int>(find_obj.value().size());
     533              :     }
     534              : 
     535              :     if (schema()["properties"].find(std::string(ObjectWord)) == schema()["properties"].end()) {
     536              :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(ObjectWord));
     537              :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
     538              :             ShowWarningError(state, fmt::format("Requested Object not found in Definitions: {}", ObjectWord));
     539              :         }
     540              :     }
     541              :     return 0;
     542       175750 : }
     543              : 
     544        47638 : bool InputProcessor::findDefault(std::string &default_value, json const &schema_field_obj)
     545              : {
     546        47638 :     auto const find_default = schema_field_obj.find("default");
     547        47638 :     if (find_default != schema_field_obj.end()) {
     548        10836 :         auto const &default_val = find_default.value();
     549        10836 :         if (default_val.is_string()) {
     550        10836 :             default_value = default_val.get<std::string>();
     551              :         } else {
     552            0 :             if (default_val.is_number_integer()) {
     553            0 :                 i64toa(default_val.get<std::int64_t>(), s);
     554              :             } else {
     555            0 :                 dtoa(default_val.get<double>(), s);
     556              :             }
     557            0 :             default_value = s;
     558              :         }
     559        32508 :         if (schema_field_obj.find("retaincase") == schema_field_obj.end()) {
     560        10377 :             default_value = Util::makeUPPER(default_value);
     561              :         }
     562        10836 :         return true;
     563              :     }
     564        36802 :     return false;
     565        47638 : }
     566              : 
     567       332581 : bool InputProcessor::findDefault(Real64 &default_value, json const &schema_field_obj)
     568              : {
     569       332581 :     auto const find_default = schema_field_obj.find("default");
     570       332581 :     default_value = 0;
     571       332581 :     if (find_default != schema_field_obj.end()) {
     572        14113 :         auto const &default_val = find_default.value();
     573        14113 :         if (default_val.is_string() && !default_val.get<std::string>().empty()) {
     574              :             // autosize and autocalculate
     575         2504 :             default_value = Constant::AutoCalculate;
     576        11609 :         } else if (default_val.is_number_integer()) {
     577          847 :             default_value = default_val.get<std::int64_t>();
     578              :         } else {
     579        10762 :             default_value = default_val.get<double>();
     580              :         }
     581        14113 :         return true;
     582              :     }
     583       318468 :     return false;
     584       332581 : }
     585              : 
     586           17 : bool InputProcessor::getDefaultValue(EnergyPlusData &state, std::string const &objectWord, std::string const &fieldName, Real64 &value)
     587              : {
     588           17 :     auto find_iterators = objectCacheMap.find(objectWord);
     589           17 :     if (find_iterators == objectCacheMap.end()) {
     590            0 :         auto const tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(objectWord));
     591            0 :         if (tmp_umit == caseInsensitiveObjectMap.end() || epJSON.find(tmp_umit->second) == epJSON.end()) {
     592            0 :             return false;
     593              :         }
     594            0 :         find_iterators = objectCacheMap.find(tmp_umit->second);
     595            0 :     }
     596           17 :     auto const &epJSON_schema_it = find_iterators->second.schemaIterator;
     597           17 :     auto const &epJSON_schema_it_val = epJSON_schema_it.value();
     598           17 :     auto const &schema_obj_props = getPatternProperties(state, epJSON_schema_it_val);
     599           17 :     auto const &sizing_factor_schema_field_obj = schema_obj_props.at(fieldName);
     600           17 :     bool defaultFound = findDefault(value, sizing_factor_schema_field_obj);
     601           17 :     return defaultFound;
     602           17 : }
     603              : 
     604            9 : bool InputProcessor::getDefaultValue(EnergyPlusData &state, std::string const &objectWord, std::string const &fieldName, std::string &value)
     605              : {
     606            9 :     auto find_iterators = objectCacheMap.find(objectWord);
     607            9 :     if (find_iterators == objectCacheMap.end()) {
     608            0 :         auto const tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(objectWord));
     609            0 :         if (tmp_umit == caseInsensitiveObjectMap.end() || epJSON.find(tmp_umit->second) == epJSON.end()) {
     610            0 :             return false;
     611              :         }
     612            0 :         find_iterators = objectCacheMap.find(tmp_umit->second);
     613            0 :     }
     614            9 :     auto const &epJSON_schema_it = find_iterators->second.schemaIterator;
     615            9 :     auto const &epJSON_schema_it_val = epJSON_schema_it.value();
     616            9 :     auto const &schema_obj_props = getPatternProperties(state, epJSON_schema_it_val);
     617            9 :     auto const &sizing_factor_schema_field_obj = schema_obj_props.at(fieldName);
     618            9 :     bool defaultFound = findDefault(value, sizing_factor_schema_field_obj);
     619            9 :     return defaultFound;
     620            9 : }
     621              : 
     622         5397 : std::string InputProcessor::getAlphaFieldValue(json const &ep_object, json const &schema_obj_props, std::string const &fieldName, bool uc)
     623              : {
     624              :     // Return the value of fieldName in ep_object as a string.
     625              :     // If the field is not present in ep_object then return its default if there is one, or return an empty string
     626         5397 :     auto const &fprops = schema_obj_props[fieldName];
     627         5397 :     assert(!fprops.empty()); // Check that field name exists in the schema for this object type
     628              : 
     629        16191 :     uc = (fprops.find("retaincase") == fprops.end());
     630              : 
     631         5397 :     auto it = ep_object.find(fieldName);
     632         5397 :     if (it != ep_object.end()) {
     633         4158 :         auto const &val = it.value();
     634         4158 :         assert(val.is_string());
     635         4158 :         if (!val.empty()) {
     636         8316 :             return uc ? Util::makeUPPER(val.get<std::string>()) : val.get<std::string>();
     637              :         }
     638              :     }
     639              : 
     640         1239 :     auto const it2 = fprops.find("default");
     641         1239 :     return (it2 != fprops.end()) ? (uc ? Util::makeUPPER(it2.value().get<std::string>()) : it2.value().get<std::string>()) : std::string();
     642              : 
     643              : #ifdef GET_OUT
     644              :     if (default_val.is_number_integer()) {
     645              :         i64toa(default_val.get<std::int64_t>(), s);
     646              :     } else if (default_val.is_number()) {
     647              :         dtoa(default_val.get<double>(), s);
     648              :     }
     649              : #endif // GET_OUT
     650         5397 : }
     651              : 
     652         7346 : Real64 InputProcessor::getRealFieldValue(json const &ep_object, json const &schema_obj_props, std::string const &fieldName)
     653              : {
     654              :     // Return the value of fieldName in ep_object as a Real64.
     655              :     // If the field value is a string, then assume autosize and return Constant::AutoCalculate(-99999).
     656              :     // If the field is not present in ep_object then return its default if there is one, or return 0.0
     657         7346 :     auto it = ep_object.find(fieldName);
     658         7346 :     if (it != ep_object.end()) {
     659         6475 :         auto const &field_value = it.value();
     660         6475 :         if (field_value.is_number()) {
     661         6348 :             return (field_value.is_number_integer()) ? field_value.get<std::int64_t>() : field_value.get<double>();
     662          127 :         } else if (!field_value.get<std::string>().empty()) {
     663          127 :             return Constant::AutoCalculate; // autosize and autocalculate
     664              :         }
     665              :     }
     666              : 
     667          871 :     auto const &schema_field_obj = schema_obj_props[fieldName];
     668          871 :     assert(!schema_field_obj.empty()); // Check that field name exists in the schema for this object type
     669              : 
     670          871 :     auto const find_default = schema_field_obj.find("default");
     671          871 :     if (find_default != schema_field_obj.end()) {
     672          837 :         auto const &default_val = find_default.value();
     673          837 :         if (default_val.is_string()) {
     674          359 :             return (!default_val.get<std::string>().empty()) ? Constant::AutoCalculate : 0.0;
     675          478 :         } else if (default_val.is_number_integer()) {
     676            2 :             return default_val.get<std::int64_t>();
     677              :         } else {
     678          476 :             return default_val.get<double>();
     679              :         }
     680              :     } else {
     681           34 :         return 0.0;
     682              :     }
     683         7346 : }
     684              : 
     685          722 : int InputProcessor::getIntFieldValue(json const &ep_object, json const &schema_obj_props, std::string const &fieldName)
     686              : {
     687              :     // Return the value of fieldName in ep_object as an integer.
     688              :     // If the field value is a string, then assume autosize or autocalculate and return Constant::AutoCalculate(-99999).
     689              :     // If the field is not present in ep_object then return its default if there is one, or return 0
     690              : 
     691          722 :     auto const &schema_field_obj = schema_obj_props[fieldName];
     692          722 :     assert(!schema_field_obj.empty()); // Check that field name exists in the schema for this object type
     693          722 :     bool isDefaulted = false;
     694          722 :     int value = 0;
     695          722 :     Real64 defaultValue = 0.0;
     696          722 :     auto it = ep_object.find(fieldName);
     697          722 :     if (it != ep_object.end()) {
     698          722 :         auto const &field_value = it.value();
     699          722 :         if (field_value.is_number_integer()) {
     700          722 :             value = field_value.get<std::int64_t>();
     701            0 :         } else if (field_value.is_number()) {
     702              :             // This is a developer error, floating point numbers should not be retrieved this way. If this field
     703              :             // really is an int then the input processor will have forced it to be an integer.
     704            0 :             assert(!field_value.is_number());
     705            0 :         } else if (field_value.get<std::string>().empty()) {
     706            0 :             isDefaulted = findDefault(defaultValue, schema_field_obj);
     707            0 :             if (isDefaulted) {
     708            0 :                 value = static_cast<int>(defaultValue);
     709              :             }
     710              :         }
     711              :     } else {
     712            0 :         isDefaulted = findDefault(defaultValue, schema_field_obj);
     713            0 :         if (isDefaulted) {
     714            0 :             value = static_cast<int>(defaultValue);
     715              :         }
     716              :     }
     717          722 :     return value;
     718          722 : }
     719              : 
     720         3415 : const json &InputProcessor::getObjectSchemaProps(EnergyPlusData &state, std::string const &objectWord)
     721              : {
     722         6830 :     auto const &schema_properties = schema().at("properties");
     723         3415 :     const json &object_schema = schema_properties.at(objectWord);
     724         3415 :     assert(!object_schema.empty()); // If this fails, the object type does not exist in the schema
     725              : 
     726         3415 :     auto const &schema_obj_props = getPatternProperties(state, object_schema);
     727         3415 :     return schema_obj_props;
     728              : }
     729              : 
     730        97498 : std::pair<std::string, bool> InputProcessor::getObjectItemValue(std::string const &field_value, json const &schema_field_obj)
     731              : {
     732        97498 :     std::pair<std::string, bool> output;
     733        97498 :     if (field_value.empty()) {
     734            0 :         findDefault(output.first, schema_field_obj);
     735            0 :         output.second = true;
     736              :     } else {
     737        97498 :         output.first = field_value;
     738        97498 :         output.second = false;
     739              :     }
     740       292494 :     if (schema_field_obj.find("retaincase") == schema_field_obj.end()) {
     741        96474 :         output.first = Util::makeUPPER(output.first);
     742              :     }
     743        97498 :     return output;
     744            0 : }
     745              : 
     746          126 : const json &InputProcessor::getObjectInstances(std::string const &ObjType)
     747              : {
     748          126 :     return epJSON.find(ObjType).value();
     749              : }
     750              : 
     751        25684 : InputProcessor::MaxFields InputProcessor::findMaxFields(
     752              :     EnergyPlusData &state, json const &ep_object, std::string const &extension_key, json const &legacy_idd, std::size_t const min_fields)
     753              : {
     754        25684 :     InputProcessor::MaxFields maxFields;
     755        25684 :     if (!state.dataGlobal->isEpJSON) {
     756        25618 :         auto found_idf_max_fields = ep_object.find("idf_max_fields");
     757        25618 :         if (found_idf_max_fields != ep_object.end()) {
     758        23633 :             maxFields.max_fields = found_idf_max_fields->get<size_t>();
     759              :         }
     760        25618 :         auto found_idf_max_extensible_fields = ep_object.find("idf_max_extensible_fields");
     761        25618 :         if (found_idf_max_extensible_fields != ep_object.end()) {
     762        23633 :             maxFields.max_extensible_fields = found_idf_max_extensible_fields->get<size_t>();
     763              :         }
     764        25618 :     } else {
     765           66 :         auto const &legacy_idd_fields = legacy_idd["fields"];
     766              :         // start with at least min_fields as the number of fields
     767           66 :         maxFields.max_fields = min_fields;
     768          278 :         for (auto const &field : ep_object.items()) {
     769          212 :             auto const &field_key = field.key();
     770          212 :             if (field_key == extension_key) {
     771           19 :                 continue;
     772              :             }
     773         1001 :             for (std::size_t i = maxFields.max_fields; i < legacy_idd_fields.size(); ++i) {
     774          808 :                 if (field_key == legacy_idd_fields[i]) {
     775           36 :                     maxFields.max_fields = (i + 1);
     776              :                 }
     777              :             }
     778           66 :         }
     779              : 
     780           66 :         auto const legacy_idd_extensibles_iter = legacy_idd.find("extensibles");
     781           66 :         if (legacy_idd_extensibles_iter != legacy_idd.end()) {
     782           19 :             auto const epJSON_extensions_array_itr = ep_object.find(extension_key);
     783           19 :             if (epJSON_extensions_array_itr != ep_object.end()) {
     784           19 :                 auto const &legacy_idd_extensibles = legacy_idd_extensibles_iter.value();
     785           19 :                 auto const &epJSON_extensions_array = epJSON_extensions_array_itr.value();
     786              : 
     787           60 :                 for (auto const &exts : epJSON_extensions_array.items()) {
     788           41 :                     std::size_t max_extensible_field = 0;
     789          134 :                     for (auto const &ext : exts.value().items()) {
     790           93 :                         auto const &ext_key = ext.key();
     791          258 :                         for (std::size_t i = max_extensible_field; i < legacy_idd_extensibles.size(); ++i) {
     792          165 :                             if (ext_key == legacy_idd_extensibles[i]) {
     793           89 :                                 max_extensible_field = (i + 1);
     794              :                             }
     795              :                         }
     796           41 :                     }
     797           41 :                     maxFields.max_extensible_fields += max_extensible_field;
     798           19 :                 }
     799              :             }
     800           19 :         }
     801           66 :     }
     802        25684 :     return maxFields;
     803              : }
     804              : 
     805       652003 : void InputProcessor::setObjectItemValue(EnergyPlusData &state,
     806              :                                         json const &ep_object,
     807              :                                         json const &ep_schema_object,
     808              :                                         std::string const &field,
     809              :                                         json const &legacy_field_info,
     810              :                                         int &alpha_index,
     811              :                                         int &numeric_index,
     812              :                                         bool within_max_fields,
     813              :                                         Array1S_string Alphas,
     814              :                                         int &NumAlphas,
     815              :                                         Array1D<Real64> &Numbers,
     816              :                                         int &NumNumbers,
     817              :                                         ObjexxFCL::Optional<Array1D_bool> NumBlank,
     818              :                                         ObjexxFCL::Optional<Array1D_bool> AlphaBlank,
     819              :                                         ObjexxFCL::Optional<Array1D_string> AlphaFieldNames,
     820              :                                         ObjexxFCL::Optional<Array1D_string> NumericFieldNames)
     821              : {
     822       652003 :     bool const is_AlphaBlank = present(AlphaBlank);
     823       652003 :     bool const is_AlphaFieldNames = present(AlphaFieldNames);
     824       652003 :     bool const is_NumBlank = present(NumBlank);
     825       652003 :     bool const is_NumericFieldNames = present(NumericFieldNames);
     826              : 
     827       652003 :     std::string field_type = legacy_field_info.at("field_type").get<std::string>();
     828       652003 :     auto const &schema_field_obj = ep_schema_object[field];
     829       652003 :     auto it = ep_object.find(field);
     830       652003 :     if (it != ep_object.end()) {
     831       271810 :         auto const &field_value = it.value();
     832       271810 :         if (field_type == "a") {
     833              :             // process alpha value
     834       104430 :             if (field_value.is_string()) {
     835        97498 :                 auto const value = getObjectItemValue(field_value.get<std::string>(), schema_field_obj); // (AUTO_OK_OBJ)
     836              : 
     837        97498 :                 Alphas(alpha_index) = value.first;
     838        97498 :                 if (is_AlphaBlank) {
     839        68790 :                     AlphaBlank()(alpha_index) = value.second;
     840              :                 }
     841              : 
     842        97498 :             } else {
     843         6932 :                 if (field_value.is_number_integer()) {
     844          824 :                     i64toa(field_value.get<std::int64_t>(), s);
     845              :                 } else {
     846         6108 :                     dtoa(field_value.get<double>(), s);
     847              :                 }
     848         6932 :                 Alphas(alpha_index) = s;
     849         6932 :                 if (is_AlphaBlank) {
     850         3478 :                     AlphaBlank()(alpha_index) = false;
     851              :                 }
     852              :             }
     853       167380 :         } else if (field_type == "n") {
     854              :             // process numeric value
     855       167380 :             if (field_value.is_number()) {
     856       163436 :                 if (field_value.is_number_integer()) {
     857        31028 :                     Numbers(numeric_index) = field_value.get<std::int64_t>();
     858              :                 } else {
     859       132408 :                     Numbers(numeric_index) = field_value.get<double>();
     860              :                 }
     861       163436 :                 if (is_NumBlank) {
     862       155395 :                     NumBlank()(numeric_index) = false;
     863              :                 }
     864              :             } else {
     865         3944 :                 bool is_empty = field_value.get<std::string>().empty();
     866         3944 :                 if (is_empty) {
     867            0 :                     findDefault(Numbers(numeric_index), schema_field_obj);
     868              :                 } else {
     869         3944 :                     Numbers(numeric_index) = Constant::AutoCalculate; // autosize and autocalculate
     870              :                 }
     871         3944 :                 if (is_NumBlank) {
     872         2754 :                     NumBlank()(numeric_index) = is_empty;
     873              :                 }
     874              :             }
     875              :         }
     876              :     } else {
     877       380193 :         if (field_type == "a") {
     878        47629 :             if (!(findDefault(Alphas(alpha_index), schema_field_obj))) {
     879        36802 :                 Alphas(alpha_index) = "";
     880              :             }
     881        47629 :             if (is_AlphaBlank) {
     882        35443 :                 AlphaBlank()(alpha_index) = true;
     883              :             }
     884       332564 :         } else if (field_type == "n") {
     885       332564 :             findDefault(Numbers(numeric_index), schema_field_obj);
     886       332564 :             if (is_NumBlank) {
     887       330115 :                 NumBlank()(numeric_index) = true;
     888              :             }
     889              :         }
     890              :     }
     891       652003 :     if (field_type == "a") {
     892       152059 :         if (within_max_fields) {
     893       119163 :             NumAlphas = alpha_index;
     894              :         }
     895       152059 :         if (is_AlphaFieldNames) {
     896       342299 :             AlphaFieldNames()(alpha_index) = (state.dataGlobal->isEpJSON) ? field : legacy_field_info.at("field_name").get<std::string>();
     897              :         }
     898       152059 :         alpha_index++;
     899       499944 :     } else if (field_type == "n") {
     900       499944 :         if (within_max_fields) {
     901       179320 :             NumNumbers = numeric_index;
     902              :         }
     903       499944 :         if (is_NumericFieldNames) {
     904      1466957 :             NumericFieldNames()(numeric_index) = (state.dataGlobal->isEpJSON) ? field : legacy_field_info.at("field_name").get<std::string>();
     905              :         }
     906       499944 :         numeric_index++;
     907              :     }
     908       652003 : }
     909              : 
     910          302 : const json &InputProcessor::getJSONObjectItem(EnergyPlusData &state, std::string_view ObjType, std::string_view ObjName)
     911              : {
     912          604 :     std::string objTypeStr(ObjType);
     913          302 :     std::string objNameStr(ObjName);
     914              : 
     915          302 :     auto objectInfo = ObjectInfo(objTypeStr, objNameStr); // (AUTO_OK_OBJ)
     916              : 
     917          302 :     auto obj_iter = epJSON.find(objTypeStr);
     918          302 :     if (obj_iter == epJSON.end() || obj_iter.value().find(objectInfo.objectName) == obj_iter.value().end()) {
     919          293 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(objectInfo.objectType));
     920          293 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
     921              :             // indicates object type not found, see function GeneralRoutines::ValidateComponent
     922            0 :             ShowFatalError(state, format(R"(ObjectType of type "{}" requested was not found in input)", objectInfo.objectType));
     923              :         }
     924          293 :         objectInfo.objectType = tmp_umit->second;
     925          293 :         obj_iter = epJSON.find(objectInfo.objectType);
     926          293 :     }
     927              : 
     928          302 :     std::string const upperObjName = convertToUpper(objectInfo.objectName);
     929              : 
     930          409 :     for (const auto &[key, val] : obj_iter->items()) {
     931          409 :         if (convertToUpper(key) == upperObjName) {
     932          302 :             objectInfo.objectName = key;
     933              :             // markObjectAsUsed(objectInfo.objectType, objectInfo.objectName);
     934          302 :             auto const find_unused = unusedInputs.find(objectInfo);
     935          302 :             if (find_unused != unusedInputs.end()) {
     936          302 :                 unusedInputs.erase(find_unused);
     937              :             }
     938          302 :             return val;
     939          302 :         }
     940          604 :     }
     941              : 
     942            0 :     ShowFatalError(state, format(R"(Name "{}" requested was not found in input for ObjectType "{}")", objectInfo.objectType, objectInfo.objectName));
     943            0 :     throw;
     944          302 : }
     945              : 
     946        25684 : void InputProcessor::getObjectItem(EnergyPlusData &state,
     947              :                                    std::string_view Object,
     948              :                                    int const Number,
     949              :                                    Array1S_string Alphas,
     950              :                                    int &NumAlphas,
     951              :                                    Array1D<Real64> &Numbers,
     952              :                                    int &NumNumbers,
     953              :                                    int &Status,
     954              :                                    ObjexxFCL::Optional<Array1D_bool> NumBlank,
     955              :                                    ObjexxFCL::Optional<Array1D_bool> AlphaBlank,
     956              :                                    ObjexxFCL::Optional<Array1D_string> AlphaFieldNames,
     957              :                                    ObjexxFCL::Optional<Array1D_string> NumericFieldNames)
     958              : {
     959              :     // SUBROUTINE INFORMATION:
     960              :     //       AUTHOR         Linda K. Lawrie
     961              :     //       DATE WRITTEN   September 1997
     962              :     //       MODIFIED       na
     963              :     //       RE-ENGINEERED  na
     964              : 
     965              :     // PURPOSE OF THIS SUBROUTINE:
     966              :     // This subroutine gets the 'number' 'object' from the IDFRecord data structure.
     967              : 
     968        25684 :     int adjustedNumber = getJSONObjNum(state, std::string(Object), Number); // if incoming input is idf, then use idf object order
     969              : 
     970        25684 :     auto objectInfo = ObjectInfo(); // (AUTO_OK_OBJ)
     971        25684 :     objectInfo.objectType = Object;
     972              :     // auto sorted_iterators = find_iterators;
     973              : 
     974        51368 :     auto find_iterators = objectCacheMap.find(std::string(Object));
     975        25684 :     if (find_iterators == objectCacheMap.end()) {
     976          159 :         auto const tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(Object));
     977          159 :         if (tmp_umit == caseInsensitiveObjectMap.end() || epJSON.find(tmp_umit->second) == epJSON.end()) {
     978            0 :             return;
     979              :         }
     980          159 :         objectInfo.objectType = tmp_umit->second;
     981          159 :         find_iterators = objectCacheMap.find(objectInfo.objectType);
     982          159 :     }
     983              : 
     984        25684 :     NumAlphas = 0;
     985        25684 :     NumNumbers = 0;
     986        25684 :     Status = -1;
     987        25684 :     bool const is_AlphaBlank = present(AlphaBlank);
     988        25684 :     bool const is_AlphaFieldNames = present(AlphaFieldNames);
     989        25684 :     bool const is_NumBlank = present(NumBlank);
     990        25684 :     bool const is_NumericFieldNames = present(NumericFieldNames);
     991              : 
     992        25684 :     auto const &epJSON_it = find_iterators->second.inputObjectIterators.at(adjustedNumber - 1);
     993        25684 :     auto const &epJSON_schema_it = find_iterators->second.schemaIterator;
     994        25684 :     auto const &epJSON_schema_it_val = epJSON_schema_it.value();
     995              : 
     996              :     // Locations in JSON schema relating to normal fields
     997        25684 :     auto const &schema_obj_props = getPatternProperties(state, epJSON_schema_it_val);
     998              : 
     999              :     // Locations in JSON schema storing the positional aspects from the IDD format, legacy prefixed
    1000        25684 :     auto const &legacy_idd = epJSON_schema_it_val["legacy_idd"];
    1001        25684 :     auto const &legacy_idd_field_info = legacy_idd["field_info"];
    1002        25684 :     auto const &legacy_idd_fields = legacy_idd["fields"];
    1003        25684 :     auto const schema_name_field = epJSON_schema_it_val.find("name");
    1004        25684 :     auto const has_idd_name_field = schema_name_field != epJSON_schema_it_val.end();
    1005        25684 :     auto const found_min_fields = epJSON_schema_it_val.find("min_fields");
    1006        25684 :     size_t min_fields = 0;
    1007        25684 :     if (found_min_fields != epJSON_schema_it_val.end()) {
    1008        12005 :         min_fields = found_min_fields.value().get<size_t>();
    1009              :     }
    1010              : 
    1011        25684 :     auto key = legacy_idd.find("extension");
    1012        25684 :     std::string extension_key;
    1013        25684 :     if (key != legacy_idd.end()) {
    1014         7259 :         extension_key = key.value().get<std::string>();
    1015              :     }
    1016              : 
    1017        25684 :     auto const &obj = epJSON_it;
    1018        25684 :     auto const &obj_val = obj.value();
    1019        25684 :     objectInfo.objectName = obj.key();
    1020              : 
    1021        25684 :     int alpha_index = 1;
    1022        25684 :     int numeric_index = 1;
    1023        25684 :     InputProcessor::MaxFields maxFields = findMaxFields(state, obj_val, extension_key, legacy_idd, min_fields);
    1024              : 
    1025        25684 :     Alphas = "";
    1026        25684 :     Numbers = 0;
    1027        25684 :     if (is_NumBlank) {
    1028        21520 :         NumBlank() = true;
    1029              :     }
    1030        25684 :     if (is_AlphaBlank) {
    1031        18987 :         AlphaBlank() = true;
    1032              :     }
    1033        25684 :     if (is_AlphaFieldNames) {
    1034        43330 :         AlphaFieldNames() = "";
    1035              :     }
    1036        25684 :     if (is_NumericFieldNames) {
    1037        43266 :         NumericFieldNames() = "";
    1038              :     }
    1039              : 
    1040        25684 :     auto const find_unused = unusedInputs.find(objectInfo);
    1041        25684 :     if (find_unused != unusedInputs.end()) {
    1042        21227 :         unusedInputs.erase(find_unused);
    1043              :     }
    1044              : 
    1045       636005 :     for (size_t i = 0; i < legacy_idd_fields.size(); ++i) {
    1046       610321 :         std::string const field = legacy_idd_fields[i].get<std::string>();
    1047       610321 :         auto const field_info = legacy_idd_field_info.find(field);
    1048       610321 :         auto const &field_info_val = field_info.value();
    1049       610321 :         if (field_info == legacy_idd_field_info.end()) {
    1050            0 :             ShowFatalError(state, fmt::format(R"(Could not find field = "{}" in "{}" in epJSON Schema.)", field, Object));
    1051              :         }
    1052              : 
    1053       610321 :         bool within_idf_fields = (i < maxFields.max_fields);
    1054              : 
    1055       610321 :         if (has_idd_name_field && field == "name") {
    1056        19283 :             auto const &name_iter = schema_name_field.value();
    1057        57849 :             if (name_iter.find("retaincase") != name_iter.end()) {
    1058          222 :                 Alphas(alpha_index) = objectInfo.objectName;
    1059              :             } else {
    1060        19061 :                 Alphas(alpha_index) = Util::makeUPPER(objectInfo.objectName);
    1061              :             }
    1062        19283 :             if (is_AlphaBlank) {
    1063        12723 :                 AlphaBlank()(alpha_index) = objectInfo.objectName.empty();
    1064              :             }
    1065        19283 :             if (is_AlphaFieldNames) {
    1066        46097 :                 AlphaFieldNames()(alpha_index) = (state.dataGlobal->isEpJSON) ? field : field_info_val.at("field_name").get<std::string>();
    1067              :             }
    1068        19283 :             NumAlphas++;
    1069        19283 :             alpha_index++;
    1070        19283 :             continue;
    1071        19283 :         }
    1072              : 
    1073       591038 :         setObjectItemValue(state,
    1074              :                            obj_val,
    1075              :                            schema_obj_props,
    1076              :                            field,
    1077              :                            field_info_val,
    1078              :                            alpha_index,
    1079              :                            numeric_index,
    1080              :                            within_idf_fields,
    1081              :                            Alphas,
    1082              :                            NumAlphas,
    1083              :                            Numbers,
    1084              :                            NumNumbers,
    1085              :                            NumBlank,
    1086              :                            AlphaBlank,
    1087              :                            AlphaFieldNames,
    1088              :                            NumericFieldNames);
    1089       629604 :     }
    1090              : 
    1091        25684 :     auto const legacy_idd_extensibles_iter = legacy_idd.find("extensibles");
    1092        25684 :     if (legacy_idd_extensibles_iter != legacy_idd.end()) {
    1093         7259 :         size_t extensible_count = 0;
    1094         7259 :         auto const epJSON_extensions_array_itr = obj_val.find(extension_key);
    1095         7259 :         if (epJSON_extensions_array_itr != obj_val.end()) {
    1096         7167 :             auto const &legacy_idd_extensibles = legacy_idd_extensibles_iter.value();
    1097         7167 :             auto const &epJSON_extensions_array = epJSON_extensions_array_itr.value();
    1098         7167 :             auto const &schema_extension_fields = schema_obj_props[extension_key]["items"]["properties"];
    1099              : 
    1100        45486 :             for (auto it = epJSON_extensions_array.begin(); it != epJSON_extensions_array.end(); ++it) {
    1101        38319 :                 auto const &epJSON_extension_obj = it.value();
    1102        99284 :                 for (size_t i = 0; i < legacy_idd_extensibles.size(); i++, extensible_count++) {
    1103        60965 :                     std::string const field_name = legacy_idd_extensibles[i].get<std::string>();
    1104        60965 :                     auto const field_info = legacy_idd_field_info.find(field_name);
    1105        60965 :                     auto const &field_info_val = field_info.value();
    1106              : 
    1107        60965 :                     if (field_info == legacy_idd_field_info.end()) {
    1108            0 :                         ShowFatalError(state, fmt::format(R"(Could not find field = "{}" in "{}" in epJSON Schema.)", field_name, Object));
    1109              :                     }
    1110              : 
    1111        60965 :                     bool within_idf_extensible_fields = (extensible_count < maxFields.max_extensible_fields);
    1112              : 
    1113        60965 :                     setObjectItemValue(state,
    1114              :                                        epJSON_extension_obj,
    1115              :                                        schema_extension_fields,
    1116              :                                        field_name,
    1117              :                                        field_info_val,
    1118              :                                        alpha_index,
    1119              :                                        numeric_index,
    1120              :                                        within_idf_extensible_fields,
    1121              :                                        Alphas,
    1122              :                                        NumAlphas,
    1123              :                                        Numbers,
    1124              :                                        NumNumbers,
    1125              :                                        NumBlank,
    1126              :                                        AlphaBlank,
    1127              :                                        AlphaFieldNames,
    1128              :                                        NumericFieldNames);
    1129        60965 :                 }
    1130         7167 :             }
    1131              :         }
    1132         7259 :     }
    1133              : 
    1134        25684 :     Status = 1;
    1135        25684 : }
    1136              : 
    1137         3056 : int InputProcessor::getIDFObjNum(EnergyPlusData &state, std::string_view Object, int const Number)
    1138              : {
    1139              :     // Given the number (index) of an object in JSON order, return it's number in original idf order
    1140              : 
    1141              :     // Only applicable if the incoming file was idf
    1142         3056 :     int idfOrderNumber = Number;
    1143         3056 :     if (state.dataGlobal->isEpJSON || !state.dataGlobal->preserveIDFOrder) {
    1144           29 :         return idfOrderNumber;
    1145              :     }
    1146              : 
    1147              :     json *obj;
    1148         6054 :     auto obj_iter = epJSON.find(std::string(Object));
    1149         3027 :     if (obj_iter == epJSON.end()) {
    1150         1769 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(Object));
    1151         1769 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
    1152            0 :             return idfOrderNumber;
    1153              :         }
    1154         1769 :         obj = &epJSON[tmp_umit->second];
    1155         1769 :     } else {
    1156         1258 :         obj = &(obj_iter.value());
    1157              :     }
    1158              : 
    1159         3027 :     std::vector<int> idfObjNums;
    1160         3027 :     std::vector<int> idfObjNumsSorted;
    1161              : 
    1162              :     // get list of saved object numbers from idf processing
    1163        10284 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1164         7257 :         int objNum = it.value()["idf_order"].get<int>();
    1165         7257 :         idfObjNums.emplace_back(objNum);
    1166         3027 :     }
    1167              : 
    1168         3027 :     idfObjNumsSorted = idfObjNums;
    1169         3027 :     std::sort(idfObjNumsSorted.begin(), idfObjNumsSorted.end());
    1170              : 
    1171              :     // find matching object number in unsorted list
    1172         3027 :     int targetIdfObjNum = idfObjNums[Number - 1];
    1173         5129 :     for (size_t i = 1; i <= idfObjNums.size(); ++i) {
    1174         5129 :         if (idfObjNumsSorted[i - 1] == targetIdfObjNum) {
    1175         3027 :             idfOrderNumber = i;
    1176         3027 :             break;
    1177              :         }
    1178              :     }
    1179         3027 :     return idfOrderNumber;
    1180         3027 : }
    1181              : 
    1182          247 : std::vector<std::string> InputProcessor::getIDFOrderedKeys(EnergyPlusData &state, std::string_view const Object)
    1183              : {
    1184              :     // Given the number (index) of an object in JSON order, return it's number in original idf order
    1185          247 :     std::vector<std::string> keys;
    1186          247 :     std::vector<int> nums;
    1187              : 
    1188              :     json *obj;
    1189          494 :     auto obj_iter = epJSON.find(std::string(Object));
    1190          247 :     if (obj_iter == epJSON.end()) {
    1191            0 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(Object));
    1192            0 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
    1193            0 :             return keys;
    1194              :         }
    1195            0 :         obj = &epJSON[tmp_umit->second];
    1196            0 :     } else {
    1197          247 :         obj = &(obj_iter.value());
    1198              :     }
    1199              : 
    1200              :     // Return names in JSON order
    1201          247 :     if (state.dataGlobal->isEpJSON || !state.dataGlobal->preserveIDFOrder) {
    1202            4 :         for (auto it = obj->begin(); it != obj->end(); ++it) {
    1203            2 :             keys.emplace_back(it.key());
    1204            2 :         }
    1205              : 
    1206            2 :         return keys;
    1207              :     }
    1208              : 
    1209              :     // Now, the real work begins
    1210              : 
    1211         1086 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1212          841 :         nums.push_back(it.value()["idf_order"].get<int>());
    1213          245 :     }
    1214          245 :     std::sort(nums.begin(), nums.end());
    1215              : 
    1216              :     // Reserve doesn't seem to work :(
    1217         1086 :     for (int i = 0; i < (int)nums.size(); ++i) {
    1218         1682 :         keys.push_back("");
    1219              :     }
    1220              : 
    1221              :     // get list of saved object numbers from idf processing
    1222         1086 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1223          841 :         int objNum = it.value()["idf_order"].get<int>();
    1224          841 :         int objIdx = std::find(nums.begin(), nums.end(), objNum) - nums.begin();
    1225          841 :         keys[objIdx] = it.key();
    1226          245 :     }
    1227              : 
    1228          245 :     return keys;
    1229          247 : }
    1230              : 
    1231        25684 : int InputProcessor::getJSONObjNum(EnergyPlusData &state, std::string const &Object, int const Number)
    1232              : {
    1233              :     // Given the number (index) of an object in original idf order, return it's number in JSON order
    1234              : 
    1235              :     // Only applicable if the incoming file was idf
    1236        25684 :     int jSONOrderNumber = Number;
    1237        25684 :     if (state.dataGlobal->isEpJSON || !state.dataGlobal->preserveIDFOrder) {
    1238           67 :         return jSONOrderNumber;
    1239              :     }
    1240              : 
    1241              :     json *obj;
    1242        25617 :     auto obj_iter = epJSON.find(Object);
    1243        25617 :     if (obj_iter == epJSON.end()) {
    1244          159 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(Object));
    1245          159 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
    1246            0 :             return jSONOrderNumber;
    1247              :         }
    1248          159 :         obj = &epJSON[tmp_umit->second];
    1249          159 :     } else {
    1250        25458 :         obj = &(obj_iter.value());
    1251              :     }
    1252              : 
    1253        25617 :     std::vector<int> idfObjNums;
    1254        25617 :     std::vector<int> idfObjNumsSorted;
    1255              : 
    1256              :     // get list of saved object numbers from idf processing
    1257       618313 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1258       296348 :         int objNum = it.value()["idf_order"].get<int>();
    1259       296348 :         idfObjNums.emplace_back(objNum);
    1260        25617 :     }
    1261              : 
    1262        25617 :     idfObjNumsSorted = idfObjNums;
    1263        25617 :     std::sort(idfObjNumsSorted.begin(), idfObjNumsSorted.end());
    1264              : 
    1265              :     // find matching object number in unsorted list
    1266        25617 :     int targetIdfObjNum = idfObjNumsSorted[Number - 1];
    1267       161023 :     for (size_t i = 1; i <= idfObjNums.size(); ++i) {
    1268       161023 :         if (idfObjNums[i - 1] == targetIdfObjNum) {
    1269        25617 :             jSONOrderNumber = i;
    1270        25617 :             break;
    1271              :         }
    1272              :     }
    1273        25617 :     return jSONOrderNumber;
    1274        25617 : }
    1275              : 
    1276         2415 : int InputProcessor::getObjectItemNum(EnergyPlusData &state,
    1277              :                                      std::string_view ObjType, // Object Type (ref: IDD Objects)
    1278              :                                      std::string_view ObjName  // Name of the object type
    1279              : )
    1280              : {
    1281              :     // PURPOSE OF THIS SUBROUTINE:
    1282              :     // Get the occurrence number of an object of type ObjType and name ObjName
    1283              : 
    1284              :     json *obj;
    1285         4830 :     auto obj_iter = epJSON.find(std::string(ObjType));
    1286         3579 :     if (obj_iter == epJSON.end() || obj_iter.value().find(std::string(ObjName)) == obj_iter.value().end()) {
    1287         2385 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(ObjType));
    1288         2385 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
    1289            2 :             return -1; // indicates object type not found, see function GeneralRoutines::ValidateComponent
    1290              :         }
    1291         2383 :         obj = &epJSON[tmp_umit->second];
    1292         2385 :     } else {
    1293           30 :         obj = &(obj_iter.value());
    1294              :     }
    1295              : 
    1296         2413 :     int object_item_num = 1;
    1297         2413 :     bool found = false;
    1298         2413 :     std::string const upperObjName = Util::makeUPPER(ObjName);
    1299         4160 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1300         4092 :         if (Util::makeUPPER(it.key()) == upperObjName) {
    1301         2345 :             found = true;
    1302         2345 :             break;
    1303              :         }
    1304         1747 :         object_item_num++;
    1305         2413 :     }
    1306              : 
    1307         2413 :     if (!found) {
    1308           68 :         return 0; // indicates object name not found, see function GeneralRoutines::ValidateComponent
    1309              :     }
    1310         4690 :     return getIDFObjNum(state, std::string(ObjType), object_item_num); // if incoming input is idf, then return idf object order
    1311         2415 : }
    1312              : 
    1313          702 : int InputProcessor::getObjectItemNum(EnergyPlusData &state,
    1314              :                                      std::string_view ObjType,       // Object Type (ref: IDD Objects)
    1315              :                                      std::string const &NameTypeVal, // Object "name" field type ( used as search key )
    1316              :                                      std::string const &ObjName      // Name of the object type
    1317              : )
    1318              : {
    1319              :     // PURPOSE OF THIS SUBROUTINE:
    1320              :     // Get the occurrence number of an object of type ObjType and name ObjName
    1321              : 
    1322              :     json *obj;
    1323         1404 :     auto obj_iter = epJSON.find(std::string(ObjType));
    1324          702 :     if (obj_iter == epJSON.end() || obj_iter.value().find(ObjName) == obj_iter.value().end()) {
    1325          701 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(ObjType));
    1326          701 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
    1327            0 :             return -1; // indicates object type not found, see function GeneralRoutines::ValidateComponent
    1328              :         }
    1329          701 :         obj = &epJSON[tmp_umit->second];
    1330          701 :     } else {
    1331            1 :         obj = &(obj_iter.value());
    1332              :     }
    1333              : 
    1334          702 :     int object_item_num = 1;
    1335          702 :     bool found = false;
    1336          702 :     std::string const upperObjName = Util::makeUPPER(ObjName);
    1337          878 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1338          499 :         auto it2 = it.value().find(NameTypeVal);
    1339              : 
    1340          499 :         if ((it2 != it.value().end()) && (Util::makeUPPER(it2.value().get<std::string>()) == upperObjName)) {
    1341          323 :             found = true;
    1342          323 :             break;
    1343              :         }
    1344          176 :         object_item_num++;
    1345         1201 :     }
    1346              : 
    1347          702 :     if (!found) {
    1348          379 :         return 0; // indicates object field name or value not found
    1349              :     }
    1350          323 :     return getIDFObjNum(state, ObjType, object_item_num); // if incoming input is idf, then return idf object order
    1351          702 : }
    1352              : 
    1353         1363 : void InputProcessor::getMaxSchemaArgs(int &NumArgs, int &NumAlpha, int &NumNumeric)
    1354              : {
    1355         1363 :     NumArgs = 0;
    1356         1363 :     NumAlpha = 0;
    1357         1363 :     NumNumeric = 0;
    1358         1363 :     std::string extension_key;
    1359         2726 :     auto const &schema_properties = schema().at("properties");
    1360              : 
    1361        17765 :     for (json::iterator object = epJSON.begin(); object != epJSON.end(); ++object) {
    1362        16402 :         int num_alpha = 0;
    1363        16402 :         int num_numeric = 0;
    1364              : 
    1365        49206 :         const json &legacy_idd = schema_properties.at(object.key()).at("legacy_idd");
    1366        16402 :         auto key = legacy_idd.find("extension");
    1367        16402 :         if (key != legacy_idd.end()) {
    1368         2531 :             extension_key = key.value().get<std::string>();
    1369              :         }
    1370              : 
    1371        16402 :         size_t max_size = 0;
    1372        51980 :         for (auto const &obj : object.value()) {
    1373        35578 :             auto const find_extensions = obj.find(extension_key);
    1374        35578 :             if (find_extensions != obj.end()) {
    1375         7991 :                 size_t const size = find_extensions.value().size();
    1376         7991 :                 if (size > max_size) {
    1377         2634 :                     max_size = size;
    1378              :                 }
    1379              :             }
    1380        51980 :         }
    1381              : 
    1382        16402 :         auto const find_alphas = legacy_idd.find("alphas");
    1383        16402 :         if (find_alphas != legacy_idd.end()) {
    1384        16402 :             json const &alphas = find_alphas.value();
    1385        16402 :             auto const find_fields = alphas.find("fields");
    1386        16402 :             if (find_fields != alphas.end()) {
    1387        16402 :                 num_alpha += find_fields.value().size();
    1388              :             }
    1389        49206 :             if (alphas.find("extensions") != alphas.end()) {
    1390         2064 :                 num_alpha += alphas["extensions"].size() * max_size;
    1391              :             }
    1392        16402 :         }
    1393        49206 :         if (legacy_idd.find("numerics") != legacy_idd.end()) {
    1394        16402 :             json const &numerics = legacy_idd["numerics"];
    1395        49206 :             if (numerics.find("fields") != numerics.end()) {
    1396        16402 :                 num_numeric += numerics["fields"].size();
    1397              :             }
    1398        49206 :             if (numerics.find("extensions") != numerics.end()) {
    1399          836 :                 num_numeric += numerics["extensions"].size() * max_size;
    1400              :             }
    1401              :         }
    1402        16402 :         if (num_alpha > NumAlpha) {
    1403         3702 :             NumAlpha = num_alpha;
    1404              :         }
    1405        16402 :         if (num_numeric > NumNumeric) {
    1406         3049 :             NumNumeric = num_numeric;
    1407              :         }
    1408        17765 :     }
    1409              : 
    1410         1363 :     NumArgs = NumAlpha + NumNumeric;
    1411         1363 : }
    1412              : 
    1413        26877 : void InputProcessor::getObjectDefMaxArgs(EnergyPlusData &state,
    1414              :                                          std::string_view const ObjectWord, // Object for definition
    1415              :                                          int &NumArgs,                      // How many arguments (max) this Object can have
    1416              :                                          int &NumAlpha,                     // How many Alpha arguments (max) this Object can have
    1417              :                                          int &NumNumeric                    // How many Numeric arguments (max) this Object can have
    1418              : )
    1419              : {
    1420              :     // PURPOSE OF THIS SUBROUTINE:
    1421              :     // This subroutine returns maximum argument limits (total, alphas, numerics) of an Object from the IDD.
    1422              :     // These dimensions (not sure what one can use the total for) can be used to dynamically dimension the
    1423              :     // arrays in the GetInput routines.
    1424              : 
    1425        26877 :     NumArgs = 0;
    1426        26877 :     NumAlpha = 0;
    1427        26877 :     NumNumeric = 0;
    1428              :     const json *object;
    1429              : 
    1430        26877 :     auto const &props = schema()["properties"];
    1431              : 
    1432        53754 :     if (auto found = props.find(std::string(ObjectWord)); found == props.end()) {
    1433          246 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(ObjectWord));
    1434          246 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
    1435            0 :             ShowSevereError(state, fmt::format(R"(getObjectDefMaxArgs: Did not find object="{}" in list of objects.)", ObjectWord));
    1436            0 :             return;
    1437              :         }
    1438          246 :         object = &props[tmp_umit->second];
    1439          246 :     } else {
    1440        26631 :         object = &found.value();
    1441        26877 :     }
    1442              : 
    1443        53754 :     const json &legacy_idd = object->at("legacy_idd");
    1444              :     json *objects;
    1445        80631 :     if (auto found = epJSON.find(std::string(ObjectWord)); found == epJSON.end()) {
    1446        18497 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(ObjectWord));
    1447        18497 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
    1448            0 :             ShowSevereError(state, fmt::format(R"(getObjectDefMaxArgs: Did not find object="{}" in list of objects.)", ObjectWord));
    1449            0 :             return;
    1450              :         }
    1451        18497 :         objects = &epJSON[tmp_umit->second];
    1452        18497 :     } else {
    1453         8380 :         objects = &found.value();
    1454        26877 :     }
    1455              : 
    1456        26877 :     size_t max_size = 0;
    1457              : 
    1458        26877 :     std::string extension_key;
    1459        26877 :     auto key = legacy_idd.find("extension");
    1460        26877 :     if (key != legacy_idd.end()) {
    1461         8173 :         extension_key = key.value().get<std::string>();
    1462              :     }
    1463              : 
    1464        45291 :     for (auto const &obj : *objects) {
    1465        18414 :         if (auto found = obj.find(extension_key); found != obj.end()) {
    1466        11397 :             size_t const size = found.value().size();
    1467        11397 :             if (size > max_size) {
    1468         3139 :                 max_size = size;
    1469              :             }
    1470        18414 :         }
    1471        26877 :     }
    1472              : 
    1473        53754 :     if (auto found = legacy_idd.find("alphas"); found != legacy_idd.end()) {
    1474        26877 :         json const &alphas = found.value();
    1475        53754 :         if (auto found2 = alphas.find("fields"); found2 != alphas.end()) {
    1476        26877 :             NumAlpha += found2.value().size();
    1477        26877 :         }
    1478        53754 :         if (auto found2 = alphas.find("extensions"); found2 != alphas.end()) {
    1479         6908 :             NumAlpha += found2.value().size() * max_size;
    1480        26877 :         }
    1481        26877 :     }
    1482        53754 :     if (auto found = legacy_idd.find("numerics"); found != legacy_idd.end()) {
    1483        26877 :         json const &numerics = found.value();
    1484        53754 :         if (auto found2 = numerics.find("fields"); found2 != numerics.end()) {
    1485        26877 :             NumNumeric += found2.value().size();
    1486        26877 :         }
    1487        53754 :         if (auto found2 = numerics.find("extensions"); found2 != numerics.end()) {
    1488         2015 :             NumNumeric += found2.value().size() * max_size;
    1489        26877 :         }
    1490        26877 :     }
    1491        26877 :     NumArgs = NumAlpha + NumNumeric;
    1492        26877 : }
    1493              : 
    1494           28 : void InputProcessor::reportIDFRecordsStats(EnergyPlusData &state)
    1495              : {
    1496              : 
    1497              :     // SUBROUTINE INFORMATION: (previously called GetIDFRecordsStats)
    1498              :     //       AUTHOR         Linda Lawrie
    1499              :     //       DATE WRITTEN   February 2009
    1500              :     //       MODIFIED       na
    1501              :     //       RE-ENGINEERED  Julien Marrec of EffiBEM, 2020 (ported to the new InputProcessor/epJSON)
    1502              : 
    1503              :     // PURPOSE OF THIS SUBROUTINE:
    1504              :     // This routine provides some statistics on the current IDF, such as number of records, total fields with defaults,
    1505              :     // number of fields that overrode the default (even if it was default value), and similarly for AutoSize.
    1506              : 
    1507              :     // METHODOLOGY EMPLOYED:
    1508              :     // Traverses the IDF Records looking at each field vs object definition for defaults and autosize.
    1509              : 
    1510              :     // Reset the globals
    1511           28 :     state.dataOutput->iNumberOfRecords = 0;             // Number of IDF Records
    1512           28 :     state.dataOutput->iNumberOfDefaultedFields = 0;     // Number of defaulted fields in IDF
    1513           28 :     state.dataOutput->iTotalFieldsWithDefaults = 0;     // Total number of fields that could be defaulted
    1514           28 :     state.dataOutput->iNumberOfAutoSizedFields = 0;     // Number of autosized fields in IDF
    1515           28 :     state.dataOutput->iTotalAutoSizableFields = 0;      // Total number of autosizable fields
    1516           28 :     state.dataOutput->iNumberOfAutoCalcedFields = 0;    // Number of autocalculated fields
    1517           28 :     state.dataOutput->iTotalAutoCalculatableFields = 0; // Total number of autocalculatable fields
    1518              : 
    1519           56 :     auto const &schema_properties = schema().at("properties");
    1520              : 
    1521              :     // Lambda to avoid repeating code twice (when processing regular fields, and extensible fields)
    1522        12223 :     auto processField = [&state](const std::string &field, const json &epJSONObj, const json &schema_field_obj) {
    1523        12223 :         bool hasDefault = false;
    1524        12223 :         bool canBeAutosized = false;
    1525        12223 :         bool canBeAutocalculated = false;
    1526              : 
    1527              :         // If we wanted to count number of fields, would do it here
    1528              : 
    1529        12223 :         std::string defaultValue;
    1530              : 
    1531        12223 :         auto const default_it = schema_field_obj.find("default");
    1532        12223 :         if (default_it != schema_field_obj.end()) {
    1533         4423 :             ++state.dataOutput->iTotalFieldsWithDefaults;
    1534         4423 :             hasDefault = true;
    1535         4423 :             auto const &default_val = default_it.value();
    1536         4423 :             if (default_val.is_string()) {
    1537         3061 :                 defaultValue = default_val.get<std::string>();
    1538              :             }
    1539              :         }
    1540              : 
    1541        12223 :         auto const anyOf_it = schema_field_obj.find("anyOf");
    1542        12223 :         if (anyOf_it != schema_field_obj.end()) {
    1543         1836 :             for (auto const &anyOf : anyOf_it.value()) {
    1544         1224 :                 auto const enum_it = anyOf.find("enum");
    1545         1224 :                 if (enum_it != anyOf.end()) {
    1546         1272 :                     for (auto const &e : enum_it.value()) {
    1547          843 :                         if (e.is_string()) {
    1548          843 :                             std::string const enumVal = e.get<std::string>();
    1549          843 :                             if (enumVal == "Autosize") {
    1550           26 :                                 ++state.dataOutput->iTotalAutoSizableFields;
    1551           26 :                                 canBeAutosized = true;
    1552          817 :                             } else if (enumVal == "Autocalculate") {
    1553          403 :                                 ++state.dataOutput->iTotalAutoCalculatableFields;
    1554          403 :                                 canBeAutocalculated = true;
    1555              :                             }
    1556          843 :                         }
    1557          429 :                     }
    1558              :                 }
    1559         1836 :             }
    1560              :         }
    1561              : 
    1562              :         // Locate the field in the ep_object
    1563        12223 :         auto it = epJSONObj.find(field);
    1564        12223 :         if (it != epJSONObj.end()) { // && !it.value().empty()) {
    1565              :             // Found it: check if Autosized or Autocalculated
    1566         9144 :             auto const &field_value = it.value();
    1567         9144 :             if (field_value.is_string()) {
    1568         4871 :                 std::string const val = field_value.get<std::string>();
    1569              :                 // In the IDF, casing is an issue and Autosize/Autocalculate are accepted as synonyms
    1570              :                 // but once converted to epJSON everything should is resolved, eg:
    1571              :                 // * if "AutoSize" is entered for an autosizable field, the result is "Autosize"
    1572              :                 // * if "AutoSize" is entered for an autocalculatable field, the result is "Autocalculate"
    1573         4871 :                 if (canBeAutosized && (val == "Autosize")) {
    1574           21 :                     ++state.dataOutput->iNumberOfAutoSizedFields;
    1575         4850 :                 } else if (canBeAutocalculated && (val == "Autocalculate")) {
    1576           55 :                     ++state.dataOutput->iNumberOfAutoCalcedFields;
    1577              :                 }
    1578         4871 :             }
    1579         3079 :         } else if (hasDefault) {
    1580              :             // Not found: was defaulted
    1581          741 :             ++state.dataOutput->iNumberOfDefaultedFields;
    1582          741 :             if (canBeAutosized && (defaultValue == "Autosize")) {
    1583            1 :                 ++state.dataOutput->iNumberOfAutoSizedFields;
    1584          740 :             } else if (canBeAutocalculated && (defaultValue == "Autocalculate")) {
    1585           29 :                 ++state.dataOutput->iNumberOfAutoCalcedFields;
    1586              :             }
    1587              :         }
    1588        12223 :     };
    1589              : 
    1590              :     // Loop on all objectTypes
    1591          759 :     for (auto epJSON_iter = epJSON.begin(); epJSON_iter != epJSON.end(); ++epJSON_iter) {
    1592          731 :         auto const &objectType = epJSON_iter.key();
    1593          731 :         auto const &objects = epJSON_iter.value();
    1594              : 
    1595          731 :         const json &object_schema = schema_properties.at(objectType);
    1596              : 
    1597              :         // Locations in JSON schema relating to normal fields
    1598          731 :         auto const &schema_obj_props = getPatternProperties(state, object_schema);
    1599          731 :         auto const schema_name_field = object_schema.find("name");
    1600          731 :         bool const has_idd_name_field = schema_name_field != object_schema.end();
    1601              : 
    1602              :         // Locations in JSON schema storing the positional aspects from the IDD format, legacy prefixed
    1603          731 :         auto const &legacy_idd = object_schema["legacy_idd"];
    1604          731 :         auto const &legacy_idd_fields = legacy_idd["fields"];
    1605              : 
    1606              :         // Look for extensible
    1607          731 :         auto key = legacy_idd.find("extension");
    1608          731 :         std::string extension_key;
    1609          731 :         if (key != legacy_idd.end()) {
    1610           78 :             extension_key = key.value().get<std::string>();
    1611              :         }
    1612              : 
    1613         2384 :         for (auto const &ep_object : objects) {
    1614              : 
    1615              :             // Count number of objects
    1616         1653 :             ++state.dataOutput->iNumberOfRecords;
    1617              : 
    1618              :             // Loop on all regular fields
    1619        12229 :             for (size_t i = 0; i < legacy_idd_fields.size(); ++i) {
    1620              : 
    1621        10576 :                 std::string const field = legacy_idd_fields[i].get<std::string>();
    1622              : 
    1623              :                 // This is weird, but some objects like Building have a Name default... and it's not in the patternProperties
    1624        10576 :                 if (has_idd_name_field && field == "name") {
    1625          779 :                     auto const &name_iter = schema_name_field.value();
    1626         2337 :                     if (name_iter.find("default") != name_iter.end()) {
    1627           28 :                         ++state.dataOutput->iTotalFieldsWithDefaults;
    1628           28 :                         auto it = ep_object.find(field);
    1629           28 :                         if (it == ep_object.end()) {
    1630           28 :                             ++state.dataOutput->iNumberOfDefaultedFields;
    1631              :                         }
    1632           28 :                     }
    1633          779 :                     continue;
    1634          779 :                 }
    1635              : 
    1636         9797 :                 auto const &schema_field_obj = schema_obj_props[field];
    1637              : 
    1638         9797 :                 processField(field, ep_object, schema_field_obj);
    1639              : 
    1640        10576 :             } // End regular fields
    1641              : 
    1642         1653 :             auto const legacy_idd_extensibles_iter = legacy_idd.find("extensibles");
    1643         1653 :             if (legacy_idd_extensibles_iter != legacy_idd.end()) {
    1644          258 :                 auto const epJSON_extensions_array_itr = ep_object.find(extension_key);
    1645          258 :                 if (epJSON_extensions_array_itr != ep_object.end()) {
    1646          258 :                     auto const &legacy_idd_extensibles = legacy_idd_extensibles_iter.value();
    1647          258 :                     auto const &epJSON_extensions_array = epJSON_extensions_array_itr.value();
    1648          258 :                     auto const &schema_extension_fields = schema_obj_props[extension_key]["items"]["properties"];
    1649              : 
    1650         1355 :                     for (auto it = epJSON_extensions_array.begin(); it != epJSON_extensions_array.end(); ++it) {
    1651         1097 :                         auto const &epJSON_extension_obj = it.value();
    1652         3523 :                         for (size_t i = 0; i < legacy_idd_extensibles.size(); ++i) {
    1653         2426 :                             std::string const &field = legacy_idd_extensibles[i].get<std::string>();
    1654         2426 :                             auto const &schema_extension_field_obj = schema_extension_fields[field];
    1655              : 
    1656         2426 :                             processField(field, epJSON_extension_obj, schema_extension_field_obj);
    1657         2426 :                         }
    1658          258 :                     }
    1659              :                 }
    1660          258 :             } // End extensible fields
    1661              : 
    1662         2384 :         } // End loop on each object of a given objectType
    1663          759 :     } // End loop on all objectTypes
    1664           28 : }
    1665              : 
    1666           25 : void InputProcessor::reportOrphanRecordObjects(EnergyPlusData &state)
    1667              : {
    1668              : 
    1669              :     // SUBROUTINE INFORMATION:
    1670              :     //       AUTHOR         Linda Lawrie
    1671              :     //       DATE WRITTEN   August 2002
    1672              :     //       MODIFIED       na
    1673              :     //       RE-ENGINEERED  Mark Adams, Oct 2016
    1674              : 
    1675              :     // PURPOSE OF THIS SUBROUTINE:
    1676              :     // This subroutine reports "orphan" objects that are in the input but were
    1677              :     // not "gotten" during the simulation.
    1678              : 
    1679           25 :     std::unordered_set<std::string> unused_object_types;
    1680           25 :     unused_object_types.reserve(unusedInputs.size());
    1681              : 
    1682           25 :     if (unusedInputs.size() && state.dataGlobal->DisplayUnusedObjects) {
    1683            2 :         ShowWarningError(state, "The following lines are \"Unused Objects\".  These objects are in the input");
    1684            2 :         ShowContinueError(state, " file but are never obtained by the simulation and therefore are NOT used.");
    1685            1 :         if (!state.dataGlobal->DisplayAllWarnings) {
    1686            3 :             ShowContinueError(
    1687              :                 state, " Only the first unused named object of an object class is shown.  Use Output:Diagnostics,DisplayAllWarnings; to see all.");
    1688              :         } else {
    1689            0 :             ShowContinueError(state, " Each unused object is shown.");
    1690              :         }
    1691            3 :         ShowContinueError(state, " See InputOutputReference document for more details.");
    1692              :     }
    1693              : 
    1694           25 :     bool first_iteration = true;
    1695           30 :     for (auto it = unusedInputs.begin(); it != unusedInputs.end(); ++it) {
    1696            5 :         std::string const &object_type = it->objectType;
    1697            5 :         std::string const &name = it->objectName;
    1698              : 
    1699              :         // there are some orphans that we are deeming as special, in that they should be warned in detail even if !DisplayUnusedObjects and
    1700              :         // !DisplayAllWarnings
    1701            5 :         if (has_prefix(object_type, "ZoneHVAC:")) {
    1702            0 :             ShowSevereError(state, "Orphaned ZoneHVAC object found.  This was object never referenced in the input, and was not used.");
    1703            0 :             ShowContinueError(state, " -- Object type: " + object_type);
    1704            0 :             ShowContinueError(state, " -- Object name: " + name);
    1705              :         }
    1706              : 
    1707            5 :         if (!state.dataGlobal->DisplayUnusedObjects) {
    1708            1 :             continue;
    1709              :         }
    1710              : 
    1711            4 :         if (!state.dataGlobal->DisplayAllWarnings) {
    1712            4 :             auto found_type = unused_object_types.find(object_type);
    1713            4 :             if (found_type != unused_object_types.end()) {
    1714              :                 // only show first unused named object of an object class
    1715            0 :                 continue;
    1716              :             } else {
    1717            4 :                 unused_object_types.emplace(object_type);
    1718              :             }
    1719            4 :         }
    1720              : 
    1721            4 :         if (first_iteration) {
    1722            1 :             if (!name.empty()) {
    1723            1 :                 ShowMessage(state, "Object=" + object_type + '=' + name);
    1724              :             } else {
    1725            0 :                 ShowMessage(state, "Object=" + object_type);
    1726              :             }
    1727            1 :             first_iteration = false;
    1728              :         } else {
    1729            3 :             if (!name.empty()) {
    1730            0 :                 ShowContinueError(state, "Object=" + object_type + '=' + name);
    1731              :             } else {
    1732            3 :                 ShowContinueError(state, "Object=" + object_type);
    1733              :             }
    1734              :         }
    1735           25 :     }
    1736              : 
    1737           25 :     if (unusedInputs.size() && !state.dataGlobal->DisplayUnusedObjects) {
    1738            1 :         u64toa(unusedInputs.size(), s);
    1739            2 :         ShowMessage(state, "There are " + std::string(s) + " unused objects in input.");
    1740            3 :         ShowMessage(state, "Use Output:Diagnostics,DisplayUnusedObjects; to see them.");
    1741              :     }
    1742           25 : }
    1743              : 
    1744         1419 : void InputProcessor::preProcessorCheck(EnergyPlusData &state, bool &PreP_Fatal) // True if a preprocessor flags a fatal error
    1745              : {
    1746              : 
    1747              :     // SUBROUTINE INFORMATION:
    1748              :     //       AUTHOR         Linda Lawrie
    1749              :     //       DATE WRITTEN   August 2005
    1750              :     //       MODIFIED       na
    1751              :     //       RE-ENGINEERED  na
    1752              : 
    1753              :     // PURPOSE OF THIS SUBROUTINE:
    1754              :     // This routine checks for existence of "Preprocessor Message" object and
    1755              :     // performs appropriate action.
    1756              : 
    1757              :     // METHODOLOGY EMPLOYED:
    1758              :     // na
    1759              : 
    1760              :     // REFERENCES:
    1761              :     // Preprocessor Message,
    1762              :     //    \memo This object does not come from a user input.  This is generated by a pre-processor
    1763              :     //    \memo so that various conditions can be gracefully passed on by the InputProcessor.
    1764              :     //    A1,        \field preprocessor name
    1765              :     //    A2,        \field error severity
    1766              :     //               \note Depending on type, InputProcessor may terminate the program.
    1767              :     //               \type choice
    1768              :     //               \key warning
    1769              :     //               \key severe
    1770              :     //               \key fatal
    1771              :     //    A3,        \field message line 1
    1772              :     //    A4,        \field message line 2
    1773              :     //    A5,        \field message line 3
    1774              :     //    A6,        \field message line 4
    1775              :     //    A7,        \field message line 5
    1776              :     //    A8,        \field message line 6
    1777              :     //    A9,        \field message line 7
    1778              :     //    A10,       \field message line 8
    1779              :     //    A11,       \field message line 9
    1780              :     //    A12;       \field message line 10
    1781              : 
    1782         1419 :     state.dataIPShortCut->cCurrentModuleObject = "Output:PreprocessorMessage";
    1783         1419 :     int NumPrePM = getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
    1784         1419 :     if (NumPrePM > 0) {
    1785              :         int NumAlphas;  // Used to retrieve names from IDF
    1786              :         int NumNumbers; // Used to retrieve rNumericArgs from IDF
    1787              :         int IOStat;     // Could be used in the Get Routines, not currently checked
    1788              :         int NumParams;  // Total Number of Parameters in 'Output:PreprocessorMessage' Object
    1789            1 :         std::string Multiples;
    1790              : 
    1791            1 :         getObjectDefMaxArgs(state, state.dataIPShortCut->cCurrentModuleObject, NumParams, NumAlphas, NumNumbers);
    1792            1 :         state.dataIPShortCut->cAlphaArgs({1, NumAlphas}) = BlankString;
    1793            2 :         for (int CountP = 1; CountP <= NumPrePM; ++CountP) {
    1794            1 :             getObjectItem(state,
    1795            1 :                           state.dataIPShortCut->cCurrentModuleObject,
    1796              :                           CountP,
    1797            1 :                           state.dataIPShortCut->cAlphaArgs,
    1798              :                           NumAlphas,
    1799            1 :                           state.dataIPShortCut->rNumericArgs,
    1800              :                           NumNumbers,
    1801              :                           IOStat,
    1802            1 :                           state.dataIPShortCut->lNumericFieldBlanks,
    1803            1 :                           state.dataIPShortCut->lAlphaFieldBlanks,
    1804            1 :                           state.dataIPShortCut->cAlphaFieldNames,
    1805            1 :                           state.dataIPShortCut->cNumericFieldNames);
    1806            1 :             if (state.dataIPShortCut->cAlphaArgs(1).empty()) {
    1807            0 :                 state.dataIPShortCut->cAlphaArgs(1) = "Unknown";
    1808              :             }
    1809            1 :             if (NumAlphas > 3) {
    1810            1 :                 Multiples = "s";
    1811              :             } else {
    1812            0 :                 Multiples = BlankString;
    1813              :             }
    1814            1 :             if (state.dataIPShortCut->cAlphaArgs(2).empty()) {
    1815            0 :                 state.dataIPShortCut->cAlphaArgs(2) = "Unknown";
    1816              :             }
    1817              :             {
    1818            1 :                 std::string const errorType = uppercased(state.dataIPShortCut->cAlphaArgs(2));
    1819            1 :                 if (errorType == "INFORMATION") {
    1820            0 :                     ShowMessage(state,
    1821            0 :                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
    1822            0 :                                     "\" has the following Information message" + Multiples + ':');
    1823            1 :                 } else if (errorType == "WARNING") {
    1824            2 :                     ShowWarningError(state,
    1825            2 :                                      state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
    1826            3 :                                          "\" has the following Warning condition" + Multiples + ':');
    1827            0 :                 } else if (errorType == "SEVERE") {
    1828            0 :                     ShowSevereError(state,
    1829            0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
    1830            0 :                                         "\" has the following Severe condition" + Multiples + ':');
    1831            0 :                 } else if (errorType == "FATAL") {
    1832            0 :                     ShowSevereError(state,
    1833            0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
    1834            0 :                                         "\" has the following Fatal condition" + Multiples + ':');
    1835            0 :                     PreP_Fatal = true;
    1836              :                 } else {
    1837            0 :                     ShowSevereError(state,
    1838            0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
    1839            0 :                                         "\" has the following " + state.dataIPShortCut->cAlphaArgs(2) + " condition" + Multiples + ':');
    1840              :                 }
    1841            1 :             }
    1842            1 :             int CountM = 3;
    1843            1 :             if (CountM > NumAlphas) {
    1844            0 :                 ShowContinueError(state,
    1845            0 :                                   state.dataIPShortCut->cCurrentModuleObject + " was blank.  Check " + state.dataIPShortCut->cAlphaArgs(1) +
    1846              :                                       " audit trail or error file for possible reasons.");
    1847              :             }
    1848            3 :             while (CountM <= NumAlphas) {
    1849            2 :                 if (len(state.dataIPShortCut->cAlphaArgs(CountM)) == Constant::MaxNameLength) {
    1850            0 :                     ShowContinueError(state, state.dataIPShortCut->cAlphaArgs(CountM) + state.dataIPShortCut->cAlphaArgs(CountM + 1));
    1851            0 :                     CountM += 2;
    1852              :                 } else {
    1853            2 :                     ShowContinueError(state, state.dataIPShortCut->cAlphaArgs(CountM));
    1854            2 :                     ++CountM;
    1855              :                 }
    1856              :             }
    1857              :         }
    1858            1 :     }
    1859         1419 : }
    1860              : 
    1861         1421 : void InputProcessor::preScanReportingVariables(EnergyPlusData &state)
    1862              : {
    1863              :     // SUBROUTINE INFORMATION:
    1864              :     //       AUTHOR         Linda Lawrie
    1865              :     //       DATE WRITTEN   July 2010
    1866              : 
    1867              :     // PURPOSE OF THIS SUBROUTINE:
    1868              :     // This routine scans the input records and determines which output variables
    1869              :     // are actually being requested for the run so that the OutputProcessor will only
    1870              :     // consider those variables for output.  (At this time, all metered variables are
    1871              :     // allowed to pass through).
    1872              : 
    1873              :     // This routine also scans any variables requested by API call for library usage.
    1874              :     // These variables are stored in a vector in output processor, and the values are added before E+ begins.
    1875              : 
    1876              :     // METHODOLOGY EMPLOYED:
    1877              :     // Uses internal records and structures.
    1878              :     // Looks at:
    1879              :     // Output:Variable
    1880              :     // Meter:Custom
    1881              :     // Meter:CustomDecrement
    1882              :     // Output:Table:Monthly
    1883              :     // Output:Table:TimeBins
    1884              :     // Output:Table:SummaryReports
    1885              :     // EnergyManagementSystem:Sensor
    1886              :     // EnergyManagementSystem:OutputVariable
    1887              : 
    1888              :     // SUBROUTINE PARAMETER DEFINITIONS:
    1889         4043 :     static std::string const OutputVariable("Output:Variable");
    1890         4043 :     static std::string const MeterCustom("Meter:Custom");
    1891         4043 :     static std::string const MeterCustomDecrement("Meter:CustomDecrement");
    1892         4043 :     static std::string const OutputTableMonthly("Output:Table:Monthly");
    1893         4043 :     static std::string const OutputTableAnnual("Output:Table:Annual");
    1894         4043 :     static std::string const OutputTableTimeBins("Output:Table:TimeBins");
    1895         4043 :     static std::string const OutputTableSummaries("Output:Table:SummaryReports");
    1896         4043 :     static std::string const EMSSensor("EnergyManagementSystem:Sensor");
    1897         4043 :     static std::string const EMSOutputVariable("EnergyManagementSystem:OutputVariable");
    1898              : 
    1899              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1900         1421 :     std::string extension_key;
    1901              :     // state.dataOutput->OutputVariablesForSimulation.reserve(1024);
    1902         1421 :     state.dataOutput->MaxConsideredOutputVariables = 10000;
    1903              : 
    1904              :     // Output Variable
    1905         1421 :     auto epJSON_objects = epJSON.find(OutputVariable);
    1906         1421 :     if (epJSON_objects != epJSON.end()) {
    1907           72 :         auto const &epJSON_object = epJSON_objects.value();
    1908          875 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1909          803 :             json const &fields = obj.value();
    1910          803 :             auto it = fields.find("key_value");
    1911          803 :             if (it != fields.end() && !it.value().empty()) {
    1912         1606 :                 addRecordToOutputVariableStructure(state, it.value().get<std::string>(), fields.at("variable_name").get<std::string>());
    1913              :             } else {
    1914            0 :                 addRecordToOutputVariableStructure(state, "*", fields.at("variable_name").get<std::string>());
    1915              :             }
    1916          875 :         }
    1917              :     }
    1918              : 
    1919         1421 :     epJSON_objects = epJSON.find(MeterCustom);
    1920         1421 :     if (epJSON_objects != epJSON.end()) {
    1921            5 :         auto const &epJSON_object = epJSON_objects.value();
    1922            5 :         auto const &legacy_idd = schema()["properties"][MeterCustom]["legacy_idd"];
    1923            5 :         auto key = legacy_idd.find("extension");
    1924            5 :         if (key != legacy_idd.end()) {
    1925            5 :             extension_key = key.value().get<std::string>();
    1926              :         }
    1927           28 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1928           23 :             json const &fields = obj.value();
    1929           52 :             for (auto const &extensions : fields[extension_key]) {
    1930           29 :                 auto it = extensions.find("key_name");
    1931           29 :                 if (it != extensions.end() && !obj.key().empty()) {
    1932           23 :                     addRecordToOutputVariableStructure(
    1933           69 :                         state, it.value().get<std::string>(), extensions.at("output_variable_or_meter_name").get<std::string>());
    1934              :                 } else {
    1935           24 :                     addRecordToOutputVariableStructure(state, "*", extensions.at("output_variable_or_meter_name").get<std::string>());
    1936              :                 }
    1937           52 :             }
    1938            5 :         }
    1939            5 :     }
    1940              : 
    1941         1421 :     epJSON_objects = epJSON.find(MeterCustomDecrement);
    1942         1421 :     if (epJSON_objects != epJSON.end()) {
    1943            1 :         auto const &epJSON_object = epJSON_objects.value();
    1944            1 :         auto const &legacy_idd = schema()["properties"][MeterCustomDecrement]["legacy_idd"];
    1945            1 :         auto key = legacy_idd.find("extension");
    1946            1 :         if (key != legacy_idd.end()) {
    1947            1 :             extension_key = key.value().get<std::string>();
    1948              :         }
    1949            2 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1950            1 :             json const &fields = obj.value();
    1951            2 :             for (auto const &extensions : fields[extension_key]) {
    1952            1 :                 auto it = extensions.find("key_name");
    1953            1 :                 if (it != extensions.end() && !obj.key().empty()) {
    1954            0 :                     addRecordToOutputVariableStructure(
    1955            0 :                         state, it.value().get<std::string>(), extensions.at("output_variable_or_meter_name").get<std::string>());
    1956              :                 } else {
    1957            4 :                     addRecordToOutputVariableStructure(state, "*", extensions.at("output_variable_or_meter_name").get<std::string>());
    1958              :                 }
    1959            2 :             }
    1960            1 :         }
    1961            1 :     }
    1962              : 
    1963         1421 :     epJSON_objects = epJSON.find(EMSSensor);
    1964         1421 :     if (epJSON_objects != epJSON.end()) {
    1965           11 :         auto const &epJSON_object = epJSON_objects.value();
    1966           30 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1967           19 :             json const &fields = obj.value();
    1968           19 :             auto it = fields.find("output_variable_or_output_meter_index_key_name");
    1969           19 :             if (it != fields.end() && !it.value().empty()) {
    1970           19 :                 addRecordToOutputVariableStructure(
    1971           57 :                     state, it.value().get<std::string>(), fields.at("output_variable_or_output_meter_name").get<std::string>());
    1972              :             } else {
    1973            0 :                 addRecordToOutputVariableStructure(state, "*", fields.at("output_variable_or_output_meter_name").get<std::string>());
    1974              :             }
    1975           30 :         }
    1976              :     }
    1977              : 
    1978         1421 :     epJSON_objects = epJSON.find(EMSOutputVariable);
    1979         1421 :     if (epJSON_objects != epJSON.end()) {
    1980            6 :         auto const &epJSON_object = epJSON_objects.value();
    1981           21 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1982           45 :             addRecordToOutputVariableStructure(state, "*", obj.key());
    1983            6 :         }
    1984              :     }
    1985              : 
    1986         1425 :     for (auto const &requestedVar : state.dataOutputProcessor->apiVarRequests) {
    1987            4 :         addRecordToOutputVariableStructure(state, requestedVar.varKey, requestedVar.varName);
    1988         1421 :     }
    1989              : 
    1990         1421 :     epJSON_objects = epJSON.find(OutputTableTimeBins);
    1991         1421 :     if (epJSON_objects != epJSON.end()) {
    1992            1 :         auto const &epJSON_object = epJSON_objects.value();
    1993            2 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1994            1 :             json const &fields = obj.value();
    1995            1 :             if (!obj.key().empty()) {
    1996            2 :                 addRecordToOutputVariableStructure(state, obj.key(), fields.at("key_value").get<std::string>());
    1997              :             } else {
    1998            0 :                 addRecordToOutputVariableStructure(state, "*", fields.at("key_value").get<std::string>());
    1999              :             }
    2000            1 :         }
    2001              :     }
    2002              : 
    2003         1421 :     epJSON_objects = epJSON.find(OutputTableMonthly);
    2004         1421 :     if (epJSON_objects != epJSON.end()) {
    2005           15 :         auto const &epJSON_object = epJSON_objects.value();
    2006           15 :         auto const &legacy_idd = schema()["properties"][OutputTableMonthly]["legacy_idd"];
    2007           15 :         auto key = legacy_idd.find("extension");
    2008           15 :         if (key != legacy_idd.end()) {
    2009           15 :             extension_key = key.value().get<std::string>();
    2010              :         }
    2011           88 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    2012           73 :             json const &fields = obj.value();
    2013          512 :             for (auto const &extensions : fields[extension_key]) {
    2014              :                 try {
    2015         1754 :                     addRecordToOutputVariableStructure(state, "*", extensions.at("variable_or_meter_name").get<std::string>());
    2016            1 :                 } catch (...) {
    2017            1 :                     continue; // blank or erroneous fields are handled at the get input function for the object
    2018            1 :                 }
    2019           73 :             }
    2020           15 :         }
    2021           15 :     }
    2022              : 
    2023         1421 :     epJSON_objects = epJSON.find(OutputTableAnnual);
    2024         1421 :     if (epJSON_objects != epJSON.end()) {
    2025            7 :         auto const &epJSON_object = epJSON_objects.value();
    2026            7 :         auto const &legacy_idd = schema()["properties"][OutputTableAnnual]["legacy_idd"];
    2027            7 :         auto key = legacy_idd.find("extension");
    2028            7 :         if (key != legacy_idd.end()) {
    2029            7 :             extension_key = key.value().get<std::string>();
    2030              :         }
    2031           14 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    2032            7 :             json const &fields = obj.value();
    2033           40 :             for (auto const &extensions : fields[extension_key]) {
    2034              :                 try {
    2035           32 :                     addRecordToOutputVariableStructure(
    2036           98 :                         state, "*", extensions.at("variable_or_meter_or_ems_variable_or_field_name").get<std::string>());
    2037            1 :                 } catch (...) {
    2038            1 :                     continue; // blank or erroneous fields are handled at the get input function for the object
    2039            1 :                 }
    2040            7 :             }
    2041            7 :         }
    2042            7 :     }
    2043              : 
    2044         1421 :     epJSON_objects = epJSON.find(OutputTableSummaries);
    2045         1421 :     if (epJSON_objects != epJSON.end()) {
    2046           70 :         auto const &epJSON_object = epJSON_objects.value();
    2047           70 :         auto const &legacy_idd = schema()["properties"][OutputTableSummaries]["legacy_idd"];
    2048           70 :         auto key = legacy_idd.find("extension");
    2049           70 :         if (key != legacy_idd.end()) {
    2050           70 :             extension_key = key.value().get<std::string>();
    2051              :         }
    2052          140 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    2053           70 :             json const &fields = obj.value();
    2054          146 :             for (auto const &extensions : fields[extension_key]) {
    2055              :                 try {
    2056           76 :                     std::string const report_name = Util::makeUPPER(extensions.at("report_name").get<std::string>());
    2057           76 :                     if (report_name == "ALLMONTHLY" || report_name == "ALLSUMMARYANDMONTHLY") {
    2058          384 :                         for (int i = 1; i <= DataOutputs::NumMonthlyReports; ++i) {
    2059          378 :                             addVariablesForMonthlyReport(state, DataOutputs::MonthlyNamedReports(i));
    2060              :                         }
    2061              :                     } else {
    2062           70 :                         addVariablesForMonthlyReport(state, report_name);
    2063              :                     }
    2064           76 :                 } catch (...) {
    2065            0 :                     continue; // blank or erroneous fields should be warned about during actual get input routines
    2066            0 :                 }
    2067           70 :             }
    2068           70 :         }
    2069           70 :     }
    2070         1421 : }
    2071              : 
    2072          448 : void InputProcessor::addVariablesForMonthlyReport(EnergyPlusData &state, std::string const &reportName)
    2073              : {
    2074              : 
    2075              :     // SUBROUTINE INFORMATION:
    2076              :     //       AUTHOR         Linda Lawrie
    2077              :     //       DATE WRITTEN   July 2010
    2078              :     //       MODIFIED       na
    2079              :     //       RE-ENGINEERED  na
    2080              : 
    2081              :     // PURPOSE OF THIS SUBROUTINE:
    2082              :     // This routine adds specific variables to the Output Variables for Simulation
    2083              :     // Structure. Note that only non-metered variables need to be added here.  Metered
    2084              :     // variables are automatically included in the minimized output variable structure.
    2085              : 
    2086          448 :     if (reportName == "ZONECOOLINGSUMMARYMONTHLY") {
    2087           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE AIR SYSTEM SENSIBLE COOLING RATE");
    2088           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2089           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2090           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE TOTAL INTERNAL LATENT GAIN ENERGY");
    2091           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE TOTAL INTERNAL LATENT GAIN RATE");
    2092              : 
    2093          442 :     } else if (reportName == "ZONEHEATINGSUMMARYMONTHLY") {
    2094           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE AIR SYSTEM SENSIBLE HEATING ENERGY"); // on meter
    2095           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE AIR SYSTEM SENSIBLE HEATING RATE");
    2096           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2097              : 
    2098          436 :     } else if (reportName == "ZONEELECTRICSUMMARYMONTHLY") {
    2099           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE LIGHTS ELECTRICITY ENERGY");
    2100           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE ELECTRIC EQUIPMENT ELECTRICITY ENERGY");
    2101              : 
    2102          430 :     } else if (reportName == "SPACEGAINSMONTHLY") {
    2103           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE PEOPLE TOTAL HEATING ENERGY");
    2104           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE LIGHTS TOTAL HEATING ENERGY");
    2105           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE ELECTRIC EQUIPMENT TOTAL HEATING ENERGY");
    2106           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE GAS EQUIPMENT TOTAL HEATING ENERGY");
    2107           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE HOT WATER EQUIPMENT TOTAL HEATING ENERGY");
    2108           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE STEAM EQUIPMENT TOTAL HEATING ENERGY");
    2109           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE OTHER EQUIPMENT TOTAL HEATING ENERGY");
    2110           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT GAIN ENERGY");
    2111           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT LOSS ENERGY");
    2112              : 
    2113          424 :     } else if (reportName == "PEAKSPACEGAINSMONTHLY") {
    2114           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE PEOPLE TOTAL HEATING ENERGY");
    2115           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE LIGHTS TOTAL HEATING ENERGY");
    2116           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE ELECTRIC EQUIPMENT TOTAL HEATING ENERGY");
    2117           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE GAS EQUIPMENT TOTAL HEATING ENERGY");
    2118           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE HOT WATER EQUIPMENT TOTAL HEATING ENERGY");
    2119           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE STEAM EQUIPMENT TOTAL HEATING ENERGY");
    2120           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE OTHER EQUIPMENT TOTAL HEATING ENERGY");
    2121           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT GAIN ENERGY");
    2122           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT LOSS ENERGY");
    2123              : 
    2124          418 :     } else if (reportName == "SPACEGAINCOMPONENTSATCOOLINGPEAKMONTHLY") {
    2125           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE AIR SYSTEM SENSIBLE COOLING RATE");
    2126           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE PEOPLE TOTAL HEATING ENERGY");
    2127           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE LIGHTS TOTAL HEATING ENERGY");
    2128           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE ELECTRIC EQUIPMENT TOTAL HEATING ENERGY");
    2129           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE GAS EQUIPMENT TOTAL HEATING ENERGY");
    2130           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE HOT WATER EQUIPMENT TOTAL HEATING ENERGY");
    2131           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE STEAM EQUIPMENT TOTAL HEATING ENERGY");
    2132           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE OTHER EQUIPMENT TOTAL HEATING ENERGY");
    2133           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT GAIN ENERGY");
    2134           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT LOSS ENERGY");
    2135              : 
    2136          412 :     } else if (reportName == "SETPOINTSNOTMETWITHTEMPERATURESMONTHLY") {
    2137           28 :         addRecordToOutputVariableStructure(state, "*", "ZONE HEATING SETPOINT NOT MET TIME");
    2138           28 :         addRecordToOutputVariableStructure(state, "*", "ZONE MEAN AIR TEMPERATURE");
    2139           28 :         addRecordToOutputVariableStructure(state, "*", "ZONE HEATING SETPOINT NOT MET WHILE OCCUPIED TIME");
    2140           28 :         addRecordToOutputVariableStructure(state, "*", "ZONE COOLING SETPOINT NOT MET TIME");
    2141           28 :         addRecordToOutputVariableStructure(state, "*", "ZONE COOLING SETPOINT NOT MET WHILE OCCUPIED TIME");
    2142              : 
    2143          405 :     } else if (reportName == "COMFORTREPORTSIMPLE55MONTHLY") {
    2144           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE THERMAL COMFORT ASHRAE 55 SIMPLE MODEL SUMMER CLOTHES NOT COMFORTABLE TIME");
    2145           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE MEAN AIR TEMPERATURE");
    2146           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE THERMAL COMFORT ASHRAE 55 SIMPLE MODEL WINTER CLOTHES NOT COMFORTABLE TIME");
    2147           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE THERMAL COMFORT ASHRAE 55 SIMPLE MODEL SUMMER OR WINTER CLOTHES NOT COMFORTABLE TIME");
    2148              : 
    2149          399 :     } else if (reportName == "UNGLAZEDTRANSPIREDSOLARCOLLECTORSUMMARYMONTHLY") {
    2150           24 :         addRecordToOutputVariableStructure(state, "*", "SOLAR COLLECTOR SYSTEM EFFICIENCY");
    2151           24 :         addRecordToOutputVariableStructure(state, "*", "SOLAR COLLECTOR OUTSIDE FACE SUCTION VELOCITY");
    2152           24 :         addRecordToOutputVariableStructure(state, "*", "SOLAR COLLECTOR SENSIBLE HEATING RATE");
    2153              : 
    2154          393 :     } else if (reportName == "OCCUPANTCOMFORTDATASUMMARYMONTHLY") {
    2155           24 :         addRecordToOutputVariableStructure(state, "*", "PEOPLE OCCUPANT COUNT");
    2156           24 :         addRecordToOutputVariableStructure(state, "*", "PEOPLE AIR TEMPERATURE");
    2157           24 :         addRecordToOutputVariableStructure(state, "*", "PEOPLE AIR RELATIVE HUMIDITY");
    2158           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE THERMAL COMFORT FANGER MODEL PMV");
    2159           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE THERMAL COMFORT FANGER MODEL PPD");
    2160              : 
    2161          387 :     } else if (reportName == "CHILLERREPORTMONTHLY") {
    2162           24 :         addRecordToOutputVariableStructure(state, "*", "CHILLER ELECTRICITY ENERGY"); // on meter
    2163           24 :         addRecordToOutputVariableStructure(state, "*", "CHILLER ELECTRICITY RATE");
    2164           24 :         addRecordToOutputVariableStructure(state, "*", "CHILLER EVAPORATOR COOLING ENERGY");      // on meter
    2165           24 :         addRecordToOutputVariableStructure(state, "*", "CHILLER CONDENSER HEAT TRANSFER ENERGY"); // on meter
    2166           24 :         addRecordToOutputVariableStructure(state, "*", "CHILLER COP");
    2167              : 
    2168          381 :     } else if (reportName == "TOWERREPORTMONTHLY") {
    2169           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER FAN ELECTRICITY ENERGY"); // on meter
    2170           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER FAN ELECTRICITY RATE");
    2171           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER HEAT TRANSFER RATE");
    2172           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER INLET TEMPERATURE");
    2173           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER OUTLET TEMPERATURE");
    2174           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER MASS FLOW RATE");
    2175              : 
    2176          375 :     } else if (reportName == "BOILERREPORTMONTHLY") {
    2177           24 :         addRecordToOutputVariableStructure(state, "*", "BOILER HEATING ENERGY");         // on meter
    2178           24 :         addRecordToOutputVariableStructure(state, "*", "BOILER NATURALGAS CONSUMPTION"); // on meter
    2179           24 :         addRecordToOutputVariableStructure(state, "*", "BOILER HEATING ENERGY");         // on meter
    2180           24 :         addRecordToOutputVariableStructure(state, "*", "BOILER HEATING RATE");
    2181           24 :         addRecordToOutputVariableStructure(state, "*", "BOILER NATURALGAS CONSUMPTION RATE");
    2182           24 :         addRecordToOutputVariableStructure(state, "*", "BOILER INLET TEMPERATURE");
    2183           24 :         addRecordToOutputVariableStructure(state, "*", "BOILER OUTLET TEMPERATURE");
    2184           24 :         addRecordToOutputVariableStructure(state, "*", "BOILER MASS FLOW RATE");
    2185           24 :         addRecordToOutputVariableStructure(state, "*", "BOILER ANCILLARY ELECTRICITY RATE");
    2186              : 
    2187          369 :     } else if (reportName == "DXREPORTMONTHLY") {
    2188           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL TOTAL COOLING ENERGY"); // on meter
    2189           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL ELECTRICITY ENERGY");   // on meter
    2190           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL SENSIBLE COOLING ENERGY");
    2191           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL LATENT COOLING ENERGY");
    2192           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL CRANKCASE HEATER ELECTRICITY ENERGY");
    2193           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL RUNTIME FRACTION");
    2194           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL TOTAL COOLING RATE");
    2195           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL SENSIBLE COOLING RATE");
    2196           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL LATENT COOLING RATE");
    2197           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL ELECTRICITY RATE");
    2198           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL CRANKCASE HEATER ELECTRICITY RATE");
    2199              : 
    2200          363 :     } else if (reportName == "WINDOWREPORTMONTHLY") {
    2201           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED SOLAR RADIATION RATE");
    2202           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED BEAM SOLAR RADIATION RATE");
    2203           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED DIFFUSE SOLAR RADIATION RATE");
    2204           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW HEAT GAIN RATE");
    2205           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW HEAT LOSS RATE");
    2206           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW INSIDE FACE GLAZING CONDENSATION STATUS");
    2207           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE SHADING DEVICE IS ON TIME FRACTION");
    2208           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE STORM WINDOW ON OFF STATUS");
    2209              : 
    2210          357 :     } else if (reportName == "WINDOWENERGYREPORTMONTHLY") {
    2211           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED SOLAR RADIATION ENERGY");
    2212           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED BEAM SOLAR RADIATION ENERGY");
    2213           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED DIFFUSE SOLAR RADIATION ENERGY");
    2214           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW HEAT GAIN ENERGY");
    2215           24 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW HEAT LOSS ENERGY");
    2216              : 
    2217          351 :     } else if (reportName == "WINDOWZONESUMMARYMONTHLY") {
    2218           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOWS TOTAL HEAT GAIN RATE");
    2219           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOWS TOTAL HEAT LOSS RATE");
    2220           24 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE WINDOWS TOTAL TRANSMITTED SOLAR RADIATION RATE");
    2221           24 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE EXTERIOR WINDOWS TOTAL TRANSMITTED BEAM SOLAR RADIATION RATE");
    2222           24 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE EXTERIOR WINDOWS TOTAL TRANSMITTED DIFFUSE SOLAR RADIATION RATE");
    2223           24 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE INTERIOR WINDOWS TOTAL TRANSMITTED DIFFUSE SOLAR RADIATION RATE");
    2224           24 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE INTERIOR WINDOWS TOTAL TRANSMITTED BEAM SOLAR RADIATION RATE");
    2225              : 
    2226          345 :     } else if (reportName == "WINDOWENERGYZONESUMMARYMONTHLY") {
    2227           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOWS TOTAL HEAT GAIN ENERGY");
    2228           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOWS TOTAL HEAT LOSS ENERGY");
    2229           24 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE WINDOWS TOTAL TRANSMITTED SOLAR RADIATION ENERGY");
    2230           24 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE EXTERIOR WINDOWS TOTAL TRANSMITTED BEAM SOLAR RADIATION ENERGY");
    2231           24 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE EXTERIOR WINDOWS TOTAL TRANSMITTED DIFFUSE SOLAR RADIATION ENERGY");
    2232           24 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE INTERIOR WINDOWS TOTAL TRANSMITTED DIFFUSE SOLAR RADIATION ENERGY");
    2233           24 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE INTERIOR WINDOWS TOTAL TRANSMITTED BEAM SOLAR RADIATION ENERGY");
    2234              : 
    2235          339 :     } else if (reportName == "AVERAGEOUTDOORCONDITIONSMONTHLY") {
    2236           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2237           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2238           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DEWPOINT TEMPERATURE");
    2239           24 :         addRecordToOutputVariableStructure(state, "*", "SITE WIND SPEED");
    2240           24 :         addRecordToOutputVariableStructure(state, "*", "SITE SKY TEMPERATURE");
    2241           24 :         addRecordToOutputVariableStructure(state, "*", "SITE DIFFUSE SOLAR RADIATION RATE PER AREA");
    2242           24 :         addRecordToOutputVariableStructure(state, "*", "SITE DIRECT SOLAR RADIATION RATE PER AREA");
    2243           24 :         addRecordToOutputVariableStructure(state, "*", "SITE RAIN STATUS");
    2244              : 
    2245          333 :     } else if (reportName == "OUTDOORCONDITIONSMAXIMUMDRYBULBMONTHLY") {
    2246           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2247           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2248           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DEWPOINT TEMPERATURE");
    2249           24 :         addRecordToOutputVariableStructure(state, "*", "SITE WIND SPEED");
    2250           24 :         addRecordToOutputVariableStructure(state, "*", "SITE SKY TEMPERATURE");
    2251           24 :         addRecordToOutputVariableStructure(state, "*", "SITE DIFFUSE SOLAR RADIATION RATE PER AREA");
    2252           24 :         addRecordToOutputVariableStructure(state, "*", "SITE DIRECT SOLAR RADIATION RATE PER AREA");
    2253              : 
    2254          327 :     } else if (reportName == "OUTDOORCONDITIONSMINIMUMDRYBULBMONTHLY") {
    2255           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2256           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2257           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DEWPOINT TEMPERATURE");
    2258           24 :         addRecordToOutputVariableStructure(state, "*", "SITE WIND SPEED");
    2259           24 :         addRecordToOutputVariableStructure(state, "*", "SITE SKY TEMPERATURE");
    2260           24 :         addRecordToOutputVariableStructure(state, "*", "SITE DIFFUSE SOLAR RADIATION RATE PER AREA");
    2261           24 :         addRecordToOutputVariableStructure(state, "*", "SITE DIRECT SOLAR RADIATION RATE PER AREA");
    2262              : 
    2263          321 :     } else if (reportName == "OUTDOORCONDITIONSMAXIMUMWETBULBMONTHLY") {
    2264           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2265           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2266           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DEWPOINT TEMPERATURE");
    2267           24 :         addRecordToOutputVariableStructure(state, "*", "SITE WIND SPEED");
    2268           24 :         addRecordToOutputVariableStructure(state, "*", "SITE SKY TEMPERATURE");
    2269           24 :         addRecordToOutputVariableStructure(state, "*", "SITE DIFFUSE SOLAR RADIATION RATE PER AREA");
    2270           24 :         addRecordToOutputVariableStructure(state, "*", "SITE DIRECT SOLAR RADIATION RATE PER AREA");
    2271              : 
    2272          315 :     } else if (reportName == "OUTDOORCONDITIONSMAXIMUMDEWPOINTMONTHLY") {
    2273           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DEWPOINT TEMPERATURE");
    2274           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2275           24 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2276           24 :         addRecordToOutputVariableStructure(state, "*", "SITE WIND SPEED");
    2277           24 :         addRecordToOutputVariableStructure(state, "*", "SITE SKY TEMPERATURE");
    2278           24 :         addRecordToOutputVariableStructure(state, "*", "SITE DIFFUSE SOLAR RADIATION RATE PER AREA");
    2279           24 :         addRecordToOutputVariableStructure(state, "*", "SITE DIRECT SOLAR RADIATION RATE PER AREA");
    2280              : 
    2281          309 :     } else if (reportName == "OUTDOORGROUNDCONDITIONSMONTHLY") {
    2282           24 :         addRecordToOutputVariableStructure(state, "*", "SITE GROUND TEMPERATURE");
    2283           24 :         addRecordToOutputVariableStructure(state, "*", "SITE SURFACE GROUND TEMPERATURE");
    2284           24 :         addRecordToOutputVariableStructure(state, "*", "SITE DEEP GROUND TEMPERATURE");
    2285           24 :         addRecordToOutputVariableStructure(state, "*", "SITE MAINS WATER TEMPERATURE");
    2286           24 :         addRecordToOutputVariableStructure(state, "*", "SITE GROUND REFLECTED SOLAR RADIATION RATE PER AREA");
    2287           24 :         addRecordToOutputVariableStructure(state, "*", "SITE SNOW ON GROUND STATUS");
    2288              : 
    2289          303 :     } else if (reportName == "WINDOWACREPORTMONTHLY") {
    2290           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER TOTAL COOLING ENERGY");
    2291           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER ELECTRICITY ENERGY");
    2292           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER TOTAL COOLING ENERGY");
    2293           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER SENSIBLE COOLING ENERGY");
    2294           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER LATENT COOLING ENERGY");
    2295           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER TOTAL COOLING RATE");
    2296           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER SENSIBLE COOLING RATE");
    2297           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER LATENT COOLING RATE");
    2298           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER ELECTRICITY RATE");
    2299              : 
    2300          297 :     } else if (reportName == "WATERHEATERREPORTMONTHLY") {
    2301           24 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER TOTAL DEMAND HEAT TRANSFER ENERGY");
    2302           24 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER USE SIDE HEAT TRANSFER ENERGY");
    2303           24 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER BURNER HEATING ENERGY");
    2304           24 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER NATURALGAS CONSUMPTION");
    2305           24 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER TOTAL DEMAND HEAT TRANSFER ENERGY");
    2306           24 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER LOSS DEMAND ENERGY");
    2307           24 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER HEAT LOSS ENERGY");
    2308           24 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER TANK TEMPERATURE");
    2309           24 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER HEAT RECOVERY SUPPLY ENERGY");
    2310           24 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER SOURCE SIDE HEAT TRANSFER ENERGY");
    2311              : 
    2312          291 :     } else if (reportName == "GENERATORREPORTMONTHLY") {
    2313           24 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR PRODUCED AC ELECTRICITY ENERGY");
    2314           24 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR DIESEL CONSUMPTION");
    2315           24 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR NATURALGAS CONSUMPTION");
    2316           24 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR PRODUCED AC ELECTRICITY ENERGY");
    2317           24 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR TOTAL HEAT RECOVERY");
    2318           24 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR JACKET HEAT RECOVERY ENERGY");
    2319           24 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR LUBE HEAT RECOVERY");
    2320           24 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR EXHAUST HEAT RECOVERY ENERGY");
    2321           24 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR EXHAUST AIR TEMPERATURE");
    2322              : 
    2323          285 :     } else if (reportName == "DAYLIGHTINGREPORTMONTHLY") {
    2324           24 :         addRecordToOutputVariableStructure(state, "*", "SITE EXTERIOR BEAM NORMAL ILLUMINANCE");
    2325           24 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING LIGHTING POWER MULTIPLIER");
    2326           24 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING LIGHTING POWER MULTIPLIER");
    2327           24 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 1 ILLUMINANCE");
    2328           24 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 1 GLARE INDEX");
    2329           24 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 1 GLARE INDEX SETPOINT EXCEEDED TIME");
    2330           24 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 1 DAYLIGHT ILLUMINANCE SETPOINT EXCEEDED TIME");
    2331           24 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 2 ILLUMINANCE");
    2332           24 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 2 GLARE INDEX");
    2333           24 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 2 GLARE INDEX SETPOINT EXCEEDED TIME");
    2334           24 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 2 DAYLIGHT ILLUMINANCE SETPOINT EXCEEDED TIME");
    2335              : 
    2336          279 :     } else if (reportName == "COILREPORTMONTHLY") {
    2337           24 :         addRecordToOutputVariableStructure(state, "*", "HEATING COIL HEATING ENERGY");
    2338           24 :         addRecordToOutputVariableStructure(state, "*", "HEATING COIL HEATING RATE");
    2339           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL SENSIBLE COOLING ENERGY");
    2340           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL TOTAL COOLING ENERGY");
    2341           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL TOTAL COOLING RATE");
    2342           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL SENSIBLE COOLING RATE");
    2343           24 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL WETTED AREA FRACTION");
    2344              : 
    2345          273 :     } else if (reportName == "PLANTLOOPDEMANDREPORTMONTHLY") {
    2346           24 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE COOLING DEMAND RATE");
    2347           24 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE HEATING DEMAND RATE");
    2348              : 
    2349          267 :     } else if (reportName == "FANREPORTMONTHLY") {
    2350           24 :         addRecordToOutputVariableStructure(state, "*", "FAN ELECTRICITY ENERGY");
    2351           24 :         addRecordToOutputVariableStructure(state, "*", "FAN RISE IN AIR TEMPERATURE");
    2352           24 :         addRecordToOutputVariableStructure(state, "*", "FAN ELECTRICITY RATE");
    2353              : 
    2354          261 :     } else if (reportName == "PUMPREPORTMONTHLY") {
    2355           24 :         addRecordToOutputVariableStructure(state, "*", "PUMP ELECTRICITY ENERGY");
    2356           24 :         addRecordToOutputVariableStructure(state, "*", "PUMP FLUID HEAT GAIN ENERGY");
    2357           24 :         addRecordToOutputVariableStructure(state, "*", "PUMP ELECTRICITY RATE");
    2358           24 :         addRecordToOutputVariableStructure(state, "*", "PUMP SHAFT POWER");
    2359           24 :         addRecordToOutputVariableStructure(state, "*", "PUMP FLUID HEAT GAIN RATE");
    2360           24 :         addRecordToOutputVariableStructure(state, "*", "PUMP OUTLET TEMPERATURE");
    2361           24 :         addRecordToOutputVariableStructure(state, "*", "PUMP MASS FLOW RATE");
    2362              : 
    2363          255 :     } else if (reportName == "CONDLOOPDEMANDREPORTMONTHLY") {
    2364           24 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE COOLING DEMAND RATE");
    2365           24 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE HEATING DEMAND RATE");
    2366           24 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE INLET TEMPERATURE");
    2367           24 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE OUTLET TEMPERATURE");
    2368              : 
    2369          249 :     } else if (reportName == "ZONETEMPERATUREOSCILLATIONREPORTMONTHLY") {
    2370           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE OSCILLATING TEMPERATURES TIME");
    2371           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE PEOPLE OCCUPANT COUNT");
    2372              : 
    2373          243 :     } else if (reportName == "AIRLOOPSYSTEMENERGYANDWATERUSEMONTHLY") {
    2374           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HOT WATER ENERGY");
    2375           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM STEAM ENERGY");
    2376           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM CHILLED WATER ENERGY");
    2377           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM ELECTRICITY ENERGY");
    2378           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM NATURALGAS ENERGY");
    2379           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM WATER VOLUME");
    2380              : 
    2381          237 :     } else if (reportName == "AIRLOOPSYSTEMCOMPONENTLOADSMONTHLY") {
    2382           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM FAN AIR HEATING ENERGY");
    2383           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM COOLING COIL TOTAL COOLING ENERGY");
    2384           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEATING COIL TOTAL HEATING ENERGY");
    2385           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEAT EXCHANGER TOTAL HEATING ENERGY");
    2386           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEAT EXCHANGER TOTAL COOLING ENERGY");
    2387           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HUMIDIFIER TOTAL HEATING ENERGY");
    2388           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM EVAPORATIVE COOLER TOTAL COOLING ENERGY");
    2389           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM DESICCANT DEHUMIDIFIER TOTAL COOLING ENERGY");
    2390              : 
    2391          231 :     } else if (reportName == "AIRLOOPSYSTEMCOMPONENTENERGYUSEMONTHLY") {
    2392           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM FAN ELECTRICITY ENERGY");
    2393           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEATING COIL HOT WATER ENERGY");
    2394           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM COOLING COIL CHILLED WATER ENERGY");
    2395           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM DX HEATING COIL ELECTRICITY ENERGY");
    2396           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM DX COOLING COIL ELECTRICITY ENERGY");
    2397           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEATING COIL ELECTRICITY ENERGY");
    2398           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEATING COIL NATURALGAS ENERGY");
    2399           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEATING COIL STEAM ENERGY");
    2400           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HUMIDIFIER ELECTRICITY ENERGY");
    2401           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM EVAPORATIVE COOLER ELECTRICITY ENERGY");
    2402           24 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM DESICCANT DEHUMIDIFIER ELECTRICITY ENERGY");
    2403              : 
    2404          225 :     } else if (reportName == "MECHANICALVENTILATIONLOADSMONTHLY") {
    2405           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION NO LOAD HEAT REMOVAL ENERGY");
    2406           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION COOLING LOAD INCREASE ENERGY");
    2407           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION COOLING LOAD INCREASE DUE TO OVERHEATING ENERGY");
    2408           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION COOLING LOAD DECREASE ENERGY");
    2409           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION NO LOAD HEAT ADDITION ENERGY");
    2410           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION HEATING LOAD INCREASE ENERGY");
    2411           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION HEATING LOAD INCREASE DUE TO OVERCOOLING ENERGY");
    2412           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION HEATING LOAD DECREASE ENERGY");
    2413           24 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION AIR CHANGES PER HOUR");
    2414              : 
    2415          219 :     } else if (reportName == "HEATEMISSIONSREPORTMONTHLY") {
    2416              :         // Place holder
    2417           24 :         addRecordToOutputVariableStructure(state, "*", "Site Total Surface Heat Emission to Air");
    2418           24 :         addRecordToOutputVariableStructure(state, "*", "Site Total Zone Exfiltration Heat Loss");
    2419           24 :         addRecordToOutputVariableStructure(state, "*", "Site Total Zone Exhaust Air Heat Loss");
    2420           24 :         addRecordToOutputVariableStructure(state, "*", "Air System Relief Air Total Heat Loss Energy");
    2421           24 :         addRecordToOutputVariableStructure(state, "*", "HVAC System Total Heat Rejection Energy");
    2422              :     } else {
    2423              :     }
    2424          448 : }
    2425              : 
    2426         2895 : void InputProcessor::addRecordToOutputVariableStructure(EnergyPlusData &state, std::string const &KeyValue, std::string const &VariableName)
    2427              : {
    2428              :     // SUBROUTINE INFORMATION:
    2429              :     //       AUTHOR         Linda Lawrie
    2430              :     //       DATE WRITTEN   July 2010
    2431              :     //       MODIFIED       March 2017
    2432              :     //       RE-ENGINEERED  na
    2433              : 
    2434              :     // PURPOSE OF THIS SUBROUTINE:
    2435              :     // This routine adds a new record (if necessary) to the Output Variable
    2436              :     // reporting structure.  DataOutputs, OutputVariablesForSimulation
    2437              : 
    2438              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2439              :     std::string::size_type vnameLen; // if < length, there were units on the line/name
    2440              : 
    2441         2895 :     std::string::size_type const rbpos = index(VariableName, '[');
    2442         2895 :     if (rbpos == std::string::npos) {
    2443         2895 :         vnameLen = len_trim(VariableName);
    2444              :     } else {
    2445            0 :         vnameLen = len_trim(VariableName.substr(0, rbpos));
    2446              :     }
    2447              : 
    2448         2895 :     std::string const VarName(VariableName.substr(0, vnameLen));
    2449              : 
    2450         2895 :     auto const found = state.dataOutput->OutputVariablesForSimulation.find(VarName);
    2451         2895 :     if (found == state.dataOutput->OutputVariablesForSimulation.end()) {
    2452              :         std::map<std::string,
    2453              :                  DataOutputs::OutputReportingVariables,
    2454              :                  // Util::case_insensitive_hasher,
    2455              :                  Util::case_insensitive_comparator>
    2456         2231 :             data;
    2457              :         // data.reserve(32);
    2458         2231 :         data.emplace(KeyValue, DataOutputs::OutputReportingVariables(state, KeyValue, VarName));
    2459         2231 :         state.dataOutput->OutputVariablesForSimulation.emplace(VarName, std::move(data));
    2460         2231 :     } else {
    2461          664 :         found->second.emplace(KeyValue, DataOutputs::OutputReportingVariables(state, KeyValue, VarName));
    2462              :     }
    2463         2895 :     state.dataOutput->NumConsideredOutputVariables++;
    2464         2895 : }
    2465              : 
    2466              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1