Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #ifndef InputProcessor_hh_INCLUDED
49 : #define InputProcessor_hh_INCLUDED
50 :
51 : // C++ Headers
52 : #include <map>
53 : #include <set>
54 : #include <string>
55 : #include <unordered_map>
56 : #include <vector>
57 :
58 : // ObjexxFCL Headers
59 : #include <ObjexxFCL/Array1D.hh>
60 : #include <ObjexxFCL/Array1S.fwd.hh>
61 : #include <ObjexxFCL/Optional.hh>
62 :
63 : #include <nlohmann/json.hpp>
64 :
65 : // EnergyPlus Headers
66 : #include <EnergyPlus/Data/BaseData.hh>
67 : #include <EnergyPlus/DataGlobals.hh>
68 : #include <EnergyPlus/EnergyPlus.hh>
69 : #include <EnergyPlus/InputProcessing/DataStorage.hh>
70 : #include <EnergyPlus/InputProcessing/IdfParser.hh>
71 : #include <EnergyPlus/InputProcessing/InputValidation.hh>
72 :
73 : class IdfParser;
74 : class Validation;
75 : struct EnergyPlusData;
76 :
77 : namespace EnergyPlus {
78 :
79 : void cleanEPJSON(nlohmann::json &epjson);
80 :
81 771 : class InputProcessor
82 : {
83 : public:
84 : using json = nlohmann::json;
85 :
86 : json::parser_callback_t callback;
87 :
88 : InputProcessor();
89 :
90 : static std::unique_ptr<InputProcessor> factory();
91 :
92 : template <typename T> T *objectFactory(EnergyPlusData &state, std::string const &objectName)
93 : {
94 : T *p = data->objectFactory<T>(objectName);
95 : if (p != nullptr) return p;
96 : auto const &fields = getFields(state, T::canonicalObjectType(), objectName);
97 : p = data->addObject<T>(objectName, fields);
98 : return p;
99 : }
100 :
101 : template <typename T> T *objectFactory(EnergyPlusData &state)
102 : {
103 : T *p = data->objectFactory<T>();
104 : if (p != nullptr) return p;
105 : auto const &fields = getFields(state, T::canonicalObjectType());
106 : p = data->addObject<T>(fields);
107 : return p;
108 : }
109 :
110 : std::pair<bool, std::string> convertInsensitiveObjectType(std::string const &objectType);
111 :
112 : void initializeMaps();
113 :
114 : void markObjectAsUsed(const std::string &objectType, const std::string &objectName);
115 :
116 : void processInput(EnergyPlusData &state);
117 :
118 : int getNumSectionsFound(std::string const &SectionWord);
119 :
120 : int getNumObjectsFound(EnergyPlusData &state, std::string_view const ObjectWord);
121 :
122 : bool findDefault(std::string &default_value, json const &schema_field_obj);
123 :
124 : bool findDefault(Real64 &default_value, json const &schema_field_obj);
125 :
126 : bool getDefaultValue(EnergyPlusData &state, std::string const &objectWord, std::string const &fieldName, Real64 &value);
127 :
128 : bool getDefaultValue(EnergyPlusData &state, std::string const &objectWord, std::string const &fieldName, std::string &value);
129 :
130 : std::string getAlphaFieldValue(json const &ep_object, json const &schema_obj_props, std::string const &fieldName);
131 :
132 : Real64 getRealFieldValue(json const &ep_object, json const &schema_obj_props, std::string const &fieldName);
133 :
134 : int getIntFieldValue(json const &ep_object, json const &schema_obj_props, std::string const &fieldName);
135 :
136 : const json &getObjectSchemaProps(EnergyPlusData &state, std::string const &objectWord);
137 :
138 : std::pair<std::string, bool> getObjectItemValue(std::string const &field_value, json const &schema_field_obj);
139 :
140 : void getObjectItem(EnergyPlusData &state,
141 : std::string_view Object,
142 : int const Number,
143 : Array1S_string Alphas,
144 : int &NumAlphas,
145 : Array1D<Real64> &Numbers,
146 : int &NumNumbers,
147 : int &Status,
148 : Optional<Array1D_bool> NumBlank = _,
149 : Optional<Array1D_bool> AlphaBlank = _,
150 : Optional<Array1D_string> AlphaFieldNames = _,
151 : Optional<Array1D_string> NumericFieldNames = _);
152 :
153 : int getIDFObjNum(EnergyPlusData &state, std::string const &Object, int const Number);
154 :
155 : int getJSONObjNum(EnergyPlusData &state, std::string const &Object, int const Number);
156 :
157 : int getObjectItemNum(EnergyPlusData &state,
158 : std::string_view ObjType, // Object Type (ref: IDD Objects)
159 : std::string_view ObjName // Name of the object type
160 : );
161 :
162 : int getObjectItemNum(EnergyPlusData &state,
163 : std::string const &ObjType, // Object Type (ref: IDD Objects)
164 : std::string const &NameTypeVal, // Object "name" field type ( used as search key )
165 : std::string const &ObjName // Name of the object type
166 : );
167 :
168 : void lowerRangeCheck(EnergyPlusData &state,
169 : bool &ErrorsFound, // Set to true if error detected
170 : std::string const &WhatFieldString, // Descriptive field for string
171 : std::string const &WhatObjectString, // Descriptive field for object, Zone Name, etc.
172 : std::string const &ErrorLevel, // 'Warning','Severe','Fatal')
173 : std::string const &LowerBoundString, // String for error message, if applicable
174 : bool const LowerBoundCondition, // Condition for error condition, if applicable
175 : std::string_view const ValueString = {}, // Value with digits if to be displayed with error
176 : std::string_view const WhatObjectName = {} // ObjectName -- used for error messages
177 : );
178 :
179 : void rangeCheck(EnergyPlusData &state,
180 : bool &ErrorsFound, // Set to true if error detected
181 : std::string const &WhatFieldString, // Descriptive field for string
182 : std::string const &WhatObjectString, // Descriptive field for object, Zone Name, etc.
183 : std::string const &ErrorLevel, // 'Warning','Severe','Fatal')
184 : std::string const &LowerBoundString, // String for error message, if applicable
185 : bool const LowerBoundCondition, // Condition for error condition, if applicable
186 : std::string const &UpperBoundString, // String for error message, if applicable
187 : bool const UpperBoundCondition, // Condition for error condition, if applicable
188 : std::string_view const ValueString = {}, // Value with digits if to be displayed with error
189 : std::string_view const WhatObjectName = {} // ObjectName -- used for error messages
190 : );
191 :
192 : void getMaxSchemaArgs(int &NumArgs, int &NumAlpha, int &NumNumeric);
193 :
194 : void getObjectDefMaxArgs(EnergyPlusData &state,
195 : std::string_view const ObjectWord, // Object for definition
196 : int &NumArgs, // How many arguments (max) this Object can have
197 : int &NumAlpha, // How many Alpha arguments (max) this Object can have
198 : int &NumNumeric // How many Numeric arguments (max) this Object can have
199 : );
200 :
201 : void preProcessorCheck(EnergyPlusData &state, bool &PreP_Fatal); // True if a preprocessor flags a fatal error
202 :
203 : void preScanReportingVariables(EnergyPlusData &state);
204 :
205 : void reportIDFRecordsStats(EnergyPlusData &state);
206 :
207 : void reportOrphanRecordObjects(EnergyPlusData &state);
208 :
209 : const json &getObjectInstances(std::string const &ObjType);
210 :
211 : bool checkForUnsupportedObjects(EnergyPlusData &state);
212 :
213 : // void clear_state();
214 : private:
215 : friend class EnergyPlusFixture;
216 : friend class InputProcessorFixture;
217 :
218 689112 : struct ObjectInfo
219 : {
220 378681 : ObjectInfo() = default;
221 :
222 310431 : ObjectInfo(std::string const &objectType, std::string const &objectName) : objectType(objectType), objectName(objectName)
223 : {
224 310431 : }
225 :
226 : ObjectInfo(std::string &&objectType, std::string &&objectName) : objectType(objectType), objectName(objectName)
227 : {
228 : }
229 :
230 7445767 : bool operator<(const ObjectInfo &rhs) const
231 : {
232 7445767 : int cmp = this->objectType.compare(rhs.objectType);
233 7445767 : if (cmp == 0) {
234 2648552 : return this->objectName < rhs.objectName;
235 : }
236 4797215 : return cmp < 0;
237 : }
238 :
239 : std::string objectType = "";
240 : std::string objectName = "";
241 : };
242 :
243 166590 : struct ObjectCache
244 : {
245 55530 : ObjectCache() = default;
246 :
247 : ObjectCache(json::const_iterator const &schemaIterator, std::vector<json::const_iterator> const &inputObjectIterators)
248 : : schemaIterator(schemaIterator), inputObjectIterators(inputObjectIterators)
249 : {
250 : }
251 :
252 : ObjectCache(json::const_iterator &&schemaIterator, std::vector<json::const_iterator> &&inputObjectIterators)
253 : : schemaIterator(schemaIterator), inputObjectIterators(inputObjectIterators)
254 : {
255 : }
256 :
257 : json::const_iterator schemaIterator;
258 : std::vector<json::const_iterator> inputObjectIterators;
259 : };
260 :
261 : struct MaxFields
262 : {
263 : MaxFields() = default;
264 : std::size_t max_fields = 0;
265 : std::size_t max_extensible_fields = 0;
266 : };
267 :
268 : MaxFields findMaxFields(
269 : EnergyPlusData &state, json const &ep_object, std::string const &extension_key, json const &legacy_idd, std::size_t const min_fields);
270 :
271 : void setObjectItemValue(EnergyPlusData &state,
272 : json const &ep_object,
273 : json const &ep_schema_object,
274 : std::string const &field,
275 : json const &legacy_field_info,
276 : int &alpha_index,
277 : int &numeric_index,
278 : bool within_max_fields,
279 : Array1S_string Alphas,
280 : int &NumAlphas,
281 : Array1D<Real64> &Numbers,
282 : int &NumNumbers,
283 : Optional<Array1D_bool> NumBlank = _,
284 : Optional<Array1D_bool> AlphaBlank = _,
285 : Optional<Array1D_string> AlphaFieldNames = _,
286 : Optional<Array1D_string> NumericFieldNames = _);
287 :
288 : void addVariablesForMonthlyReport(EnergyPlusData &state, std::string const &reportName);
289 :
290 : void addRecordToOutputVariableStructure(EnergyPlusData &state, std::string const &KeyValue, std::string const &VariableName);
291 :
292 : std::vector<std::string> const &validationErrors();
293 :
294 : std::vector<std::string> const &validationWarnings();
295 :
296 : bool checkVersionMatch(EnergyPlusData &state);
297 :
298 : bool processErrors(EnergyPlusData &state);
299 :
300 : json const &getFields(EnergyPlusData &state, std::string const &objectType, std::string const &objectName);
301 :
302 : json const &getFields(EnergyPlusData &state, std::string const &objectType);
303 :
304 : json const &getPatternProperties(EnergyPlusData &state, json const &schema_obj);
305 :
306 1172106 : inline std::string convertToUpper(std::string s)
307 : {
308 1172106 : size_t len = s.size();
309 36414433 : for (size_t i = 0; i < len; ++i) {
310 35242327 : char c = s[i];
311 35242327 : s[i] = ('a' <= c && c <= 'z') ? c ^ 0x20 : c; // ASCII only
312 : }
313 1172106 : return s;
314 : }
315 :
316 : using UnorderedObjectTypeMap = std::unordered_map<std::string, std::string>;
317 : using UnorderedObjectCacheMap = std::unordered_map<std::string, ObjectCache>;
318 : using UnusedObjectSet = std::set<ObjectInfo>;
319 :
320 : std::unique_ptr<IdfParser> idf_parser;
321 : std::unique_ptr<Validation> validation;
322 : std::unique_ptr<DataStorage> data;
323 : static const json &schema();
324 :
325 : public:
326 : json epJSON;
327 :
328 : private:
329 : UnorderedObjectTypeMap caseInsensitiveObjectMap;
330 : UnorderedObjectCacheMap objectCacheMap;
331 : UnusedObjectSet unusedInputs;
332 : char s[129] = {0};
333 :
334 : }; // InputProcessor
335 :
336 1542 : struct DataInputProcessing : BaseGlobalStruct
337 : {
338 : std::unique_ptr<InputProcessor> inputProcessor = InputProcessor::factory();
339 :
340 0 : void clear_state() override
341 : {
342 0 : inputProcessor.reset();
343 0 : inputProcessor = EnergyPlus::InputProcessor::factory();
344 0 : }
345 : };
346 :
347 : } // namespace EnergyPlus
348 :
349 : #endif
|