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 : #ifndef OutputProcessor_hh_INCLUDED
49 : #define OutputProcessor_hh_INCLUDED
50 :
51 : // C++ Headers
52 : #include <array>
53 : #include <iosfwd>
54 : #include <map>
55 :
56 : // ObjexxFCL Headers
57 : #include <ObjexxFCL/Array1D.hh>
58 : #include <ObjexxFCL/Array2D.hh>
59 :
60 : // EnergyPlus Headers
61 : #include <EnergyPlus/Data/BaseData.hh>
62 : #include <EnergyPlus/DataGlobals.hh>
63 : #include <EnergyPlus/DisplayRoutines.hh>
64 : #include <EnergyPlus/EPVector.hh>
65 : #include <EnergyPlus/EnergyPlus.hh>
66 : #include <EnergyPlus/ScheduleManager.hh>
67 :
68 : // Third party Headers
69 : #include "re2/re2.h"
70 :
71 : namespace EnergyPlus {
72 :
73 : // Forward declarations
74 : class InputOutputFile;
75 : struct EnergyPlusData;
76 :
77 : namespace OutputProcessor {
78 :
79 : enum class ReportVDD
80 : {
81 : Invalid = -1,
82 : No, // Don't report the variable dictionaries in any form
83 : Yes, // Report the variable dictionaries in "report format"
84 : IDF, // Report the variable dictionaries in "IDF format"
85 : Num
86 : };
87 :
88 : constexpr Real64 MinSetValue(99999999999999.0);
89 : constexpr Real64 MaxSetValue(-99999999999999.0);
90 : constexpr int IMinSetValue(999999);
91 : constexpr int IMaxSetValue(-999999);
92 :
93 : enum class VariableType
94 : {
95 : Invalid = -1,
96 : // NotFound, // ref: GetVariableKeyCountandType, 0 = not found // TODO: This is actually used separately from Invalid, need to get rid of it
97 : Integer, // ref: GetVariableKeyCountandType, 1 = integer
98 : Real, // ref: GetVariableKeyCountandType, 2 = real
99 : Meter, // ref: GetVariableKeyCountandType, 3 = meter
100 : Schedule, // ref: GetVariableKeyCountandType, 4 = schedule
101 : Num
102 : };
103 :
104 : enum class MeterType
105 : {
106 : Invalid = -1,
107 : Normal, // Type value for normal meters
108 : Custom, // Type value for custom meters
109 : CustomDec, // Type value for custom meters that decrement another meter
110 : CustomDiff, // Type value for custom meters that difference another meter
111 : Num
112 : };
113 :
114 : constexpr int N_WriteTimeStampFormatData(100);
115 :
116 : // For IP Units (tabular reports) certain resources will be put in sub-tables
117 : enum class RT_IPUnits
118 : {
119 : Invalid = -1,
120 : OtherJ,
121 : Electricity,
122 : Gas,
123 : Cooling,
124 : Water,
125 : OtherKG,
126 : OtherM3,
127 : OtherL,
128 : Num
129 : };
130 :
131 : enum class ReportFreq
132 : {
133 : Invalid = -1,
134 : EachCall, // Write out each time UpdatedataandReport is called
135 : TimeStep, // Write out at 'EndTimeStepFlag'
136 : Hour, // Write out at 'EndHourFlag'
137 : Day, // Write out at 'EndDayFlag'
138 : Month, // Write out at end of month (must be determined)
139 : Simulation, // Write out once per environment 'EndEnvrnFlag'
140 : Year, // Write out at 'EndYearFlag'
141 : Num
142 : };
143 :
144 : static constexpr std::array<std::string_view, (int)ReportFreq::Num> reportFreqNames = {
145 : "Each Call", // EachCall
146 : "TimeStep", // TimeStep
147 : "Hourly", // Hourly
148 : "Daily", // Daily
149 : "Monthly", // Monthly
150 : "RunPeriod", // Simulation
151 : "Annual" // Yearly
152 : };
153 :
154 : static constexpr std::array<std::string_view, (int)ReportFreq::Num> reportFreqNamesUC = {
155 : "EACH CALL", // EachCall
156 : "TIMESTEP", // TimeStep
157 : "HOURLY", // Hourly
158 : "DAILY", // Daily
159 : "MONTHLY", // Monthly
160 : "RUNPERIOD", // Simulation
161 : "ANNUAL" // Yearly
162 : };
163 :
164 : // What is this thing?
165 : constexpr std::array<int, (int)ReportFreq::Num> reportFreqArbitraryInts = {1, 1, 1, 7, 9, 11, 11};
166 :
167 : enum class StoreType
168 : {
169 : Invalid = -1,
170 : Average, // Type value for "averaged" variables // TODO: is this just for printing annual tables
171 : Sum, // Type value for "summed" variables
172 : Num
173 : };
174 :
175 : constexpr std::array<std::string_view, (int)StoreType::Num> storeTypeNames = {
176 : // "UNUSED",
177 : "Average", // Averaged
178 : "Sum" // Summed
179 : };
180 :
181 : enum class TimeStepType
182 : {
183 : Invalid = -1,
184 : Zone, // Type value for "zone" timestep variables // TODO: is this just for printing Annual tables?
185 : System, // Type value for "system" timestep variables
186 : Num
187 : };
188 :
189 : constexpr std::array<std::string_view, (int)TimeStepType::Num> timeStepTypeNames = {
190 : // "UNUSED",
191 : "Zone", // Zone
192 : "System" // System
193 : };
194 :
195 : enum class EndUseCat
196 : {
197 : Invalid = -1,
198 : Heating,
199 : Cooling,
200 : InteriorLights,
201 : ExteriorLights,
202 : InteriorEquipment,
203 : ExteriorEquipment,
204 : Fans,
205 : Pumps,
206 : HeatRejection,
207 : Humidification,
208 : HeatRecovery,
209 : WaterSystem,
210 : Refrigeration,
211 : Cogeneration,
212 : Baseboard,
213 : Boilers,
214 : CarbonEquivalentEmissions,
215 : Chillers,
216 : CoalEmissions,
217 : ColdStorageCharge,
218 : ColdStorageDischarge,
219 : Condensate,
220 : CoolingCoils,
221 : CoolingPanel,
222 : DieselEmissions,
223 : DistrictChilledWater,
224 : DistrictHotWater,
225 : ElectricityEmissions,
226 : ElectricStorage,
227 : FreeCooling,
228 : FuelOilNo1Emissions,
229 : FuelOilNo2Emissions,
230 : GasolineEmissions,
231 : HeatingCoils,
232 : HeatProduced,
233 : HeatRecoveryForCooling,
234 : HeatRecoveryForHeating,
235 : LoopToLoop,
236 : MainsWater,
237 : NaturalGasEmissions,
238 : OtherFuel1Emissions,
239 : OtherFuel2Emissions,
240 : Photovoltaic,
241 : PowerConversion,
242 : PropaneEmissions,
243 : PurchasedElectricityEmissions,
244 : RainWater,
245 : SoldElectricityEmissions,
246 : WellWater,
247 : WindTurbine,
248 : Num
249 : };
250 :
251 : static constexpr std::array<std::string_view, (int)EndUseCat::Num> endUseCatNames = {"Heating",
252 : "Cooling",
253 : "InteriorLights",
254 : "ExteriorLights",
255 : "InteriorEquipment",
256 : "ExteriorEquipment",
257 : "Fans",
258 : "Pumps",
259 : "HeatRejection",
260 : "Humidifier",
261 : "HeatRecovery",
262 : "WaterSystems",
263 : "Refrigeration",
264 : "Cogeneration",
265 : "Baseboard",
266 : "Boilers",
267 : "CarbonEquivalentEmissions",
268 : "Chillers",
269 : "CoalEmissions",
270 : "ColdStorageCharge",
271 : "ColdStorageDischarge",
272 : "Condensate",
273 : "CoolingCoils",
274 : "CoolingPanel",
275 : "DieselEmissions",
276 : "DistrictChilledWater",
277 : "DistrictHotWater",
278 : "ElectricityEmissions",
279 : "ElectricStorage",
280 : "FreeCooling",
281 : "FuelOilNo1Emissions",
282 : "FuelOilNo2Emissions",
283 : "GasolineEmissions",
284 : "HeatingCoils",
285 : "HeatProduced",
286 : "HeatRecoveryForCooling",
287 : "HeatRecoveryForHeating",
288 : "LoopToLoop",
289 : "MainsWater",
290 : "NaturalGasEmissions",
291 : "OtherFuel1Emissions",
292 : "OtherFuel2Emissions",
293 : "Photovoltaic",
294 : "PowerConversion",
295 : "PropaneEmissions",
296 : "PurchasedElectricityEmissions",
297 : "RainWater",
298 : "SoldElectricityEmissions",
299 : "WellWater",
300 : "WindTurbine"};
301 :
302 : static constexpr std::array<std::string_view, (int)EndUseCat::Num> endUseCatNamesUC = {"HEATING",
303 : "COOLING",
304 : "INTERIORLIGHTS",
305 : "EXTERIORLIGHTS",
306 : "INTERIOREQUIPMENT",
307 : "EXTERIOREQUIPMENT",
308 : "FANS",
309 : "PUMPS",
310 : "HEATREJECTION",
311 : "HUMIDIFIER",
312 : "HEATRECOVERY",
313 : "WATERSYSTEMS",
314 : "REFRIGERATION",
315 : "COGENERATION",
316 : "BASEBOARD",
317 : "BOILERS",
318 : "CARBONEQUIVALENTEMISSIONS",
319 : "CHILLERS",
320 : "COALEMISSIONS",
321 : "COLDSTORAGECHARGE",
322 : "COLDSTORAGEDISCHARGE",
323 : "CONDENSATE",
324 : "COOLINGCOILS",
325 : "COOLINGPANEL",
326 : "DIESELEMISSIONS",
327 : "DISTRICTCHILLEDWATER",
328 : "DISTRICTHOTWATER",
329 : "ELECTRICITYEMISSIONS",
330 : "ELECTRICSTORAGE",
331 : "FREECOOLING",
332 : "FUELOILNO1EMISSIONS",
333 : "FUELOILNO2EMISSIONS",
334 : "GASOLINEEMISSIONS",
335 : "HEATINGCOILS",
336 : "HEATPRODUCED",
337 : "HEATRECOVERYFORCOOLING",
338 : "HEATRECOVERYFORHEATING",
339 : "LOOPTOLOOP",
340 : "MAINSWATER",
341 : "NATURALGASEMISSIONS",
342 : "OTHERFUEL1EMISSIONS",
343 : "OTHERFUEL2EMISSIONS",
344 : "PHOTOVOLTAIC",
345 : "POWERCONVERSION",
346 : "PROPANEEMISSIONS",
347 : "PURCHASEDELECTRICITYEMISSIONS",
348 : "RAINWATER",
349 : "SOLDELECTRICITYEMISSIONS",
350 : "WELLWATER",
351 : "WINDTURBINE"};
352 :
353 : static constexpr std::array<Constant::EndUse, (int)EndUseCat::Num> endUseCat2endUse = {
354 : Constant::EndUse::Heating, // Heating
355 : Constant::EndUse::Cooling, // Cooling
356 : Constant::EndUse::InteriorLights, // InteriorLights
357 : Constant::EndUse::ExteriorLights, // ExteriorLights
358 : Constant::EndUse::InteriorEquipment, // InteriorEquipment
359 : Constant::EndUse::ExteriorEquipment, // ExteriorEquipment
360 : Constant::EndUse::Fans, // Fans
361 : Constant::EndUse::Pumps, // Pumps
362 : Constant::EndUse::HeatRejection, // HeatRejection
363 : Constant::EndUse::Humidification, // Humidification
364 : Constant::EndUse::HeatRecovery, // HeatRecovery
365 : Constant::EndUse::WaterSystem, // WaterSystem
366 : Constant::EndUse::Refrigeration, // Refrigeration
367 : Constant::EndUse::Cogeneration, // Cogeneration
368 : Constant::EndUse::Invalid, // Baseboard
369 : Constant::EndUse::Invalid, // Boilers
370 : Constant::EndUse::Invalid, // CarbonEquivalentEmissions
371 : Constant::EndUse::Invalid, // Chillers
372 : Constant::EndUse::Invalid, // CoalEmissions
373 : Constant::EndUse::Invalid, // ColdStorageCharge
374 : Constant::EndUse::Invalid, // ColdStorageDischarge
375 : Constant::EndUse::Invalid, // Condensate
376 : Constant::EndUse::Invalid, // CoolingCoils
377 : Constant::EndUse::Invalid, // CoolingPanel
378 : Constant::EndUse::Invalid, // DieselEmissions
379 : Constant::EndUse::Invalid, // DistrictChilledWater
380 : Constant::EndUse::Invalid, // DistrictHotWater
381 : Constant::EndUse::Invalid, // ElectricityEmissions
382 : Constant::EndUse::Invalid, // ElectricStorage
383 : Constant::EndUse::Invalid, // FreeCooling
384 : Constant::EndUse::Invalid, // FuelOilNo1Emissions
385 : Constant::EndUse::Invalid, // FuelOilNo2Emissions
386 : Constant::EndUse::Invalid, // GasolineEmissions
387 : Constant::EndUse::Invalid, // HeatingCoils
388 : Constant::EndUse::Invalid, // HeatProduced
389 : Constant::EndUse::Invalid, // HeatRecoveryForCooling
390 : Constant::EndUse::Invalid, // HeatRecoveryForHeating
391 : Constant::EndUse::Invalid, // LoopToLoop
392 : Constant::EndUse::Invalid, // MainsWater
393 : Constant::EndUse::Invalid, // NaturalGasEmissions
394 : Constant::EndUse::Invalid, // OtherFuel1Emissions
395 : Constant::EndUse::Invalid, // OtherFuel2Emissions
396 : Constant::EndUse::Invalid, // Photovoltaic
397 : Constant::EndUse::Invalid, // PowerConversion
398 : Constant::EndUse::Invalid, // PropaneEmissions
399 : Constant::EndUse::Invalid, // PurchasedElectricityEmissions
400 : Constant::EndUse::Invalid, // RainWater
401 : Constant::EndUse::Invalid, // SoldElectricityEmissions
402 : Constant::EndUse::Invalid, // WellWater,
403 : Constant::EndUse::Invalid, // WindTurbine,
404 : };
405 :
406 : enum class Group
407 : {
408 : Invalid = -1,
409 : Building,
410 : HVAC,
411 : Plant,
412 : Zone,
413 : SpaceType,
414 : Num
415 : };
416 :
417 : static constexpr std::array<std::string_view, (int)Group::Num> groupNames = {"Building", "HVAC", "Plant", "Zone", "SpaceType"};
418 : static constexpr std::array<std::string_view, (int)Group::Num> groupNamesUC = {"BUILDING", "HVAC", "PLANT", "ZONE", "SPACETYPE"};
419 :
420 : struct TimeSteps
421 : {
422 : Real64 *TimeStep = nullptr; // Pointer to the Actual Time Step Variable (Zone or HVAC)
423 : Real64 CurMinute = 0.0; // Current minute (decoded from real Time Step Value)
424 : };
425 :
426 : struct OutVar
427 : {
428 : int ddVarNum = -1;
429 : VariableType varType = VariableType::Invalid;
430 : TimeStepType timeStepType = TimeStepType::Zone; // Zone or System
431 : StoreType storeType = StoreType::Average; // Variable Type (Summed/Non-Static or Average/Static)
432 : Real64 Value = 0.0; // Current Value of the variable (to resolution of Zone Time Step)
433 : Real64 TSValue = 0.0; // Value of this variable at the Zone Time Step
434 : Real64 EITSValue = 0.0; // Value of this variable at the Zone Time Step for external interface
435 : Real64 StoreValue = 0.0; // At end of Zone Time Step, value is placed here for later reporting
436 : Real64 NumStored = 0.0; // Number of hours stored
437 : bool Stored = false; // True when value is stored
438 : bool Report = false; // User has requested reporting of this variable in the IDF
439 : bool tsStored = false; // if stored for this zone timestep
440 : bool thisTSStored = false; // if stored for this zone timestep
441 : int thisTSCount = 0;
442 : ReportFreq freq = ReportFreq::Hour; // How often to report this variable
443 : Real64 MaxValue = -9999.0; // Maximum reporting (only for Averaged variables, and those greater than Time Step)
444 : Real64 MinValue = 9999.0; // Minimum reporting (only for Averaged variables, and those greater than Time Step)
445 : int maxValueDate = 0; // Date stamp of maximum
446 : int minValueDate = 0; // Date stamp of minimum
447 : int ReportID = 0; // Report variable ID number
448 : Sched::Schedule *sched = nullptr; // If scheduled, this is schedule
449 : int ZoneMult = 1; // If metered, Zone Multiplier is applied
450 : int ZoneListMult = 1; // If metered, Zone List Multiplier is applied
451 :
452 : std::string keyColonName = ""; // Name of Variable key:variable
453 : std::string keyColonNameUC = ""; // Name of Variable (Uppercase)
454 : std::string name = ""; // Name of Variable
455 : std::string nameUC = ""; // Name of Variable with out key in uppercase
456 : std::string key = ""; // Name of key only
457 : std::string keyUC = ""; // Name of key only witht out variable in uppercase
458 :
459 : Constant::Units units = Constant::Units::Invalid; // Units for Variable
460 : std::string unitNameCustomEMS; // name of units when customEMS is used for EMS variables that are unusual
461 :
462 : std::string indexGroup = "";
463 : int indexGroupKey = -1; // Is this thing even used?
464 :
465 : std::vector<int> meterNums; // Meter Numbers
466 :
467 8401 : virtual ~OutVar(){};
468 :
469 : std::string multiplierString() const;
470 :
471 : void writeReportData(EnergyPlusData &state);
472 :
473 : void writeOutput(EnergyPlusData &state, // Real variable to write out
474 : ReportFreq const freq);
475 :
476 : void writeReportDictionaryItem(EnergyPlusData &state);
477 : };
478 :
479 : struct OutVarReal : public OutVar
480 : {
481 : Real64 *Which = nullptr; // Pointer to the actual variable holding the value
482 :
483 9590 : OutVarReal()
484 9590 : {
485 9590 : varType = VariableType::Real;
486 9590 : }
487 : };
488 :
489 : struct OutVarInt : public OutVar
490 : {
491 : // Members
492 : int *Which = nullptr; // The POINTER to the actual variable holding the value
493 :
494 51 : OutVarInt()
495 51 : {
496 51 : varType = VariableType::Integer;
497 51 : }
498 : };
499 :
500 : struct DDOutVar
501 : {
502 : // Members
503 : std::string name = ""; // Name of Variable
504 : TimeStepType timeStepType = TimeStepType::Invalid; // Type whether Zone or HVAC
505 : StoreType storeType = StoreType::Invalid; // Variable Type (Summed/Non-Static or Average/Static)
506 : VariableType variableType = VariableType::Invalid; // Integer, Real.
507 : int Next = -1; // Next variable of same name (different units)
508 : bool ReportedOnDDFile = false; // true after written to .rdd/.mdd file
509 : Constant::Units units = Constant::Units::Invalid; // Units for Variable
510 : std::string unitNameCustomEMS = ""; // name of units when customEMS is used for EMS variables that are unusual
511 :
512 : std::vector<int> keyOutVarNums;
513 : };
514 :
515 : struct ReqVar // Structure for requested Report Variables
516 : {
517 : // Members
518 : std::string key = ""; // Could be blank or "*"
519 : std::string name = ""; // Name of Variable
520 : ReportFreq freq = ReportFreq::Hour; // Reporting Frequency
521 : Sched::Schedule *sched = nullptr; // Schedule
522 : bool Used = false; // True when this combination (key, varname, frequency) has been set
523 :
524 : bool is_simple_string = true; // Whether the Key potentially includes a Regular Expression pattern
525 : std::shared_ptr<RE2> case_insensitive_pattern = nullptr;
526 : };
527 :
528 : struct MeterPeriod
529 : {
530 : Real64 Value = 0.0; // Daily Value
531 : Real64 MaxVal = MaxSetValue; // Maximum Value
532 : int MaxValDate = -1; // Date stamp of maximum
533 : Real64 MinVal = MinSetValue; // Minimum Value
534 : int MinValDate = -1; // Date stamp of minimum
535 :
536 : bool Rpt = false; // Report at End of Day
537 : bool RptFO = false; // Report at End of Day -- meter file only
538 : int RptNum = 0; // Report Number
539 : bool accRpt = false;
540 : bool accRptFO = false;
541 : int accRptNum = 0;
542 :
543 0 : void resetVals()
544 : {
545 0 : Value = 0.0;
546 0 : MaxVal = MaxSetValue;
547 0 : MaxValDate = 0;
548 0 : MinVal = MinSetValue;
549 0 : MinValDate = 0;
550 0 : }
551 :
552 : void WriteReportData(EnergyPlusData &state, ReportFreq freq);
553 : };
554 :
555 : struct Meter
556 : {
557 : // Members
558 : std::string Name = ""; // Name of the meter
559 : MeterType type = MeterType::Invalid; // type of meter
560 : Constant::eResource resource = Constant::eResource::Invalid; // Resource Type of the meter
561 : EndUseCat endUseCat = EndUseCat::Invalid; // End Use of the meter
562 : std::string EndUseSub = ""; // End Use subcategory of the meter
563 : Group group = Group::Invalid; // Group of the meter
564 : Constant::Units units = Constant::Units::Invalid; // Units for the Meter
565 : RT_IPUnits RT_forIPUnits; // Resource type number for IP Units (tabular) reporting
566 :
567 : Real64 CurTSValue = 0.0; // Current TimeStep Value (internal access)
568 :
569 : std::string indexGroup = "";
570 :
571 : std::array<MeterPeriod, (int)ReportFreq::Num> periods;
572 :
573 : MeterPeriod periodLastSM;
574 : MeterPeriod periodFinYrSM;
575 :
576 : std::vector<int> dstMeterNums; // Destination meters for custom meters
577 :
578 : int decMeterNum = -1; // for custom decrement meters, the number of the meter being subtracted from
579 : std::vector<int> srcVarNums; // Source variables for custom meters
580 : std::vector<int> srcMeterNums; // Source meters for custom meters
581 :
582 9511 : Meter(std::string_view name)
583 66577 : {
584 9511 : Name = std::string(name);
585 9511 : }
586 : };
587 :
588 : struct MeteredVar
589 : {
590 : int num = -1;
591 : std::string name = "";
592 : Constant::eResource resource = Constant::eResource::Invalid;
593 : Constant::Units units = Constant::Units::Invalid;
594 : VariableType varType = VariableType::Invalid;
595 : TimeStepType timeStepType = TimeStepType::Invalid;
596 : EndUseCat endUseCat = EndUseCat::Invalid;
597 : Group group = Group::Invalid;
598 : int rptNum = -1;
599 : };
600 :
601 : struct MeterData : MeteredVar
602 : {
603 : Constant::HeatOrCool heatOrCool = Constant::HeatOrCool::NoHeatNoCool;
604 : Real64 curMeterReading = 0.0;
605 :
606 : // C++ doesn't figure this out automatically, so we have to do it ourselves
607 455 : MeterData &operator=(MeteredVar const &mv)
608 : {
609 455 : MeteredVar::operator=(mv);
610 455 : return *this;
611 : }
612 : };
613 :
614 : struct EndUseCategoryType
615 : {
616 : // Members
617 : std::string Name; // End use category name
618 : std::string DisplayName; // Display name for output table
619 : int NumSubcategories = 0;
620 : Array1D_string SubcategoryName; // Array of subcategory names
621 : int numSpaceTypes = 0;
622 : Array1D_string spaceTypeName; // Array of space type names
623 : };
624 :
625 : int DetermineMinuteForReporting(EnergyPlusData const &state);
626 :
627 : void InitializeOutput(EnergyPlusData &state);
628 :
629 : void SetupTimePointers(EnergyPlusData &state,
630 : OutputProcessor::TimeStepType timeStepType, // Which timestep is being set up, 'Zone'=1, 'HVAC'=2
631 : Real64 &TimeStep // The timestep variable. Used to get the address
632 : );
633 :
634 : void CheckReportVariable(EnergyPlusData &state,
635 : std::string_view const name, // String Name of variable (without units)
636 : std::string const &key, // Associated Key for this variable
637 : std::vector<int> &reqVarNums);
638 :
639 : void GetReportVariableInput(EnergyPlusData &state);
640 :
641 : ReportFreq determineFrequency(EnergyPlusData &state, std::string_view const FreqString);
642 :
643 : std::string produceDateString(int DateValue, // Date of min/max
644 : ReportFreq freq // Reporting Frequency
645 : );
646 :
647 : // *****************************************************************************
648 : // The following routines implement Energy Meters in EnergyPlus.
649 : // *****************************************************************************
650 :
651 : void GetCustomMeterInput(EnergyPlusData &state, bool &ErrorsFound);
652 :
653 : int AddMeter(EnergyPlusData &state,
654 : std::string const &Name, // Name for the meter
655 : Constant::Units units, // Units for the meter
656 : Constant::eResource resource, // ResourceType for the meter
657 : EndUseCat endUseCat, // EndUse for the meter
658 : std::string_view const EndUseSub, // EndUse subcategory for the meter
659 : Group group, // Group for the meter
660 : int outVarNum);
661 :
662 : void AttachMeters(EnergyPlusData &state,
663 : Constant::Units units, // Units for this meter
664 : Constant::eResource resource, // Electricity, Gas, etc.
665 : EndUseCat endUseCat, // End-use category (Lights, Heating, etc.)
666 : std::string_view const EndUseSub, // End-use subcategory (user-defined, e.g., General Lights, Task Lights, etc.)
667 : Group group, // Group key (Facility, Zone, Building, etc.)
668 : std::string const &ZoneName, // Zone key only applicable for Building group
669 : std::string const &SpaceTypeName, // Space Type key only applicable for Building group
670 : int RepVarNum // Number of this report variable
671 : );
672 :
673 : OutputProcessor::RT_IPUnits GetResourceIPUnits(EnergyPlusData &state,
674 : Constant::eResource resource, // Resource Type
675 : Constant::Units units, // Meter units
676 : bool &ErrorsFound // true if errors found during subroutine
677 : );
678 :
679 : void UpdateMeters(EnergyPlusData &state, int TimeStamp); // Current TimeStamp (for max/min)
680 :
681 : void ReportTSMeters(EnergyPlusData &state,
682 : Real64 StartMinute, // Start Minute for TimeStep
683 : Real64 EndMinute, // End Minute for TimeStep
684 : bool &PrintESOTimeStamp, // True if the ESO Time Stamp also needs to be printed
685 : bool PrintTimeStampToSQL // Print Time Stamp to SQL file
686 : );
687 :
688 : void ReportMeters(EnergyPlusData &state, ReportFreq freq, bool PrintTimeStampToSQL // Print Time Stamp to SQL file
689 : );
690 :
691 : void ReportForTabularReports(EnergyPlusData &state);
692 :
693 : std::string DateToStringWithMonth(int codedDate); // word containing encoded month, day, hour, minute
694 :
695 : void ReportMeterDetails(EnergyPlusData &state);
696 :
697 : // *****************************************************************************
698 : // End of routines for Energy Meters implementation in EnergyPlus.
699 : // *****************************************************************************
700 :
701 : void WriteTimeStampFormatData(EnergyPlusData &state,
702 : InputOutputFile &outputFile,
703 : ReportFreq freq, // Reporting frequency.
704 : int reportID, // The ID of the time stamp
705 : std::string const &DayOfSimChr, // the number of days simulated so far
706 : bool writeToSQL, // write to SQLite
707 : int const Month = -1, // the month of the reporting interval
708 : int const DayOfMonth = -1, // The day of the reporting interval
709 : int const Hour = -1, // The hour of the reporting interval
710 : Real64 const EndMinute = -1.0, // The last minute in the reporting interval
711 : Real64 const StartMinute = -1.0, // The starting minute of the reporting interval
712 : int const DST = -1, // A flag indicating whether daylight savings time is observed
713 : std::string_view const DayType = "" // The day tied for the data (e.g., Monday)
714 : );
715 :
716 : void WriteYearlyTimeStamp(EnergyPlusData &state,
717 : InputOutputFile &outputFile,
718 : int reportID,
719 : std::string const &yearOfSimChr, // the year of the simulation
720 : bool writeToSQL);
721 :
722 : void WriteMeterDictionaryItem(EnergyPlusData &state,
723 : ReportFreq freq, // The reporting interval (e.g., hourly, daily)
724 : StoreType storeType,
725 : int reportID, // The reporting ID in for the variable
726 : std::string const &indexGroup, // The reporting group for the variable
727 : std::string const &meterName, // The variable's meter name
728 : Constant::Units unit, // The variables units
729 : bool cumulativeMeterFlag, // A flag indicating cumulative data
730 : bool meterFileOnlyFlag // A flag indicating whether the data is to be written to standard output
731 : );
732 :
733 : void WriteCumulativeReportMeterData(EnergyPlusData &state,
734 : int reportID, // The variable's report ID
735 : Real64 repValue, // The variable's value
736 : bool meterOnlyFlag // A flag that indicates if the data should be written to standard output
737 : );
738 :
739 : void WriteNumericData(EnergyPlusData &state,
740 : int reportID, // The variable's reporting ID
741 : Real64 repValue // The variable's value
742 : );
743 :
744 : void WriteNumericData(EnergyPlusData &state,
745 : int reportID, // The variable's reporting ID
746 : int32_t repValue // The variable's value
747 : );
748 :
749 : int DetermineIndexGroupKeyFromMeterName(EnergyPlusData &state, std::string const &meterName); // the meter name
750 :
751 : std::string DetermineIndexGroupFromMeterGroup(Meter const *meter); // the meter
752 :
753 : void SetInternalVariableValue(EnergyPlusData &state,
754 : OutputProcessor::VariableType varType, // 1=integer, 2=real, 3=meter
755 : int keyVarIndex, // Array index
756 : Real64 SetRealVal, // real value to set, if type is real or meter
757 : int SetIntVal // integer value to set if type is integer
758 : );
759 :
760 : std::string unitStringFromDDitem(EnergyPlusData &state, int ddItemPtr // index provided for DDVariableTypes
761 : );
762 :
763 : struct APIOutputVariableRequest
764 : {
765 : std::string varName;
766 : std::string varKey;
767 : };
768 :
769 : std::string standardizeEndUseSub(EndUseCat endUseCat, std::string_view const endUseSubCat);
770 : void addEndUseSubcategory(EnergyPlusData &state, EndUseCat endUseCat, std::string_view const endUseSubCat);
771 : void addEndUseSpaceType(EnergyPlusData &state, EndUseCat endUseCat, std::string_view const endUseSpTypeName);
772 : } // namespace OutputProcessor
773 :
774 : //==============================================================================================
775 : // *****************************************************************************
776 : // These routines are available outside the OutputProcessor Module (i.e. calling
777 : // routines do not have to "USE OutputProcessor". But each of these routines
778 : // will use the OutputProcessor and take advantage that everything is PUBLIC
779 : // within the OutputProcessor.
780 : // *****************************************************************************
781 :
782 : void SetupOutputVariable(
783 : EnergyPlusData &state,
784 : std::string_view const name, // String Name of variable (with units)
785 : Constant::Units units, // Actual units corresponding to the actual variable
786 : Real64 &ActualVariable, // Actual Variable, used to set up pointer
787 : OutputProcessor::TimeStepType timeStepType, // Zone, HeatBalance=1, HVAC, System, Plant=2
788 : OutputProcessor::StoreType variableType, // State, Average=1, NonState, Sum=2
789 : std::string const &key, // Associated Key for this variable
790 : Constant::eResource resource = Constant::eResource::Invalid, // Meter Resource Type (Electricity, Gas, etc)
791 : OutputProcessor::Group group = OutputProcessor::Group::Invalid, // Meter Super Group Key (Building, System, Plant)
792 : OutputProcessor::EndUseCat endUseCat = OutputProcessor::EndUseCat::Invalid, // Meter End Use Key (Lights, Heating, etc)
793 : std::string_view const endUseSub = {}, // Meter End Use Sub Key (General Lights, Task Lights, etc)
794 : std::string const &zone = {}, // Meter Zone Key (zone name)
795 : int const zoneMult = 1, // Zone Multiplier, defaults to 1
796 : int const zoneListMult = 1, // Zone List Multiplier, defaults to 1
797 : std::string const &spaceType = {}, // Space type (applicable for Building group only)
798 : int const indexGroupKey = -999, // Group identifier for SQL output
799 : std::string_view const customUnitName = {}, // the custom name for the units from EMS definition of units
800 : OutputProcessor::ReportFreq reportFreq = OutputProcessor::ReportFreq::Hour // Internal use -- causes reporting at this freqency
801 : );
802 :
803 : void SetupOutputVariable(EnergyPlusData &state,
804 : std::string_view const VariableName, // String Name of variable
805 : Constant::Units VariableUnit, // Actual units corresponding to the actual variable
806 : int &ActualVariable, // Actual Variable, used to set up pointer
807 : OutputProcessor::TimeStepType TimeStepType, // Zone, HeatBalance=1, HVAC, System, Plant=2
808 : OutputProcessor::StoreType VariableType, // State, Average=1, NonState, Sum=2
809 : std::string const &KeyedValue, // Associated Key for this variable
810 : int const indexGroupKey = -999, // Group identifier for SQL output
811 : OutputProcessor::ReportFreq freq = OutputProcessor::ReportFreq::Hour // Internal use -- causes reporting at this freqency
812 : );
813 :
814 : void UpdateDataandReport(EnergyPlusData &state, OutputProcessor::TimeStepType TimeStepTypeKey); // What kind of data to update (Zone, HVAC)
815 :
816 : void GenOutputVariablesAuditReport(EnergyPlusData &state);
817 :
818 : void UpdateMeterReporting(EnergyPlusData &state);
819 :
820 : void SetInitialMeterReportingAndOutputNames(EnergyPlusData &state,
821 : int WhichMeter, // Which meter number
822 : bool MeterFileOnlyIndicator, // true if this is a meter file only reporting
823 : OutputProcessor::ReportFreq freq, // at what frequency is the meter reported
824 : bool CumulativeIndicator // true if this is a Cumulative meter reporting
825 : );
826 :
827 : int GetMeterIndex(EnergyPlusData const &state, std::string const &MeterName);
828 :
829 : Constant::eResource GetMeterResourceType(EnergyPlusData const &state, int MeterNumber); // Which Meter Number (from GetMeterIndex)
830 :
831 : Real64 GetCurrentMeterValue(EnergyPlusData const &state, int MeterNumber); // Which Meter Number (from GetMeterIndex)
832 :
833 : Real64 GetInstantMeterValue(EnergyPlusData &state,
834 : int MeterNumber, // Which Meter Number (from GetMeterIndex)
835 : OutputProcessor::TimeStepType TimeStepType // Whether this is zone of HVAC
836 : );
837 :
838 : Real64 GetInternalVariableValue(EnergyPlusData &state,
839 : OutputProcessor::VariableType varType, // 1=integer, 2=real, 3=meter
840 : int keyVarIndex // Array index
841 : );
842 :
843 : Real64 GetInternalVariableValueExternalInterface(EnergyPlusData &state,
844 : OutputProcessor::VariableType varType, // 1=integer, 2=REAL(r64), 3=meter
845 : int keyVarIndex // Array index
846 : );
847 :
848 : int GetNumMeteredVariables(EnergyPlusData const &state,
849 : std::string const &ComponentType, // Given Component Type
850 : std::string const &ComponentName // Given Component Name (user defined)
851 : );
852 :
853 : int GetMeteredVariables(EnergyPlusData &state,
854 : std::string const &ComponentName, // Given Component Name (user defined)
855 : Array1D<OutputProcessor::MeteredVar> &meteredVars // Number Found
856 : );
857 :
858 : void GetVariableKeyCountandType(EnergyPlusData &state,
859 : std::string const &varName, // Standard variable name
860 : int &numKeys, // Number of keys found
861 : OutputProcessor::VariableType &varType,
862 : OutputProcessor::StoreType &varAvgSum, // Variable is Averaged=1 or Summed=2
863 : OutputProcessor::TimeStepType &varStepType, // Variable time step is Zone=1 or HVAC=2
864 : Constant::Units &varUnits // Units enumeration
865 : );
866 :
867 : void GetVariableKeys(EnergyPlusData &state,
868 : std::string const &varName, // Standard variable name
869 : OutputProcessor::VariableType varType,
870 : Array1D_string &keyNames,
871 : Array1D_int &keyVarNums // Array index for
872 : );
873 :
874 : bool ReportingThisVariable(EnergyPlusData &state, std::string const &RepVarName);
875 :
876 : void InitPollutionMeterReporting(EnergyPlusData &state, OutputProcessor::ReportFreq freq);
877 :
878 : void ProduceRDDMDD(EnergyPlusData &state);
879 :
880 : int AddDDOutVar(EnergyPlusData const &state,
881 : std::string_view const nameUC, // Variable Name
882 : OutputProcessor::TimeStepType TimeStepType,
883 : OutputProcessor::StoreType StateType,
884 : OutputProcessor::VariableType VariableType,
885 : Constant::Units unitsForVar,
886 : std::string_view const customUnitName = {} // the custom name for the units from EMS definition of units
887 : );
888 :
889 : int initErrorFile(EnergyPlusData &state);
890 :
891 : struct OutputProcessorData : BaseGlobalStruct
892 : {
893 : int NumVariablesForOutput = 0;
894 : int MaxVariablesForOutput = 0;
895 : int NumTotalRVariable = 0;
896 : int NumOfRVariable = 0;
897 : int NumOfRVariable_Setup = 0;
898 : int NumOfRVariable_Sum = 0;
899 : int NumOfRVariable_Meter = 0;
900 : int NumOfIVariable = 0;
901 : int NumOfIVariable_Setup = 0;
902 : int NumTotalIVariable = 0;
903 : int NumOfIVariable_Sum = 0;
904 : bool OutputInitialized = false;
905 : OutputProcessor::ReportVDD ProduceReportVDD = OutputProcessor::ReportVDD::No;
906 : int NumHoursInMonth = 0;
907 : int NumHoursInSim = 0;
908 : std::vector<Real64> meterValues; // This holds the current timestep value for each meter.
909 :
910 : std::array<int, (int)OutputProcessor::ReportFreq::Num> freqStampReportNums = {-1, -1, -1, -1, -1, -1, -1};
911 : std::array<bool, (int)OutputProcessor::ReportFreq::Num> freqTrackingVariables = {false, false, false, false, false, false, false};
912 :
913 : Real64 TimeStepZoneSec = 0; // Seconds from NumTimeStepInHour
914 : bool ErrorsLogged = false;
915 : bool isFinalYear = false;
916 : bool GetOutputInputFlag = true;
917 : OutputProcessor::ReportFreq minimumReportFreq = OutputProcessor::ReportFreq::EachCall;
918 : std::vector<OutputProcessor::APIOutputVariableRequest> apiVarRequests;
919 : int ReportNumberCounter = 0; // The report number is used in output reports as a key.
920 : int LHourP = -1; // Helps set hours for timestamp output
921 : Real64 LStartMin = -1.0; // Helps set minutes for timestamp output
922 : Real64 LEndMin = -1.0; // Helps set minutes for timestamp output
923 : bool GetMeterIndexFirstCall = true; // trigger setup in GetMeterIndex
924 : bool InitFlag = true;
925 :
926 : std::array<OutputProcessor::TimeSteps, (int)OutputProcessor::TimeStepType::Num> TimeValue; // Pointers to the actual TimeStep variables
927 :
928 : std::vector<OutputProcessor::OutVar *> outVars; // Variables array (use NumOfRVariables to traverse)
929 : std::vector<OutputProcessor::DDOutVar *> ddOutVars; // Variable Types structure (use NumVariablesForOutput to traverse)
930 : std::map<std::string, int> ddOutVarMap;
931 : std::vector<OutputProcessor::ReqVar *> reqVars;
932 :
933 : std::vector<OutputProcessor::Meter *> meters;
934 : std::map<std::string, int> meterMap;
935 :
936 : char stamp[OutputProcessor::N_WriteTimeStampFormatData];
937 : bool Rept = false;
938 : bool OpaqSurfWarned = false;
939 :
940 : // End-use stuff
941 : int MaxNumSubcategories = 1;
942 : int maxNumEndUseSpaceTypes = 1;
943 : EPVector<OutputProcessor::EndUseCategoryType> EndUseCategory;
944 :
945 2126 : void init_constant_state([[maybe_unused]] EnergyPlusData &state) override
946 : {
947 2126 : }
948 :
949 1152 : void init_state([[maybe_unused]] EnergyPlusData &state) override
950 : {
951 1152 : }
952 :
953 2100 : void clear_state() override
954 : {
955 2100 : this->NumVariablesForOutput = 0;
956 2100 : this->MaxVariablesForOutput = 0;
957 2100 : this->NumOfRVariable_Setup = 0;
958 2100 : this->NumTotalRVariable = 0;
959 2100 : this->NumOfRVariable_Sum = 0;
960 2100 : this->NumOfRVariable_Meter = 0;
961 2100 : this->NumOfIVariable_Setup = 0;
962 2100 : this->NumTotalIVariable = 0;
963 2100 : this->NumOfIVariable_Sum = 0;
964 2100 : this->OutputInitialized = false;
965 2100 : this->ProduceReportVDD = OutputProcessor::ReportVDD::No;
966 2100 : this->NumHoursInMonth = 0;
967 2100 : this->NumHoursInSim = 0;
968 2100 : this->meterValues.clear();
969 2100 : this->freqStampReportNums = {-1, -1, -1, -1, -1, -1, -1};
970 2100 : this->freqTrackingVariables = {false};
971 2100 : this->TimeStepZoneSec = 0;
972 2100 : this->ErrorsLogged = false;
973 2100 : this->isFinalYear = false;
974 2100 : this->GetOutputInputFlag = true;
975 2100 : this->minimumReportFreq = OutputProcessor::ReportFreq::EachCall;
976 2100 : this->apiVarRequests.clear();
977 2100 : this->ReportNumberCounter = 0;
978 2100 : this->LHourP = -1;
979 2100 : this->LStartMin = -1.0;
980 2100 : this->LEndMin = -1.0;
981 2100 : this->GetMeterIndexFirstCall = true;
982 2100 : this->InitFlag = true;
983 :
984 6300 : for (int i = 0; i < (int)OutputProcessor::TimeStepType::Num; ++i)
985 4200 : new (&this->TimeValue[i]) OutputProcessor::TimeSteps();
986 :
987 10498 : for (int i = 0; i < (int)this->outVars.size(); ++i)
988 8398 : delete this->outVars[i];
989 2100 : this->outVars.clear();
990 :
991 54297 : for (int i = 0; i < (int)this->ddOutVars.size(); ++i)
992 52197 : delete this->ddOutVars[i];
993 2100 : this->ddOutVars.clear();
994 2100 : this->ddOutVarMap.clear();
995 :
996 2400 : for (int i = 0; i < (int)this->reqVars.size(); ++i)
997 300 : delete this->reqVars[i];
998 2100 : this->reqVars.clear();
999 :
1000 10955 : for (int i = 0; i < (int)this->meters.size(); ++i)
1001 8855 : delete this->meters[i];
1002 2100 : this->meters.clear();
1003 2100 : this->meterMap.clear();
1004 :
1005 2100 : this->Rept = false;
1006 2100 : this->OpaqSurfWarned = false;
1007 :
1008 2100 : this->MaxNumSubcategories = 1;
1009 2100 : this->maxNumEndUseSpaceTypes = 1;
1010 2100 : this->EndUseCategory.deallocate();
1011 2100 : }
1012 : };
1013 :
1014 : } // namespace EnergyPlus
1015 :
1016 : #endif
|