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