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 ResultsSchema_hh_INCLUDED
49 : #define ResultsSchema_hh_INCLUDED
50 :
51 : #include <memory>
52 : #include <unordered_map>
53 :
54 : // ObjexxFCL Headers
55 : #include <ObjexxFCL/Array1D.hh>
56 : #include <ObjexxFCL/Array2D.hh>
57 : #include <ObjexxFCL/Reference.hh>
58 :
59 : #include <nlohmann/json.hpp>
60 :
61 : // EnergyPlus Headers
62 : #include <EnergyPlus/Data/BaseData.hh>
63 : #include <EnergyPlus/DataGlobals.hh>
64 : #include <EnergyPlus/EnergyPlus.hh>
65 : #include <EnergyPlus/OutputProcessor.hh>
66 :
67 : namespace EnergyPlus {
68 :
69 : // Forward declarations
70 : class EnergyPlusFixture;
71 : class ResultsFrameworkFixture;
72 : struct EnergyPlusData;
73 : struct JsonOutputFilePaths;
74 :
75 : namespace ResultsFramework {
76 :
77 : using json = nlohmann::json;
78 :
79 : // trim string
80 : std::string trim(std::string_view const s);
81 :
82 : // base result object
83 : class BaseResultObject
84 : {
85 : public:
86 23195 : BaseResultObject(){};
87 : };
88 :
89 1542 : class SimInfo : public BaseResultObject
90 : {
91 : public:
92 : void setProgramVersion(const std::string &programVersion);
93 : std::string getProgramVersion() const;
94 : void setSimulationEnvironment(const std::string &simulationEnvironment);
95 : void setInputModelURI(const std::string &inputModelURI);
96 : void setStartDateTimeStamp(const std::string &startDateTimeStamp);
97 : void setRunTime(const std::string &elapsedTime);
98 : void setNumErrorsWarmup(const std::string &numWarningsDuringWarmup, const std::string &numSevereDuringWarmup);
99 : void setNumErrorsSizing(const std::string &numWarningsDuringSizing, const std::string &numSevereDuringSizing);
100 : void setNumErrorsSummary(const std::string &numWarnings, const std::string &numSevere);
101 : json getJSON() const;
102 :
103 : protected:
104 : std::string ProgramVersion;
105 : std::string SimulationEnvironment;
106 : std::string InputModelURI;
107 : std::string StartDateTimeStamp;
108 : std::string RunTime;
109 : std::string NumWarningsDuringWarmup, NumSevereDuringWarmup, NumWarningsDuringSizing, NumSevereDuringSizing, NumWarnings, NumSevere;
110 : };
111 :
112 25124 : class Variable : public BaseResultObject
113 : {
114 : public:
115 378 : Variable() = default;
116 : Variable(const std::string &VarName,
117 : const OutputProcessor::ReportingFrequency reportFrequency,
118 : const OutputProcessor::TimeStepType timeStepType,
119 : const int ReportID,
120 : OutputProcessor::Unit units);
121 : Variable(const std::string &VarName,
122 : const OutputProcessor::ReportingFrequency reportFrequency,
123 : const OutputProcessor::TimeStepType timeStepType,
124 : const int ReportID,
125 : OutputProcessor::Unit units,
126 : const std::string &customUnits);
127 :
128 : std::string variableName() const;
129 : void setVariableName(const std::string &VarName);
130 :
131 : std::string sReportFrequency() const;
132 : OutputProcessor::ReportingFrequency iReportFrequency() const;
133 : void setReportFrequency(const OutputProcessor::ReportingFrequency reportFrequency);
134 :
135 : OutputProcessor::TimeStepType timeStepType() const;
136 : void setTimeStepType(const OutputProcessor::TimeStepType timeStepType);
137 :
138 : int reportID() const;
139 : void setReportID(const int Id);
140 :
141 : OutputProcessor::Unit units() const;
142 : void setUnits(OutputProcessor::Unit units);
143 :
144 : std::string customUnits() const;
145 : void setCustomUnits(const std::string &customUnits);
146 :
147 : void pushValue(const double val);
148 : double value(size_t index) const;
149 : size_t numValues() const;
150 :
151 : virtual json getJSON() const;
152 :
153 : protected:
154 : std::string varName;
155 : std::string sReportFreq;
156 : OutputProcessor::ReportingFrequency iReportFreq = OutputProcessor::ReportingFrequency::EachCall;
157 : OutputProcessor::TimeStepType m_timeStepType = OutputProcessor::TimeStepType::Zone;
158 : int rptID = -1;
159 : OutputProcessor::Unit Units;
160 : std::string m_customUnits;
161 : std::vector<double> Values;
162 : };
163 :
164 30 : class OutputVariable : public Variable
165 : {
166 : public:
167 : OutputVariable(const std::string &VarName,
168 : const OutputProcessor::ReportingFrequency reportFrequency,
169 : const OutputProcessor::TimeStepType timeStepType,
170 : const int ReportID,
171 : OutputProcessor::Unit units);
172 :
173 : OutputVariable(const std::string &VarName,
174 : const OutputProcessor::ReportingFrequency reportFrequency,
175 : const OutputProcessor::TimeStepType timeStepType,
176 : const int ReportID,
177 : OutputProcessor::Unit units,
178 : const std::string &customUnits);
179 : };
180 :
181 23202 : class MeterVariable : public Variable
182 : {
183 : public:
184 0 : MeterVariable() = default;
185 : MeterVariable(const std::string &VarName,
186 : const OutputProcessor::ReportingFrequency reportFrequency,
187 : const int ReportID,
188 : OutputProcessor::Unit units,
189 : const bool MeterOnly,
190 : const bool Acculumative = false);
191 :
192 : bool accumulative() const;
193 : void setAccumulative(bool state);
194 : bool meterOnly() const;
195 : void setMeterOnly(bool state);
196 :
197 : json getJSON() const override;
198 :
199 : protected:
200 : bool acc = false;
201 : bool meter_only = true;
202 : };
203 :
204 : class DataFrame : public BaseResultObject
205 : {
206 : public:
207 : typedef std::pair<int, Variable> VarPtrPair;
208 :
209 : explicit DataFrame(const std::string &ReportFreq);
210 10794 : virtual ~DataFrame() = default;
211 :
212 : void addVariable(Variable const &var);
213 :
214 : void setRDataFrameEnabled(bool state);
215 : void setIDataFrameEnabled(bool state);
216 :
217 : bool rDataFrameEnabled() const;
218 : bool iDataFrameEnabled() const;
219 :
220 : void setRVariablesScanned(bool state);
221 : void setIVariablesScanned(bool state);
222 :
223 : bool rVariablesScanned() const;
224 : bool iVariablesScanned() const;
225 :
226 : void newRow(const int month, const int dayOfMonth, int hourOfDay, int curMin);
227 : // void newRow(const std::string &ts);
228 : virtual void pushVariableValue(const int reportID, double value);
229 :
230 : Variable &lastVariable();
231 :
232 : json getVariablesJSON();
233 : json getJSON() const;
234 :
235 : void writeReport(JsonOutputFilePaths &jsonOutputFilePaths, bool outputJSON, bool outputCBOR, bool outputMsgPack);
236 :
237 : protected:
238 : bool IDataFrameEnabled = false;
239 : bool RDataFrameEnabled = false;
240 : bool RVariablesScanned = false;
241 : bool IVariablesScanned = false;
242 : std::string ReportFrequency;
243 : std::vector<std::string> TS;
244 : std::map<int, Variable> variableMap;
245 : int lastVarID = -1;
246 : };
247 :
248 : class MeterDataFrame : public DataFrame
249 : {
250 : public:
251 4626 : explicit MeterDataFrame(const std::string &ReportFreq) : DataFrame(ReportFreq){};
252 4626 : virtual ~MeterDataFrame() = default;
253 :
254 : void addVariable(MeterVariable const &var);
255 :
256 : void pushVariableValue(const int reportID, double value) override;
257 :
258 : json getJSON(bool meterOnlyCheck = false) const;
259 :
260 : protected:
261 : std::map<int, MeterVariable> meterMap;
262 : };
263 :
264 3684 : class Table : public BaseResultObject
265 : {
266 : public:
267 : std::string TableName;
268 : std::string FootnoteText;
269 : std::vector<std::string> ColHeaders;
270 : std::vector<std::string> RowHeaders;
271 : std::vector<std::vector<std::string>> Data;
272 :
273 : Table(Array2D_string const &body,
274 : Array1D_string const &rowLabels,
275 : Array1D_string const &columnLabels,
276 : std::string const &tableName,
277 : std::string const &footnoteText);
278 :
279 : json getJSON() const;
280 : };
281 :
282 1994 : class Report : public BaseResultObject
283 : {
284 : public:
285 : std::string ReportName;
286 : std::string ReportForString;
287 : std::vector<Table> Tables;
288 :
289 : json getJSON() const;
290 : };
291 :
292 771 : class ReportsCollection : public BaseResultObject
293 : {
294 : public:
295 : typedef std::pair<std::string, Report> RptPtrPair;
296 :
297 : ReportsCollection();
298 :
299 : void addReportTable(Array2D_string const &body,
300 : Array1D_string const &rowLabels,
301 : Array1D_string const &columnLabels,
302 : std::string const &reportName,
303 : std::string const &reportForString,
304 : std::string const &tableName);
305 :
306 : void addReportTable(Array2D_string const &body,
307 : Array1D_string const &rowLabels,
308 : Array1D_string const &columnLabels,
309 : std::string const &reportName,
310 : std::string const &reportForString,
311 : std::string const &tableName,
312 : std::string const &footnoteText);
313 :
314 : json getJSON() const;
315 :
316 : protected:
317 : std::unordered_map<std::string, Report> reportsMap;
318 : Report rpt;
319 : };
320 :
321 8 : class CSVWriter : public BaseResultObject
322 : {
323 : public:
324 : CSVWriter() = default;
325 8 : explicit CSVWriter(std::size_t num_output_variables)
326 8 : {
327 8 : outputVariableIndices = std::vector<bool>(num_output_variables, false);
328 8 : }
329 :
330 : void writeOutput(EnergyPlusData &state, std::vector<std::string> const &outputVariables, InputOutputFile &outputFile, bool outputControl);
331 : void parseTSOutputs(EnergyPlusData &state,
332 : json const &data,
333 : std::vector<std::string> const &outputVariables,
334 : OutputProcessor::ReportingFrequency reportingFrequency);
335 :
336 : private:
337 : friend class EnergyPlus::EnergyPlusFixture;
338 : friend class EnergyPlus::ResultsFrameworkFixture;
339 :
340 : char s[129] = {0};
341 : OutputProcessor::ReportingFrequency smallestReportingFrequency = OutputProcessor::ReportingFrequency::Yearly;
342 : std::map<std::string, std::vector<std::string>> outputs;
343 : std::vector<bool> outputVariableIndices;
344 :
345 : static std::string &convertToMonth(EnergyPlusData &state, std::string &datetime);
346 : void updateReportingFrequency(OutputProcessor::ReportingFrequency reportingFrequency);
347 : // void readRVI();
348 : // void readMVI();
349 : };
350 :
351 : class ResultsFramework : public BaseResultObject
352 : {
353 : public:
354 771 : ResultsFramework() = default;
355 :
356 1542 : virtual ~ResultsFramework() = default;
357 :
358 : void setupOutputOptions(EnergyPlusData &state);
359 :
360 : bool timeSeriesEnabled() const;
361 :
362 : bool timeSeriesAndTabularEnabled() const;
363 :
364 : bool JSONEnabled() const;
365 :
366 : bool CBOREnabled() const;
367 :
368 : bool MsgPackEnabled() const;
369 :
370 : void initializeRTSDataFrame(const OutputProcessor::ReportingFrequency reportFrequency,
371 : const Array1D<OutputProcessor::RealVariableType> &RVariableTypes,
372 : const int NumOfRVariable,
373 : const OutputProcessor::TimeStepType timeStepType = OutputProcessor::TimeStepType::Zone);
374 :
375 : void initializeITSDataFrame(const OutputProcessor::ReportingFrequency reportFrequency,
376 : const Array1D<OutputProcessor::IntegerVariableType> &IVariableTypes,
377 : const int NumOfIVariable,
378 : const OutputProcessor::TimeStepType timeStepType = OutputProcessor::TimeStepType::Zone);
379 :
380 : void initializeMeters(const Array1D<OutputProcessor::MeterType> &EnergyMeters, const OutputProcessor::ReportingFrequency reportFrequency);
381 :
382 : DataFrame RIDetailedZoneTSData = DataFrame("Detailed-Zone");
383 : DataFrame RIDetailedHVACTSData = DataFrame("Detailed-HVAC");
384 : DataFrame RITimestepTSData = DataFrame("TimeStep");
385 : DataFrame RIHourlyTSData = DataFrame("Hourly");
386 : DataFrame RIDailyTSData = DataFrame("Daily");
387 : DataFrame RIMonthlyTSData = DataFrame("Monthly");
388 : DataFrame RIRunPeriodTSData = DataFrame("RunPeriod");
389 : DataFrame RIYearlyTSData = DataFrame("Yearly");
390 : MeterDataFrame TSMeters = MeterDataFrame("TimeStep");
391 : MeterDataFrame HRMeters = MeterDataFrame("Hourly");
392 : MeterDataFrame DYMeters = MeterDataFrame("Daily");
393 : MeterDataFrame MNMeters = MeterDataFrame("Monthly");
394 : MeterDataFrame SMMeters = MeterDataFrame("RunPeriod");
395 : MeterDataFrame YRMeters = MeterDataFrame("Yearly");
396 :
397 : void writeOutputs(EnergyPlusData &state);
398 :
399 : void addReportVariable(std::string_view const keyedValue,
400 : std::string_view const variableName,
401 : std::string const &units,
402 : OutputProcessor::ReportingFrequency const reportingInterval);
403 :
404 : void addReportMeter(std::string const &meter, std::string const &units, OutputProcessor::ReportingFrequency const reportingInterval);
405 :
406 : SimInfo SimulationInformation;
407 :
408 : std::vector<std::string> MDD;
409 : std::vector<std::string> RDD;
410 : ReportsCollection TabularReportsCollection;
411 :
412 : protected:
413 : bool tsEnabled = false;
414 : bool tsAndTabularEnabled = false;
415 : bool outputJSON = false;
416 : bool outputCBOR = false;
417 : bool outputMsgPack = false;
418 : std::vector<std::string> outputVariables;
419 :
420 : void writeTimeSeriesReports(JsonOutputFilePaths &jsonOutputFilePaths);
421 :
422 : void writeReport(JsonOutputFilePaths &jsonOutputFilePaths);
423 :
424 : void writeCSVOutput(EnergyPlusData &state);
425 :
426 : private:
427 : friend class EnergyPlus::EnergyPlusFixture;
428 : friend class EnergyPlus::ResultsFrameworkFixture;
429 :
430 : protected:
431 13 : inline bool hasRIDetailedZoneTSData() const
432 : {
433 13 : return RIDetailedZoneTSData.iDataFrameEnabled() || RIDetailedZoneTSData.rDataFrameEnabled();
434 : };
435 :
436 11 : inline bool hasRIDetailedHVACTSData() const
437 : {
438 11 : return RIDetailedHVACTSData.iDataFrameEnabled() || RIDetailedHVACTSData.rDataFrameEnabled();
439 : };
440 :
441 9 : inline bool hasRITimestepTSData() const
442 : {
443 9 : return RITimestepTSData.iDataFrameEnabled() || RITimestepTSData.rDataFrameEnabled();
444 : };
445 :
446 9 : inline bool hasRIHourlyTSData() const
447 : {
448 9 : return RIHourlyTSData.iDataFrameEnabled() || RIHourlyTSData.rDataFrameEnabled();
449 : };
450 :
451 9 : inline bool hasRIDailyTSData() const
452 : {
453 9 : return RIDailyTSData.iDataFrameEnabled() || RIDailyTSData.rDataFrameEnabled();
454 : };
455 :
456 9 : inline bool hasRIMonthlyTSData() const
457 : {
458 9 : return RIMonthlyTSData.iDataFrameEnabled() || RIMonthlyTSData.rDataFrameEnabled();
459 : };
460 :
461 9 : inline bool hasRIRunPeriodTSData() const
462 : {
463 9 : return RIRunPeriodTSData.iDataFrameEnabled() || RIRunPeriodTSData.rDataFrameEnabled();
464 : };
465 :
466 9 : inline bool hasRIYearlyTSData() const
467 : {
468 9 : return RIYearlyTSData.iDataFrameEnabled() || RIYearlyTSData.rDataFrameEnabled();
469 : };
470 :
471 12 : inline bool hasTSMeters() const
472 : {
473 12 : return TSMeters.rDataFrameEnabled();
474 : };
475 :
476 12 : inline bool hasHRMeters() const
477 : {
478 12 : return HRMeters.rDataFrameEnabled();
479 : };
480 :
481 11 : inline bool hasDYMeters() const
482 : {
483 11 : return DYMeters.rDataFrameEnabled();
484 : };
485 :
486 11 : inline bool hasMNMeters() const
487 : {
488 11 : return MNMeters.rDataFrameEnabled();
489 : };
490 :
491 9 : inline bool hasSMMeters() const
492 : {
493 9 : return SMMeters.rDataFrameEnabled();
494 : };
495 :
496 9 : inline bool hasYRMeters() const
497 : {
498 9 : return YRMeters.rDataFrameEnabled();
499 : };
500 :
501 4 : inline bool hasMeterData() const
502 : {
503 4 : return hasTSMeters() || hasHRMeters() || hasDYMeters() || hasMNMeters() || hasSMMeters() || hasYRMeters();
504 : };
505 :
506 4 : inline bool hasTSData() const
507 : {
508 6 : return hasRIDetailedZoneTSData() || hasRIDetailedHVACTSData() || hasRITimestepTSData() || hasRIHourlyTSData() || hasRIDailyTSData() ||
509 4 : hasRIMonthlyTSData() || hasRIRunPeriodTSData() || hasRIYearlyTSData();
510 : };
511 :
512 4 : inline bool hasOutputData() const
513 : {
514 4 : return hasTSData() || hasMeterData();
515 : };
516 : };
517 :
518 : } // namespace ResultsFramework
519 :
520 1542 : struct ResultsFrameworkData : BaseGlobalStruct
521 : {
522 :
523 : std::unique_ptr<ResultsFramework::ResultsFramework> resultsFramework = std::make_unique<ResultsFramework::ResultsFramework>();
524 :
525 0 : void clear_state() override
526 : {
527 0 : this->resultsFramework->DYMeters.setRDataFrameEnabled(false);
528 0 : this->resultsFramework->DYMeters.setRVariablesScanned(false);
529 0 : this->resultsFramework->DYMeters.setIVariablesScanned(false);
530 0 : this->resultsFramework->DYMeters.setIDataFrameEnabled(false);
531 :
532 0 : this->resultsFramework->TSMeters.setRVariablesScanned(false);
533 0 : this->resultsFramework->TSMeters.setRDataFrameEnabled(false);
534 0 : this->resultsFramework->TSMeters.setIDataFrameEnabled(false);
535 0 : this->resultsFramework->TSMeters.setIVariablesScanned(false);
536 :
537 0 : this->resultsFramework->HRMeters.setRVariablesScanned(false);
538 0 : this->resultsFramework->HRMeters.setRDataFrameEnabled(false);
539 0 : this->resultsFramework->HRMeters.setIDataFrameEnabled(false);
540 0 : this->resultsFramework->HRMeters.setIVariablesScanned(false);
541 :
542 0 : this->resultsFramework->MNMeters.setRVariablesScanned(false);
543 0 : this->resultsFramework->MNMeters.setRDataFrameEnabled(false);
544 0 : this->resultsFramework->MNMeters.setIDataFrameEnabled(false);
545 0 : this->resultsFramework->MNMeters.setIVariablesScanned(false);
546 :
547 0 : this->resultsFramework->SMMeters.setRVariablesScanned(false);
548 0 : this->resultsFramework->SMMeters.setRDataFrameEnabled(false);
549 0 : this->resultsFramework->SMMeters.setIDataFrameEnabled(false);
550 0 : this->resultsFramework->SMMeters.setIVariablesScanned(false);
551 :
552 0 : this->resultsFramework->YRMeters.setRVariablesScanned(false);
553 0 : this->resultsFramework->YRMeters.setRDataFrameEnabled(false);
554 0 : this->resultsFramework->YRMeters.setIDataFrameEnabled(false);
555 0 : this->resultsFramework->YRMeters.setIVariablesScanned(false);
556 0 : }
557 : };
558 :
559 : } // namespace EnergyPlus
560 :
561 : #endif
|