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