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