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