LCOV - code coverage report
Current view: top level - EnergyPlus/InputProcessing - InputProcessor.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 1152 1358 84.8 %
Date: 2023-01-17 19:17:23 Functions: 41 48 85.4 %

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

Generated by: LCOV version 1.13