LCOV - code coverage report
Current view: top level - EnergyPlus/InputProcessing - InputProcessor.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 88.7 % 1471 1305
Test Date: 2025-06-03 15:18:44 Functions: 87.0 % 46 40

            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       168084 : 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       168084 :     static const auto json_schema = json::from_cbor(EmbeddedEpJSONSchema::embeddedEpJSONSchema()); // (AUTO_OK_OBJ)
     112       168084 :     return json_schema;
     113              : }
     114              : 
     115          801 : InputProcessor::InputProcessor() : idf_parser(std::make_unique<IdfParser>()), data(std::make_unique<DataStorage>())
     116              : {
     117          801 :     const json &loc = schema()["properties"];
     118          801 :     caseInsensitiveObjectMap.reserve(loc.size());
     119       680850 :     for (auto it = loc.begin(); it != loc.end(); ++it) {
     120       680049 :         caseInsensitiveObjectMap.emplace(convertToUpper(it.key()), it.key());
     121          801 :     }
     122          801 :     idf_parser = std::make_unique<IdfParser>();
     123          801 :     data = std::make_unique<DataStorage>();
     124          801 :     epJSON = json::object();
     125              :     //    objectCacheMap.clear();
     126              :     //    unusedInputs.clear();
     127          801 :     validation = std::make_unique<Validation>(&schema());
     128          801 : }
     129              : 
     130          801 : std::unique_ptr<InputProcessor> InputProcessor::factory()
     131              : {
     132          801 :     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       464210 : json const &InputProcessor::getPatternProperties(EnergyPlusData &state, json const &schema_obj)
     171              : {
     172       464210 :     std::string pattern_property;
     173       464210 :     auto const &pattern_properties = schema_obj["patternProperties"];
     174       928420 :     int dot_star_present = pattern_properties.count(".*");
     175       464210 :     int no_whitespace_present = pattern_properties.count(R"(^.*\S.*$)");
     176       464210 :     if (dot_star_present) {
     177        88481 :         pattern_property = ".*";
     178       375729 :     } else if (no_whitespace_present) {
     179       375729 :         pattern_property = R"(^.*\S.*$)";
     180              :     } else {
     181            0 :         ShowFatalError(state, R"(The patternProperties value is not a valid choice (".*", "^.*\S.*$"))");
     182              :     }
     183       464210 :     auto const &schema_obj_props = pattern_properties[pattern_property]["properties"];
     184       464210 :     return schema_obj_props;
     185       464210 : }
     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            0 : std::vector<std::string> const &InputProcessor::validationErrors()
     199              : {
     200            0 :     return validation->errors();
     201              : }
     202              : 
     203            0 : std::vector<std::string> const &InputProcessor::validationWarnings()
     204              : {
     205            0 :     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          801 : void InputProcessor::initializeMaps()
     218              : {
     219          801 :     unusedInputs.clear();
     220          801 :     objectCacheMap.clear();
     221          801 :     objectCacheMap.reserve(epJSON.size());
     222         1602 :     auto const &schema_properties = schema().at("properties");
     223              : 
     224        58830 :     for (auto epJSON_iter = epJSON.begin(); epJSON_iter != epJSON.end(); ++epJSON_iter) {
     225        58029 :         auto const &objects = epJSON_iter.value();
     226        58029 :         auto const &objectType = epJSON_iter.key();
     227        58029 :         ObjectCache objectCache;
     228        58029 :         objectCache.inputObjectIterators.reserve(objects.size());
     229       361983 :         for (auto epJSON_obj_iter = objects.begin(); epJSON_obj_iter != objects.end(); ++epJSON_obj_iter) {
     230       303954 :             objectCache.inputObjectIterators.emplace_back(epJSON_obj_iter);
     231       303954 :             unusedInputs.emplace(objectType, epJSON_obj_iter.key());
     232        58029 :         }
     233        58029 :         auto const schema_iter = schema_properties.find(objectType);
     234        58029 :         objectCache.schemaIterator = schema_iter;
     235        58029 :         objectCacheMap.emplace(schema_iter.key(), objectCache);
     236        58830 :     }
     237          801 : }
     238              : 
     239        34157 : void InputProcessor::markObjectAsUsed(const std::string &objectType, const std::string &objectName)
     240              : {
     241        34157 :     auto const find_unused = unusedInputs.find({objectType, objectName});
     242        34157 :     if (find_unused != unusedInputs.end()) {
     243        34150 :         unusedInputs.erase(find_unused);
     244              :     }
     245        34157 : }
     246              : 
     247            0 : void cleanEPJSON(json &epjson)
     248              : {
     249            0 :     if (epjson.type() == json::value_t::object) {
     250            0 :         epjson.erase("idf_order");
     251            0 :         epjson.erase("idf_max_fields");
     252            0 :         epjson.erase("idf_max_extensible_fields");
     253            0 :         for (auto it = epjson.begin(); it != epjson.end(); ++it) {
     254            0 :             cleanEPJSON(epjson[it.key()]);
     255            0 :         }
     256              :     }
     257            0 : }
     258              : 
     259          801 : void InputProcessor::processInput(EnergyPlusData &state)
     260              : {
     261          801 :     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          801 :         if (!state.dataGlobal->isEpJSON) {
     268          800 :             auto input_file = FileSystem::readFile(state.dataStrGlobals->inputFilePath); // (AUTO_OK_OBJ)
     269              : 
     270          800 :             bool success = true;
     271          800 :             epJSON = idf_parser->decode(input_file, schema(), success);
     272              : 
     273          800 :             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          800 :         } else {
     281            1 :             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          801 :     bool is_valid = validation->validate(epJSON);
     289          801 :     bool hasErrors = processErrors(state);
     290          801 :     bool versionMatch = checkVersionMatch(state);
     291          801 :     bool unsupportedFound = checkForUnsupportedObjects(state);
     292              : 
     293          801 :     if (!is_valid || hasErrors || unsupportedFound) {
     294            0 :         ShowFatalError(state, "Errors occurred on processing input file. Preceding condition(s) cause termination.");
     295              :     }
     296              : 
     297          801 :     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          801 :     initializeMaps();
     309              : 
     310          801 :     int MaxArgs = 0;
     311          801 :     int MaxAlpha = 0;
     312          801 :     int MaxNumeric = 0;
     313          801 :     getMaxSchemaArgs(MaxArgs, MaxAlpha, MaxNumeric);
     314              : 
     315          801 :     state.dataIPShortCut->cAlphaFieldNames.allocate(MaxAlpha);
     316          801 :     state.dataIPShortCut->cAlphaArgs.allocate(MaxAlpha);
     317          801 :     state.dataIPShortCut->lAlphaFieldBlanks.dimension(MaxAlpha, false);
     318          801 :     state.dataIPShortCut->cNumericFieldNames.allocate(MaxNumeric);
     319          801 :     state.dataIPShortCut->rNumericArgs.dimension(MaxNumeric, 0.0);
     320          801 :     state.dataIPShortCut->lNumericFieldBlanks.dimension(MaxNumeric, false);
     321              : 
     322          801 :     reportIDFRecordsStats(state);
     323              : }
     324              : 
     325          801 : bool InputProcessor::checkVersionMatch(EnergyPlusData &state)
     326              : {
     327              :     using DataStringGlobals::MatchVersion;
     328         1602 :     auto it = epJSON.find("Version");
     329          801 :     if (it != epJSON.end()) {
     330         1602 :         for (auto const &version : it.value()) {
     331          801 :             std::string v = version["version_identifier"].get<std::string>();
     332          801 :             if (v.empty()) {
     333            0 :                 ShowWarningError(state, "Input errors occurred and version ID was left blank, verify file version");
     334              :             } else {
     335          801 :                 std::string::size_type const lenVer(len(MatchVersion));
     336              :                 int Which;
     337          801 :                 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          801 :                     Which = static_cast<int>(index(v, MatchVersion));
     341              :                 }
     342          801 :                 if (Which != 0) {
     343            0 :                     ShowWarningError(state, "Version: in IDF=\"" + v + "\" not the same as expected=\"" + MatchVersion + "\"");
     344            0 :                     return false;
     345              :                 }
     346              :             }
     347         1602 :         }
     348              :     }
     349          801 :     return true;
     350          801 : }
     351              : 
     352          801 : bool InputProcessor::checkForUnsupportedObjects(EnergyPlusData &state)
     353              : {
     354          801 :     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          801 :     bool objectFound = false;
     390          801 :     std::string objectType;
     391        52866 :     for (size_t count = 0; count < hvacTemplateObjects.size(); ++count) {
     392        25632 :         objectType = hvacTemplateObjects[count];
     393        25632 :         auto it = epJSON.find(objectType);
     394        25632 :         if (it != epJSON.end()) {
     395            0 :             objectFound = true;
     396            0 :             break;
     397              :         }
     398        25632 :     }
     399          801 :     if (objectFound) {
     400            0 :         ShowSevereError(state, "HVACTemplate:* objects found. These objects are not supported directly by EnergyPlus.");
     401            0 :         ShowContinueError(state, "You must run the ExpandObjects program on this input.");
     402            0 :         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          801 :     objectFound = false;
     433        43254 :     for (size_t count = 0; count < groundHTObjects.size(); ++count) {
     434        20826 :         objectType = groundHTObjects[count];
     435        20826 :         auto it = epJSON.find(objectType);
     436        20826 :         if (it != epJSON.end()) {
     437            0 :             objectFound = true;
     438            0 :             break;
     439              :         }
     440        20826 :     }
     441          801 :     if (objectFound) {
     442            0 :         ShowSevereError(state, "GroundHeatTransfer:* objects found. These objects are not supported directly by EnergyPlus.");
     443            0 :         ShowContinueError(state, "You must run the ExpandObjects program on this input.");
     444            0 :         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          801 :     objectFound = false;
     451         8010 :     for (size_t count = 0; count < parametricObjects.size(); ++count) {
     452         3204 :         objectType = parametricObjects[count];
     453         3204 :         auto it = epJSON.find(objectType);
     454         3204 :         if (it != epJSON.end()) {
     455            0 :             objectFound = true;
     456            0 :             break;
     457              :         }
     458         3204 :     }
     459          801 :     if (objectFound) {
     460            0 :         ShowSevereError(state, "Parametric:* objects found. These objects are not supported directly by EnergyPlus.");
     461            0 :         ShowContinueError(state, "You must run the ParametricPreprocesor program on this input.");
     462            0 :         errorsFound = true;
     463              :     }
     464          801 :     return errorsFound;
     465          801 : }
     466              : 
     467          801 : bool InputProcessor::processErrors(EnergyPlusData &state)
     468              : {
     469          801 :     for (auto const &error : idf_parser->errors()) {
     470            0 :         ShowSevereError(state, error);
     471          801 :     }
     472          801 :     for (auto const &warning : idf_parser->warnings()) {
     473            0 :         ShowWarningError(state, warning);
     474          801 :     }
     475          801 :     for (auto const &error : validation->errors()) {
     476            0 :         ShowSevereError(state, error);
     477          801 :     }
     478          801 :     for (auto const &warning : validation->warnings()) {
     479            0 :         ShowWarningError(state, warning);
     480          801 :     }
     481              : 
     482          801 :     bool has_errors = validation->hasErrors() || idf_parser->hasErrors();
     483              : 
     484          801 :     return has_errors;
     485              : }
     486              : 
     487         6356 : 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         6356 :     auto const SectionWord_iter = epJSON.find(SectionWord);
     499         6356 :     if (SectionWord_iter == epJSON.end()) {
     500         6356 :         return -1;
     501              :     }
     502            0 :     return static_cast<int>(SectionWord_iter.value().size());
     503         6356 : }
     504              : 
     505       466413 : 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       932826 :     auto const find_obj = epJSON.find(std::string(ObjectWord));
     524              : 
     525       466413 :     if (find_obj == epJSON.end()) {
     526       349228 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(ObjectWord));
     527       349228 :         if (tmp_umit == caseInsensitiveObjectMap.end() || epJSON.find(tmp_umit->second) == epJSON.end()) {
     528       347755 :             return 0;
     529              :         }
     530         1473 :         return static_cast<int>(epJSON[tmp_umit->second].size());
     531       349228 :     } else {
     532       117185 :         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       466413 : }
     543              : 
     544       915374 : bool InputProcessor::findDefault(std::string &default_value, json const &schema_field_obj)
     545              : {
     546       915374 :     auto const find_default = schema_field_obj.find("default");
     547       915374 :     if (find_default != schema_field_obj.end()) {
     548       224117 :         auto const &default_val = find_default.value();
     549       224117 :         if (default_val.is_string()) {
     550       224117 :             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       672351 :         if (schema_field_obj.find("retaincase") == schema_field_obj.end()) {
     560       217582 :             default_value = Util::makeUPPER(default_value);
     561              :         }
     562       224117 :         return true;
     563              :     }
     564       691257 :     return false;
     565       915374 : }
     566              : 
     567      1874648 : bool InputProcessor::findDefault(Real64 &default_value, json const &schema_field_obj)
     568              : {
     569      1874648 :     auto const find_default = schema_field_obj.find("default");
     570      1874648 :     default_value = 0;
     571      1874648 :     if (find_default != schema_field_obj.end()) {
     572       236596 :         auto const &default_val = find_default.value();
     573       236596 :         if (default_val.is_string() && !default_val.get<std::string>().empty()) {
     574              :             // autosize and autocalculate
     575        22009 :             default_value = Constant::AutoCalculate;
     576       214587 :         } else if (default_val.is_number_integer()) {
     577         2277 :             default_value = default_val.get<std::int64_t>();
     578              :         } else {
     579       212310 :             default_value = default_val.get<double>();
     580              :         }
     581       236596 :         return true;
     582              :     }
     583      1638052 :     return false;
     584      1874648 : }
     585              : 
     586            2 : bool InputProcessor::getDefaultValue(EnergyPlusData &state, std::string const &objectWord, std::string const &fieldName, Real64 &value)
     587              : {
     588            2 :     auto find_iterators = objectCacheMap.find(objectWord);
     589            2 :     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            2 :     auto const &epJSON_schema_it = find_iterators->second.schemaIterator;
     597            2 :     auto const &epJSON_schema_it_val = epJSON_schema_it.value();
     598            2 :     auto const &schema_obj_props = getPatternProperties(state, epJSON_schema_it_val);
     599            2 :     auto const &sizing_factor_schema_field_obj = schema_obj_props.at(fieldName);
     600            2 :     bool defaultFound = findDefault(value, sizing_factor_schema_field_obj);
     601            2 :     return defaultFound;
     602            2 : }
     603              : 
     604          271 : bool InputProcessor::getDefaultValue(EnergyPlusData &state, std::string const &objectWord, std::string const &fieldName, std::string &value)
     605              : {
     606          271 :     auto find_iterators = objectCacheMap.find(objectWord);
     607          271 :     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          271 :     auto const &epJSON_schema_it = find_iterators->second.schemaIterator;
     615          271 :     auto const &epJSON_schema_it_val = epJSON_schema_it.value();
     616          271 :     auto const &schema_obj_props = getPatternProperties(state, epJSON_schema_it_val);
     617          271 :     auto const &sizing_factor_schema_field_obj = schema_obj_props.at(fieldName);
     618          271 :     bool defaultFound = findDefault(value, sizing_factor_schema_field_obj);
     619          271 :     return defaultFound;
     620          271 : }
     621              : 
     622        86785 : 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        86785 :     auto const &fprops = schema_obj_props[fieldName];
     627        86785 :     assert(!fprops.empty()); // Check that field name exists in the schema for this object type
     628              : 
     629       260355 :     uc = (fprops.find("retaincase") == fprops.end());
     630              : 
     631        86785 :     auto it = ep_object.find(fieldName);
     632        86785 :     if (it != ep_object.end()) {
     633        72688 :         auto const &val = it.value();
     634        72688 :         assert(val.is_string());
     635        72688 :         if (!val.empty()) {
     636       145376 :             return uc ? Util::makeUPPER(val.get<std::string>()) : val.get<std::string>();
     637              :         }
     638              :     }
     639              : 
     640        14097 :     auto const it2 = fprops.find("default");
     641        14097 :     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        86785 : }
     651              : 
     652        69619 : 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        69619 :     auto it = ep_object.find(fieldName);
     658        69619 :     if (it != ep_object.end()) {
     659        65926 :         auto const &field_value = it.value();
     660        65926 :         if (field_value.is_number()) {
     661        63175 :             return (field_value.is_number_integer()) ? field_value.get<std::int64_t>() : field_value.get<double>();
     662         2751 :         } else if (!field_value.get<std::string>().empty()) {
     663         2751 :             return Constant::AutoCalculate; // autosize and autocalculate
     664              :         }
     665              :     }
     666              : 
     667         3693 :     auto const &schema_field_obj = schema_obj_props[fieldName];
     668         3693 :     assert(!schema_field_obj.empty()); // Check that field name exists in the schema for this object type
     669              : 
     670         3693 :     auto const find_default = schema_field_obj.find("default");
     671         3693 :     if (find_default != schema_field_obj.end()) {
     672         3285 :         auto const &default_val = find_default.value();
     673         3285 :         if (default_val.is_string()) {
     674          736 :             return (!default_val.get<std::string>().empty()) ? Constant::AutoCalculate : 0.0;
     675         2549 :         } else if (default_val.is_number_integer()) {
     676            0 :             return default_val.get<std::int64_t>();
     677              :         } else {
     678         2549 :             return default_val.get<double>();
     679              :         }
     680              :     } else {
     681          408 :         return 0.0;
     682              :     }
     683        69619 : }
     684              : 
     685        10382 : 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        10382 :     auto const &schema_field_obj = schema_obj_props[fieldName];
     692        10382 :     assert(!schema_field_obj.empty()); // Check that field name exists in the schema for this object type
     693        10382 :     bool isDefaulted = false;
     694        10382 :     int value = 0;
     695        10382 :     Real64 defaultValue = 0.0;
     696        10382 :     auto it = ep_object.find(fieldName);
     697        10382 :     if (it != ep_object.end()) {
     698        10382 :         auto const &field_value = it.value();
     699        10382 :         if (field_value.is_number_integer()) {
     700        10382 :             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        10382 :     return value;
     718        10382 : }
     719              : 
     720        20601 : const json &InputProcessor::getObjectSchemaProps(EnergyPlusData &state, std::string const &objectWord)
     721              : {
     722        41202 :     auto const &schema_properties = schema().at("properties");
     723        20601 :     const json &object_schema = schema_properties.at(objectWord);
     724        20601 :     assert(!object_schema.empty()); // If this fails, the object type does not exist in the schema
     725              : 
     726        20601 :     auto const &schema_obj_props = getPatternProperties(state, object_schema);
     727        20601 :     return schema_obj_props;
     728              : }
     729              : 
     730      2053197 : std::pair<std::string, bool> InputProcessor::getObjectItemValue(std::string const &field_value, json const &schema_field_obj)
     731              : {
     732      2053197 :     std::pair<std::string, bool> output;
     733      2053197 :     if (field_value.empty()) {
     734            0 :         findDefault(output.first, schema_field_obj);
     735            0 :         output.second = true;
     736              :     } else {
     737      2053197 :         output.first = field_value;
     738      2053197 :         output.second = false;
     739              :     }
     740      6159591 :     if (schema_field_obj.find("retaincase") == schema_field_obj.end()) {
     741      2022202 :         output.first = Util::makeUPPER(output.first);
     742              :     }
     743      2053197 :     return output;
     744            0 : }
     745              : 
     746          120 : const json &InputProcessor::getObjectInstances(std::string const &ObjType)
     747              : {
     748          120 :     return epJSON.find(ObjType).value();
     749              : }
     750              : 
     751       385307 : 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       385307 :     InputProcessor::MaxFields maxFields;
     755       385307 :     if (!state.dataGlobal->isEpJSON) {
     756       384560 :         auto found_idf_max_fields = ep_object.find("idf_max_fields");
     757       384560 :         if (found_idf_max_fields != ep_object.end()) {
     758       384560 :             maxFields.max_fields = found_idf_max_fields->get<size_t>();
     759              :         }
     760       384560 :         auto found_idf_max_extensible_fields = ep_object.find("idf_max_extensible_fields");
     761       384560 :         if (found_idf_max_extensible_fields != ep_object.end()) {
     762       384560 :             maxFields.max_extensible_fields = found_idf_max_extensible_fields->get<size_t>();
     763              :         }
     764       384560 :     } else {
     765          747 :         auto const &legacy_idd_fields = legacy_idd["fields"];
     766              :         // start with at least min_fields as the number of fields
     767          747 :         maxFields.max_fields = min_fields;
     768         5625 :         for (auto const &field : ep_object.items()) {
     769         4878 :             auto const &field_key = field.key();
     770         4878 :             if (field_key == extension_key) {
     771          242 :                 continue;
     772              :             }
     773        21090 :             for (std::size_t i = maxFields.max_fields; i < legacy_idd_fields.size(); ++i) {
     774        16454 :                 if (field_key == legacy_idd_fields[i]) {
     775          764 :                     maxFields.max_fields = (i + 1);
     776              :                 }
     777              :             }
     778          747 :         }
     779              : 
     780          747 :         auto const legacy_idd_extensibles_iter = legacy_idd.find("extensibles");
     781          747 :         if (legacy_idd_extensibles_iter != legacy_idd.end()) {
     782          244 :             auto const epJSON_extensions_array_itr = ep_object.find(extension_key);
     783          244 :             if (epJSON_extensions_array_itr != ep_object.end()) {
     784          242 :                 auto const &legacy_idd_extensibles = legacy_idd_extensibles_iter.value();
     785          242 :                 auto const &epJSON_extensions_array = epJSON_extensions_array_itr.value();
     786              : 
     787         1766 :                 for (auto const &exts : epJSON_extensions_array.items()) {
     788         1524 :                     std::size_t max_extensible_field = 0;
     789         4150 :                     for (auto const &ext : exts.value().items()) {
     790         2626 :                         auto const &ext_key = ext.key();
     791         6854 :                         for (std::size_t i = max_extensible_field; i < legacy_idd_extensibles.size(); ++i) {
     792         4228 :                             if (ext_key == legacy_idd_extensibles[i]) {
     793         2570 :                                 max_extensible_field = (i + 1);
     794              :                             }
     795              :                         }
     796         1524 :                     }
     797         1524 :                     maxFields.max_extensible_fields += max_extensible_field;
     798          242 :                 }
     799              :             }
     800          244 :         }
     801          747 :     }
     802       385307 :     return maxFields;
     803              : }
     804              : 
     805      7859590 : 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      7859590 :     bool const is_AlphaBlank = present(AlphaBlank);
     823      7859590 :     bool const is_AlphaFieldNames = present(AlphaFieldNames);
     824      7859590 :     bool const is_NumBlank = present(NumBlank);
     825      7859590 :     bool const is_NumericFieldNames = present(NumericFieldNames);
     826              : 
     827      7859590 :     std::string field_type = legacy_field_info.at("field_type").get<std::string>();
     828      7859590 :     auto const &schema_field_obj = ep_schema_object[field];
     829      7859590 :     auto it = ep_object.find(field);
     830      7859590 :     if (it != ep_object.end()) {
     831      5069841 :         auto const &field_value = it.value();
     832      5069841 :         if (field_type == "a") {
     833              :             // process alpha value
     834      2216925 :             if (field_value.is_string()) {
     835      2053197 :                 auto const value = getObjectItemValue(field_value.get<std::string>(), schema_field_obj); // (AUTO_OK_OBJ)
     836              : 
     837      2053197 :                 Alphas(alpha_index) = value.first;
     838      2053197 :                 if (is_AlphaBlank) {
     839      1205670 :                     AlphaBlank()(alpha_index) = value.second;
     840              :                 }
     841              : 
     842      2053197 :             } else {
     843       163728 :                 if (field_value.is_number_integer()) {
     844        21689 :                     i64toa(field_value.get<std::int64_t>(), s);
     845              :                 } else {
     846       142039 :                     dtoa(field_value.get<double>(), s);
     847              :                 }
     848       163728 :                 Alphas(alpha_index) = s;
     849       163728 :                 if (is_AlphaBlank) {
     850        83692 :                     AlphaBlank()(alpha_index) = false;
     851              :                 }
     852              :             }
     853      2852916 :         } else if (field_type == "n") {
     854              :             // process numeric value
     855      2852916 :             if (field_value.is_number()) {
     856      2676362 :                 if (field_value.is_number_integer()) {
     857       273082 :                     Numbers(numeric_index) = field_value.get<std::int64_t>();
     858              :                 } else {
     859      2403280 :                     Numbers(numeric_index) = field_value.get<double>();
     860              :                 }
     861      2676362 :                 if (is_NumBlank) {
     862      2490717 :                     NumBlank()(numeric_index) = false;
     863              :                 }
     864              :             } else {
     865       176554 :                 bool is_empty = field_value.get<std::string>().empty();
     866       176554 :                 if (is_empty) {
     867            0 :                     findDefault(Numbers(numeric_index), schema_field_obj);
     868              :                 } else {
     869       176554 :                     Numbers(numeric_index) = Constant::AutoCalculate; // autosize and autocalculate
     870              :                 }
     871       176554 :                 if (is_NumBlank) {
     872        86518 :                     NumBlank()(numeric_index) = is_empty;
     873              :                 }
     874              :             }
     875              :         }
     876              :     } else {
     877      2789749 :         if (field_type == "a") {
     878       915103 :             if (!(findDefault(Alphas(alpha_index), schema_field_obj))) {
     879       691257 :                 Alphas(alpha_index) = "";
     880              :             }
     881       915103 :             if (is_AlphaBlank) {
     882       550428 :                 AlphaBlank()(alpha_index) = true;
     883              :             }
     884      1874646 :         } else if (field_type == "n") {
     885      1874646 :             findDefault(Numbers(numeric_index), schema_field_obj);
     886      1874646 :             if (is_NumBlank) {
     887      1733620 :                 NumBlank()(numeric_index) = true;
     888              :             }
     889              :         }
     890              :     }
     891      7859590 :     if (field_type == "a") {
     892      3132028 :         if (within_max_fields) {
     893      2484764 :             NumAlphas = alpha_index;
     894              :         }
     895      3132028 :         if (is_AlphaFieldNames) {
     896      5575979 :             AlphaFieldNames()(alpha_index) = (state.dataGlobal->isEpJSON) ? field : legacy_field_info.at("field_name").get<std::string>();
     897              :         }
     898      3132028 :         alpha_index++;
     899      4727562 :     } else if (field_type == "n") {
     900      4727562 :         if (within_max_fields) {
     901      3079407 :             NumNumbers = numeric_index;
     902              :         }
     903      4727562 :         if (is_NumericFieldNames) {
     904     12957938 :             NumericFieldNames()(numeric_index) = (state.dataGlobal->isEpJSON) ? field : legacy_field_info.at("field_name").get<std::string>();
     905              :         }
     906      4727562 :         numeric_index++;
     907              :     }
     908      7859590 : }
     909              : 
     910         4461 : const json &InputProcessor::getJSONObjectItem(EnergyPlusData &state, std::string_view ObjType, std::string_view ObjName)
     911              : {
     912         8922 :     std::string objTypeStr(ObjType);
     913         4461 :     std::string objNameStr(ObjName);
     914              : 
     915         4461 :     auto objectInfo = ObjectInfo(objTypeStr, objNameStr); // (AUTO_OK_OBJ)
     916              : 
     917         4461 :     auto obj_iter = epJSON.find(objTypeStr);
     918         4461 :     if (obj_iter == epJSON.end() || obj_iter.value().find(objectInfo.objectName) == obj_iter.value().end()) {
     919         4371 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(objectInfo.objectType));
     920         4371 :         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         4371 :         objectInfo.objectType = tmp_umit->second;
     925         4371 :         obj_iter = epJSON.find(objectInfo.objectType);
     926         4371 :     }
     927              : 
     928         4461 :     std::string const upperObjName = convertToUpper(objectInfo.objectName);
     929              : 
     930        69188 :     for (const auto &[key, val] : obj_iter->items()) {
     931        69188 :         if (convertToUpper(key) == upperObjName) {
     932         4461 :             objectInfo.objectName = key;
     933              :             // markObjectAsUsed(objectInfo.objectType, objectInfo.objectName);
     934         4461 :             auto const find_unused = unusedInputs.find(objectInfo);
     935         4461 :             if (find_unused != unusedInputs.end()) {
     936         4461 :                 unusedInputs.erase(find_unused);
     937              :             }
     938         4461 :             return val;
     939         4461 :         }
     940         8922 :     }
     941              : 
     942            0 :     ShowFatalError(state, format(R"(Name "{}" requested was not found in input for ObjectType "{}")", objectInfo.objectType, objectInfo.objectName));
     943            0 :     throw;
     944         4461 : }
     945              : 
     946       385307 : 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       385307 :     int adjustedNumber = getJSONObjNum(state, std::string(Object), Number); // if incoming input is idf, then use idf object order
     969              : 
     970       385307 :     auto objectInfo = ObjectInfo(); // (AUTO_OK_OBJ)
     971       385307 :     objectInfo.objectType = Object;
     972              :     // auto sorted_iterators = find_iterators;
     973              : 
     974       770614 :     auto find_iterators = objectCacheMap.find(std::string(Object));
     975       385307 :     if (find_iterators == objectCacheMap.end()) {
     976         1776 :         auto const tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(Object));
     977         1776 :         if (tmp_umit == caseInsensitiveObjectMap.end() || epJSON.find(tmp_umit->second) == epJSON.end()) {
     978            0 :             return;
     979              :         }
     980         1776 :         objectInfo.objectType = tmp_umit->second;
     981         1776 :         find_iterators = objectCacheMap.find(objectInfo.objectType);
     982         1776 :     }
     983              : 
     984       385307 :     NumAlphas = 0;
     985       385307 :     NumNumbers = 0;
     986       385307 :     Status = -1;
     987       385307 :     bool const is_AlphaBlank = present(AlphaBlank);
     988       385307 :     bool const is_AlphaFieldNames = present(AlphaFieldNames);
     989       385307 :     bool const is_NumBlank = present(NumBlank);
     990       385307 :     bool const is_NumericFieldNames = present(NumericFieldNames);
     991              : 
     992       385307 :     auto const &epJSON_it = find_iterators->second.inputObjectIterators.at(adjustedNumber - 1);
     993       385307 :     auto const &epJSON_schema_it = find_iterators->second.schemaIterator;
     994       385307 :     auto const &epJSON_schema_it_val = epJSON_schema_it.value();
     995              : 
     996              :     // Locations in JSON schema relating to normal fields
     997       385307 :     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       385307 :     auto const &legacy_idd = epJSON_schema_it_val["legacy_idd"];
    1001       385307 :     auto const &legacy_idd_field_info = legacy_idd["field_info"];
    1002       385307 :     auto const &legacy_idd_fields = legacy_idd["fields"];
    1003       385307 :     auto const schema_name_field = epJSON_schema_it_val.find("name");
    1004       385307 :     auto const has_idd_name_field = schema_name_field != epJSON_schema_it_val.end();
    1005       385307 :     auto const found_min_fields = epJSON_schema_it_val.find("min_fields");
    1006       385307 :     size_t min_fields = 0;
    1007       385307 :     if (found_min_fields != epJSON_schema_it_val.end()) {
    1008       236167 :         min_fields = found_min_fields.value().get<size_t>();
    1009              :     }
    1010              : 
    1011       385307 :     auto key = legacy_idd.find("extension");
    1012       385307 :     std::string extension_key;
    1013       385307 :     if (key != legacy_idd.end()) {
    1014       116323 :         extension_key = key.value().get<std::string>();
    1015              :     }
    1016              : 
    1017       385307 :     auto const &obj = epJSON_it;
    1018       385307 :     auto const &obj_val = obj.value();
    1019       385307 :     objectInfo.objectName = obj.key();
    1020              : 
    1021       385307 :     int alpha_index = 1;
    1022       385307 :     int numeric_index = 1;
    1023       385307 :     InputProcessor::MaxFields maxFields = findMaxFields(state, obj_val, extension_key, legacy_idd, min_fields);
    1024              : 
    1025       385307 :     Alphas = "";
    1026       385307 :     Numbers = 0;
    1027       385307 :     if (is_NumBlank) {
    1028       276805 :         NumBlank() = true;
    1029              :     }
    1030       385307 :     if (is_AlphaBlank) {
    1031       272649 :         AlphaBlank() = true;
    1032              :     }
    1033       385307 :     if (is_AlphaFieldNames) {
    1034       560052 :         AlphaFieldNames() = "";
    1035              :     }
    1036       385307 :     if (is_NumericFieldNames) {
    1037       559452 :         NumericFieldNames() = "";
    1038              :     }
    1039              : 
    1040       385307 :     auto const find_unused = unusedInputs.find(objectInfo);
    1041       385307 :     if (find_unused != unusedInputs.end()) {
    1042       263762 :         unusedInputs.erase(find_unused);
    1043              :     }
    1044              : 
    1045      6604303 :     for (size_t i = 0; i < legacy_idd_fields.size(); ++i) {
    1046      6218996 :         std::string const field = legacy_idd_fields[i].get<std::string>();
    1047      6218996 :         auto const field_info = legacy_idd_field_info.find(field);
    1048      6218996 :         auto const &field_info_val = field_info.value();
    1049      6218996 :         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      6218996 :         bool within_idf_fields = (i < maxFields.max_fields);
    1054              : 
    1055      6218996 :         if (has_idd_name_field && field == "name") {
    1056       318162 :             auto const &name_iter = schema_name_field.value();
    1057       954486 :             if (name_iter.find("retaincase") != name_iter.end()) {
    1058         1166 :                 Alphas(alpha_index) = objectInfo.objectName;
    1059              :             } else {
    1060       316996 :                 Alphas(alpha_index) = Util::makeUPPER(objectInfo.objectName);
    1061              :             }
    1062       318162 :             if (is_AlphaBlank) {
    1063       207936 :                 AlphaBlank()(alpha_index) = objectInfo.objectName.empty();
    1064              :             }
    1065       318162 :             if (is_AlphaFieldNames) {
    1066       644784 :                 AlphaFieldNames()(alpha_index) = (state.dataGlobal->isEpJSON) ? field : field_info_val.at("field_name").get<std::string>();
    1067              :             }
    1068       318162 :             NumAlphas++;
    1069       318162 :             alpha_index++;
    1070       318162 :             continue;
    1071       318162 :         }
    1072              : 
    1073      5900834 :         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      6537158 :     }
    1090              : 
    1091       385307 :     auto const legacy_idd_extensibles_iter = legacy_idd.find("extensibles");
    1092       385307 :     if (legacy_idd_extensibles_iter != legacy_idd.end()) {
    1093       116323 :         size_t extensible_count = 0;
    1094       116323 :         auto const epJSON_extensions_array_itr = obj_val.find(extension_key);
    1095       116323 :         if (epJSON_extensions_array_itr != obj_val.end()) {
    1096       115959 :             auto const &legacy_idd_extensibles = legacy_idd_extensibles_iter.value();
    1097       115959 :             auto const &epJSON_extensions_array = epJSON_extensions_array_itr.value();
    1098       115959 :             auto const &schema_extension_fields = schema_obj_props[extension_key]["items"]["properties"];
    1099              : 
    1100      1626443 :             for (auto it = epJSON_extensions_array.begin(); it != epJSON_extensions_array.end(); ++it) {
    1101      1510484 :                 auto const &epJSON_extension_obj = it.value();
    1102      3469240 :                 for (size_t i = 0; i < legacy_idd_extensibles.size(); i++, extensible_count++) {
    1103      1958756 :                     std::string const field_name = legacy_idd_extensibles[i].get<std::string>();
    1104      1958756 :                     auto const field_info = legacy_idd_field_info.find(field_name);
    1105      1958756 :                     auto const &field_info_val = field_info.value();
    1106              : 
    1107      1958756 :                     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      1958756 :                     bool within_idf_extensible_fields = (extensible_count < maxFields.max_extensible_fields);
    1112              : 
    1113      1958756 :                     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      1958756 :                 }
    1130       115959 :             }
    1131              :         }
    1132       116323 :     }
    1133              : 
    1134       385307 :     Status = 1;
    1135       385307 : }
    1136              : 
    1137        68358 : 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        68358 :     int idfOrderNumber = Number;
    1143        68358 :     if (state.dataGlobal->isEpJSON || !state.dataGlobal->preserveIDFOrder) {
    1144          178 :         return idfOrderNumber;
    1145              :     }
    1146              : 
    1147              :     json *obj;
    1148       136360 :     auto obj_iter = epJSON.find(std::string(Object));
    1149        68180 :     if (obj_iter == epJSON.end()) {
    1150        37997 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(Object));
    1151        37997 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
    1152            0 :             return idfOrderNumber;
    1153              :         }
    1154        37997 :         obj = &epJSON[tmp_umit->second];
    1155        37997 :     } else {
    1156        30183 :         obj = &(obj_iter.value());
    1157              :     }
    1158              : 
    1159        68180 :     std::vector<int> idfObjNums;
    1160        68180 :     std::vector<int> idfObjNumsSorted;
    1161              : 
    1162              :     // get list of saved object numbers from idf processing
    1163      1807989 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1164      1739809 :         int objNum = it.value()["idf_order"].get<int>();
    1165      1739809 :         idfObjNums.emplace_back(objNum);
    1166        68180 :     }
    1167              : 
    1168        68180 :     idfObjNumsSorted = idfObjNums;
    1169        68180 :     std::sort(idfObjNumsSorted.begin(), idfObjNumsSorted.end());
    1170              : 
    1171              :     // find matching object number in unsorted list
    1172        68180 :     int targetIdfObjNum = idfObjNums[Number - 1];
    1173       907993 :     for (size_t i = 1; i <= idfObjNums.size(); ++i) {
    1174       907993 :         if (idfObjNumsSorted[i - 1] == targetIdfObjNum) {
    1175        68180 :             idfOrderNumber = i;
    1176        68180 :             break;
    1177              :         }
    1178              :     }
    1179        68180 :     return idfOrderNumber;
    1180        68180 : }
    1181              : 
    1182          768 : 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          768 :     std::vector<std::string> keys;
    1186          768 :     std::vector<int> nums;
    1187              : 
    1188              :     json *obj;
    1189         1536 :     auto obj_iter = epJSON.find(std::string(Object));
    1190          768 :     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          768 :         obj = &(obj_iter.value());
    1198              :     }
    1199              : 
    1200              :     // Return names in JSON order
    1201          768 :     if (state.dataGlobal->isEpJSON || !state.dataGlobal->preserveIDFOrder) {
    1202           15 :         for (auto it = obj->begin(); it != obj->end(); ++it) {
    1203           14 :             keys.emplace_back(it.key());
    1204            1 :         }
    1205              : 
    1206            1 :         return keys;
    1207              :     }
    1208              : 
    1209              :     // Now, the real work begins
    1210              : 
    1211         9448 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1212         8681 :         nums.push_back(it.value()["idf_order"].get<int>());
    1213          767 :     }
    1214          767 :     std::sort(nums.begin(), nums.end());
    1215              : 
    1216              :     // Reserve doesn't seem to work :(
    1217         9448 :     for (int i = 0; i < (int)nums.size(); ++i) {
    1218        17362 :         keys.push_back("");
    1219              :     }
    1220              : 
    1221              :     // get list of saved object numbers from idf processing
    1222         9448 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1223         8681 :         int objNum = it.value()["idf_order"].get<int>();
    1224         8681 :         int objIdx = std::find(nums.begin(), nums.end(), objNum) - nums.begin();
    1225         8681 :         keys[objIdx] = it.key();
    1226          767 :     }
    1227              : 
    1228          767 :     return keys;
    1229          768 : }
    1230              : 
    1231       385307 : 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       385307 :     int jSONOrderNumber = Number;
    1237       385307 :     if (state.dataGlobal->isEpJSON || !state.dataGlobal->preserveIDFOrder) {
    1238          747 :         return jSONOrderNumber;
    1239              :     }
    1240              : 
    1241              :     json *obj;
    1242       384560 :     auto obj_iter = epJSON.find(Object);
    1243       384560 :     if (obj_iter == epJSON.end()) {
    1244         1775 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(Object));
    1245         1775 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
    1246            0 :             return jSONOrderNumber;
    1247              :         }
    1248         1775 :         obj = &epJSON[tmp_umit->second];
    1249         1775 :     } else {
    1250       382785 :         obj = &(obj_iter.value());
    1251              :     }
    1252              : 
    1253       384560 :     std::vector<int> idfObjNums;
    1254       384560 :     std::vector<int> idfObjNumsSorted;
    1255              : 
    1256              :     // get list of saved object numbers from idf processing
    1257     42152872 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1258     20884156 :         int objNum = it.value()["idf_order"].get<int>();
    1259     20884156 :         idfObjNums.emplace_back(objNum);
    1260       384560 :     }
    1261              : 
    1262       384560 :     idfObjNumsSorted = idfObjNums;
    1263       384560 :     std::sort(idfObjNumsSorted.begin(), idfObjNumsSorted.end());
    1264              : 
    1265              :     // find matching object number in unsorted list
    1266       384560 :     int targetIdfObjNum = idfObjNumsSorted[Number - 1];
    1267     10634255 :     for (size_t i = 1; i <= idfObjNums.size(); ++i) {
    1268     10634255 :         if (idfObjNums[i - 1] == targetIdfObjNum) {
    1269       384560 :             jSONOrderNumber = i;
    1270       384560 :             break;
    1271              :         }
    1272              :     }
    1273       384560 :     return jSONOrderNumber;
    1274       384560 : }
    1275              : 
    1276        46973 : 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        93946 :     auto obj_iter = epJSON.find(std::string(ObjType));
    1286        64679 :     if (obj_iter == epJSON.end() || obj_iter.value().find(std::string(ObjName)) == obj_iter.value().end()) {
    1287        46882 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(ObjType));
    1288        46882 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
    1289            0 :             return -1; // indicates object type not found, see function GeneralRoutines::ValidateComponent
    1290              :         }
    1291        46882 :         obj = &epJSON[tmp_umit->second];
    1292        46882 :     } else {
    1293           91 :         obj = &(obj_iter.value());
    1294              :     }
    1295              : 
    1296        46973 :     int object_item_num = 1;
    1297        46973 :     bool found = false;
    1298        46973 :     std::string const upperObjName = Util::makeUPPER(ObjName);
    1299       577955 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1300       577912 :         if (Util::makeUPPER(it.key()) == upperObjName) {
    1301        46930 :             found = true;
    1302        46930 :             break;
    1303              :         }
    1304       530982 :         object_item_num++;
    1305        46973 :     }
    1306              : 
    1307        46973 :     if (!found) {
    1308           43 :         return 0; // indicates object name not found, see function GeneralRoutines::ValidateComponent
    1309              :     }
    1310        93860 :     return getIDFObjNum(state, std::string(ObjType), object_item_num); // if incoming input is idf, then return idf object order
    1311        46973 : }
    1312              : 
    1313         5220 : 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        10440 :     auto obj_iter = epJSON.find(std::string(ObjType));
    1324         5220 :     if (obj_iter == epJSON.end() || obj_iter.value().find(ObjName) == obj_iter.value().end()) {
    1325         5220 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(ObjType));
    1326         5220 :         if (tmp_umit == caseInsensitiveObjectMap.end()) {
    1327            0 :             return -1; // indicates object type not found, see function GeneralRoutines::ValidateComponent
    1328              :         }
    1329         5220 :         obj = &epJSON[tmp_umit->second];
    1330         5220 :     } else {
    1331            0 :         obj = &(obj_iter.value());
    1332              :     }
    1333              : 
    1334         5220 :     int object_item_num = 1;
    1335         5220 :     bool found = false;
    1336         5220 :     std::string const upperObjName = Util::makeUPPER(ObjName);
    1337        78664 :     for (auto it = obj->begin(); it != obj->end(); ++it) {
    1338        77922 :         auto it2 = it.value().find(NameTypeVal);
    1339              : 
    1340        77922 :         if ((it2 != it.value().end()) && (Util::makeUPPER(it2.value().get<std::string>()) == upperObjName)) {
    1341         4478 :             found = true;
    1342         4478 :             break;
    1343              :         }
    1344        73444 :         object_item_num++;
    1345        83142 :     }
    1346              : 
    1347         5220 :     if (!found) {
    1348          742 :         return 0; // indicates object field name or value not found
    1349              :     }
    1350         4478 :     return getIDFObjNum(state, ObjType, object_item_num); // if incoming input is idf, then return idf object order
    1351         5220 : }
    1352              : 
    1353          801 : void InputProcessor::getMaxSchemaArgs(int &NumArgs, int &NumAlpha, int &NumNumeric)
    1354              : {
    1355          801 :     NumArgs = 0;
    1356          801 :     NumAlpha = 0;
    1357          801 :     NumNumeric = 0;
    1358          801 :     std::string extension_key;
    1359         1602 :     auto const &schema_properties = schema().at("properties");
    1360              : 
    1361        58830 :     for (json::iterator object = epJSON.begin(); object != epJSON.end(); ++object) {
    1362        58029 :         int num_alpha = 0;
    1363        58029 :         int num_numeric = 0;
    1364              : 
    1365       174087 :         const json &legacy_idd = schema_properties.at(object.key()).at("legacy_idd");
    1366        58029 :         auto key = legacy_idd.find("extension");
    1367        58029 :         if (key != legacy_idd.end()) {
    1368        11562 :             extension_key = key.value().get<std::string>();
    1369              :         }
    1370              : 
    1371        58029 :         size_t max_size = 0;
    1372       361983 :         for (auto const &obj : object.value()) {
    1373       303954 :             auto const find_extensions = obj.find(extension_key);
    1374       303954 :             if (find_extensions != obj.end()) {
    1375       103202 :                 size_t const size = find_extensions.value().size();
    1376       103202 :                 if (size > max_size) {
    1377        15204 :                     max_size = size;
    1378              :                 }
    1379              :             }
    1380       361983 :         }
    1381              : 
    1382        58029 :         auto const find_alphas = legacy_idd.find("alphas");
    1383        58029 :         if (find_alphas != legacy_idd.end()) {
    1384        58029 :             json const &alphas = find_alphas.value();
    1385        58029 :             auto const find_fields = alphas.find("fields");
    1386        58029 :             if (find_fields != alphas.end()) {
    1387        58029 :                 num_alpha += find_fields.value().size();
    1388              :             }
    1389       174087 :             if (alphas.find("extensions") != alphas.end()) {
    1390        10294 :                 num_alpha += alphas["extensions"].size() * max_size;
    1391              :             }
    1392        58029 :         }
    1393       174087 :         if (legacy_idd.find("numerics") != legacy_idd.end()) {
    1394        58029 :             json const &numerics = legacy_idd["numerics"];
    1395       174087 :             if (numerics.find("fields") != numerics.end()) {
    1396        58029 :                 num_numeric += numerics["fields"].size();
    1397              :             }
    1398       174087 :             if (numerics.find("extensions") != numerics.end()) {
    1399         2150 :                 num_numeric += numerics["extensions"].size() * max_size;
    1400              :             }
    1401              :         }
    1402        58029 :         if (num_alpha > NumAlpha) {
    1403         4095 :             NumAlpha = num_alpha;
    1404              :         }
    1405        58029 :         if (num_numeric > NumNumeric) {
    1406         3767 :             NumNumeric = num_numeric;
    1407              :         }
    1408        58830 :     }
    1409              : 
    1410          801 :     NumArgs = NumAlpha + NumNumeric;
    1411          801 : }
    1412              : 
    1413       141687 : 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       141687 :     NumArgs = 0;
    1426       141687 :     NumAlpha = 0;
    1427       141687 :     NumNumeric = 0;
    1428              :     const json *object;
    1429              : 
    1430       141687 :     auto const &props = schema()["properties"];
    1431              : 
    1432       283374 :     if (auto found = props.find(std::string(ObjectWord)); found == props.end()) {
    1433          116 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(ObjectWord));
    1434          116 :         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          116 :         object = &props[tmp_umit->second];
    1439          116 :     } else {
    1440       141571 :         object = &found.value();
    1441       141687 :     }
    1442              : 
    1443       283374 :     const json &legacy_idd = object->at("legacy_idd");
    1444              :     json *objects;
    1445       425061 :     if (auto found = epJSON.find(std::string(ObjectWord)); found == epJSON.end()) {
    1446        76387 :         auto tmp_umit = caseInsensitiveObjectMap.find(convertToUpper(ObjectWord));
    1447        76387 :         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        76387 :         objects = &epJSON[tmp_umit->second];
    1452        76387 :     } else {
    1453        65300 :         objects = &found.value();
    1454       141687 :     }
    1455              : 
    1456       141687 :     size_t max_size = 0;
    1457              : 
    1458       141687 :     std::string extension_key;
    1459       141687 :     auto key = legacy_idd.find("extension");
    1460       141687 :     if (key != legacy_idd.end()) {
    1461        33350 :         extension_key = key.value().get<std::string>();
    1462              :     }
    1463              : 
    1464       617423 :     for (auto const &obj : *objects) {
    1465       475736 :         if (auto found = obj.find(extension_key); found != obj.end()) {
    1466       329041 :             size_t const size = found.value().size();
    1467       329041 :             if (size > max_size) {
    1468        28081 :                 max_size = size;
    1469              :             }
    1470       475736 :         }
    1471       141687 :     }
    1472              : 
    1473       283374 :     if (auto found = legacy_idd.find("alphas"); found != legacy_idd.end()) {
    1474       141687 :         json const &alphas = found.value();
    1475       283374 :         if (auto found2 = alphas.find("fields"); found2 != alphas.end()) {
    1476       141687 :             NumAlpha += found2.value().size();
    1477       141687 :         }
    1478       283374 :         if (auto found2 = alphas.find("extensions"); found2 != alphas.end()) {
    1479        29144 :             NumAlpha += found2.value().size() * max_size;
    1480       141687 :         }
    1481       141687 :     }
    1482       283374 :     if (auto found = legacy_idd.find("numerics"); found != legacy_idd.end()) {
    1483       141687 :         json const &numerics = found.value();
    1484       283374 :         if (auto found2 = numerics.find("fields"); found2 != numerics.end()) {
    1485       141687 :             NumNumeric += found2.value().size();
    1486       141687 :         }
    1487       283374 :         if (auto found2 = numerics.find("extensions"); found2 != numerics.end()) {
    1488         7448 :             NumNumeric += found2.value().size() * max_size;
    1489       141687 :         }
    1490       141687 :     }
    1491       141687 :     NumArgs = NumAlpha + NumNumeric;
    1492       141687 : }
    1493              : 
    1494          801 : 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          801 :     state.dataOutput->iNumberOfRecords = 0;             // Number of IDF Records
    1512          801 :     state.dataOutput->iNumberOfDefaultedFields = 0;     // Number of defaulted fields in IDF
    1513          801 :     state.dataOutput->iTotalFieldsWithDefaults = 0;     // Total number of fields that could be defaulted
    1514          801 :     state.dataOutput->iNumberOfAutoSizedFields = 0;     // Number of autosized fields in IDF
    1515          801 :     state.dataOutput->iTotalAutoSizableFields = 0;      // Total number of autosizable fields
    1516          801 :     state.dataOutput->iNumberOfAutoCalcedFields = 0;    // Number of autocalculated fields
    1517          801 :     state.dataOutput->iTotalAutoCalculatableFields = 0; // Total number of autocalculatable fields
    1518              : 
    1519         1602 :     auto const &schema_properties = schema().at("properties");
    1520              : 
    1521              :     // Lambda to avoid repeating code twice (when processing regular fields, and extensible fields)
    1522      5345938 :     auto processField = [&state](const std::string &field, const json &epJSONObj, const json &schema_field_obj) {
    1523      5345938 :         bool hasDefault = false;
    1524      5345938 :         bool canBeAutosized = false;
    1525      5345938 :         bool canBeAutocalculated = false;
    1526              : 
    1527              :         // If we wanted to count number of fields, would do it here
    1528              : 
    1529      5345938 :         std::string defaultValue;
    1530              : 
    1531      5345938 :         auto const default_it = schema_field_obj.find("default");
    1532      5345938 :         if (default_it != schema_field_obj.end()) {
    1533       880696 :             ++state.dataOutput->iTotalFieldsWithDefaults;
    1534       880696 :             hasDefault = true;
    1535       880696 :             auto const &default_val = default_it.value();
    1536       880696 :             if (default_val.is_string()) {
    1537       502301 :                 defaultValue = default_val.get<std::string>();
    1538              :             }
    1539              :         }
    1540              : 
    1541      5345938 :         auto const anyOf_it = schema_field_obj.find("anyOf");
    1542      5345938 :         if (anyOf_it != schema_field_obj.end()) {
    1543      1244661 :             for (auto const &anyOf : anyOf_it.value()) {
    1544       829774 :                 auto const enum_it = anyOf.find("enum");
    1545       829774 :                 if (enum_it != anyOf.end()) {
    1546       521525 :                     for (auto const &e : enum_it.value()) {
    1547       336409 :                         if (e.is_string()) {
    1548       336291 :                             std::string const enumVal = e.get<std::string>();
    1549       336291 :                             if (enumVal == "Autosize") {
    1550        76781 :                                 ++state.dataOutput->iTotalAutoSizableFields;
    1551        76781 :                                 canBeAutosized = true;
    1552       259510 :                             } else if (enumVal == "Autocalculate") {
    1553       108223 :                                 ++state.dataOutput->iTotalAutoCalculatableFields;
    1554       108223 :                                 canBeAutocalculated = true;
    1555              :                             }
    1556       336291 :                         }
    1557       185116 :                     }
    1558              :                 }
    1559      1244661 :             }
    1560              :         }
    1561              : 
    1562              :         // Locate the field in the ep_object
    1563      5345938 :         auto it = epJSONObj.find(field);
    1564      5345938 :         if (it != epJSONObj.end()) { // && !it.value().empty()) {
    1565              :             // Found it: check if Autosized or Autocalculated
    1566      3743411 :             auto const &field_value = it.value();
    1567      3743411 :             if (field_value.is_string()) {
    1568      1325099 :                 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      1325099 :                 if (canBeAutosized && (val == "Autosize")) {
    1574        49782 :                     ++state.dataOutput->iNumberOfAutoSizedFields;
    1575      1275317 :                 } else if (canBeAutocalculated && (val == "Autocalculate")) {
    1576        29245 :                     ++state.dataOutput->iNumberOfAutoCalcedFields;
    1577              :                 }
    1578      1325099 :             }
    1579      1602527 :         } else if (hasDefault) {
    1580              :             // Not found: was defaulted
    1581       227810 :             ++state.dataOutput->iNumberOfDefaultedFields;
    1582       227810 :             if (canBeAutosized && (defaultValue == "Autosize")) {
    1583         6565 :                 ++state.dataOutput->iNumberOfAutoSizedFields;
    1584       221245 :             } else if (canBeAutocalculated && (defaultValue == "Autocalculate")) {
    1585         9263 :                 ++state.dataOutput->iNumberOfAutoCalcedFields;
    1586              :             }
    1587              :         }
    1588      5345938 :     };
    1589              : 
    1590              :     // Loop on all objectTypes
    1591        58830 :     for (auto epJSON_iter = epJSON.begin(); epJSON_iter != epJSON.end(); ++epJSON_iter) {
    1592        58029 :         auto const &objectType = epJSON_iter.key();
    1593        58029 :         auto const &objects = epJSON_iter.value();
    1594              : 
    1595        58029 :         const json &object_schema = schema_properties.at(objectType);
    1596              : 
    1597              :         // Locations in JSON schema relating to normal fields
    1598        58029 :         auto const &schema_obj_props = getPatternProperties(state, object_schema);
    1599        58029 :         auto const schema_name_field = object_schema.find("name");
    1600        58029 :         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        58029 :         auto const &legacy_idd = object_schema["legacy_idd"];
    1604        58029 :         auto const &legacy_idd_fields = legacy_idd["fields"];
    1605              : 
    1606              :         // Look for extensible
    1607        58029 :         auto key = legacy_idd.find("extension");
    1608        58029 :         std::string extension_key;
    1609        58029 :         if (key != legacy_idd.end()) {
    1610        11562 :             extension_key = key.value().get<std::string>();
    1611              :         }
    1612              : 
    1613       361983 :         for (auto const &ep_object : objects) {
    1614              : 
    1615              :             // Count number of objects
    1616       303954 :             ++state.dataOutput->iNumberOfRecords;
    1617              : 
    1618              :             // Loop on all regular fields
    1619      4069785 :             for (size_t i = 0; i < legacy_idd_fields.size(); ++i) {
    1620              : 
    1621      3765831 :                 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      3765831 :                 if (has_idd_name_field && field == "name") {
    1625       245201 :                     auto const &name_iter = schema_name_field.value();
    1626       735603 :                     if (name_iter.find("default") != name_iter.end()) {
    1627          801 :                         ++state.dataOutput->iTotalFieldsWithDefaults;
    1628          801 :                         auto it = ep_object.find(field);
    1629          801 :                         if (it == ep_object.end()) {
    1630          801 :                             ++state.dataOutput->iNumberOfDefaultedFields;
    1631              :                         }
    1632          801 :                     }
    1633       245201 :                     continue;
    1634       245201 :                 }
    1635              : 
    1636      3520630 :                 auto const &schema_field_obj = schema_obj_props[field];
    1637              : 
    1638      3520630 :                 processField(field, ep_object, schema_field_obj);
    1639              : 
    1640      3765831 :             } // End regular fields
    1641              : 
    1642       303954 :             auto const legacy_idd_extensibles_iter = legacy_idd.find("extensibles");
    1643       303954 :             if (legacy_idd_extensibles_iter != legacy_idd.end()) {
    1644       103589 :                 auto const epJSON_extensions_array_itr = ep_object.find(extension_key);
    1645       103589 :                 if (epJSON_extensions_array_itr != ep_object.end()) {
    1646       103202 :                     auto const &legacy_idd_extensibles = legacy_idd_extensibles_iter.value();
    1647       103202 :                     auto const &epJSON_extensions_array = epJSON_extensions_array_itr.value();
    1648       103202 :                     auto const &schema_extension_fields = schema_obj_props[extension_key]["items"]["properties"];
    1649              : 
    1650      1449013 :                     for (auto it = epJSON_extensions_array.begin(); it != epJSON_extensions_array.end(); ++it) {
    1651      1345811 :                         auto const &epJSON_extension_obj = it.value();
    1652      3171119 :                         for (size_t i = 0; i < legacy_idd_extensibles.size(); ++i) {
    1653      1825308 :                             std::string const &field = legacy_idd_extensibles[i].get<std::string>();
    1654      1825308 :                             auto const &schema_extension_field_obj = schema_extension_fields[field];
    1655              : 
    1656      1825308 :                             processField(field, epJSON_extension_obj, schema_extension_field_obj);
    1657      1825308 :                         }
    1658       103202 :                     }
    1659              :                 }
    1660       103589 :             } // End extensible fields
    1661              : 
    1662       361983 :         } // End loop on each object of a given objectType
    1663        58830 :     } // End loop on all objectTypes
    1664          801 : }
    1665              : 
    1666          799 : 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          799 :     std::unordered_set<std::string> unused_object_types;
    1680          799 :     unused_object_types.reserve(unusedInputs.size());
    1681              : 
    1682          799 :     if (unusedInputs.size() && state.dataGlobal->DisplayUnusedObjects) {
    1683           36 :         ShowWarningError(state, "The following lines are \"Unused Objects\".  These objects are in the input");
    1684           36 :         ShowContinueError(state, " file but are never obtained by the simulation and therefore are NOT used.");
    1685           18 :         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           51 :             ShowContinueError(state, " Each unused object is shown.");
    1690              :         }
    1691           54 :         ShowContinueError(state, " See InputOutputReference document for more details.");
    1692              :     }
    1693              : 
    1694          799 :     bool first_iteration = true;
    1695         2220 :     for (auto it = unusedInputs.begin(); it != unusedInputs.end(); ++it) {
    1696         1421 :         std::string const &object_type = it->objectType;
    1697         1421 :         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         1421 :         if (has_prefix(object_type, "ZoneHVAC:")) {
    1702            2 :             ShowSevereError(state, "Orphaned ZoneHVAC object found.  This was object never referenced in the input, and was not used.");
    1703            1 :             ShowContinueError(state, " -- Object type: " + object_type);
    1704            1 :             ShowContinueError(state, " -- Object name: " + name);
    1705              :         }
    1706              : 
    1707         1421 :         if (!state.dataGlobal->DisplayUnusedObjects) {
    1708         1378 :             continue;
    1709              :         }
    1710              : 
    1711           43 :         if (!state.dataGlobal->DisplayAllWarnings) {
    1712            9 :             auto found_type = unused_object_types.find(object_type);
    1713            9 :             if (found_type != unused_object_types.end()) {
    1714              :                 // only show first unused named object of an object class
    1715            8 :                 continue;
    1716              :             } else {
    1717            1 :                 unused_object_types.emplace(object_type);
    1718              :             }
    1719            9 :         }
    1720              : 
    1721           35 :         if (first_iteration) {
    1722           18 :             if (!name.empty()) {
    1723           18 :                 ShowMessage(state, "Object=" + object_type + '=' + name);
    1724              :             } else {
    1725            0 :                 ShowMessage(state, "Object=" + object_type);
    1726              :             }
    1727           18 :             first_iteration = false;
    1728              :         } else {
    1729           17 :             if (!name.empty()) {
    1730           17 :                 ShowContinueError(state, "Object=" + object_type + '=' + name);
    1731              :             } else {
    1732            0 :                 ShowContinueError(state, "Object=" + object_type);
    1733              :             }
    1734              :         }
    1735          799 :     }
    1736              : 
    1737          799 :     if (unusedInputs.size() && !state.dataGlobal->DisplayUnusedObjects) {
    1738          135 :         u64toa(unusedInputs.size(), s);
    1739          270 :         ShowMessage(state, "There are " + std::string(s) + " unused objects in input.");
    1740          405 :         ShowMessage(state, "Use Output:Diagnostics,DisplayUnusedObjects; to see them.");
    1741              :     }
    1742          799 : }
    1743              : 
    1744          801 : 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          801 :     state.dataIPShortCut->cCurrentModuleObject = "Output:PreprocessorMessage";
    1783          801 :     int NumPrePM = getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
    1784          801 :     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            8 :         std::string Multiples;
    1790              : 
    1791            8 :         getObjectDefMaxArgs(state, state.dataIPShortCut->cCurrentModuleObject, NumParams, NumAlphas, NumNumbers);
    1792            8 :         state.dataIPShortCut->cAlphaArgs({1, NumAlphas}) = BlankString;
    1793           16 :         for (int CountP = 1; CountP <= NumPrePM; ++CountP) {
    1794            8 :             getObjectItem(state,
    1795            8 :                           state.dataIPShortCut->cCurrentModuleObject,
    1796              :                           CountP,
    1797            8 :                           state.dataIPShortCut->cAlphaArgs,
    1798              :                           NumAlphas,
    1799            8 :                           state.dataIPShortCut->rNumericArgs,
    1800              :                           NumNumbers,
    1801              :                           IOStat,
    1802            8 :                           state.dataIPShortCut->lNumericFieldBlanks,
    1803            8 :                           state.dataIPShortCut->lAlphaFieldBlanks,
    1804            8 :                           state.dataIPShortCut->cAlphaFieldNames,
    1805            8 :                           state.dataIPShortCut->cNumericFieldNames);
    1806            8 :             if (state.dataIPShortCut->cAlphaArgs(1).empty()) {
    1807            0 :                 state.dataIPShortCut->cAlphaArgs(1) = "Unknown";
    1808              :             }
    1809            8 :             if (NumAlphas > 3) {
    1810            5 :                 Multiples = "s";
    1811              :             } else {
    1812            3 :                 Multiples = BlankString;
    1813              :             }
    1814            8 :             if (state.dataIPShortCut->cAlphaArgs(2).empty()) {
    1815            0 :                 state.dataIPShortCut->cAlphaArgs(2) = "Unknown";
    1816              :             }
    1817              :             {
    1818            8 :                 std::string const errorType = uppercased(state.dataIPShortCut->cAlphaArgs(2));
    1819            8 :                 if (errorType == "INFORMATION") {
    1820            2 :                     ShowMessage(state,
    1821            2 :                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
    1822            3 :                                     "\" has the following Information message" + Multiples + ':');
    1823            7 :                 } else if (errorType == "WARNING") {
    1824           14 :                     ShowWarningError(state,
    1825           14 :                                      state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
    1826           21 :                                          "\" 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            8 :             }
    1842            8 :             int CountM = 3;
    1843            8 :             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           27 :             while (CountM <= NumAlphas) {
    1849           19 :                 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           19 :                     ShowContinueError(state, state.dataIPShortCut->cAlphaArgs(CountM));
    1854           19 :                     ++CountM;
    1855              :                 }
    1856              :             }
    1857              :         }
    1858            8 :     }
    1859          801 : }
    1860              : 
    1861          801 : 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         2403 :     static std::string const OutputVariable("Output:Variable");
    1890         2403 :     static std::string const MeterCustom("Meter:Custom");
    1891         2403 :     static std::string const MeterCustomDecrement("Meter:CustomDecrement");
    1892         2403 :     static std::string const OutputTableMonthly("Output:Table:Monthly");
    1893         2403 :     static std::string const OutputTableAnnual("Output:Table:Annual");
    1894         2403 :     static std::string const OutputTableTimeBins("Output:Table:TimeBins");
    1895         2403 :     static std::string const OutputTableSummaries("Output:Table:SummaryReports");
    1896         2403 :     static std::string const EMSSensor("EnergyManagementSystem:Sensor");
    1897         2403 :     static std::string const EMSOutputVariable("EnergyManagementSystem:OutputVariable");
    1898              : 
    1899              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1900          801 :     std::string extension_key;
    1901              :     // state.dataOutput->OutputVariablesForSimulation.reserve(1024);
    1902          801 :     state.dataOutput->MaxConsideredOutputVariables = 10000;
    1903              : 
    1904              :     // Output Variable
    1905          801 :     auto epJSON_objects = epJSON.find(OutputVariable);
    1906          801 :     if (epJSON_objects != epJSON.end()) {
    1907          783 :         auto const &epJSON_object = epJSON_objects.value();
    1908        22576 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1909        21793 :             json const &fields = obj.value();
    1910        21793 :             auto it = fields.find("key_value");
    1911        21793 :             if (it != fields.end() && !it.value().empty()) {
    1912        43582 :                 addRecordToOutputVariableStructure(state, it.value().get<std::string>(), fields.at("variable_name").get<std::string>());
    1913              :             } else {
    1914            8 :                 addRecordToOutputVariableStructure(state, "*", fields.at("variable_name").get<std::string>());
    1915              :             }
    1916        22576 :         }
    1917              :     }
    1918              : 
    1919          801 :     epJSON_objects = epJSON.find(MeterCustom);
    1920          801 :     if (epJSON_objects != epJSON.end()) {
    1921           46 :         auto const &epJSON_object = epJSON_objects.value();
    1922           46 :         auto const &legacy_idd = schema()["properties"][MeterCustom]["legacy_idd"];
    1923           46 :         auto key = legacy_idd.find("extension");
    1924           46 :         if (key != legacy_idd.end()) {
    1925           46 :             extension_key = key.value().get<std::string>();
    1926              :         }
    1927          143 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1928           97 :             json const &fields = obj.value();
    1929          477 :             for (auto const &extensions : fields[extension_key]) {
    1930          380 :                 auto it = extensions.find("key_name");
    1931          380 :                 if (it != extensions.end() && !obj.key().empty()) {
    1932          321 :                     addRecordToOutputVariableStructure(
    1933          963 :                         state, it.value().get<std::string>(), extensions.at("output_variable_or_meter_name").get<std::string>());
    1934              :                 } else {
    1935          236 :                     addRecordToOutputVariableStructure(state, "*", extensions.at("output_variable_or_meter_name").get<std::string>());
    1936              :                 }
    1937          477 :             }
    1938           46 :         }
    1939           46 :     }
    1940              : 
    1941          801 :     epJSON_objects = epJSON.find(MeterCustomDecrement);
    1942          801 :     if (epJSON_objects != epJSON.end()) {
    1943           41 :         auto const &epJSON_object = epJSON_objects.value();
    1944           41 :         auto const &legacy_idd = schema()["properties"][MeterCustomDecrement]["legacy_idd"];
    1945           41 :         auto key = legacy_idd.find("extension");
    1946           41 :         if (key != legacy_idd.end()) {
    1947           41 :             extension_key = key.value().get<std::string>();
    1948              :         }
    1949           82 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1950           41 :             json const &fields = obj.value();
    1951           82 :             for (auto const &extensions : fields[extension_key]) {
    1952           41 :                 auto it = extensions.find("key_name");
    1953           41 :                 if (it != extensions.end() && !obj.key().empty()) {
    1954            4 :                     addRecordToOutputVariableStructure(
    1955           12 :                         state, it.value().get<std::string>(), extensions.at("output_variable_or_meter_name").get<std::string>());
    1956              :                 } else {
    1957          148 :                     addRecordToOutputVariableStructure(state, "*", extensions.at("output_variable_or_meter_name").get<std::string>());
    1958              :                 }
    1959           82 :             }
    1960           41 :         }
    1961           41 :     }
    1962              : 
    1963          801 :     epJSON_objects = epJSON.find(EMSSensor);
    1964          801 :     if (epJSON_objects != epJSON.end()) {
    1965           54 :         auto const &epJSON_object = epJSON_objects.value();
    1966         1920 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1967         1866 :             json const &fields = obj.value();
    1968         1866 :             auto it = fields.find("output_variable_or_output_meter_index_key_name");
    1969         1866 :             if (it != fields.end() && !it.value().empty()) {
    1970         1819 :                 addRecordToOutputVariableStructure(
    1971         5457 :                     state, it.value().get<std::string>(), fields.at("output_variable_or_output_meter_name").get<std::string>());
    1972              :             } else {
    1973          188 :                 addRecordToOutputVariableStructure(state, "*", fields.at("output_variable_or_output_meter_name").get<std::string>());
    1974              :             }
    1975         1920 :         }
    1976              :     }
    1977              : 
    1978          801 :     epJSON_objects = epJSON.find(EMSOutputVariable);
    1979          801 :     if (epJSON_objects != epJSON.end()) {
    1980           40 :         auto const &epJSON_object = epJSON_objects.value();
    1981          394 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1982         1062 :             addRecordToOutputVariableStructure(state, "*", obj.key());
    1983           40 :         }
    1984              :     }
    1985              : 
    1986          801 :     for (auto const &requestedVar : state.dataOutputProcessor->apiVarRequests) {
    1987            0 :         addRecordToOutputVariableStructure(state, requestedVar.varKey, requestedVar.varName);
    1988          801 :     }
    1989              : 
    1990          801 :     epJSON_objects = epJSON.find(OutputTableTimeBins);
    1991          801 :     if (epJSON_objects != epJSON.end()) {
    1992           58 :         auto const &epJSON_object = epJSON_objects.value();
    1993          278 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    1994          220 :             json const &fields = obj.value();
    1995          220 :             if (!obj.key().empty()) {
    1996          440 :                 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           58 :         }
    2001              :     }
    2002              : 
    2003          801 :     epJSON_objects = epJSON.find(OutputTableMonthly);
    2004          801 :     if (epJSON_objects != epJSON.end()) {
    2005          142 :         auto const &epJSON_object = epJSON_objects.value();
    2006          142 :         auto const &legacy_idd = schema()["properties"][OutputTableMonthly]["legacy_idd"];
    2007          142 :         auto key = legacy_idd.find("extension");
    2008          142 :         if (key != legacy_idd.end()) {
    2009          142 :             extension_key = key.value().get<std::string>();
    2010              :         }
    2011         1344 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    2012         1202 :             json const &fields = obj.value();
    2013         7875 :             for (auto const &extensions : fields[extension_key]) {
    2014              :                 try {
    2015        26692 :                     addRecordToOutputVariableStructure(state, "*", extensions.at("variable_or_meter_name").get<std::string>());
    2016            0 :                 } catch (...) {
    2017            0 :                     continue; // blank or erroneous fields are handled at the get input function for the object
    2018            0 :                 }
    2019         1202 :             }
    2020          142 :         }
    2021          142 :     }
    2022              : 
    2023          801 :     epJSON_objects = epJSON.find(OutputTableAnnual);
    2024          801 :     if (epJSON_objects != epJSON.end()) {
    2025            1 :         auto const &epJSON_object = epJSON_objects.value();
    2026            1 :         auto const &legacy_idd = schema()["properties"][OutputTableAnnual]["legacy_idd"];
    2027            1 :         auto key = legacy_idd.find("extension");
    2028            1 :         if (key != legacy_idd.end()) {
    2029            1 :             extension_key = key.value().get<std::string>();
    2030              :         }
    2031           15 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    2032           14 :             json const &fields = obj.value();
    2033           94 :             for (auto const &extensions : fields[extension_key]) {
    2034              :                 try {
    2035           80 :                     addRecordToOutputVariableStructure(
    2036          240 :                         state, "*", extensions.at("variable_or_meter_or_ems_variable_or_field_name").get<std::string>());
    2037            0 :                 } catch (...) {
    2038            0 :                     continue; // blank or erroneous fields are handled at the get input function for the object
    2039            0 :                 }
    2040           14 :             }
    2041            1 :         }
    2042            1 :     }
    2043              : 
    2044          801 :     epJSON_objects = epJSON.find(OutputTableSummaries);
    2045          801 :     if (epJSON_objects != epJSON.end()) {
    2046          761 :         auto const &epJSON_object = epJSON_objects.value();
    2047          761 :         auto const &legacy_idd = schema()["properties"][OutputTableSummaries]["legacy_idd"];
    2048          761 :         auto key = legacy_idd.find("extension");
    2049          761 :         if (key != legacy_idd.end()) {
    2050          761 :             extension_key = key.value().get<std::string>();
    2051              :         }
    2052         1522 :         for (auto obj = epJSON_object.begin(); obj != epJSON_object.end(); ++obj) {
    2053          761 :             json const &fields = obj.value();
    2054         2085 :             for (auto const &extensions : fields[extension_key]) {
    2055              :                 try {
    2056         1324 :                     std::string const report_name = Util::makeUPPER(extensions.at("report_name").get<std::string>());
    2057         1324 :                     if (report_name == "ALLMONTHLY" || report_name == "ALLSUMMARYANDMONTHLY") {
    2058         1536 :                         for (int i = 1; i <= DataOutputs::NumMonthlyReports; ++i) {
    2059         1512 :                             addVariablesForMonthlyReport(state, DataOutputs::MonthlyNamedReports(i));
    2060              :                         }
    2061              :                     } else {
    2062         1300 :                         addVariablesForMonthlyReport(state, report_name);
    2063              :                     }
    2064         1324 :                 } catch (...) {
    2065            0 :                     continue; // blank or erroneous fields should be warned about during actual get input routines
    2066            0 :                 }
    2067          761 :             }
    2068          761 :         }
    2069          761 :     }
    2070          801 : }
    2071              : 
    2072         2812 : 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         2812 :     if (reportName == "ZONECOOLINGSUMMARYMONTHLY") {
    2087           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE AIR SYSTEM SENSIBLE COOLING RATE");
    2088           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2089           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2090           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE TOTAL INTERNAL LATENT GAIN ENERGY");
    2091           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE TOTAL INTERNAL LATENT GAIN RATE");
    2092              : 
    2093         2788 :     } else if (reportName == "ZONEHEATINGSUMMARYMONTHLY") {
    2094           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE AIR SYSTEM SENSIBLE HEATING ENERGY"); // on meter
    2095           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE AIR SYSTEM SENSIBLE HEATING RATE");
    2096           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2097              : 
    2098         2764 :     } else if (reportName == "ZONEELECTRICSUMMARYMONTHLY") {
    2099          100 :         addRecordToOutputVariableStructure(state, "*", "ZONE LIGHTS ELECTRICITY ENERGY");
    2100          100 :         addRecordToOutputVariableStructure(state, "*", "ZONE ELECTRIC EQUIPMENT ELECTRICITY ENERGY");
    2101              : 
    2102         2739 :     } else if (reportName == "SPACEGAINSMONTHLY") {
    2103           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE PEOPLE TOTAL HEATING ENERGY");
    2104           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE LIGHTS TOTAL HEATING ENERGY");
    2105           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE ELECTRIC EQUIPMENT TOTAL HEATING ENERGY");
    2106           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE GAS EQUIPMENT TOTAL HEATING ENERGY");
    2107           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE HOT WATER EQUIPMENT TOTAL HEATING ENERGY");
    2108           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE STEAM EQUIPMENT TOTAL HEATING ENERGY");
    2109           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE OTHER EQUIPMENT TOTAL HEATING ENERGY");
    2110           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT GAIN ENERGY");
    2111           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT LOSS ENERGY");
    2112              : 
    2113         2715 :     } else if (reportName == "PEAKSPACEGAINSMONTHLY") {
    2114           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE PEOPLE TOTAL HEATING ENERGY");
    2115           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE LIGHTS TOTAL HEATING ENERGY");
    2116           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE ELECTRIC EQUIPMENT TOTAL HEATING ENERGY");
    2117           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE GAS EQUIPMENT TOTAL HEATING ENERGY");
    2118           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE HOT WATER EQUIPMENT TOTAL HEATING ENERGY");
    2119           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE STEAM EQUIPMENT TOTAL HEATING ENERGY");
    2120           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE OTHER EQUIPMENT TOTAL HEATING ENERGY");
    2121           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT GAIN ENERGY");
    2122           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT LOSS ENERGY");
    2123              : 
    2124         2691 :     } else if (reportName == "SPACEGAINCOMPONENTSATCOOLINGPEAKMONTHLY") {
    2125           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE AIR SYSTEM SENSIBLE COOLING RATE");
    2126           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE PEOPLE TOTAL HEATING ENERGY");
    2127           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE LIGHTS TOTAL HEATING ENERGY");
    2128           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE ELECTRIC EQUIPMENT TOTAL HEATING ENERGY");
    2129           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE GAS EQUIPMENT TOTAL HEATING ENERGY");
    2130           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE HOT WATER EQUIPMENT TOTAL HEATING ENERGY");
    2131           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE STEAM EQUIPMENT TOTAL HEATING ENERGY");
    2132           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE OTHER EQUIPMENT TOTAL HEATING ENERGY");
    2133           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT GAIN ENERGY");
    2134           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE INFILTRATION SENSIBLE HEAT LOSS ENERGY");
    2135              : 
    2136         2667 :     } else if (reportName == "SETPOINTSNOTMETWITHTEMPERATURESMONTHLY") {
    2137           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE HEATING SETPOINT NOT MET TIME");
    2138           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE MEAN AIR TEMPERATURE");
    2139           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE HEATING SETPOINT NOT MET WHILE OCCUPIED TIME");
    2140           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE COOLING SETPOINT NOT MET TIME");
    2141           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE COOLING SETPOINT NOT MET WHILE OCCUPIED TIME");
    2142              : 
    2143         2643 :     } else if (reportName == "COMFORTREPORTSIMPLE55MONTHLY") {
    2144           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE THERMAL COMFORT ASHRAE 55 SIMPLE MODEL SUMMER CLOTHES NOT COMFORTABLE TIME");
    2145           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE MEAN AIR TEMPERATURE");
    2146           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE THERMAL COMFORT ASHRAE 55 SIMPLE MODEL WINTER CLOTHES NOT COMFORTABLE TIME");
    2147           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE THERMAL COMFORT ASHRAE 55 SIMPLE MODEL SUMMER OR WINTER CLOTHES NOT COMFORTABLE TIME");
    2148              : 
    2149         2619 :     } else if (reportName == "UNGLAZEDTRANSPIREDSOLARCOLLECTORSUMMARYMONTHLY") {
    2150           96 :         addRecordToOutputVariableStructure(state, "*", "SOLAR COLLECTOR SYSTEM EFFICIENCY");
    2151           96 :         addRecordToOutputVariableStructure(state, "*", "SOLAR COLLECTOR OUTSIDE FACE SUCTION VELOCITY");
    2152           96 :         addRecordToOutputVariableStructure(state, "*", "SOLAR COLLECTOR SENSIBLE HEATING RATE");
    2153              : 
    2154         2595 :     } else if (reportName == "OCCUPANTCOMFORTDATASUMMARYMONTHLY") {
    2155           96 :         addRecordToOutputVariableStructure(state, "*", "PEOPLE OCCUPANT COUNT");
    2156           96 :         addRecordToOutputVariableStructure(state, "*", "PEOPLE AIR TEMPERATURE");
    2157           96 :         addRecordToOutputVariableStructure(state, "*", "PEOPLE AIR RELATIVE HUMIDITY");
    2158           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE THERMAL COMFORT FANGER MODEL PMV");
    2159           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE THERMAL COMFORT FANGER MODEL PPD");
    2160              : 
    2161         2571 :     } else if (reportName == "CHILLERREPORTMONTHLY") {
    2162           96 :         addRecordToOutputVariableStructure(state, "*", "CHILLER ELECTRICITY ENERGY"); // on meter
    2163           96 :         addRecordToOutputVariableStructure(state, "*", "CHILLER ELECTRICITY RATE");
    2164           96 :         addRecordToOutputVariableStructure(state, "*", "CHILLER EVAPORATOR COOLING ENERGY");      // on meter
    2165           96 :         addRecordToOutputVariableStructure(state, "*", "CHILLER CONDENSER HEAT TRANSFER ENERGY"); // on meter
    2166           96 :         addRecordToOutputVariableStructure(state, "*", "CHILLER COP");
    2167              : 
    2168         2547 :     } else if (reportName == "TOWERREPORTMONTHLY") {
    2169           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER FAN ELECTRICITY ENERGY"); // on meter
    2170           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER FAN ELECTRICITY RATE");
    2171           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER HEAT TRANSFER RATE");
    2172           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER INLET TEMPERATURE");
    2173           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER OUTLET TEMPERATURE");
    2174           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING TOWER MASS FLOW RATE");
    2175              : 
    2176         2523 :     } else if (reportName == "BOILERREPORTMONTHLY") {
    2177           96 :         addRecordToOutputVariableStructure(state, "*", "BOILER HEATING ENERGY");         // on meter
    2178           96 :         addRecordToOutputVariableStructure(state, "*", "BOILER NATURALGAS CONSUMPTION"); // on meter
    2179           96 :         addRecordToOutputVariableStructure(state, "*", "BOILER HEATING ENERGY");         // on meter
    2180           96 :         addRecordToOutputVariableStructure(state, "*", "BOILER HEATING RATE");
    2181           96 :         addRecordToOutputVariableStructure(state, "*", "BOILER NATURALGAS CONSUMPTION RATE");
    2182           96 :         addRecordToOutputVariableStructure(state, "*", "BOILER INLET TEMPERATURE");
    2183           96 :         addRecordToOutputVariableStructure(state, "*", "BOILER OUTLET TEMPERATURE");
    2184           96 :         addRecordToOutputVariableStructure(state, "*", "BOILER MASS FLOW RATE");
    2185           96 :         addRecordToOutputVariableStructure(state, "*", "BOILER ANCILLARY ELECTRICITY RATE");
    2186              : 
    2187         2499 :     } else if (reportName == "DXREPORTMONTHLY") {
    2188           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL TOTAL COOLING ENERGY"); // on meter
    2189           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL ELECTRICITY ENERGY");   // on meter
    2190           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL SENSIBLE COOLING ENERGY");
    2191           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL LATENT COOLING ENERGY");
    2192           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL CRANKCASE HEATER ELECTRICITY ENERGY");
    2193           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL RUNTIME FRACTION");
    2194           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL TOTAL COOLING RATE");
    2195           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL SENSIBLE COOLING RATE");
    2196           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL LATENT COOLING RATE");
    2197           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL ELECTRICITY RATE");
    2198           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL CRANKCASE HEATER ELECTRICITY RATE");
    2199              : 
    2200         2475 :     } else if (reportName == "WINDOWREPORTMONTHLY") {
    2201           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED SOLAR RADIATION RATE");
    2202           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED BEAM SOLAR RADIATION RATE");
    2203           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED DIFFUSE SOLAR RADIATION RATE");
    2204           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW HEAT GAIN RATE");
    2205           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW HEAT LOSS RATE");
    2206           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW INSIDE FACE GLAZING CONDENSATION STATUS");
    2207           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE SHADING DEVICE IS ON TIME FRACTION");
    2208           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE STORM WINDOW ON OFF STATUS");
    2209              : 
    2210         2451 :     } else if (reportName == "WINDOWENERGYREPORTMONTHLY") {
    2211           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED SOLAR RADIATION ENERGY");
    2212           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED BEAM SOLAR RADIATION ENERGY");
    2213           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW TRANSMITTED DIFFUSE SOLAR RADIATION ENERGY");
    2214           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW HEAT GAIN ENERGY");
    2215           96 :         addRecordToOutputVariableStructure(state, "*", "SURFACE WINDOW HEAT LOSS ENERGY");
    2216              : 
    2217         2427 :     } else if (reportName == "WINDOWZONESUMMARYMONTHLY") {
    2218           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOWS TOTAL HEAT GAIN RATE");
    2219           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOWS TOTAL HEAT LOSS RATE");
    2220           96 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE WINDOWS TOTAL TRANSMITTED SOLAR RADIATION RATE");
    2221           96 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE EXTERIOR WINDOWS TOTAL TRANSMITTED BEAM SOLAR RADIATION RATE");
    2222           96 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE EXTERIOR WINDOWS TOTAL TRANSMITTED DIFFUSE SOLAR RADIATION RATE");
    2223           96 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE INTERIOR WINDOWS TOTAL TRANSMITTED DIFFUSE SOLAR RADIATION RATE");
    2224           96 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE INTERIOR WINDOWS TOTAL TRANSMITTED BEAM SOLAR RADIATION RATE");
    2225              : 
    2226         2403 :     } else if (reportName == "WINDOWENERGYZONESUMMARYMONTHLY") {
    2227           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOWS TOTAL HEAT GAIN ENERGY");
    2228           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOWS TOTAL HEAT LOSS ENERGY");
    2229           96 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE WINDOWS TOTAL TRANSMITTED SOLAR RADIATION ENERGY");
    2230           96 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE EXTERIOR WINDOWS TOTAL TRANSMITTED BEAM SOLAR RADIATION ENERGY");
    2231           96 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE EXTERIOR WINDOWS TOTAL TRANSMITTED DIFFUSE SOLAR RADIATION ENERGY");
    2232           96 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE INTERIOR WINDOWS TOTAL TRANSMITTED DIFFUSE SOLAR RADIATION ENERGY");
    2233           96 :         addRecordToOutputVariableStructure(state, "*", "ENCLOSURE INTERIOR WINDOWS TOTAL TRANSMITTED BEAM SOLAR RADIATION ENERGY");
    2234              : 
    2235         2379 :     } else if (reportName == "AVERAGEOUTDOORCONDITIONSMONTHLY") {
    2236           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2237           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2238           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DEWPOINT TEMPERATURE");
    2239           96 :         addRecordToOutputVariableStructure(state, "*", "SITE WIND SPEED");
    2240           96 :         addRecordToOutputVariableStructure(state, "*", "SITE SKY TEMPERATURE");
    2241           96 :         addRecordToOutputVariableStructure(state, "*", "SITE DIFFUSE SOLAR RADIATION RATE PER AREA");
    2242           96 :         addRecordToOutputVariableStructure(state, "*", "SITE DIRECT SOLAR RADIATION RATE PER AREA");
    2243           96 :         addRecordToOutputVariableStructure(state, "*", "SITE RAIN STATUS");
    2244              : 
    2245         2355 :     } else if (reportName == "OUTDOORCONDITIONSMAXIMUMDRYBULBMONTHLY") {
    2246           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2247           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2248           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DEWPOINT TEMPERATURE");
    2249           96 :         addRecordToOutputVariableStructure(state, "*", "SITE WIND SPEED");
    2250           96 :         addRecordToOutputVariableStructure(state, "*", "SITE SKY TEMPERATURE");
    2251           96 :         addRecordToOutputVariableStructure(state, "*", "SITE DIFFUSE SOLAR RADIATION RATE PER AREA");
    2252           96 :         addRecordToOutputVariableStructure(state, "*", "SITE DIRECT SOLAR RADIATION RATE PER AREA");
    2253              : 
    2254         2331 :     } else if (reportName == "OUTDOORCONDITIONSMINIMUMDRYBULBMONTHLY") {
    2255           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2256           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2257           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DEWPOINT TEMPERATURE");
    2258           96 :         addRecordToOutputVariableStructure(state, "*", "SITE WIND SPEED");
    2259           96 :         addRecordToOutputVariableStructure(state, "*", "SITE SKY TEMPERATURE");
    2260           96 :         addRecordToOutputVariableStructure(state, "*", "SITE DIFFUSE SOLAR RADIATION RATE PER AREA");
    2261           96 :         addRecordToOutputVariableStructure(state, "*", "SITE DIRECT SOLAR RADIATION RATE PER AREA");
    2262              : 
    2263         2307 :     } else if (reportName == "OUTDOORCONDITIONSMAXIMUMWETBULBMONTHLY") {
    2264           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2265           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2266           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DEWPOINT TEMPERATURE");
    2267           96 :         addRecordToOutputVariableStructure(state, "*", "SITE WIND SPEED");
    2268           96 :         addRecordToOutputVariableStructure(state, "*", "SITE SKY TEMPERATURE");
    2269           96 :         addRecordToOutputVariableStructure(state, "*", "SITE DIFFUSE SOLAR RADIATION RATE PER AREA");
    2270           96 :         addRecordToOutputVariableStructure(state, "*", "SITE DIRECT SOLAR RADIATION RATE PER AREA");
    2271              : 
    2272         2283 :     } else if (reportName == "OUTDOORCONDITIONSMAXIMUMDEWPOINTMONTHLY") {
    2273           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DEWPOINT TEMPERATURE");
    2274           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR DRYBULB TEMPERATURE");
    2275           96 :         addRecordToOutputVariableStructure(state, "*", "SITE OUTDOOR AIR WETBULB TEMPERATURE");
    2276           96 :         addRecordToOutputVariableStructure(state, "*", "SITE WIND SPEED");
    2277           96 :         addRecordToOutputVariableStructure(state, "*", "SITE SKY TEMPERATURE");
    2278           96 :         addRecordToOutputVariableStructure(state, "*", "SITE DIFFUSE SOLAR RADIATION RATE PER AREA");
    2279           96 :         addRecordToOutputVariableStructure(state, "*", "SITE DIRECT SOLAR RADIATION RATE PER AREA");
    2280              : 
    2281         2259 :     } else if (reportName == "OUTDOORGROUNDCONDITIONSMONTHLY") {
    2282           96 :         addRecordToOutputVariableStructure(state, "*", "SITE GROUND TEMPERATURE");
    2283           96 :         addRecordToOutputVariableStructure(state, "*", "SITE SURFACE GROUND TEMPERATURE");
    2284           96 :         addRecordToOutputVariableStructure(state, "*", "SITE DEEP GROUND TEMPERATURE");
    2285           96 :         addRecordToOutputVariableStructure(state, "*", "SITE MAINS WATER TEMPERATURE");
    2286           96 :         addRecordToOutputVariableStructure(state, "*", "SITE GROUND REFLECTED SOLAR RADIATION RATE PER AREA");
    2287           96 :         addRecordToOutputVariableStructure(state, "*", "SITE SNOW ON GROUND STATUS");
    2288              : 
    2289         2235 :     } else if (reportName == "WINDOWACREPORTMONTHLY") {
    2290           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER TOTAL COOLING ENERGY");
    2291           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER ELECTRICITY ENERGY");
    2292           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER TOTAL COOLING ENERGY");
    2293           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER SENSIBLE COOLING ENERGY");
    2294           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER LATENT COOLING ENERGY");
    2295           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER TOTAL COOLING RATE");
    2296           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER SENSIBLE COOLING RATE");
    2297           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER LATENT COOLING RATE");
    2298           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE WINDOW AIR CONDITIONER ELECTRICITY RATE");
    2299              : 
    2300         2211 :     } else if (reportName == "WATERHEATERREPORTMONTHLY") {
    2301           96 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER TOTAL DEMAND HEAT TRANSFER ENERGY");
    2302           96 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER USE SIDE HEAT TRANSFER ENERGY");
    2303           96 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER BURNER HEATING ENERGY");
    2304           96 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER NATURALGAS CONSUMPTION");
    2305           96 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER TOTAL DEMAND HEAT TRANSFER ENERGY");
    2306           96 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER LOSS DEMAND ENERGY");
    2307           96 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER HEAT LOSS ENERGY");
    2308           96 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER TANK TEMPERATURE");
    2309           96 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER HEAT RECOVERY SUPPLY ENERGY");
    2310           96 :         addRecordToOutputVariableStructure(state, "*", "WATER HEATER SOURCE SIDE HEAT TRANSFER ENERGY");
    2311              : 
    2312         2187 :     } else if (reportName == "GENERATORREPORTMONTHLY") {
    2313           96 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR PRODUCED AC ELECTRICITY ENERGY");
    2314           96 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR DIESEL CONSUMPTION");
    2315           96 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR NATURALGAS CONSUMPTION");
    2316           96 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR PRODUCED AC ELECTRICITY ENERGY");
    2317           96 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR TOTAL HEAT RECOVERY");
    2318           96 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR JACKET HEAT RECOVERY ENERGY");
    2319           96 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR LUBE HEAT RECOVERY");
    2320           96 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR EXHAUST HEAT RECOVERY ENERGY");
    2321           96 :         addRecordToOutputVariableStructure(state, "*", "GENERATOR EXHAUST AIR TEMPERATURE");
    2322              : 
    2323         2163 :     } else if (reportName == "DAYLIGHTINGREPORTMONTHLY") {
    2324           96 :         addRecordToOutputVariableStructure(state, "*", "SITE EXTERIOR BEAM NORMAL ILLUMINANCE");
    2325           96 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING LIGHTING POWER MULTIPLIER");
    2326           96 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING LIGHTING POWER MULTIPLIER");
    2327           96 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 1 ILLUMINANCE");
    2328           96 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 1 GLARE INDEX");
    2329           96 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 1 GLARE INDEX SETPOINT EXCEEDED TIME");
    2330           96 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 1 DAYLIGHT ILLUMINANCE SETPOINT EXCEEDED TIME");
    2331           96 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 2 ILLUMINANCE");
    2332           96 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 2 GLARE INDEX");
    2333           96 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 2 GLARE INDEX SETPOINT EXCEEDED TIME");
    2334           96 :         addRecordToOutputVariableStructure(state, "*", "DAYLIGHTING REFERENCE POINT 2 DAYLIGHT ILLUMINANCE SETPOINT EXCEEDED TIME");
    2335              : 
    2336         2139 :     } else if (reportName == "COILREPORTMONTHLY") {
    2337           96 :         addRecordToOutputVariableStructure(state, "*", "HEATING COIL HEATING ENERGY");
    2338           96 :         addRecordToOutputVariableStructure(state, "*", "HEATING COIL HEATING RATE");
    2339           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL SENSIBLE COOLING ENERGY");
    2340           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL TOTAL COOLING ENERGY");
    2341           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL TOTAL COOLING RATE");
    2342           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL SENSIBLE COOLING RATE");
    2343           96 :         addRecordToOutputVariableStructure(state, "*", "COOLING COIL WETTED AREA FRACTION");
    2344              : 
    2345         2115 :     } else if (reportName == "PLANTLOOPDEMANDREPORTMONTHLY") {
    2346           96 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE COOLING DEMAND RATE");
    2347           96 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE HEATING DEMAND RATE");
    2348              : 
    2349         2091 :     } else if (reportName == "FANREPORTMONTHLY") {
    2350          100 :         addRecordToOutputVariableStructure(state, "*", "FAN ELECTRICITY ENERGY");
    2351          100 :         addRecordToOutputVariableStructure(state, "*", "FAN RISE IN AIR TEMPERATURE");
    2352          100 :         addRecordToOutputVariableStructure(state, "*", "FAN ELECTRICITY RATE");
    2353              : 
    2354         2066 :     } else if (reportName == "PUMPREPORTMONTHLY") {
    2355           96 :         addRecordToOutputVariableStructure(state, "*", "PUMP ELECTRICITY ENERGY");
    2356           96 :         addRecordToOutputVariableStructure(state, "*", "PUMP FLUID HEAT GAIN ENERGY");
    2357           96 :         addRecordToOutputVariableStructure(state, "*", "PUMP ELECTRICITY RATE");
    2358           96 :         addRecordToOutputVariableStructure(state, "*", "PUMP SHAFT POWER");
    2359           96 :         addRecordToOutputVariableStructure(state, "*", "PUMP FLUID HEAT GAIN RATE");
    2360           96 :         addRecordToOutputVariableStructure(state, "*", "PUMP OUTLET TEMPERATURE");
    2361           96 :         addRecordToOutputVariableStructure(state, "*", "PUMP MASS FLOW RATE");
    2362              : 
    2363         2042 :     } else if (reportName == "CONDLOOPDEMANDREPORTMONTHLY") {
    2364           96 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE COOLING DEMAND RATE");
    2365           96 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE HEATING DEMAND RATE");
    2366           96 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE INLET TEMPERATURE");
    2367           96 :         addRecordToOutputVariableStructure(state, "*", "PLANT SUPPLY SIDE OUTLET TEMPERATURE");
    2368              : 
    2369         2018 :     } else if (reportName == "ZONETEMPERATUREOSCILLATIONREPORTMONTHLY") {
    2370           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE OSCILLATING TEMPERATURES TIME");
    2371           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE PEOPLE OCCUPANT COUNT");
    2372              : 
    2373         1994 :     } else if (reportName == "AIRLOOPSYSTEMENERGYANDWATERUSEMONTHLY") {
    2374           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HOT WATER ENERGY");
    2375           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM STEAM ENERGY");
    2376           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM CHILLED WATER ENERGY");
    2377           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM ELECTRICITY ENERGY");
    2378           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM NATURALGAS ENERGY");
    2379           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM WATER VOLUME");
    2380              : 
    2381         1970 :     } else if (reportName == "AIRLOOPSYSTEMCOMPONENTLOADSMONTHLY") {
    2382           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM FAN AIR HEATING ENERGY");
    2383           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM COOLING COIL TOTAL COOLING ENERGY");
    2384           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEATING COIL TOTAL HEATING ENERGY");
    2385           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEAT EXCHANGER TOTAL HEATING ENERGY");
    2386           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEAT EXCHANGER TOTAL COOLING ENERGY");
    2387           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HUMIDIFIER TOTAL HEATING ENERGY");
    2388           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM EVAPORATIVE COOLER TOTAL COOLING ENERGY");
    2389           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM DESICCANT DEHUMIDIFIER TOTAL COOLING ENERGY");
    2390              : 
    2391         1946 :     } else if (reportName == "AIRLOOPSYSTEMCOMPONENTENERGYUSEMONTHLY") {
    2392           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM FAN ELECTRICITY ENERGY");
    2393           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEATING COIL HOT WATER ENERGY");
    2394           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM COOLING COIL CHILLED WATER ENERGY");
    2395           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM DX HEATING COIL ELECTRICITY ENERGY");
    2396           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM DX COOLING COIL ELECTRICITY ENERGY");
    2397           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEATING COIL ELECTRICITY ENERGY");
    2398           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEATING COIL NATURALGAS ENERGY");
    2399           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HEATING COIL STEAM ENERGY");
    2400           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM HUMIDIFIER ELECTRICITY ENERGY");
    2401           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM EVAPORATIVE COOLER ELECTRICITY ENERGY");
    2402           96 :         addRecordToOutputVariableStructure(state, "*", "AIR SYSTEM DESICCANT DEHUMIDIFIER ELECTRICITY ENERGY");
    2403              : 
    2404         1922 :     } else if (reportName == "MECHANICALVENTILATIONLOADSMONTHLY") {
    2405           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION NO LOAD HEAT REMOVAL ENERGY");
    2406           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION COOLING LOAD INCREASE ENERGY");
    2407           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION COOLING LOAD INCREASE DUE TO OVERHEATING ENERGY");
    2408           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION COOLING LOAD DECREASE ENERGY");
    2409           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION NO LOAD HEAT ADDITION ENERGY");
    2410           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION HEATING LOAD INCREASE ENERGY");
    2411           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION HEATING LOAD INCREASE DUE TO OVERCOOLING ENERGY");
    2412           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION HEATING LOAD DECREASE ENERGY");
    2413           96 :         addRecordToOutputVariableStructure(state, "*", "ZONE MECHANICAL VENTILATION AIR CHANGES PER HOUR");
    2414              : 
    2415         1898 :     } else if (reportName == "HEATEMISSIONSREPORTMONTHLY") {
    2416              :         // Place holder
    2417          100 :         addRecordToOutputVariableStructure(state, "*", "Site Total Surface Heat Emission to Air");
    2418          100 :         addRecordToOutputVariableStructure(state, "*", "Site Total Zone Exfiltration Heat Loss");
    2419          100 :         addRecordToOutputVariableStructure(state, "*", "Site Total Zone Exhaust Air Heat Loss");
    2420          100 :         addRecordToOutputVariableStructure(state, "*", "Air System Relief Air Total Heat Loss Energy");
    2421          100 :         addRecordToOutputVariableStructure(state, "*", "HVAC System Total Heat Rejection Energy");
    2422              :     } else {
    2423              :     }
    2424         2812 : }
    2425              : 
    2426        37609 : 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        37609 :     std::string::size_type const rbpos = index(VariableName, '[');
    2442        37609 :     if (rbpos == std::string::npos) {
    2443        37609 :         vnameLen = len_trim(VariableName);
    2444              :     } else {
    2445            0 :         vnameLen = len_trim(VariableName.substr(0, rbpos));
    2446              :     }
    2447              : 
    2448        37609 :     std::string const VarName(VariableName.substr(0, vnameLen));
    2449              : 
    2450        37609 :     auto const found = state.dataOutput->OutputVariablesForSimulation.find(VarName);
    2451        37609 :     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        25945 :             data;
    2457              :         // data.reserve(32);
    2458        25945 :         data.emplace(KeyValue, DataOutputs::OutputReportingVariables(state, KeyValue, VarName));
    2459        25945 :         state.dataOutput->OutputVariablesForSimulation.emplace(VarName, std::move(data));
    2460        25945 :     } else {
    2461        11664 :         found->second.emplace(KeyValue, DataOutputs::OutputReportingVariables(state, KeyValue, VarName));
    2462              :     }
    2463        37609 :     state.dataOutput->NumConsideredOutputVariables++;
    2464        37609 : }
    2465              : 
    2466              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1