LCOV - code coverage report
Current view: top level - EnergyPlus/InputProcessing - InputProcessor.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 1253 1420 88.2 %
Date: 2024-08-24 18:31:18 Functions: 38 45 84.4 %

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

Generated by: LCOV version 1.14