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