Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #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 : 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, bool uc = true);
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 : const json &getJSONObjectItem(EnergyPlusData &state, std::string_view ObjType, std::string_view ObjName);
141 :
142 : void getObjectItem(EnergyPlusData &state,
143 : std::string_view Object,
144 : int const Number,
145 : Array1S_string Alphas,
146 : int &NumAlphas,
147 : Array1D<Real64> &Numbers,
148 : int &NumNumbers,
149 : int &Status,
150 : ObjexxFCL::Optional<Array1D_bool> NumBlank = _,
151 : ObjexxFCL::Optional<Array1D_bool> AlphaBlank = _,
152 : ObjexxFCL::Optional<Array1D_string> AlphaFieldNames = _,
153 : ObjexxFCL::Optional<Array1D_string> NumericFieldNames = _);
154 :
155 : int getIDFObjNum(EnergyPlusData &state, std::string_view Object, int const Number);
156 :
157 : int getJSONObjNum(EnergyPlusData &state, std::string const &Object, int const Number);
158 :
159 : int getObjectItemNum(EnergyPlusData &state,
160 : std::string_view ObjType, // Object Type (ref: IDD Objects)
161 : std::string_view ObjName // Name of the object type
162 : );
163 :
164 : int getObjectItemNum(EnergyPlusData &state,
165 : std::string_view ObjType, // Object Type (ref: IDD Objects)
166 : std::string const &NameTypeVal, // Object "name" field type ( used as search key )
167 : std::string const &ObjName // Name of the object type
168 : );
169 :
170 : void getMaxSchemaArgs(int &NumArgs, int &NumAlpha, int &NumNumeric);
171 :
172 : void getObjectDefMaxArgs(EnergyPlusData &state,
173 : std::string_view const ObjectWord, // Object for definition
174 : int &NumArgs, // How many arguments (max) this Object can have
175 : int &NumAlpha, // How many Alpha arguments (max) this Object can have
176 : int &NumNumeric // How many Numeric arguments (max) this Object can have
177 : );
178 :
179 : void preProcessorCheck(EnergyPlusData &state, bool &PreP_Fatal); // True if a preprocessor flags a fatal error
180 :
181 : void preScanReportingVariables(EnergyPlusData &state);
182 :
183 : void reportIDFRecordsStats(EnergyPlusData &state);
184 :
185 : void reportOrphanRecordObjects(EnergyPlusData &state);
186 :
187 : const json &getObjectInstances(std::string const &ObjType);
188 :
189 : bool checkForUnsupportedObjects(EnergyPlusData &state);
190 :
191 : // void clear_state();
192 : private:
193 : friend class EnergyPlusFixture;
194 : friend class InputProcessorFixture;
195 :
196 : struct ObjectInfo
197 : {
198 372678 : ObjectInfo() = default;
199 :
200 332706 : ObjectInfo(std::string const &objectType, std::string const &objectName) : objectType(objectType), objectName(objectName)
201 : {
202 332706 : }
203 :
204 : ObjectInfo(std::string &&objectType, std::string &&objectName) : objectType(objectType), objectName(objectName)
205 : {
206 : }
207 :
208 7700683 : bool operator<(const ObjectInfo &rhs) const
209 : {
210 7700683 : int cmp = this->objectType.compare(rhs.objectType);
211 7700683 : if (cmp == 0) {
212 2767271 : return this->objectName < rhs.objectName;
213 : }
214 4933412 : return cmp < 0;
215 : }
216 :
217 : std::string objectType = "";
218 : std::string objectName = "";
219 : };
220 :
221 : struct ObjectCache
222 : {
223 57492 : ObjectCache() = default;
224 :
225 : ObjectCache(json::const_iterator const &schemaIterator, std::vector<json::const_iterator> const &inputObjectIterators)
226 : : schemaIterator(schemaIterator), inputObjectIterators(inputObjectIterators)
227 : {
228 : }
229 :
230 : ObjectCache(json::const_iterator &&schemaIterator, std::vector<json::const_iterator> &&inputObjectIterators)
231 : : schemaIterator(schemaIterator), inputObjectIterators(inputObjectIterators)
232 : {
233 : }
234 :
235 : json::const_iterator schemaIterator;
236 : std::vector<json::const_iterator> inputObjectIterators;
237 : };
238 :
239 : struct MaxFields
240 : {
241 : MaxFields() = default;
242 : std::size_t max_fields = 0;
243 : std::size_t max_extensible_fields = 0;
244 : };
245 :
246 : MaxFields findMaxFields(
247 : EnergyPlusData &state, json const &ep_object, std::string const &extension_key, json const &legacy_idd, std::size_t const min_fields);
248 :
249 : void setObjectItemValue(EnergyPlusData &state,
250 : json const &ep_object,
251 : json const &ep_schema_object,
252 : std::string const &field,
253 : json const &legacy_field_info,
254 : int &alpha_index,
255 : int &numeric_index,
256 : bool within_max_fields,
257 : Array1S_string Alphas,
258 : int &NumAlphas,
259 : Array1D<Real64> &Numbers,
260 : int &NumNumbers,
261 : ObjexxFCL::Optional<Array1D_bool> NumBlank = _,
262 : ObjexxFCL::Optional<Array1D_bool> AlphaBlank = _,
263 : ObjexxFCL::Optional<Array1D_string> AlphaFieldNames = _,
264 : ObjexxFCL::Optional<Array1D_string> NumericFieldNames = _);
265 :
266 : void addVariablesForMonthlyReport(EnergyPlusData &state, std::string const &reportName);
267 :
268 : void addRecordToOutputVariableStructure(EnergyPlusData &state, std::string const &KeyValue, std::string const &VariableName);
269 :
270 : std::vector<std::string> const &validationErrors();
271 :
272 : std::vector<std::string> const &validationWarnings();
273 :
274 : bool checkVersionMatch(EnergyPlusData &state);
275 :
276 : bool processErrors(EnergyPlusData &state);
277 :
278 : json const &getFields(EnergyPlusData &state, std::string const &objectType, std::string const &objectName);
279 :
280 : json const &getFields(EnergyPlusData &state, std::string const &objectType);
281 :
282 : json const &getPatternProperties(EnergyPlusData &state, json const &schema_obj);
283 :
284 1243553 : inline std::string convertToUpper(std::string_view s)
285 : {
286 1243553 : std::string s2;
287 1243553 : size_t len = s.size();
288 1243553 : s2.resize(len);
289 38001610 : for (size_t i = 0; i < len; ++i) {
290 36758057 : char c = s[i];
291 36758057 : s2[i] = ('a' <= c && c <= 'z') ? c ^ 0x20 : c; // ASCII only
292 : }
293 1243553 : s2[len] = '\0';
294 1243553 : return s2;
295 0 : }
296 :
297 : using UnorderedObjectTypeMap = std::unordered_map<std::string, std::string>;
298 : using UnorderedObjectCacheMap = std::unordered_map<std::string, ObjectCache>;
299 : using UnusedObjectSet = std::set<ObjectInfo>;
300 :
301 : std::unique_ptr<IdfParser> idf_parser;
302 : std::unique_ptr<Validation> validation;
303 : std::unique_ptr<DataStorage> data;
304 : static const json &schema();
305 :
306 : public:
307 : json epJSON;
308 :
309 : private:
310 : // Maps OBJECTTYPE to ObjectType (example entry: {"ZONEHVAC:EQUIPMENTLIST", "ZoneHVAC:EquipmentList"})
311 : UnorderedObjectTypeMap caseInsensitiveObjectMap;
312 : // Maps ObjectType to ObjectCache (json::const_iterator const &schemaIterator, std::vector<json::const_iterator> const &inputObjectIterators)
313 : UnorderedObjectCacheMap objectCacheMap;
314 :
315 : // ObjectType to vector of ObjectName
316 : UnusedObjectSet unusedInputs;
317 : char s[129] = {0};
318 :
319 : }; // InputProcessor
320 :
321 : struct DataInputProcessing : BaseGlobalStruct
322 : {
323 : std::unique_ptr<InputProcessor> inputProcessor = InputProcessor::factory();
324 :
325 796 : void init_state([[maybe_unused]] EnergyPlusData &state) override
326 : {
327 796 : }
328 :
329 0 : void clear_state() override
330 : {
331 0 : inputProcessor.reset();
332 0 : inputProcessor = EnergyPlus::InputProcessor::factory();
333 0 : }
334 : };
335 :
336 : } // namespace EnergyPlus
337 :
338 : #endif
|