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 : // C++ Headers
49 : #include <algorithm>
50 : #include <cassert>
51 : #include <cmath>
52 : #include <cstdio>
53 : #include <cstring>
54 : #include <memory>
55 : #include <string>
56 : #include <unordered_set>
57 :
58 : // ObjexxFCL Headers
59 : #include <ObjexxFCL/Array.functions.hh>
60 : #include <ObjexxFCL/Fmath.hh>
61 : #include <ObjexxFCL/string.functions.hh>
62 :
63 : // EnergyPlus Headers
64 : #include "re2/re2.h"
65 : #include <EnergyPlus/Data/EnergyPlusData.hh>
66 : #include <EnergyPlus/DataEnvironment.hh>
67 : #include <EnergyPlus/DataGlobalConstants.hh>
68 : #include <EnergyPlus/DataIPShortCuts.hh>
69 : #include <EnergyPlus/DataOutputs.hh>
70 : #include <EnergyPlus/DataStringGlobals.hh>
71 : #include <EnergyPlus/DataSystemVariables.hh>
72 : #include <EnergyPlus/General.hh>
73 : #include <EnergyPlus/GlobalNames.hh>
74 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
75 : #include <EnergyPlus/OutputProcessor.hh>
76 : #include <EnergyPlus/OutputReportPredefined.hh>
77 : #include <EnergyPlus/ResultsFramework.hh>
78 : #include <EnergyPlus/SQLiteProcedures.hh>
79 : #include <EnergyPlus/ScheduleManager.hh>
80 : #include <EnergyPlus/SortAndStringUtilities.hh>
81 : #include <EnergyPlus/UtilityRoutines.hh>
82 :
83 : #include <fmt/ostream.h>
84 : #include <milo/dtoa.h>
85 : #include <milo/itoa.h>
86 :
87 : namespace EnergyPlus {
88 :
89 : namespace OutputProcessor {
90 :
91 : // MODULE INFORMATION:
92 : // AUTHOR Linda Lawrie
93 : // DATE WRITTEN December 1998
94 : // MODIFIED na
95 : // RE-ENGINEERED na
96 :
97 : // PURPOSE OF THIS MODULE:
98 : // This module contains the major Output Processor routines.
99 : // In addition, in this file are several routines which can be called
100 : // without using the OutputProcessor Module
101 :
102 : // METHODOLOGY EMPLOYED:
103 : // Lots of pointers and other fancy data stuff.
104 :
105 : // Routines tagged on the end of this module:
106 : // AddToOutputVariableList
107 : // AssignReportNumber
108 : // GenOutputVariablesAuditReport
109 : // GetCurrentMeterValue
110 : // GetInstantMeterValue
111 : // GetInternalVariableValue
112 : // GetInternalVariableValueExternalInterface
113 : // GetMeteredVariables
114 : // GetMeterIndex
115 : // GetMeterResourceType
116 : // GetNumMeteredVariables
117 : // GetVariableKeyCountandType
118 : // GetVariableKeys
119 : // InitPollutionMeterReporting
120 : // ProduceRDDMDD
121 : // ReportingThisVariable
122 : // SetInitialMeterReportingAndOutputNames
123 : // SetupOutputVariable
124 : // UpdateDataandReport
125 : // UpdateMeterReporting
126 :
127 : // Functions
128 :
129 59 : inline void ReallocateRVar(EnergyPlusData &state)
130 : {
131 59 : state.dataOutputProcessor->RVariableTypes.redimension(state.dataOutputProcessor->MaxRVariable += RVarAllocInc);
132 59 : }
133 :
134 302 : inline void ReallocateIVar(EnergyPlusData &state)
135 : {
136 302 : state.dataOutputProcessor->IVariableTypes.redimension(state.dataOutputProcessor->MaxIVariable += IVarAllocInc);
137 302 : }
138 :
139 771 : void InitializeOutput(EnergyPlusData &state)
140 : {
141 :
142 : // SUBROUTINE INFORMATION:
143 : // AUTHOR Linda K. Lawrie
144 : // DATE WRITTEN December 1998
145 : // MODIFIED na
146 : // RE-ENGINEERED na
147 :
148 : // PURPOSE OF THIS SUBROUTINE:
149 : // This subroutine initializes the OutputProcessor data structures.
150 :
151 : // METHODOLOGY EMPLOYED:
152 : // na
153 :
154 : // REFERENCES:
155 : // na
156 :
157 : // USE STATEMENTS:
158 : // na
159 :
160 : // SUBROUTINE ARGUMENT DEFINITIONS:
161 : // na
162 :
163 : // SUBROUTINE PARAMETER DEFINITIONS:
164 : // na
165 :
166 : // INTERFACE BLOCK SPECIFICATIONS:
167 : // na
168 :
169 : // DERIVED TYPE DEFINITIONS:
170 : // na
171 :
172 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
173 :
174 771 : auto &op(state.dataOutputProcessor);
175 :
176 771 : op->RVariableTypes.allocate(RVarAllocInc);
177 771 : op->MaxRVariable = RVarAllocInc;
178 :
179 771 : op->IVariableTypes.allocate(IVarAllocInc);
180 771 : op->MaxIVariable = IVarAllocInc;
181 :
182 : // First index is the frequency designation (-1 = each call, etc)
183 : // Second index is the variable type (1=Average, 2=Sum)
184 : // Note, Meters always report like Average (with min/max, etc) for hourly and above
185 : // FreqNotice( 1, -1 ) = " !Each Call";
186 : // FreqNotice( 1, 0 ) = " !TimeStep";
187 : // FreqNotice( 1, 1 ) = " !Hourly";
188 : // FreqNotice( 1, 2 ) = " !Daily [Value,Min,Hour,Minute,Max,Hour,Minute]";
189 : // FreqNotice( 1, 3 ) = " !Monthly [Value,Min,Day,Hour,Minute,Max,Day,Hour,Minute]";
190 : // FreqNotice( 1, 4 ) = " !RunPeriod [Value,Min,Month,Day,Hour,Minute,Max,Month,Day,Hour,Minute]";
191 : // FreqNotice( 2, -1 ) = " !Each Call";
192 : // FreqNotice( 2, 0 ) = " !TimeStep";
193 : // FreqNotice( 2, 1 ) = " !Hourly";
194 : // FreqNotice( 2, 2 ) = " !Daily [Value,Min,Hour,Minute,Max,Hour,Minute]";
195 : // FreqNotice( 2, 3 ) = " !Monthly [Value,Min,Day,Hour,Minute,Max,Day,Hour,Minute]";
196 : // FreqNotice( 2, 4 ) = " !RunPeriod [Value,Min,Month,Day,Hour,Minute,Max,Month,Day,Hour,Minute]";
197 :
198 771 : op->ReportList.allocate(500);
199 771 : op->NumReportList = 500;
200 771 : op->ReportList = 0;
201 771 : op->NumExtraVars = 0;
202 :
203 : // Initialize end use category names - the indices must match up with endUseNames in OutputReportTabular
204 771 : op->EndUseCategory.allocate(state.dataGlobalConst->iEndUse.size());
205 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Heating)).Name = "Heating";
206 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Cooling)).Name = "Cooling";
207 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::InteriorLights)).Name = "InteriorLights";
208 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::ExteriorLights)).Name = "ExteriorLights";
209 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::InteriorEquipment)).Name = "InteriorEquipment";
210 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::ExteriorEquipment)).Name = "ExteriorEquipment";
211 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Fans)).Name = "Fans";
212 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Pumps)).Name = "Pumps";
213 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::HeatRejection)).Name = "HeatRejection";
214 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Humidification)).Name = "Humidifier";
215 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::HeatRecovery)).Name = "HeatRecovery";
216 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::WaterSystem)).Name = "WaterSystems";
217 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Refrigeration)).Name = "Refrigeration";
218 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Cogeneration)).Name = "Cogeneration";
219 :
220 : // Initialize display names for output table - this could go away if end use key names are changed to match
221 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Heating)).DisplayName = "Heating";
222 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Cooling)).DisplayName = "Cooling";
223 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::InteriorLights)).DisplayName = "Interior Lighting";
224 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::ExteriorLights)).DisplayName = "Exterior Lighting";
225 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::InteriorEquipment)).DisplayName = "Interior Equipment";
226 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::ExteriorEquipment)).DisplayName = "Exterior Equipment";
227 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Fans)).DisplayName = "Fans";
228 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Pumps)).DisplayName = "Pumps";
229 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::HeatRejection)).DisplayName = "Heat Rejection";
230 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Humidification)).DisplayName = "Humidification";
231 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::HeatRecovery)).DisplayName = "Heat Recovery";
232 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::WaterSystem)).DisplayName = "Water Systems";
233 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Refrigeration)).DisplayName = "Refrigeration";
234 771 : op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Cogeneration)).DisplayName = "Generators";
235 :
236 771 : op->OutputInitialized = true;
237 :
238 771 : op->TimeStepZoneSec = double(state.dataGlobal->MinutesPerTimeStep) * 60.0;
239 :
240 771 : InitializeMeters(state);
241 771 : }
242 :
243 1542 : void SetupTimePointers(EnergyPlusData &state,
244 : OutputProcessor::SOVTimeStepType const TimeStepTypeKey, // Which timestep is being set up, 'Zone'=1, 'HVAC'=2
245 : Real64 &TimeStep // The timestep variable. Used to get the address
246 : )
247 : {
248 :
249 : // SUBROUTINE INFORMATION:
250 : // AUTHOR Linda K. Lawrie
251 : // DATE WRITTEN December 1998
252 : // MODIFIED na
253 : // RE-ENGINEERED na
254 :
255 : // PURPOSE OF THIS SUBROUTINE:
256 : // This subroutine sets up the derived type for the output processor that
257 : // contains pointers to the TimeStep values used in the simulation.
258 :
259 : // METHODOLOGY EMPLOYED:
260 : // Indicate that the TimeStep passed in is a target for the pointer
261 : // attributes in the derived types.
262 :
263 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
264 : // ValidateTimeStepType will throw a Fatal if not valid
265 1542 : TimeStepType timeStepType = ValidateTimeStepType(state, TimeStepTypeKey);
266 :
267 1542 : TimeSteps tPtr;
268 1542 : tPtr.TimeStep = &TimeStep;
269 1542 : if (!state.dataOutputProcessor->TimeValue.insert(std::make_pair(timeStepType, tPtr)).second) {
270 : // The element was already present... shouldn't happen
271 0 : ShowFatalError(state, format("SetupTimePointers was already called for {}", sovTimeStepTypeStrings[(int)TimeStepTypeKey]));
272 : }
273 1542 : }
274 :
275 6082900 : void CheckReportVariable(EnergyPlusData &state, std::string_view const KeyedValue, std::string_view const VarName)
276 : {
277 :
278 : // SUBROUTINE INFORMATION:
279 : // AUTHOR Linda K. Lawrie
280 : // DATE WRITTEN December 1998
281 : // MODIFIED na
282 : // RE-ENGINEERED na
283 :
284 : // PURPOSE OF THIS SUBROUTINE:
285 : // This subroutine will get the report variable information from input and
286 : // determine if this variable (KeyedValue and VariableName) should be reported
287 : // and, if so, what frequency to report.
288 :
289 : // This routine is called when SetupOutputVariable is called with no "optional"
290 : // Reporting Frequency. It is expected that SetupOutputVariable would only be
291 : // called once for each keyed variable to be triggered for output (from the input
292 : // requests). The optional report frequency would only be used for debugging
293 : // purposes. Therefore, this routine will collect all occasions where this
294 : // passed variablename would be reported from the requested input. It builds
295 : // a list of these requests (ReportList) so that the calling routine can propagate
296 : // the requests into the correct data structure.
297 :
298 : // METHODOLOGY EMPLOYED:
299 : // This instance being requested will always have a key associated with it. Matching
300 : // instances (from input) may or may not have keys, but only one instance of a reporting
301 : // frequency per variable is allowed. ReportList will be populated with ReqRepVars indices
302 : // of those extra things from input that satisfy this condition.
303 :
304 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
305 :
306 : // Make sure that input has been read
307 6082900 : GetReportVariableInput(state);
308 :
309 6082900 : auto &op(state.dataOutputProcessor);
310 :
311 : // Zero out the array / counter we use to determine if there are duplicates
312 6082900 : op->NumExtraVars = 0;
313 6082900 : op->ReportList = 0;
314 :
315 177729968 : for (int i = 1; i <= op->NumOfReqVariables; ++i) {
316 171647068 : auto &reqRepVar = op->ReqRepVars(i);
317 :
318 171647068 : if (!UtilityRoutines::SameString(reqRepVar.VarName, VarName)) {
319 170928873 : continue;
320 : }
321 :
322 2753480 : if (!reqRepVar.Key.empty() && !(reqRepVar.is_simple_string && UtilityRoutines::SameString(reqRepVar.Key, KeyedValue)) &&
323 1376740 : !(!reqRepVar.is_simple_string && RE2::FullMatch(std::string{KeyedValue}, *(reqRepVar.case_insensitive_pattern)))) {
324 658545 : continue;
325 : }
326 :
327 : // A match. Make sure doesn't duplicate
328 59650 : reqRepVar.Used = true;
329 59650 : bool Dup = false;
330 : // op->ReportList is allocated to a large value, so we can't use a std::find_if on it
331 61897 : for (int Loop1 = 1; Loop1 <= op->NumExtraVars; ++Loop1) {
332 4728 : if (op->ReqRepVars(op->ReportList(Loop1)).frequency == reqRepVar.frequency &&
333 1275 : op->ReqRepVars(op->ReportList(Loop1)).SchedPtr == reqRepVar.SchedPtr) {
334 1206 : Dup = true;
335 1206 : break;
336 : }
337 : }
338 :
339 59650 : if (!Dup) {
340 58444 : ++op->NumExtraVars;
341 58444 : if (op->NumExtraVars == op->NumReportList) {
342 0 : op->ReportList.redimension(op->NumReportList += 100, 0);
343 : }
344 58444 : op->ReportList(op->NumExtraVars) = i;
345 : }
346 : }
347 6082900 : }
348 :
349 66262 : static std::string frequencyNotice([[maybe_unused]] StoreType storeType, ReportingFrequency reportingInterval)
350 : {
351 66262 : switch (reportingInterval) {
352 1414 : case ReportingFrequency::EachCall:
353 1414 : return " !Each Call";
354 : break;
355 20655 : case ReportingFrequency::TimeStep:
356 20655 : return " !TimeStep";
357 : break;
358 29126 : case ReportingFrequency::Hourly:
359 29126 : return " !Hourly";
360 : break;
361 4833 : case ReportingFrequency::Daily:
362 4833 : return " !Daily [Value,Min,Hour,Minute,Max,Hour,Minute]";
363 : break;
364 5689 : case ReportingFrequency::Monthly:
365 5689 : return " !Monthly [Value,Min,Day,Hour,Minute,Max,Day,Hour,Minute]";
366 : break;
367 1445 : case ReportingFrequency::Yearly:
368 1445 : return " !Annual [Value,Min,Month,Day,Hour,Minute,Max,Month,Day,Hour,Minute]";
369 : break;
370 3100 : case ReportingFrequency::Simulation:
371 3100 : return " !RunPeriod [Value,Min,Month,Day,Hour,Minute,Max,Month,Day,Hour,Minute]";
372 : break;
373 0 : default:
374 0 : return " !Hourly";
375 : }
376 : }
377 :
378 66262 : std::string reportingFrequency(ReportingFrequency reportingInterval)
379 : {
380 66262 : switch (reportingInterval) {
381 1414 : case ReportingFrequency::EachCall:
382 1414 : return "Each Call";
383 : break;
384 20655 : case ReportingFrequency::TimeStep:
385 20655 : return "TimeStep";
386 : break;
387 29126 : case ReportingFrequency::Hourly:
388 29126 : return "Hourly";
389 : break;
390 4833 : case ReportingFrequency::Daily:
391 4833 : return "Daily";
392 : break;
393 5689 : case ReportingFrequency::Monthly:
394 5689 : return "Monthly";
395 : break;
396 1445 : case ReportingFrequency::Yearly:
397 1445 : return "Annual";
398 : break;
399 3100 : case ReportingFrequency::Simulation:
400 3100 : return "RunPeriod";
401 : break;
402 0 : default:
403 0 : return "Hourly";
404 : }
405 : }
406 :
407 26991 : ReportingFrequency determineFrequency(EnergyPlusData &state, const std::string &FreqString)
408 : {
409 :
410 : // SUBROUTINE INFORMATION:
411 : // AUTHOR Linda K. Lawrie
412 : // DATE WRITTEN December 1998
413 : // MODIFIED December 2017; Jason DeGraw
414 : // RE-ENGINEERED na
415 :
416 : // PURPOSE OF THIS SUBROUTINE:
417 : // This subroutine looks at the passed in report frequency string and
418 : // determines the reporting frequency.
419 :
420 : // METHODOLOGY EMPLOYED:
421 : // na
422 :
423 : // REFERENCES:
424 : // \field Reporting Frequency
425 : // \type choice
426 : // \key Detailed
427 : // \note Detailed lists every instance (i.e. HVAC variable timesteps)
428 : // \key Timestep
429 : // \note Timestep refers to the zone Timestep/Number of Timesteps in hour value
430 : // \note RunPeriod, Environment, and Annual are the same
431 : // \key Hourly
432 : // \key Daily
433 : // \key Monthly
434 : // \key RunPeriod
435 : // \key Environment
436 : // \key Annual
437 : // \default Hourly
438 : // \note RunPeriod and Environment are synonymous
439 :
440 : // Locals
441 : // SUBROUTINE ARGUMENT DEFINITIONS:
442 :
443 : // SUBROUTINE PARAMETER DEFINITIONS:
444 26991 : static std::vector<std::string> const PossibleFreqs({"DETA", "TIME", "HOUR", "DAIL", "MONT", "RUNP", "ENVI", "ANNU"});
445 : //=(/'detail','Timestep','Hourly','Daily','Monthly','RunPeriod','Environment','Annual'/)
446 : static std::vector<std::string> const ExactFreqStrings(
447 26991 : {"Detailed", "Timestep", "Hourly", "Daily", "Monthly", "RunPeriod", "Environment", "Annual"});
448 : static std::vector<std::string> const ExactFreqStringsUpper(
449 26991 : {"DETAILED", "TIMESTEP", "HOURLY", "DAILY", "MONTHLY", "RUNPERIOD", "ENVIRONMENT", "ANNUAL"});
450 : // Vector of the result, was { -1, 0, 1, 2, 3, 4, 4, 4 } before the addition of Yearly;
451 : static std::vector<ReportingFrequency> const FreqValues({ReportingFrequency::EachCall,
452 : ReportingFrequency::TimeStep,
453 : ReportingFrequency::Hourly,
454 : ReportingFrequency::Daily,
455 : ReportingFrequency::Monthly,
456 : ReportingFrequency::Simulation,
457 : ReportingFrequency::Simulation,
458 26991 : ReportingFrequency::Yearly});
459 : // note: runperiod and environment are synonomous
460 :
461 : // INTERFACE BLOCK SPECIFICATIONS:
462 : // na
463 :
464 : // DERIVED TYPE DEFINITIONS:
465 : // na
466 :
467 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
468 :
469 26991 : ReportingFrequency ReportFreq(ReportingFrequency::Hourly); // Default
470 : // TODO: I think it's supposed to be upper case already, but tests aren't doing that at least...
471 53982 : const std::string FreqStringUpper = UtilityRoutines::MakeUPPERCase(FreqString);
472 26991 : std::string::size_type const LenString = min(len(FreqString), static_cast<std::string::size_type>(4u));
473 :
474 26991 : if (LenString < 4u) {
475 8 : return ReportFreq;
476 : }
477 :
478 53966 : std::string const FreqStringTrim(FreqStringUpper.substr(0, LenString));
479 89206 : for (unsigned Loop = 0; Loop < FreqValues.size(); ++Loop) {
480 89206 : if (FreqStringTrim == PossibleFreqs[Loop]) {
481 26983 : if (FreqStringUpper != ExactFreqStringsUpper[Loop]) {
482 0 : ShowWarningError(state, format("DetermineFrequency: Entered frequency=\"{}\" is not an exact match to key strings.", FreqString));
483 0 : ShowContinueError(state, format("Frequency={} will be used.", ExactFreqStrings[Loop]));
484 : }
485 26983 : ReportFreq = std::max(FreqValues[Loop], state.dataOutputProcessor->minimumReportFrequency);
486 26983 : break;
487 : }
488 : }
489 26983 : return ReportFreq;
490 : }
491 :
492 6082900 : void GetReportVariableInput(EnergyPlusData &state)
493 : {
494 :
495 : // SUBROUTINE INFORMATION:
496 : // AUTHOR Linda K. Lawrie
497 : // DATE WRITTEN December 1998
498 : // MODIFIED December 2017; Jason DeGraw
499 : // RE-ENGINEERED na
500 :
501 : // PURPOSE OF THIS SUBROUTINE:
502 : // This subroutine gets the requested report variables from
503 : // the input file.
504 : // Report Variable,
505 : // \memo each Report Variable command picks variables to be put onto the standard output file (.eso)
506 : // \memo some variables may not be reported for every simulation
507 : // A1 , \field Key_Value
508 : // \note use '*' (without quotes) to apply this variable to all keys
509 : // A2 , \field Variable_Name
510 : // A3 , \field Reporting_Frequency
511 : // \type choice
512 : // \key detailed
513 : // \key timestep
514 : // \key hourly
515 : // \key daily
516 : // \key monthly
517 : // \key runperiod
518 : // A4 ; \field Schedule_Name
519 : // \type object-list
520 : // \object-list ScheduleNames
521 :
522 : // Using/Aliasing
523 : using ScheduleManager::GetScheduleIndex;
524 :
525 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
526 : int Loop;
527 : int NumAlpha;
528 : int NumNumbers;
529 : int IOStat;
530 6082900 : bool ErrorsFound(false); // If errors detected in input
531 6083671 : std::string cCurrentModuleObject;
532 6083671 : Array1D_string cAlphaArgs(4);
533 6083671 : Array1D_string cAlphaFieldNames(4);
534 6083671 : Array1D_bool lAlphaFieldBlanks(4);
535 6083671 : Array1D<Real64> rNumericArgs(1);
536 6083671 : Array1D_string cNumericFieldNames(1);
537 6083671 : Array1D_bool lNumericFieldBlanks(1);
538 6082900 : auto &op(state.dataOutputProcessor);
539 :
540 : // Bail out if the input has already been read in
541 6082900 : if (!op->GetOutputInputFlag) {
542 6082129 : return;
543 : }
544 771 : op->GetOutputInputFlag = false;
545 :
546 : // First check environment variable to see of possible override for minimum reporting frequency
547 771 : if (!state.dataSysVars->MinReportFrequency.empty()) {
548 : // Formats
549 : static constexpr std::string_view Format_800("! <Minimum Reporting Frequency (overriding input value)>, Value, Input Value\n");
550 : static constexpr std::string_view Format_801(" Minimum Reporting Frequency, {},{}\n");
551 0 : op->minimumReportFrequency = determineFrequency(state, state.dataSysVars->MinReportFrequency);
552 0 : print(state.files.eio, Format_800);
553 0 : print(
554 0 : state.files.eio, Format_801, frequencyNotice(StoreType::Averaged, op->minimumReportFrequency), state.dataSysVars->MinReportFrequency);
555 : }
556 :
557 771 : cCurrentModuleObject = "Output:Variable";
558 771 : op->NumOfReqVariables = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
559 771 : op->ReqRepVars.allocate(op->NumOfReqVariables);
560 :
561 21128 : for (Loop = 1; Loop <= op->NumOfReqVariables; ++Loop) {
562 :
563 20357 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
564 : cCurrentModuleObject,
565 : Loop,
566 : cAlphaArgs,
567 : NumAlpha,
568 : rNumericArgs,
569 : NumNumbers,
570 : IOStat,
571 : lNumericFieldBlanks,
572 : lAlphaFieldBlanks,
573 : cAlphaFieldNames,
574 : cNumericFieldNames);
575 :
576 : // Check for duplicates?
577 20357 : auto &reqRepVar = op->ReqRepVars(Loop);
578 20357 : reqRepVar.Key = cAlphaArgs(1);
579 20357 : if (reqRepVar.Key == "*") {
580 14867 : reqRepVar.Key = std::string();
581 : }
582 :
583 20357 : bool is_simple_string = !DataOutputs::isKeyRegexLike(reqRepVar.Key);
584 20357 : reqRepVar.is_simple_string = is_simple_string;
585 20357 : if (!is_simple_string) {
586 0 : reqRepVar.case_insensitive_pattern = std::make_shared<RE2>("(?i)" + reqRepVar.Key);
587 : }
588 :
589 20357 : std::string::size_type const lbpos = index(cAlphaArgs(2), '['); // Remove Units designation if user put it in
590 20357 : if (lbpos != std::string::npos) {
591 0 : cAlphaArgs(2).erase(lbpos);
592 : // right trim
593 0 : cAlphaArgs(2) = cAlphaArgs(2).substr(0, std::min(cAlphaArgs(2).find_last_not_of(" \f\n\r\t\v") + 1, cAlphaArgs(2).size()));
594 : }
595 20357 : reqRepVar.VarName = cAlphaArgs(2);
596 :
597 20357 : reqRepVar.frequency = determineFrequency(state, cAlphaArgs(3));
598 :
599 : // Schedule information
600 20357 : reqRepVar.SchedName = cAlphaArgs(4);
601 20357 : if (not_blank(reqRepVar.SchedName)) {
602 635 : reqRepVar.SchedPtr = GetScheduleIndex(state, reqRepVar.SchedName);
603 635 : if (reqRepVar.SchedPtr == 0) {
604 0 : ShowSevereError(state,
605 0 : "GetReportVariableInput: " + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + ':' + reqRepVar.VarName +
606 0 : "\" invalid " + cAlphaFieldNames(4) + "=\"" + reqRepVar.SchedName + "\" - not found.");
607 0 : ErrorsFound = true;
608 : }
609 : } else {
610 19722 : reqRepVar.SchedPtr = 0;
611 : }
612 :
613 20357 : reqRepVar.Used = false;
614 : }
615 :
616 771 : if (ErrorsFound) {
617 0 : ShowFatalError(state, "GetReportVariableInput:" + cCurrentModuleObject + ": errors in input.");
618 : }
619 : }
620 :
621 102114 : void ProduceMinMaxString(std::string &String, // Current value
622 : int const DateValue, // Date of min/max
623 : ReportingFrequency const ReportFreq // Reporting Frequency
624 : )
625 : {
626 :
627 : // SUBROUTINE INFORMATION:
628 : // AUTHOR Linda K. Lawrie
629 : // DATE WRITTEN December 1998
630 : // MODIFIED na
631 : // RE-ENGINEERED na
632 :
633 : // PURPOSE OF THIS SUBROUTINE:
634 : // This subroutine produces the appropriate min/max string depending
635 : // on the reporting frequency.
636 :
637 : // METHODOLOGY EMPLOYED:
638 : // Prior to calling this routine, the basic value string will be
639 : // produced, but DecodeMonDayHrMin will not have been called.
640 :
641 : // REFERENCES:
642 : // na
643 :
644 : // Using/Aliasing
645 : using General::DecodeMonDayHrMin;
646 :
647 : // Locals
648 : // SUBROUTINE ARGUMENT DEFINITIONS:
649 :
650 : // SUBROUTINE PARAMETER DEFINITIONS:
651 : static constexpr std::string_view DayFormat("{},{:2},{:2}");
652 : static constexpr std::string_view MonthFormat("{},{:2},{:2},{:2}");
653 : static constexpr std::string_view EnvrnFormat("{},{:2},{:2},{:2},{:2}");
654 :
655 : // INTERFACE BLOCK SPECIFICATIONS:
656 : // na
657 :
658 : // DERIVED TYPE DEFINITIONS:
659 : // na
660 :
661 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
662 : int Mon;
663 : int Day;
664 : int Hour;
665 : int Minute;
666 204228 : std::string StrOut;
667 :
668 102114 : DecodeMonDayHrMin(DateValue, Mon, Day, Hour, Minute);
669 :
670 102114 : switch (ReportFreq) {
671 20238 : case ReportingFrequency::Daily:
672 20238 : StrOut = format(DayFormat, strip(String), Hour, Minute);
673 20238 : break;
674 68740 : case ReportingFrequency::Monthly:
675 68740 : StrOut = format(MonthFormat, strip(String), Day, Hour, Minute);
676 68740 : break;
677 13136 : case ReportingFrequency::Yearly:
678 : case ReportingFrequency::Simulation:
679 13136 : StrOut = format(EnvrnFormat, strip(String), Mon, Day, Hour, Minute);
680 13136 : break;
681 0 : default: // Each, TimeStep, Hourly dont have this
682 0 : StrOut = std::string();
683 0 : break;
684 : }
685 :
686 102114 : String = StrOut;
687 102114 : }
688 :
689 6086118 : TimeStepType ValidateTimeStepType(EnergyPlusData &state,
690 : OutputProcessor::SOVTimeStepType const TimeStepTypeKey) // Index type (Zone, HVAC) for variables
691 : {
692 :
693 : // FUNCTION INFORMATION:
694 : // AUTHOR Linda K. Lawrie
695 : // DATE WRITTEN December 1998
696 : // MODIFIED na
697 : // RE-ENGINEERED na
698 :
699 : // PURPOSE OF THIS FUNCTION:
700 : // This function validates the requested "index" type and returns
701 : // the proper value for use inside the OutputProcessor.
702 :
703 : // METHODOLOGY EMPLOYED:
704 : // Look it up in a list of valid index types.
705 6086118 : switch (TimeStepTypeKey) {
706 4095581 : case OutputProcessor::SOVTimeStepType::Zone:
707 4095581 : return TimeStepType::Zone;
708 1990537 : case OutputProcessor::SOVTimeStepType::HVAC:
709 : case OutputProcessor::SOVTimeStepType::System:
710 : case OutputProcessor::SOVTimeStepType::Plant:
711 1990537 : return TimeStepType::System;
712 0 : case OutputProcessor::SOVTimeStepType::Invalid:
713 : case OutputProcessor::SOVTimeStepType::Num:
714 0 : ShowFatalError(state, "Bad SOVTimeStepType passed to ValidateTimeStepType");
715 : }
716 0 : return TimeStepType::System; // compiler doesn't understand that ShowFatalError aborts
717 : }
718 :
719 875230 : std::string StandardTimeStepTypeKey(TimeStepType const timeStepType)
720 : {
721 :
722 : // FUNCTION INFORMATION:
723 : // AUTHOR Linda K. Lawrie
724 : // DATE WRITTEN December 1998
725 : // MODIFIED na
726 : // RE-ENGINEERED na
727 :
728 : // PURPOSE OF THIS FUNCTION:
729 : // This function gives the standard string for the index type
730 : // given.
731 :
732 : // METHODOLOGY EMPLOYED:
733 : // Look it up in a list of valid index types.
734 :
735 : // REFERENCES:
736 : // na
737 :
738 : // USE STATEMENTS:
739 : // na
740 :
741 : // Return value
742 875230 : std::string StandardTimeStepTypeKey;
743 :
744 : // Locals
745 : // FUNCTION ARGUMENT DEFINITIONS:
746 :
747 : // FUNCTION PARAMETER DEFINITIONS:
748 : // na
749 :
750 : // INTERFACE BLOCK SPECIFICATIONS:
751 : // na
752 :
753 : // DERIVED TYPE DEFINITIONS:
754 : // na
755 :
756 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
757 : // na
758 :
759 875230 : if (timeStepType == TimeStepType::Zone) {
760 509004 : StandardTimeStepTypeKey = "Zone";
761 366226 : } else if (timeStepType == TimeStepType::System) {
762 366226 : StandardTimeStepTypeKey = "HVAC";
763 : } else {
764 0 : StandardTimeStepTypeKey = "UNKW";
765 : }
766 :
767 875230 : return StandardTimeStepTypeKey;
768 : }
769 :
770 6084576 : StoreType validateVariableType(EnergyPlusData &state, OutputProcessor::SOVStoreType const VariableTypeKey)
771 : {
772 :
773 : // FUNCTION INFORMATION:
774 : // AUTHOR Linda K. Lawrie
775 : // DATE WRITTEN December 1998
776 : // MODIFIED December 2017; Jason DeGraw
777 : // RE-ENGINEERED na
778 :
779 : // PURPOSE OF THIS FUNCTION:
780 : // This function validates the VariableTypeKey passed to the SetupVariable
781 : // routine and assigns it the value used in the OutputProcessor.
782 :
783 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
784 6084576 : switch (VariableTypeKey) {
785 4883795 : case OutputProcessor::SOVStoreType::State:
786 : case OutputProcessor::SOVStoreType::Average:
787 4883795 : return StoreType::Averaged;
788 1200781 : case OutputProcessor::SOVStoreType::NonState:
789 : case OutputProcessor::SOVStoreType::Summed:
790 1200781 : return StoreType::Summed;
791 0 : case OutputProcessor::SOVStoreType::Invalid:
792 : case OutputProcessor::SOVStoreType::Num:
793 0 : ShowFatalError(state, "Bad SOVStoreType passed to validateVariableType");
794 : }
795 0 : return StoreType::Summed; // compiler doesn't understand that ShowFatalError aborts
796 : }
797 :
798 875230 : std::string standardVariableTypeKey(StoreType const VariableType)
799 : {
800 :
801 : // FUNCTION INFORMATION:
802 : // AUTHOR Linda K. Lawrie
803 : // DATE WRITTEN July 1999
804 : // MODIFIED December 2017; Jason DeGraw
805 : // RE-ENGINEERED na
806 :
807 : // PURPOSE OF THIS FUNCTION:
808 : // This function gives the standard string for the variable type
809 : // given.
810 :
811 : // METHODOLOGY EMPLOYED:
812 : // From variable type value, produce proper string.
813 :
814 : // REFERENCES:
815 : // na
816 :
817 : // USE STATEMENTS:
818 : // na
819 :
820 : // Return value
821 : // na
822 :
823 : // Locals
824 : // FUNCTION ARGUMENT DEFINITIONS:
825 :
826 : // FUNCTION PARAMETER DEFINITIONS:
827 : // na
828 :
829 : // INTERFACE BLOCK SPECIFICATIONS:
830 : // na
831 :
832 : // DERIVED TYPE DEFINITIONS:
833 : // na
834 :
835 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
836 : // na
837 :
838 875230 : switch (VariableType) {
839 555036 : case StoreType::Averaged:
840 555036 : return "Average";
841 : break;
842 320194 : case StoreType::Summed:
843 320194 : return "Sum";
844 : break;
845 0 : default:
846 0 : return "Unknown";
847 : }
848 : }
849 :
850 : // *****************************************************************************
851 : // The following routines implement Energy Meters in EnergyPlus.
852 : // *****************************************************************************
853 :
854 771 : void InitializeMeters(EnergyPlusData &state)
855 : {
856 :
857 : // SUBROUTINE INFORMATION:
858 : // AUTHOR Linda Lawrie
859 : // DATE WRITTEN January 2001
860 : // MODIFIED na
861 : // RE-ENGINEERED na
862 :
863 : // PURPOSE OF THIS SUBROUTINE:
864 : // This subroutine creates the set of meters in EnergyPlus. In this initial
865 : // implementation, it is a static set of meters.
866 :
867 : // METHODOLOGY EMPLOYED:
868 : // Allocate the static set. Use "AddMeter" with appropriate arguments that will
869 : // allow expansion later.
870 :
871 : // REFERENCES:
872 : // na
873 :
874 : // USE STATEMENTS:
875 : // na
876 :
877 : // Locals
878 : // SUBROUTINE ARGUMENT DEFINITIONS:
879 : // na
880 :
881 : // SUBROUTINE PARAMETER DEFINITIONS:
882 : // na
883 :
884 : // INTERFACE BLOCK SPECIFICATIONS:
885 : // na
886 :
887 : // DERIVED TYPE DEFINITIONS:
888 : // na
889 :
890 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
891 :
892 771 : state.files.mtd.ensure_open(state, "InitializeMeters", state.files.outputControl.mtd);
893 771 : }
894 :
895 769 : void GetCustomMeterInput(EnergyPlusData &state, bool &ErrorsFound)
896 : {
897 :
898 : // SUBROUTINE INFORMATION:
899 : // AUTHOR Linda Lawrie
900 : // DATE WRITTEN January 2006
901 : // MODIFIED na
902 : // RE-ENGINEERED na
903 :
904 : // PURPOSE OF THIS SUBROUTINE:
905 : // This routine will help implement "custom"/user defined meters. However, it must be called after all
906 : // the other meters are set up and all report variables are established.
907 :
908 : // METHODOLOGY EMPLOYED:
909 : // na
910 :
911 : // REFERENCES:
912 : // Processes the objects:
913 : // Meter:Custom,
914 : // \extensible:2 - repeat last two fields, remembering to remove ; from "inner" fields.
915 : // \memo Used to allow users to combine specific variables and/or meters into
916 : // \memo "custom" meter configurations.
917 : // A1, \field Name
918 : // \required-field
919 : // \reference CustomMeterNames
920 : // A2, \field Fuel Type
921 : // \type choice
922 : // \key Electricity
923 : // \key NaturalGas
924 : // \key PropaneGas
925 : // \key FuelOilNo1
926 : // \key FuelOilNo2
927 : // \key Coal
928 : // \key Diesel
929 : // \key Gasoline
930 : // \key Water
931 : // \key Generic
932 : // \key OtherFuel1
933 : // \key OtherFuel2
934 : // A3, \field Key Name 1
935 : // \required-field
936 : // \begin-extensible
937 : // A4, \field Report Variable or Meter Name 1
938 : // \required-field
939 : // <etc>
940 : // AND
941 : // Meter:CustomDecrement,
942 : // \extensible:2 - repeat last two fields, remembering to remove ; from "inner" fields.
943 : // \memo Used to allow users to combine specific variables and/or meters into
944 : // \memo "custom" meter configurations.
945 : // A1, \field Name
946 : // \required-field
947 : // \reference CustomMeterNames
948 : // A2, \field Fuel Type
949 : // \type choice
950 : // \key Electricity
951 : // \key NaturalGas
952 : // \key PropaneGas
953 : // \key FuelOilNo1
954 : // \key FuelOilNo2
955 : // \key Coal
956 : // \key Diesel
957 : // \key Gasoline
958 : // \key Water
959 : // \key Generic
960 : // \key OtherFuel1
961 : // \key OtherFuel2
962 : // A3, \field Source Meter Name
963 : // \required-field
964 : // A4, \field Key Name 1
965 : // \required-field
966 : // \begin-extensible
967 : // A5, \field Report Variable or Meter Name 1
968 : // \required-field
969 : // <etc>
970 :
971 : // Using/Aliasing
972 :
973 : // Locals
974 : // SUBROUTINE ARGUMENT DEFINITIONS:
975 :
976 : // SUBROUTINE PARAMETER DEFINITIONS:
977 : // na
978 :
979 : // INTERFACE BLOCK SPECIFICATIONS:
980 : // na
981 :
982 : // DERIVED TYPE DEFINITIONS:
983 : // na
984 :
985 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
986 769 : auto &op(state.dataOutputProcessor);
987 : int NumAlpha;
988 : int NumNumbers;
989 : int Loop;
990 : int IOStat;
991 : int NumCustomMeters;
992 : int NumCustomDecMeters;
993 : int fldIndex;
994 : bool KeyIsStar;
995 1538 : Array1D_string NamesOfKeys; // Specific key name
996 1538 : Array1D_int IndexesForKeyVar; // Array index
997 769 : OutputProcessor::Unit UnitsVar(OutputProcessor::Unit::None); // Units enumeration
998 769 : OutputProcessor::Unit MeterUnits(OutputProcessor::Unit::None); // Units enumeration
999 : int KeyCount;
1000 : VariableType TypeVar;
1001 : OutputProcessor::StoreType AvgSumVar;
1002 : OutputProcessor::TimeStepType StepTypeVar;
1003 : int iKey;
1004 : int iKey1;
1005 : bool MeterCreated;
1006 1538 : Array1D_int VarsOnCustomMeter;
1007 : int MaxVarsOnCustomMeter;
1008 : int NumVarsOnCustomMeter;
1009 1538 : Array1D_int VarsOnSourceMeter;
1010 : int MaxVarsOnSourceMeter;
1011 : int NumVarsOnSourceMeter;
1012 : int iOnMeter;
1013 : int WhichMeter;
1014 : bool errFlag;
1015 : bool BigErrorsFound;
1016 : bool testa;
1017 : bool testb;
1018 : bool Tagged; // variable is appropriate to put on meter
1019 : std::string::size_type lbrackPos;
1020 :
1021 769 : BigErrorsFound = false;
1022 769 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
1023 :
1024 769 : cCurrentModuleObject = "Meter:Custom";
1025 769 : NumCustomMeters = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
1026 :
1027 : // make list of names for all Meter:Custom since they cannot refer to other Meter:Custom's
1028 1538 : std::unordered_set<std::string> namesOfMeterCustom;
1029 769 : namesOfMeterCustom.reserve(NumCustomMeters);
1030 :
1031 860 : for (Loop = 1; Loop <= NumCustomMeters; ++Loop) {
1032 637 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1033 : cCurrentModuleObject,
1034 : Loop,
1035 91 : state.dataIPShortCut->cAlphaArgs,
1036 : NumAlpha,
1037 91 : state.dataIPShortCut->rNumericArgs,
1038 : NumNumbers,
1039 : IOStat,
1040 91 : state.dataIPShortCut->lNumericFieldBlanks,
1041 91 : state.dataIPShortCut->lAlphaFieldBlanks,
1042 91 : state.dataIPShortCut->cAlphaFieldNames,
1043 91 : state.dataIPShortCut->cNumericFieldNames);
1044 91 : namesOfMeterCustom.emplace(UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(1)));
1045 : }
1046 :
1047 860 : for (Loop = 1; Loop <= NumCustomMeters; ++Loop) {
1048 637 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1049 : cCurrentModuleObject,
1050 : Loop,
1051 91 : state.dataIPShortCut->cAlphaArgs,
1052 : NumAlpha,
1053 91 : state.dataIPShortCut->rNumericArgs,
1054 : NumNumbers,
1055 : IOStat,
1056 91 : state.dataIPShortCut->lNumericFieldBlanks,
1057 91 : state.dataIPShortCut->lAlphaFieldBlanks,
1058 91 : state.dataIPShortCut->cAlphaFieldNames,
1059 91 : state.dataIPShortCut->cNumericFieldNames);
1060 91 : lbrackPos = index(state.dataIPShortCut->cAlphaArgs(1), '[');
1061 91 : if (lbrackPos != std::string::npos) state.dataIPShortCut->cAlphaArgs(1).erase(lbrackPos);
1062 91 : MeterCreated = false;
1063 182 : if (GlobalNames::VerifyUniqueInterObjectName(state,
1064 91 : op->UniqueMeterNames,
1065 91 : state.dataIPShortCut->cAlphaArgs(1),
1066 : cCurrentModuleObject,
1067 91 : state.dataIPShortCut->cAlphaFieldNames(1),
1068 : ErrorsFound)) {
1069 0 : continue;
1070 : }
1071 91 : if (allocated(VarsOnCustomMeter)) VarsOnCustomMeter.deallocate();
1072 91 : VarsOnCustomMeter.allocate(1000);
1073 91 : VarsOnCustomMeter = 0;
1074 91 : MaxVarsOnCustomMeter = 1000;
1075 91 : NumVarsOnCustomMeter = 0;
1076 : // check if any fields reference another Meter:Custom
1077 91 : int found = 0;
1078 450 : for (fldIndex = 4; fldIndex <= NumAlpha; fldIndex += 2) {
1079 359 : if (namesOfMeterCustom.find(UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(fldIndex))) != namesOfMeterCustom.end()) {
1080 0 : found = fldIndex;
1081 0 : break;
1082 : }
1083 : }
1084 91 : if (found != 0) {
1085 0 : ShowWarningError(state,
1086 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", contains a reference to another " +
1087 0 : cCurrentModuleObject + " in field: " + state.dataIPShortCut->cAlphaFieldNames(found) + "=\"" +
1088 0 : state.dataIPShortCut->cAlphaArgs(found) + "\".");
1089 0 : continue;
1090 : }
1091 :
1092 450 : for (fldIndex = 3; fldIndex <= NumAlpha; fldIndex += 2) {
1093 359 : if (state.dataIPShortCut->cAlphaArgs(fldIndex) == "*" || state.dataIPShortCut->lAlphaFieldBlanks(fldIndex)) {
1094 58 : KeyIsStar = true;
1095 58 : state.dataIPShortCut->cAlphaArgs(fldIndex) = "*";
1096 : } else {
1097 301 : KeyIsStar = false;
1098 : }
1099 359 : if (state.dataIPShortCut->lAlphaFieldBlanks(fldIndex + 1)) {
1100 0 : ShowSevereError(state,
1101 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", blank " +
1102 0 : state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + '.');
1103 0 : ShowContinueError(state, "...cannot create custom meter.");
1104 0 : BigErrorsFound = true;
1105 0 : continue;
1106 : }
1107 359 : if (BigErrorsFound) continue;
1108 : // Don't build/check things out if there were errors anywhere. Use "GetVariableKeys" to map to actual variables...
1109 359 : lbrackPos = index(state.dataIPShortCut->cAlphaArgs(fldIndex + 1), '[');
1110 359 : if (lbrackPos != std::string::npos) state.dataIPShortCut->cAlphaArgs(fldIndex + 1).erase(lbrackPos);
1111 359 : Tagged = false;
1112 359 : GetVariableKeyCountandType(
1113 359 : state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), KeyCount, TypeVar, AvgSumVar, StepTypeVar, UnitsVar);
1114 359 : if (TypeVar == VariableType::NotFound) {
1115 0 : ShowWarningError(state,
1116 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " +
1117 0 : state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
1118 0 : state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
1119 0 : ShowContinueError(state, "...will not be shown with the Meter results.");
1120 0 : continue;
1121 : }
1122 359 : if (!MeterCreated) {
1123 91 : MeterUnits = UnitsVar; // meter units are same as first variable on custom meter
1124 91 : AddMeter(state, state.dataIPShortCut->cAlphaArgs(1), UnitsVar, std::string(), std::string(), std::string(), std::string());
1125 91 : op->EnergyMeters(op->NumEnergyMeters).TypeOfMeter = MtrType::Custom;
1126 : // Can't use resource type in AddMeter cause it will confuse it with other meters. So, now:
1127 91 : GetStandardMeterResourceType(state,
1128 91 : op->EnergyMeters(op->NumEnergyMeters).ResourceType,
1129 182 : UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(2)),
1130 : errFlag);
1131 91 : if (errFlag) {
1132 0 : ShowContinueError(state, "..on " + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\".");
1133 0 : BigErrorsFound = true;
1134 : }
1135 273 : DetermineMeterIPUnits(state,
1136 91 : op->EnergyMeters(op->NumEnergyMeters).RT_forIPUnits,
1137 91 : op->EnergyMeters(op->NumEnergyMeters).ResourceType,
1138 : UnitsVar,
1139 : errFlag);
1140 91 : if (errFlag) {
1141 1 : ShowContinueError(state, "..on " + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\".");
1142 1 : ShowContinueError(state, "..requests for IP units from this meter will be ignored.");
1143 : }
1144 : // EnergyMeters(NumEnergyMeters)%RT_forIPUnits=DetermineMeterIPUnits(EnergyMeters(NumEnergyMeters)%ResourceType,UnitsVar)
1145 91 : MeterCreated = true;
1146 : }
1147 359 : if (UnitsVar != MeterUnits) {
1148 0 : ShowWarningError(state,
1149 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", differing units in " +
1150 0 : state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
1151 0 : state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
1152 0 : ShowContinueError(state,
1153 0 : "...will not be shown with the Meter results; units for meter=" + unitEnumToString(MeterUnits) +
1154 0 : ", units for this variable=" + unitEnumToString(UnitsVar) + '.');
1155 0 : continue;
1156 : }
1157 359 : if ((TypeVar == VariableType::Real || TypeVar == VariableType::Integer) && AvgSumVar == StoreType::Summed) {
1158 314 : Tagged = true;
1159 314 : NamesOfKeys.allocate(KeyCount);
1160 314 : IndexesForKeyVar.allocate(KeyCount);
1161 314 : GetVariableKeys(state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), TypeVar, NamesOfKeys, IndexesForKeyVar);
1162 314 : iOnMeter = 0;
1163 314 : if (KeyIsStar) {
1164 26 : for (iKey = 1; iKey <= KeyCount; ++iKey) {
1165 13 : ++NumVarsOnCustomMeter;
1166 13 : if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
1167 0 : VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
1168 : }
1169 13 : VarsOnCustomMeter(NumVarsOnCustomMeter) = IndexesForKeyVar(iKey);
1170 13 : iOnMeter = 1;
1171 : }
1172 13 : if (iOnMeter == 0) {
1173 0 : ShowSevereError(state,
1174 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid (all keys) " +
1175 0 : state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
1176 0 : state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
1177 0 : ErrorsFound = true;
1178 : }
1179 : } else { // Key is not "*"
1180 6610 : for (iKey = 1; iKey <= KeyCount; ++iKey) {
1181 6309 : if (NamesOfKeys(iKey) != state.dataIPShortCut->cAlphaArgs(fldIndex)) continue;
1182 301 : ++NumVarsOnCustomMeter;
1183 301 : if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
1184 0 : VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
1185 : }
1186 301 : VarsOnCustomMeter(NumVarsOnCustomMeter) = IndexesForKeyVar(iKey);
1187 301 : iOnMeter = 1;
1188 : }
1189 301 : if (iOnMeter == 0) {
1190 0 : ShowSevereError(state,
1191 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " +
1192 0 : state.dataIPShortCut->cAlphaArgs(fldIndex) + ':' + state.dataIPShortCut->cAlphaArgs(fldIndex + 1));
1193 0 : ErrorsFound = true;
1194 : }
1195 : }
1196 314 : NamesOfKeys.deallocate();
1197 314 : IndexesForKeyVar.deallocate();
1198 : }
1199 359 : if (TypeVar == VariableType::Meter && AvgSumVar == StoreType::Summed) {
1200 45 : Tagged = true;
1201 45 : NamesOfKeys.allocate(KeyCount);
1202 45 : IndexesForKeyVar.allocate(KeyCount);
1203 45 : GetVariableKeys(state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), TypeVar, NamesOfKeys, IndexesForKeyVar);
1204 45 : WhichMeter = IndexesForKeyVar(1);
1205 45 : NamesOfKeys.deallocate();
1206 45 : IndexesForKeyVar.deallocate();
1207 : // for meters there will only be one key... but it has variables associated...
1208 2045 : for (iOnMeter = 1; iOnMeter <= op->NumVarMeterArrays; ++iOnMeter) {
1209 2000 : if (!any_eq(op->VarMeterArrays(iOnMeter).OnMeters, WhichMeter)) continue;
1210 324 : ++NumVarsOnCustomMeter;
1211 324 : if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
1212 0 : VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
1213 : }
1214 324 : VarsOnCustomMeter(NumVarsOnCustomMeter) = op->VarMeterArrays(iOnMeter).RepVariable;
1215 : }
1216 : }
1217 359 : if (!Tagged) { // couldn't find place for this item on a meter
1218 0 : if (AvgSumVar != StoreType::Summed) {
1219 0 : ShowWarningError(state,
1220 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", variable not summed variable " +
1221 0 : state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
1222 0 : state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
1223 0 : ShowContinueError(state,
1224 0 : "...will not be shown with the Meter results; units for meter=" + unitEnumToString(MeterUnits) +
1225 0 : ", units for this variable=" + unitEnumToString(UnitsVar) + '.');
1226 : }
1227 : }
1228 : }
1229 : // Check for duplicates
1230 729 : for (iKey = 1; iKey <= NumVarsOnCustomMeter; ++iKey) {
1231 638 : if (VarsOnCustomMeter(iKey) == 0) continue;
1232 5083 : for (iKey1 = iKey + 1; iKey1 <= NumVarsOnCustomMeter; ++iKey1) {
1233 4445 : if (iKey == iKey1) continue;
1234 4445 : if (VarsOnCustomMeter(iKey) != VarsOnCustomMeter(iKey1)) continue;
1235 0 : ShowWarningError(state,
1236 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", duplicate name=\"" +
1237 0 : op->RVariableTypes(VarsOnCustomMeter(iKey1)).VarName + "\".");
1238 0 : ShowContinueError(state, "...only one value with this name will be shown with the Meter results.");
1239 0 : VarsOnCustomMeter(iKey1) = 0;
1240 : }
1241 : }
1242 729 : for (iKey = 1; iKey <= NumVarsOnCustomMeter; ++iKey) {
1243 638 : if (VarsOnCustomMeter(iKey) == 0) continue;
1244 638 : auto &tmpVar = op->RVariableTypes(VarsOnCustomMeter(iKey)).VarPtr;
1245 638 : AttachCustomMeters(state, VarsOnCustomMeter(iKey), tmpVar.MeterArrayPtr, op->NumEnergyMeters);
1246 : }
1247 91 : if (NumVarsOnCustomMeter == 0) {
1248 0 : ShowWarningError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", no items assigned ");
1249 0 : ShowContinueError(
1250 : state, "...will not be shown with the Meter results. This may be caused by a Meter:Custom be assigned to another Meter:Custom.");
1251 : }
1252 : }
1253 :
1254 769 : cCurrentModuleObject = "Meter:CustomDecrement";
1255 769 : NumCustomDecMeters = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
1256 :
1257 807 : for (Loop = 1; Loop <= NumCustomDecMeters; ++Loop) {
1258 266 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1259 : cCurrentModuleObject,
1260 : Loop,
1261 38 : state.dataIPShortCut->cAlphaArgs,
1262 : NumAlpha,
1263 38 : state.dataIPShortCut->rNumericArgs,
1264 : NumNumbers,
1265 : IOStat,
1266 38 : state.dataIPShortCut->lNumericFieldBlanks,
1267 38 : state.dataIPShortCut->lAlphaFieldBlanks,
1268 38 : state.dataIPShortCut->cAlphaFieldNames,
1269 38 : state.dataIPShortCut->cNumericFieldNames);
1270 38 : lbrackPos = index(state.dataIPShortCut->cAlphaArgs(1), '[');
1271 38 : if (lbrackPos != std::string::npos) state.dataIPShortCut->cAlphaArgs(1).erase(lbrackPos);
1272 38 : MeterCreated = false;
1273 76 : if (GlobalNames::VerifyUniqueInterObjectName(state,
1274 38 : op->UniqueMeterNames,
1275 38 : state.dataIPShortCut->cAlphaArgs(1),
1276 : cCurrentModuleObject,
1277 38 : state.dataIPShortCut->cAlphaFieldNames(1),
1278 : ErrorsFound)) {
1279 0 : continue;
1280 : }
1281 38 : if (allocated(VarsOnCustomMeter)) VarsOnCustomMeter.deallocate();
1282 38 : VarsOnCustomMeter.allocate(1000);
1283 38 : VarsOnCustomMeter = 0;
1284 38 : MaxVarsOnCustomMeter = 1000;
1285 38 : NumVarsOnCustomMeter = 0;
1286 :
1287 38 : lbrackPos = index(state.dataIPShortCut->cAlphaArgs(3), '[');
1288 38 : if (lbrackPos != std::string::npos) state.dataIPShortCut->cAlphaArgs(1).erase(lbrackPos);
1289 38 : WhichMeter = UtilityRoutines::FindItem(state.dataIPShortCut->cAlphaArgs(3), op->EnergyMeters);
1290 38 : if (WhichMeter == 0) {
1291 0 : ShowSevereError(state,
1292 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " +
1293 0 : state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" + state.dataIPShortCut->cAlphaArgs(3) + "\".");
1294 0 : ErrorsFound = true;
1295 0 : continue;
1296 : }
1297 : // Set up array of Vars that are on the source meter (for later validation).
1298 38 : if (allocated(VarsOnSourceMeter)) VarsOnSourceMeter.deallocate();
1299 38 : VarsOnSourceMeter.allocate(1000);
1300 38 : VarsOnSourceMeter = 0;
1301 38 : MaxVarsOnSourceMeter = 1000;
1302 38 : NumVarsOnSourceMeter = 0;
1303 5730 : for (iKey = 1; iKey <= op->NumVarMeterArrays; ++iKey) {
1304 5692 : if (op->VarMeterArrays(iKey).NumOnMeters == 0 && op->VarMeterArrays(iKey).NumOnCustomMeters == 0) continue;
1305 : // On a meter
1306 6278 : if (any_eq(op->VarMeterArrays(iKey).OnMeters, WhichMeter)) {
1307 586 : ++NumVarsOnSourceMeter;
1308 586 : if (NumVarsOnSourceMeter > MaxVarsOnSourceMeter) {
1309 0 : VarsOnSourceMeter.redimension(MaxVarsOnSourceMeter += 100, 0);
1310 : }
1311 586 : VarsOnSourceMeter(NumVarsOnSourceMeter) = op->VarMeterArrays(iKey).RepVariable;
1312 586 : continue;
1313 : }
1314 5106 : if (op->VarMeterArrays(iKey).NumOnCustomMeters == 0) continue;
1315 156 : if (any_eq(op->VarMeterArrays(iKey).OnCustomMeters, WhichMeter)) {
1316 0 : ++NumVarsOnSourceMeter;
1317 0 : if (NumVarsOnSourceMeter > MaxVarsOnSourceMeter) {
1318 0 : VarsOnSourceMeter.redimension(MaxVarsOnSourceMeter += 100, 0);
1319 : }
1320 0 : VarsOnSourceMeter(NumVarsOnSourceMeter) = op->VarMeterArrays(iKey).RepVariable;
1321 0 : continue;
1322 : }
1323 : }
1324 :
1325 76 : for (fldIndex = 4; fldIndex <= NumAlpha; fldIndex += 2) {
1326 38 : if (state.dataIPShortCut->cAlphaArgs(fldIndex) == "*" || state.dataIPShortCut->lAlphaFieldBlanks(fldIndex)) {
1327 34 : KeyIsStar = true;
1328 34 : state.dataIPShortCut->cAlphaArgs(fldIndex) = "*";
1329 : } else {
1330 4 : KeyIsStar = false;
1331 : }
1332 38 : if (state.dataIPShortCut->lAlphaFieldBlanks(fldIndex + 1)) {
1333 0 : ShowSevereError(state,
1334 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", blank " +
1335 0 : state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + '.');
1336 0 : ShowContinueError(state, "...cannot create custom meter.");
1337 0 : BigErrorsFound = true;
1338 0 : continue;
1339 : }
1340 38 : if (BigErrorsFound) continue;
1341 38 : Tagged = false;
1342 38 : lbrackPos = index(state.dataIPShortCut->cAlphaArgs(fldIndex + 1), '[');
1343 38 : if (lbrackPos != std::string::npos) state.dataIPShortCut->cAlphaArgs(fldIndex + 1).erase(lbrackPos);
1344 : // Don't build/check things out if there were errors anywhere. Use "GetVariableKeys" to map to actual variables...
1345 38 : GetVariableKeyCountandType(
1346 38 : state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), KeyCount, TypeVar, AvgSumVar, StepTypeVar, UnitsVar);
1347 38 : if (TypeVar == VariableType::NotFound) {
1348 0 : ShowWarningError(state,
1349 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " +
1350 0 : state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
1351 0 : state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
1352 0 : ShowContinueError(state, "...will not be shown with the Meter results.");
1353 0 : continue;
1354 : }
1355 38 : if (!MeterCreated) {
1356 38 : MeterUnits = UnitsVar;
1357 38 : AddMeter(state, state.dataIPShortCut->cAlphaArgs(1), UnitsVar, std::string(), std::string(), std::string(), std::string());
1358 38 : op->EnergyMeters(op->NumEnergyMeters).TypeOfMeter = MtrType::CustomDec;
1359 38 : op->EnergyMeters(op->NumEnergyMeters).SourceMeter = WhichMeter;
1360 :
1361 : // Can't use resource type in AddMeter cause it will confuse it with other meters. So, now:
1362 38 : GetStandardMeterResourceType(state,
1363 38 : op->EnergyMeters(op->NumEnergyMeters).ResourceType,
1364 76 : UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(2)),
1365 : errFlag);
1366 38 : if (errFlag) {
1367 0 : ShowContinueError(state, "..on " + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\".");
1368 0 : BigErrorsFound = true;
1369 : }
1370 114 : DetermineMeterIPUnits(state,
1371 38 : op->EnergyMeters(op->NumEnergyMeters).RT_forIPUnits,
1372 38 : op->EnergyMeters(op->NumEnergyMeters).ResourceType,
1373 : UnitsVar,
1374 : errFlag);
1375 38 : if (errFlag) {
1376 0 : ShowContinueError(state, "..on " + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\".");
1377 0 : ShowContinueError(state, "..requests for IP units from this meter will be ignored.");
1378 : }
1379 : // EnergyMeters(NumEnergyMeters)%RT_forIPUnits=DetermineMeterIPUnits(EnergyMeters(NumEnergyMeters)%ResourceType,UnitsVar)
1380 38 : MeterCreated = true;
1381 : }
1382 38 : if (UnitsVar != MeterUnits) {
1383 0 : ShowWarningError(state,
1384 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", differing units in " +
1385 0 : state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
1386 0 : state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
1387 0 : ShowContinueError(state,
1388 0 : "...will not be shown with the Meter results; units for meter=" + unitEnumToString(MeterUnits) +
1389 0 : ", units for this variable=" + unitEnumToString(UnitsVar) + '.');
1390 0 : continue;
1391 : }
1392 38 : if ((TypeVar == VariableType::Real || TypeVar == VariableType::Integer) && AvgSumVar == StoreType::Summed) {
1393 4 : Tagged = true;
1394 4 : NamesOfKeys.allocate(KeyCount);
1395 4 : IndexesForKeyVar.allocate(KeyCount);
1396 4 : GetVariableKeys(state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), TypeVar, NamesOfKeys, IndexesForKeyVar);
1397 4 : iOnMeter = 0;
1398 4 : if (KeyIsStar) {
1399 0 : for (iKey = 1; iKey <= KeyCount; ++iKey) {
1400 0 : ++NumVarsOnCustomMeter;
1401 0 : if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
1402 0 : VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
1403 : }
1404 0 : VarsOnCustomMeter(NumVarsOnCustomMeter) = IndexesForKeyVar(iKey);
1405 0 : iOnMeter = 1;
1406 : }
1407 0 : if (iOnMeter == 0) {
1408 0 : ShowSevereError(state,
1409 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid (all keys) " +
1410 0 : state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
1411 0 : state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
1412 0 : ErrorsFound = true;
1413 : }
1414 : } else {
1415 203 : for (iKey = 1; iKey <= KeyCount; ++iKey) {
1416 199 : if (NamesOfKeys(iKey) != state.dataIPShortCut->cAlphaArgs(fldIndex)) continue;
1417 4 : ++NumVarsOnCustomMeter;
1418 4 : if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
1419 0 : VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
1420 : }
1421 4 : VarsOnCustomMeter(NumVarsOnCustomMeter) = IndexesForKeyVar(iKey);
1422 4 : iOnMeter = 1;
1423 : }
1424 4 : if (iOnMeter == 0) {
1425 0 : ShowSevereError(state,
1426 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " +
1427 0 : state.dataIPShortCut->cAlphaArgs(fldIndex) + ':' + state.dataIPShortCut->cAlphaArgs(fldIndex + 1));
1428 0 : ErrorsFound = true;
1429 : }
1430 : }
1431 4 : NamesOfKeys.deallocate();
1432 4 : IndexesForKeyVar.deallocate();
1433 : }
1434 38 : if (TypeVar == VariableType::Meter && AvgSumVar == StoreType::Summed) {
1435 34 : Tagged = true;
1436 34 : NamesOfKeys.allocate(KeyCount);
1437 34 : IndexesForKeyVar.allocate(KeyCount);
1438 34 : GetVariableKeys(state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), TypeVar, NamesOfKeys, IndexesForKeyVar);
1439 34 : WhichMeter = IndexesForKeyVar(1);
1440 34 : NamesOfKeys.deallocate();
1441 34 : IndexesForKeyVar.deallocate();
1442 : // for meters there will only be one key... but it has variables associated...
1443 2770 : for (iOnMeter = 1; iOnMeter <= op->NumVarMeterArrays; ++iOnMeter) {
1444 2736 : testa = any_eq(op->VarMeterArrays(iOnMeter).OnMeters, WhichMeter);
1445 2736 : testb = false;
1446 2736 : if (op->VarMeterArrays(iOnMeter).NumOnCustomMeters > 0) {
1447 459 : testb = any_eq(op->VarMeterArrays(iOnMeter).OnCustomMeters, WhichMeter);
1448 : }
1449 2736 : if (!(testa || testb)) continue;
1450 169 : ++NumVarsOnCustomMeter;
1451 169 : if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
1452 0 : VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
1453 : }
1454 169 : VarsOnCustomMeter(NumVarsOnCustomMeter) = op->VarMeterArrays(iOnMeter).RepVariable;
1455 : }
1456 : }
1457 38 : if (!Tagged) { // couldn't find place for this item on a meter
1458 0 : if (AvgSumVar != StoreType::Summed) {
1459 0 : ShowWarningError(state,
1460 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", variable not summed variable " +
1461 0 : state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
1462 0 : state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
1463 0 : ShowContinueError(state,
1464 0 : "...will not be shown with the Meter results; units for meter=" + unitEnumToString(MeterUnits) +
1465 0 : ", units for this variable=" + unitEnumToString(UnitsVar) + '.');
1466 : }
1467 : }
1468 : }
1469 : // Check for duplicates
1470 211 : for (iKey = 1; iKey <= NumVarsOnCustomMeter; ++iKey) {
1471 173 : if (VarsOnCustomMeter(iKey) == 0) continue;
1472 515 : for (iKey1 = iKey + 1; iKey1 <= NumVarsOnCustomMeter; ++iKey1) {
1473 342 : if (iKey == iKey1) continue;
1474 342 : if (VarsOnCustomMeter(iKey) != VarsOnCustomMeter(iKey1)) continue;
1475 0 : ShowWarningError(state,
1476 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", duplicate name=\"" +
1477 0 : op->RVariableTypes(VarsOnCustomMeter(iKey1)).VarName + "\".");
1478 0 : ShowContinueError(state, "...only one value with this name will be shown with the Meter results.");
1479 0 : VarsOnCustomMeter(iKey1) = 0;
1480 : }
1481 : }
1482 211 : for (iKey = 1; iKey <= NumVarsOnCustomMeter; ++iKey) {
1483 173 : if (VarsOnCustomMeter(iKey) == 0) continue;
1484 173 : auto &tmpVar = op->RVariableTypes(VarsOnCustomMeter(iKey)).VarPtr;
1485 173 : AttachCustomMeters(state, VarsOnCustomMeter(iKey), tmpVar.MeterArrayPtr, op->NumEnergyMeters);
1486 : }
1487 :
1488 38 : errFlag = false;
1489 211 : for (iKey = 1; iKey <= NumVarsOnCustomMeter; ++iKey) {
1490 173 : for (iKey1 = 1; iKey1 <= NumVarsOnSourceMeter; ++iKey1) {
1491 173 : if (any_eq(VarsOnSourceMeter, VarsOnCustomMeter(iKey))) break;
1492 0 : if (!errFlag) {
1493 0 : ShowSevereError(state,
1494 0 : cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid specification to " +
1495 0 : state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" + state.dataIPShortCut->cAlphaArgs(3) + "\".");
1496 0 : errFlag = true;
1497 : }
1498 0 : ShowContinueError(state, "..Variable=" + op->RVariableTypes(VarsOnCustomMeter(iKey)).VarName);
1499 0 : ErrorsFound = true;
1500 0 : break;
1501 : }
1502 : }
1503 38 : if (NumVarsOnCustomMeter == 0) {
1504 0 : ShowWarningError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", no items assigned ");
1505 0 : ShowContinueError(state, "...will not be shown with the Meter results");
1506 : }
1507 :
1508 38 : VarsOnCustomMeter.deallocate();
1509 38 : VarsOnSourceMeter.deallocate();
1510 : }
1511 :
1512 769 : if (BigErrorsFound) ErrorsFound = true;
1513 769 : }
1514 :
1515 56191 : void GetStandardMeterResourceType(EnergyPlusData &state,
1516 : std::string &OutResourceType,
1517 : std::string const &UserInputResourceType, // Passed uppercase
1518 : bool &ErrorsFound)
1519 : {
1520 :
1521 : // SUBROUTINE INFORMATION:
1522 : // AUTHOR Linda Lawrie
1523 : // DATE WRITTEN April 2006
1524 : // MODIFIED na
1525 : // RE-ENGINEERED na
1526 :
1527 : // PURPOSE OF THIS SUBROUTINE:
1528 : // This routine compares the user input resource type with valid ones and returns
1529 : // the standard resource type.
1530 :
1531 56191 : ErrorsFound = false;
1532 :
1533 : // Basic ResourceType for Meters
1534 : {
1535 56191 : auto const &meterType(UserInputResourceType);
1536 :
1537 56191 : if (meterType == "ELECTRICITY") {
1538 18854 : OutResourceType = "Electricity";
1539 :
1540 37337 : } else if (meterType == "NATURALGAS") {
1541 2117 : OutResourceType = "NaturalGas";
1542 :
1543 35220 : } else if (meterType == "GASOLINE") {
1544 2 : OutResourceType = "Gasoline";
1545 :
1546 35218 : } else if (meterType == "DIESEL") {
1547 19 : OutResourceType = "Diesel";
1548 :
1549 35199 : } else if (meterType == "COAL") {
1550 2 : OutResourceType = "Coal";
1551 :
1552 35197 : } else if (meterType == "FUELOILNO1") {
1553 2 : OutResourceType = "FuelOilNo1";
1554 :
1555 35195 : } else if (meterType == "FUELOILNO2") {
1556 5 : OutResourceType = "FuelOilNo2";
1557 :
1558 35190 : } else if (meterType == "PROPANE") {
1559 2 : OutResourceType = "Propane";
1560 :
1561 35188 : } else if (meterType == "WATER" || meterType == "H2O") {
1562 1495 : OutResourceType = "Water"; // this is water "use"
1563 :
1564 33693 : } else if (meterType == "ONSITEWATER" || meterType == "WATERPRODUCED" || meterType == "ONSITE WATER") {
1565 4 : OutResourceType = "OnSiteWater"; // these are for supply record keeping
1566 :
1567 33689 : } else if (meterType == "MAINSWATER" || meterType == "WATERSUPPLY") {
1568 1499 : OutResourceType = "MainsWater"; // record keeping
1569 :
1570 32190 : } else if (meterType == "RAINWATER" || meterType == "PRECIPITATION") {
1571 0 : OutResourceType = "RainWater"; // record keeping
1572 :
1573 32190 : } else if (meterType == "WELLWATER" || meterType == "GROUNDWATER") {
1574 0 : OutResourceType = "WellWater"; // record keeping
1575 :
1576 32190 : } else if (meterType == "CONDENSATE") {
1577 0 : OutResourceType = "Condensate"; // record keeping
1578 :
1579 32190 : } else if (meterType == "ENERGYTRANSFER" || meterType == "ENERGYXFER" || meterType == "XFER") {
1580 18486 : OutResourceType = "EnergyTransfer";
1581 :
1582 13704 : } else if (meterType == "STEAM") {
1583 5 : OutResourceType = "Steam";
1584 :
1585 13699 : } else if (meterType == "DISTRICTCOOLING") {
1586 349 : OutResourceType = "DistrictCooling";
1587 :
1588 13350 : } else if (meterType == "DISTRICTHEATING") {
1589 396 : OutResourceType = "DistrictHeating";
1590 :
1591 12954 : } else if (meterType == "ELECTRICITYPRODUCED") {
1592 107 : OutResourceType = "ElectricityProduced";
1593 :
1594 12847 : } else if (meterType == "ELECTRICITYPURCHASED") {
1595 703 : OutResourceType = "ElectricityPurchased";
1596 :
1597 12144 : } else if (meterType == "ELECTRICITYSURPLUSSOLD") {
1598 703 : OutResourceType = "ElectricitySurplusSold";
1599 :
1600 11441 : } else if (meterType == "ELECTRICITYNET") {
1601 703 : OutResourceType = "ElectricityNet";
1602 :
1603 10738 : } else if (meterType == "SOLARWATER") {
1604 19 : OutResourceType = "SolarWater";
1605 :
1606 10719 : } else if (meterType == "SOLARAIR") {
1607 10 : OutResourceType = "SolarAir";
1608 :
1609 10709 : } else if (meterType == "SO2") {
1610 204 : OutResourceType = "SO2";
1611 :
1612 10505 : } else if (meterType == "NOX") {
1613 204 : OutResourceType = "NOx";
1614 :
1615 10301 : } else if (meterType == "N2O") {
1616 204 : OutResourceType = "N2O";
1617 :
1618 10097 : } else if (meterType == "PM") {
1619 204 : OutResourceType = "PM";
1620 :
1621 9893 : } else if (meterType == "PM2.5") {
1622 204 : OutResourceType = "PM2.5";
1623 :
1624 9689 : } else if (meterType == "PM10") {
1625 204 : OutResourceType = "PM10";
1626 :
1627 9485 : } else if (meterType == "CO") {
1628 204 : OutResourceType = "CO";
1629 :
1630 9281 : } else if (meterType == "CO2") {
1631 204 : OutResourceType = "CO2";
1632 :
1633 9077 : } else if (meterType == "CH4") {
1634 204 : OutResourceType = "CH4";
1635 :
1636 8873 : } else if (meterType == "NH3") {
1637 204 : OutResourceType = "NH3";
1638 :
1639 8669 : } else if (meterType == "NMVOC") {
1640 204 : OutResourceType = "NMVOC";
1641 :
1642 8465 : } else if (meterType == "HG") {
1643 204 : OutResourceType = "Hg";
1644 :
1645 8261 : } else if (meterType == "PB") {
1646 204 : OutResourceType = "Pb";
1647 :
1648 8057 : } else if (meterType == "NUCLEAR HIGH") {
1649 204 : OutResourceType = "Nuclear High";
1650 :
1651 7853 : } else if (meterType == "NUCLEAR LOW") {
1652 204 : OutResourceType = "Nuclear Low";
1653 :
1654 7649 : } else if (meterType == "WATERENVIRONMENTALFACTORS") {
1655 204 : OutResourceType = "WaterEnvironmentalFactors";
1656 :
1657 7445 : } else if (meterType == "CARBON EQUIVALENT") {
1658 2307 : OutResourceType = "Carbon Equivalent";
1659 :
1660 5138 : } else if (meterType == "SOURCE") {
1661 370 : OutResourceType = "Source";
1662 :
1663 4768 : } else if (meterType == "PLANTLOOPHEATINGDEMAND") {
1664 3939 : OutResourceType = "PlantLoopHeatingDemand";
1665 :
1666 829 : } else if (meterType == "PLANTLOOPCOOLINGDEMAND") {
1667 818 : OutResourceType = "PlantLoopCoolingDemand";
1668 :
1669 11 : } else if (meterType == "GENERIC") { // only used by custom meters
1670 6 : OutResourceType = "Generic";
1671 :
1672 5 : } else if (meterType == "OTHERFUEL1") { // other fuel type (defined by user)
1673 3 : OutResourceType = "OtherFuel1";
1674 :
1675 2 : } else if (meterType == "OTHERFUEL2") { // other fuel type (defined by user)
1676 2 : OutResourceType = "OtherFuel2";
1677 :
1678 : } else {
1679 0 : ShowSevereError(state, "GetStandardMeterResourceType: Illegal OutResourceType (for Meters) Entered=" + UserInputResourceType);
1680 0 : ErrorsFound = true;
1681 : }
1682 : }
1683 56191 : }
1684 :
1685 93065 : void AddMeter(EnergyPlusData &state,
1686 : std::string const &Name, // Name for the meter
1687 : OutputProcessor::Unit const MtrUnits, // Units for the meter
1688 : std::string const &ResourceType, // ResourceType for the meter
1689 : std::string const &EndUse, // EndUse for the meter
1690 : std::string const &EndUseSub, // EndUse subcategory for the meter
1691 : std::string const &Group // Group for the meter
1692 : )
1693 : {
1694 :
1695 : // SUBROUTINE INFORMATION:
1696 : // AUTHOR Linda Lawrie
1697 : // DATE WRITTEN January 2001
1698 : // MODIFIED na
1699 : // RE-ENGINEERED na
1700 :
1701 : // PURPOSE OF THIS SUBROUTINE:
1702 : // This subroutine adds a meter to the current definition set of meters. If the maximum has
1703 : // already been reached, a reallocation procedure begins. This action needs to be done at the
1704 : // start of the simulation, primarily before any output is stored.
1705 :
1706 : // Make sure this isn't already in the list of meter names
1707 93065 : auto &op(state.dataOutputProcessor);
1708 : int Found;
1709 :
1710 93065 : if (op->NumEnergyMeters > 0) {
1711 92294 : Found = UtilityRoutines::FindItemInList(Name, op->EnergyMeters);
1712 : } else {
1713 771 : Found = 0;
1714 : }
1715 :
1716 93065 : if (Found == 0) {
1717 93065 : op->EnergyMeters.redimension(++op->NumEnergyMeters);
1718 93065 : op->EnergyMeters(op->NumEnergyMeters).Name = Name;
1719 93065 : op->EnergyMeters(op->NumEnergyMeters).ResourceType = ResourceType;
1720 93065 : op->EnergyMeters(op->NumEnergyMeters).EndUse = EndUse;
1721 93065 : op->EnergyMeters(op->NumEnergyMeters).EndUseSub = EndUseSub;
1722 93065 : op->EnergyMeters(op->NumEnergyMeters).Group = Group;
1723 93065 : op->EnergyMeters(op->NumEnergyMeters).Units = MtrUnits;
1724 93065 : op->EnergyMeters(op->NumEnergyMeters).TSValue = 0.0;
1725 93065 : op->EnergyMeters(op->NumEnergyMeters).CurTSValue = 0.0;
1726 93065 : op->EnergyMeters(op->NumEnergyMeters).RptTS = false;
1727 93065 : op->EnergyMeters(op->NumEnergyMeters).RptTSFO = false;
1728 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).TSRptNum);
1729 93065 : op->EnergyMeters(op->NumEnergyMeters).TSRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).TSRptNum);
1730 93065 : op->EnergyMeters(op->NumEnergyMeters).HRValue = 0.0;
1731 93065 : op->EnergyMeters(op->NumEnergyMeters).RptHR = false;
1732 93065 : op->EnergyMeters(op->NumEnergyMeters).RptHRFO = false;
1733 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).HRRptNum);
1734 93065 : op->EnergyMeters(op->NumEnergyMeters).HRRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).HRRptNum);
1735 93065 : op->EnergyMeters(op->NumEnergyMeters).DYValue = 0.0;
1736 93065 : op->EnergyMeters(op->NumEnergyMeters).DYMaxVal = MaxSetValue;
1737 93065 : op->EnergyMeters(op->NumEnergyMeters).DYMaxValDate = 0;
1738 93065 : op->EnergyMeters(op->NumEnergyMeters).DYMinVal = MinSetValue;
1739 93065 : op->EnergyMeters(op->NumEnergyMeters).DYMinValDate = 0;
1740 93065 : op->EnergyMeters(op->NumEnergyMeters).RptDY = false;
1741 93065 : op->EnergyMeters(op->NumEnergyMeters).RptDYFO = false;
1742 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).DYRptNum);
1743 93065 : op->EnergyMeters(op->NumEnergyMeters).DYRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).DYRptNum);
1744 93065 : op->EnergyMeters(op->NumEnergyMeters).MNValue = 0.0;
1745 93065 : op->EnergyMeters(op->NumEnergyMeters).MNMaxVal = MaxSetValue;
1746 93065 : op->EnergyMeters(op->NumEnergyMeters).MNMaxValDate = 0;
1747 93065 : op->EnergyMeters(op->NumEnergyMeters).MNMinVal = MinSetValue;
1748 93065 : op->EnergyMeters(op->NumEnergyMeters).MNMinValDate = 0;
1749 93065 : op->EnergyMeters(op->NumEnergyMeters).RptMN = false;
1750 93065 : op->EnergyMeters(op->NumEnergyMeters).RptMNFO = false;
1751 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).MNRptNum);
1752 93065 : op->EnergyMeters(op->NumEnergyMeters).MNRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).MNRptNum);
1753 93065 : op->EnergyMeters(op->NumEnergyMeters).YRValue = 0.0;
1754 93065 : op->EnergyMeters(op->NumEnergyMeters).YRMaxVal = MaxSetValue;
1755 93065 : op->EnergyMeters(op->NumEnergyMeters).YRMaxValDate = 0;
1756 93065 : op->EnergyMeters(op->NumEnergyMeters).YRMinVal = MinSetValue;
1757 93065 : op->EnergyMeters(op->NumEnergyMeters).YRMinValDate = 0;
1758 93065 : op->EnergyMeters(op->NumEnergyMeters).RptYR = false;
1759 93065 : op->EnergyMeters(op->NumEnergyMeters).RptYRFO = false;
1760 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).YRRptNum);
1761 93065 : op->EnergyMeters(op->NumEnergyMeters).YRRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).YRRptNum);
1762 93065 : op->EnergyMeters(op->NumEnergyMeters).SMValue = 0.0;
1763 93065 : op->EnergyMeters(op->NumEnergyMeters).SMMaxVal = MaxSetValue;
1764 93065 : op->EnergyMeters(op->NumEnergyMeters).SMMaxValDate = 0;
1765 93065 : op->EnergyMeters(op->NumEnergyMeters).SMMinVal = MinSetValue;
1766 93065 : op->EnergyMeters(op->NumEnergyMeters).SMMinValDate = 0;
1767 93065 : op->EnergyMeters(op->NumEnergyMeters).RptSM = false;
1768 93065 : op->EnergyMeters(op->NumEnergyMeters).RptSMFO = false;
1769 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).SMRptNum);
1770 93065 : op->EnergyMeters(op->NumEnergyMeters).SMRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).SMRptNum);
1771 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).TSAccRptNum);
1772 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).HRAccRptNum);
1773 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).DYAccRptNum);
1774 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).MNAccRptNum);
1775 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).YRAccRptNum);
1776 93065 : AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).SMAccRptNum);
1777 93065 : op->EnergyMeters(op->NumEnergyMeters).FinYrSMValue = 0.0;
1778 93065 : op->EnergyMeters(op->NumEnergyMeters).FinYrSMMaxVal = MaxSetValue;
1779 93065 : op->EnergyMeters(op->NumEnergyMeters).FinYrSMMaxValDate = 0;
1780 93065 : op->EnergyMeters(op->NumEnergyMeters).FinYrSMMinVal = MinSetValue;
1781 93065 : op->EnergyMeters(op->NumEnergyMeters).FinYrSMMinValDate = 0;
1782 : } else {
1783 0 : ShowFatalError(state, "Requested to Add Meter which was already present=" + Name);
1784 : }
1785 93065 : if (!ResourceType.empty()) {
1786 : bool errFlag;
1787 92936 : DetermineMeterIPUnits(state, op->EnergyMeters(op->NumEnergyMeters).RT_forIPUnits, ResourceType, MtrUnits, errFlag);
1788 92936 : if (errFlag) {
1789 0 : ShowContinueError(state, "..on Meter=\"" + Name + "\".");
1790 0 : ShowContinueError(state, "..requests for IP units from this meter will be ignored.");
1791 : }
1792 : }
1793 93065 : }
1794 :
1795 56062 : void AttachMeters(EnergyPlusData &state,
1796 : OutputProcessor::Unit const MtrUnits, // Units for this meter
1797 : std::string &ResourceType, // Electricity, Gas, etc.
1798 : std::string &EndUse, // End-use category (Lights, Heating, etc.)
1799 : std::string &EndUseSub, // End-use subcategory (user-defined, e.g., General Lights, Task Lights, etc.)
1800 : std::string &Group, // Group key (Facility, Zone, Building, etc.)
1801 : std::string const &ZoneName, // Zone key only applicable for Building group
1802 : std::string const &SpaceType, // Space Type key only applicable for Building group
1803 : int const RepVarNum, // Number of this report variable
1804 : int &MeterArrayPtr, // Output set of Pointers to Meters
1805 : bool &ErrorsFound // True if errors in this call
1806 : )
1807 : {
1808 :
1809 : // SUBROUTINE INFORMATION:
1810 : // AUTHOR Linda Lawrie
1811 : // DATE WRITTEN January 2001
1812 : // MODIFIED na
1813 : // RE-ENGINEERED na
1814 :
1815 : // PURPOSE OF THIS SUBROUTINE:
1816 : // This subroutine determines which meters this variable will be on (if any),
1817 : // sets up the meter pointer arrays, and returns a index value to this array which
1818 : // is stored with the variable.
1819 :
1820 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1821 56062 : auto &op(state.dataOutputProcessor);
1822 :
1823 56062 : ValidateNStandardizeMeterTitles(state, MtrUnits, ResourceType, EndUse, EndUseSub, Group, ErrorsFound, ZoneName, SpaceType);
1824 :
1825 56062 : op->VarMeterArrays.redimension(++op->NumVarMeterArrays);
1826 56062 : MeterArrayPtr = op->NumVarMeterArrays;
1827 56062 : op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters = 0;
1828 56062 : op->VarMeterArrays(op->NumVarMeterArrays).RepVariable = RepVarNum;
1829 56062 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters = 0;
1830 56062 : int Found = UtilityRoutines::FindItem(ResourceType + ":Facility", op->EnergyMeters);
1831 56062 : if (Found != 0) {
1832 56062 : ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
1833 56062 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
1834 : }
1835 56062 : if (!Group.empty()) {
1836 49880 : Found = UtilityRoutines::FindItem(ResourceType + ':' + Group, op->EnergyMeters);
1837 49880 : if (Found != 0) {
1838 49880 : ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
1839 49880 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
1840 : }
1841 49880 : if (UtilityRoutines::SameString(Group, "Building")) { // Match to Zone and Space Type
1842 19147 : if (!ZoneName.empty()) {
1843 18825 : Found = UtilityRoutines::FindItem(ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
1844 18825 : if (Found != 0) {
1845 18825 : ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
1846 18825 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
1847 : }
1848 : }
1849 19147 : if (!SpaceType.empty()) {
1850 8348 : Found = UtilityRoutines::FindItem(ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
1851 8348 : if (Found != 0) {
1852 8348 : ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
1853 8348 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
1854 : }
1855 : }
1856 : }
1857 : }
1858 :
1859 : //!! Following if EndUse is by ResourceType
1860 56062 : if (!EndUse.empty()) {
1861 56048 : Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType, op->EnergyMeters);
1862 56048 : if (Found != 0) {
1863 56048 : ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
1864 56048 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
1865 : }
1866 56048 : if (UtilityRoutines::SameString(Group, "Building")) { // Match to Zone
1867 19144 : if (!ZoneName.empty()) {
1868 18825 : Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
1869 18825 : if (Found != 0) {
1870 18825 : ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
1871 18825 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
1872 : }
1873 : }
1874 19144 : if (!SpaceType.empty()) {
1875 8348 : Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
1876 8348 : if (Found != 0) {
1877 8348 : ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
1878 8348 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
1879 :
1880 8348 : addEndUseSpaceType(state, EndUse, SpaceType);
1881 : }
1882 : }
1883 : }
1884 :
1885 : // End use subcategory
1886 56048 : if (!EndUseSub.empty()) {
1887 39049 : Found = UtilityRoutines::FindItem(EndUseSub + ':' + EndUse + ':' + ResourceType, op->EnergyMeters);
1888 39049 : if (Found != 0) {
1889 39049 : ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
1890 39049 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
1891 :
1892 39049 : addEndUseSubcategory(state, EndUse, EndUseSub);
1893 : }
1894 39049 : if (UtilityRoutines::SameString(Group, "Building")) { // Match to Zone
1895 19144 : if (!ZoneName.empty()) {
1896 18825 : Found = UtilityRoutines::FindItem(EndUseSub + ':' + EndUse + ':' + ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
1897 18825 : if (Found != 0) {
1898 18825 : ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
1899 18825 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
1900 : }
1901 : }
1902 19144 : if (!SpaceType.empty()) {
1903 8348 : Found =
1904 16696 : UtilityRoutines::FindItem(EndUseSub + ':' + EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
1905 8348 : if (Found != 0) {
1906 8348 : ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
1907 8348 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
1908 : }
1909 : }
1910 : }
1911 : }
1912 : }
1913 56062 : }
1914 :
1915 811 : void AttachCustomMeters(EnergyPlusData &state,
1916 : int const RepVarNum, // Number of this report variable
1917 : int &MeterArrayPtr, // Input/Output set of Pointers to Meters
1918 : int const MeterIndex // Which meter this is
1919 : )
1920 : {
1921 :
1922 : // SUBROUTINE INFORMATION:
1923 : // AUTHOR Linda Lawrie
1924 : // DATE WRITTEN January 2006
1925 : // MODIFIED na
1926 : // RE-ENGINEERED na
1927 :
1928 : // PURPOSE OF THIS SUBROUTINE:
1929 : // This subroutine determines which meters this variable will be on (if any),
1930 : // sets up the meter pointer arrays, and returns a index value to this array which
1931 : // is stored with the variable.
1932 :
1933 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1934 811 : auto &op(state.dataOutputProcessor);
1935 :
1936 811 : if (MeterArrayPtr == 0) {
1937 161 : op->VarMeterArrays.redimension(++op->NumVarMeterArrays);
1938 161 : MeterArrayPtr = op->NumVarMeterArrays;
1939 161 : op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters = 0;
1940 161 : op->VarMeterArrays(op->NumVarMeterArrays).RepVariable = RepVarNum;
1941 161 : op->VarMeterArrays(op->NumVarMeterArrays).OnMeters = 0;
1942 161 : op->VarMeterArrays(op->NumVarMeterArrays).OnCustomMeters.allocate(1);
1943 161 : op->VarMeterArrays(op->NumVarMeterArrays).NumOnCustomMeters = 1;
1944 : } else { // MeterArrayPtr set
1945 650 : op->VarMeterArrays(MeterArrayPtr).OnCustomMeters.redimension(++op->VarMeterArrays(MeterArrayPtr).NumOnCustomMeters);
1946 : }
1947 811 : op->VarMeterArrays(MeterArrayPtr).OnCustomMeters(op->VarMeterArrays(MeterArrayPtr).NumOnCustomMeters) = MeterIndex;
1948 811 : }
1949 :
1950 56062 : void ValidateNStandardizeMeterTitles(EnergyPlusData &state,
1951 : OutputProcessor::Unit const MtrUnits, // Units for the meter
1952 : std::string &ResourceType, // Electricity, Gas, etc.
1953 : std::string &EndUse, // End Use Type (Lights, Heating, etc.)
1954 : std::string &EndUseSub, // End Use Sub Type (General Lights, Task Lights, etc.)
1955 : std::string &Group, // Group key (Facility, Zone, Building, etc.)
1956 : bool &ErrorsFound, // True if errors in this call
1957 : const std::string &ZoneName, // Zone Name when Group=Building
1958 : const std::string &SpaceType // Space Type when Group=Building
1959 : )
1960 : {
1961 :
1962 : // SUBROUTINE INFORMATION:
1963 : // AUTHOR Linda Lawrie
1964 : // DATE WRITTEN January 2001
1965 : // MODIFIED na
1966 : // RE-ENGINEERED na
1967 :
1968 : // PURPOSE OF THIS SUBROUTINE:
1969 : // This subroutine uses the keys for the Energy Meters given to the SetupOutputVariable routines
1970 : // and makes sure they are "standard" as well as creating meters which need to be added as this
1971 : // is the first use of that kind of meter designation.
1972 :
1973 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1974 : int Found; // For checking whether meter is already defined
1975 56062 : bool LocalErrorsFound = false;
1976 112124 : std::string MeterName;
1977 56062 : auto &op(state.dataOutputProcessor);
1978 :
1979 : // Basic ResourceType Meters
1980 56062 : GetStandardMeterResourceType(state, ResourceType, UtilityRoutines::MakeUPPERCase(ResourceType), LocalErrorsFound);
1981 :
1982 56062 : if (!LocalErrorsFound) {
1983 56062 : if (op->NumEnergyMeters > 0) {
1984 55291 : Found = UtilityRoutines::FindItem(ResourceType + ":Facility", op->EnergyMeters);
1985 : } else {
1986 771 : Found = 0;
1987 : }
1988 56062 : if (Found == 0) AddMeter(state, ResourceType + ":Facility", MtrUnits, ResourceType, "", "", "");
1989 : }
1990 :
1991 : //! Group Meters
1992 : {
1993 112124 : auto const groupMeter(uppercased(Group));
1994 :
1995 56062 : if (groupMeter.empty()) {
1996 :
1997 49880 : } else if (groupMeter == "BUILDING") {
1998 19147 : Group = "Building";
1999 :
2000 30733 : } else if (groupMeter == "HVAC" || groupMeter == "SYSTEM") {
2001 18961 : Group = "HVAC";
2002 :
2003 11772 : } else if (groupMeter == "PLANT") {
2004 11772 : Group = "Plant";
2005 :
2006 : } else {
2007 0 : ShowSevereError(state, "Illegal Group (for Meters) Entered=" + Group);
2008 0 : LocalErrorsFound = true;
2009 : }
2010 : }
2011 :
2012 56062 : if (!LocalErrorsFound && !Group.empty()) {
2013 49880 : Found = UtilityRoutines::FindItem(ResourceType + ':' + Group, op->EnergyMeters);
2014 49880 : if (Found == 0) AddMeter(state, ResourceType + ':' + Group, MtrUnits, ResourceType, "", "", Group);
2015 49880 : if (Group == "Building") {
2016 19147 : if (!ZoneName.empty()) {
2017 18825 : Found = UtilityRoutines::FindItem(ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
2018 18825 : if (Found == 0) {
2019 9027 : AddMeter(state, ResourceType + ":Zone:" + ZoneName, MtrUnits, ResourceType, "", "", "Zone");
2020 : }
2021 : }
2022 19147 : if (!SpaceType.empty()) {
2023 8348 : Found = UtilityRoutines::FindItem(ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
2024 8348 : if (Found == 0) {
2025 695 : AddMeter(state, ResourceType + ":SpaceType:" + SpaceType, MtrUnits, ResourceType, "", "", "SpaceType");
2026 : }
2027 : }
2028 : }
2029 : }
2030 :
2031 : //!!! EndUse Meters
2032 : {
2033 112124 : auto const endUseMeter(uppercased(EndUse));
2034 :
2035 56062 : if (endUseMeter.empty()) {
2036 :
2037 56048 : } else if (endUseMeter == "INTERIOR LIGHTS" || endUseMeter == "INTERIORLIGHTS") {
2038 4051 : EndUse = "InteriorLights";
2039 :
2040 51997 : } else if (endUseMeter == "EXTERIOR LIGHTS" || endUseMeter == "EXTERIORLIGHTS") {
2041 182 : EndUse = "ExteriorLights";
2042 :
2043 51815 : } else if (endUseMeter == "HEATING" || endUseMeter == "HTG") {
2044 9368 : EndUse = "Heating";
2045 :
2046 42447 : } else if (endUseMeter == "HEATPRODUCED") {
2047 29 : EndUse = "HeatProduced";
2048 :
2049 42418 : } else if (endUseMeter == "COOLING" || endUseMeter == "CLG") {
2050 7782 : EndUse = "Cooling";
2051 :
2052 34636 : } else if (endUseMeter == "DOMESTICHOTWATER" || endUseMeter == "DHW" || endUseMeter == "DOMESTIC HOT WATER") {
2053 1218 : EndUse = "WaterSystems";
2054 :
2055 33418 : } else if (endUseMeter == "COGEN" || endUseMeter == "COGENERATION") {
2056 2175 : EndUse = "Cogeneration";
2057 :
2058 31243 : } else if (endUseMeter == "INTERIOREQUIPMENT" || endUseMeter == "INTERIOR EQUIPMENT") {
2059 4297 : EndUse = "InteriorEquipment";
2060 :
2061 53821 : } else if (endUseMeter == "EXTERIOREQUIPMENT" || endUseMeter == "EXTERIOR EQUIPMENT" || endUseMeter == "EXT EQ" ||
2062 26875 : endUseMeter == "EXTERIOREQ") {
2063 71 : EndUse = "ExteriorEquipment";
2064 :
2065 26875 : } else if (endUseMeter == "EXTERIOR:WATEREQUIPMENT") {
2066 0 : EndUse = "ExteriorEquipment";
2067 :
2068 26875 : } else if (endUseMeter == "PURCHASEDHOTWATER" || endUseMeter == "DISTRICTHOTWATER" || endUseMeter == "PURCHASED HEATING") {
2069 0 : EndUse = "DistrictHotWater";
2070 :
2071 107500 : } else if (endUseMeter == "PURCHASEDCOLDWATER" || endUseMeter == "DISTRICTCHILLEDWATER" || endUseMeter == "PURCHASEDCHILLEDWATER" ||
2072 80625 : endUseMeter == "PURCHASED COLD WATER" || endUseMeter == "PURCHASED COOLING") {
2073 0 : EndUse = "DistrictChilledWater";
2074 :
2075 26875 : } else if (endUseMeter == "FANS" || endUseMeter == "FAN") {
2076 2288 : EndUse = "Fans";
2077 :
2078 41944 : } else if (endUseMeter == "HEATINGCOILS" || endUseMeter == "HEATINGCOIL" || endUseMeter == "HEATING COILS" ||
2079 17357 : endUseMeter == "HEATING COIL") {
2080 7230 : EndUse = "HeatingCoils";
2081 :
2082 32191 : } else if (endUseMeter == "COOLINGCOILS" || endUseMeter == "COOLINGCOIL" || endUseMeter == "COOLING COILS" ||
2083 14834 : endUseMeter == "COOLING COIL") {
2084 2523 : EndUse = "CoolingCoils";
2085 :
2086 14834 : } else if (endUseMeter == "PUMPS" || endUseMeter == "PUMP") {
2087 1154 : EndUse = "Pumps";
2088 :
2089 13680 : } else if (endUseMeter == "FREECOOLING" || endUseMeter == "FREE COOLING") {
2090 3 : EndUse = "Freecooling";
2091 :
2092 13677 : } else if (endUseMeter == "LOOPTOLOOP") {
2093 22 : EndUse = "LoopToLoop";
2094 :
2095 13655 : } else if (endUseMeter == "CHILLERS" || endUseMeter == "CHILLER") {
2096 424 : EndUse = "Chillers";
2097 :
2098 13231 : } else if (endUseMeter == "BOILERS" || endUseMeter == "BOILER") {
2099 209 : EndUse = "Boilers";
2100 :
2101 13022 : } else if (endUseMeter == "BASEBOARD" || endUseMeter == "BASEBOARDS") {
2102 151 : EndUse = "Baseboard";
2103 :
2104 12871 : } else if (endUseMeter == "COOLINGPANEL" || endUseMeter == "COOLINGPANELS") {
2105 8 : EndUse = "CoolingPanel";
2106 :
2107 12863 : } else if (endUseMeter == "HEATREJECTION" || endUseMeter == "HEAT REJECTION") {
2108 1247 : EndUse = "HeatRejection";
2109 :
2110 11616 : } else if (endUseMeter == "HUMIDIFIER" || endUseMeter == "HUMIDIFIERS") {
2111 109 : EndUse = "Humidifier";
2112 :
2113 11507 : } else if (endUseMeter == "HEATRECOVERY" || endUseMeter == "HEAT RECOVERY") {
2114 192 : EndUse = "HeatRecovery";
2115 :
2116 11315 : } else if (endUseMeter == "PHOTOVOLTAICS" || endUseMeter == "PV" || endUseMeter == "PHOTOVOLTAIC") {
2117 51 : EndUse = "Photovoltaic";
2118 :
2119 11264 : } else if (endUseMeter == "WINDTURBINES" || endUseMeter == "WT" || endUseMeter == "WINDTURBINE") {
2120 3 : EndUse = "WindTurbine";
2121 :
2122 11261 : } else if (endUseMeter == "ELECTRICSTORAGE") {
2123 16 : EndUse = "ElectricStorage";
2124 :
2125 11245 : } else if (endUseMeter == "POWERCONVERSION") {
2126 :
2127 16 : EndUse = "PowerConversion";
2128 :
2129 22300 : } else if (endUseMeter == "HEAT RECOVERY FOR COOLING" || endUseMeter == "HEATRECOVERYFORCOOLING" ||
2130 11071 : endUseMeter == "HEATRECOVERYCOOLING") {
2131 158 : EndUse = "HeatRecoveryForCooling";
2132 :
2133 21984 : } else if (endUseMeter == "HEAT RECOVERY FOR HEATING" || endUseMeter == "HEATRECOVERYFORHEATING" ||
2134 10913 : endUseMeter == "HEATRECOVERYHEATING") {
2135 158 : EndUse = "HeatRecoveryForHeating";
2136 :
2137 10913 : } else if (endUseMeter == "ELECTRICITYEMISSIONS") {
2138 1411 : EndUse = "ElectricityEmissions";
2139 :
2140 9502 : } else if (endUseMeter == "PURCHASEDELECTRICITYEMISSIONS") {
2141 83 : EndUse = "PurchasedElectricityEmissions";
2142 :
2143 9419 : } else if (endUseMeter == "SOLDELECTRICITYEMISSIONS") {
2144 83 : EndUse = "SoldElectricityEmissions";
2145 :
2146 9336 : } else if (endUseMeter == "NATURALGASEMISSIONS") {
2147 1292 : EndUse = "NaturalGasEmissions";
2148 :
2149 8044 : } else if (endUseMeter == "FUELOILNO1EMISSIONS") {
2150 357 : EndUse = "FuelOilNo1Emissions";
2151 :
2152 7687 : } else if (endUseMeter == "FUELOILNO2EMISSIONS") {
2153 0 : EndUse = "FuelOilNo2Emissions";
2154 :
2155 7687 : } else if (endUseMeter == "COALEMISSIONS") {
2156 0 : EndUse = "CoalEmissions";
2157 :
2158 7687 : } else if (endUseMeter == "GASOLINEEMISSIONS") {
2159 0 : EndUse = "GasolineEmissions";
2160 :
2161 7687 : } else if (endUseMeter == "PROPANEEMISSIONS") {
2162 357 : EndUse = "PropaneEmissions";
2163 :
2164 7330 : } else if (endUseMeter == "DIESELEMISSIONS") {
2165 34 : EndUse = "DieselEmissions";
2166 :
2167 7296 : } else if (endUseMeter == "OTHERFUEL1EMISSIONS") {
2168 17 : EndUse = "OtherFuel1Emissions";
2169 :
2170 7279 : } else if (endUseMeter == "OTHERFUEL2EMISSIONS") {
2171 0 : EndUse = "OtherFuel2Emissions";
2172 :
2173 7279 : } else if (endUseMeter == "CARBONEQUIVALENTEMISSIONS") {
2174 2307 : EndUse = "CarbonEquivalentEmissions";
2175 :
2176 4972 : } else if (endUseMeter == "REFRIGERATION") {
2177 1386 : EndUse = "Refrigeration";
2178 :
2179 3586 : } else if (endUseMeter == "COLDSTORAGECHARGE") {
2180 0 : EndUse = "ColdStorageCharge";
2181 :
2182 3586 : } else if (endUseMeter == "COLDSTORAGEDISCHARGE") {
2183 0 : EndUse = "ColdStorageDischarge";
2184 :
2185 3586 : } else if (endUseMeter == "WATERSYSTEMS" || endUseMeter == "WATERSYSTEM" || endUseMeter == "Water System") {
2186 3582 : EndUse = "WaterSystems";
2187 :
2188 4 : } else if (endUseMeter == "RAINWATER") {
2189 2 : EndUse = "Rainwater";
2190 :
2191 2 : } else if (endUseMeter == "CONDENSATE") {
2192 0 : EndUse = "Condensate";
2193 :
2194 2 : } else if (endUseMeter == "WELLWATER") {
2195 2 : EndUse = "Wellwater";
2196 :
2197 0 : } else if (endUseMeter == "MAINSWATER" || endUseMeter == "PURCHASEDWATER") {
2198 0 : EndUse = "MainsWater";
2199 :
2200 : } else {
2201 0 : ShowSevereError(state, "Illegal EndUse (for Meters) Entered=" + EndUse);
2202 0 : LocalErrorsFound = true;
2203 : }
2204 : }
2205 :
2206 : //!! Following if we do EndUse by ResourceType
2207 56062 : if (!LocalErrorsFound && !EndUse.empty()) {
2208 56048 : Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType, op->EnergyMeters);
2209 56048 : if (Found == 0) AddMeter(state, EndUse + ':' + ResourceType, MtrUnits, ResourceType, EndUse, "", "");
2210 :
2211 56048 : if (Group == "Building") { // Match to Zone and Space
2212 19144 : if (!ZoneName.empty()) {
2213 18825 : Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
2214 18825 : if (Found == 0) {
2215 17872 : AddMeter(state, EndUse + ':' + ResourceType + ":Zone:" + ZoneName, MtrUnits, ResourceType, EndUse, "", "Zone");
2216 : }
2217 : }
2218 19144 : if (!SpaceType.empty()) {
2219 8348 : Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
2220 8348 : if (Found == 0) {
2221 1323 : AddMeter(state, EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType, MtrUnits, ResourceType, EndUse, "", "SpaceType");
2222 : }
2223 : }
2224 : }
2225 14 : } else if (LocalErrorsFound) {
2226 0 : ErrorsFound = true;
2227 : }
2228 :
2229 : // End-Use Subcategories
2230 56062 : if (!LocalErrorsFound && !EndUseSub.empty()) {
2231 39049 : MeterName = EndUseSub + ':' + EndUse + ':' + ResourceType;
2232 39049 : Found = UtilityRoutines::FindItem(MeterName, op->EnergyMeters);
2233 39049 : if (Found == 0) AddMeter(state, MeterName, MtrUnits, ResourceType, EndUse, EndUseSub, "");
2234 :
2235 39049 : if (Group == "Building") { // Match to Zone and Space
2236 19144 : if (!ZoneName.empty()) {
2237 18825 : Found = UtilityRoutines::FindItem(EndUseSub + ':' + EndUse + ':' + ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
2238 18825 : if (Found == 0) {
2239 54366 : AddMeter(state,
2240 36244 : EndUseSub + ':' + EndUse + ':' + ResourceType + ":Zone:" + ZoneName,
2241 : MtrUnits,
2242 : ResourceType,
2243 : EndUse,
2244 : EndUseSub,
2245 : "Zone");
2246 : }
2247 : }
2248 19144 : if (!SpaceType.empty()) {
2249 8348 : Found = UtilityRoutines::FindItem(EndUseSub + ':' + EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
2250 8348 : if (Found == 0) {
2251 4473 : AddMeter(state,
2252 2982 : EndUseSub + ':' + EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType,
2253 : MtrUnits,
2254 : ResourceType,
2255 : EndUse,
2256 : EndUseSub,
2257 : "SpaceType");
2258 : }
2259 : }
2260 : }
2261 17013 : } else if (LocalErrorsFound) {
2262 0 : ErrorsFound = true;
2263 : }
2264 56062 : }
2265 :
2266 93065 : void DetermineMeterIPUnits(EnergyPlusData &state,
2267 : OutputProcessor::RT_IPUnits &CodeForIPUnits, // Output Code for IP Units
2268 : std::string const &ResourceType, // Resource Type
2269 : OutputProcessor::Unit const MtrUnits, // Meter units
2270 : bool &ErrorsFound // true if errors found during subroutine
2271 : )
2272 : {
2273 :
2274 : // SUBROUTINE INFORMATION:
2275 : // AUTHOR Linda Lawrie
2276 : // DATE WRITTEN January 2012
2277 : // MODIFIED September 2012; made into subroutine
2278 : // RE-ENGINEERED na
2279 :
2280 : // PURPOSE OF THIS SUBROUTINE:
2281 : // In order to set up tabular reports for IP units, need to search on same strings
2282 : // that tabular reports does for IP conversion.
2283 :
2284 : // REFERENCES:
2285 : // OutputReportTabular looks for:
2286 : // CONSUMP - not used in meters
2287 : // ELEC - Electricity (kWH)
2288 : // GAS - Gas (therm)
2289 : // COOL - Cooling (ton)
2290 : // and we need to add WATER (for m3/gal, etc)
2291 :
2292 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2293 186130 : std::string UC_ResourceType;
2294 :
2295 93065 : ErrorsFound = false;
2296 93065 : UC_ResourceType = UtilityRoutines::MakeUPPERCase(ResourceType);
2297 :
2298 93065 : CodeForIPUnits = RT_IPUnits::OtherJ;
2299 93065 : if (has(UC_ResourceType, "ELEC")) {
2300 43259 : CodeForIPUnits = RT_IPUnits::Electricity;
2301 49806 : } else if (has(UC_ResourceType, "GAS")) {
2302 2489 : CodeForIPUnits = RT_IPUnits::Gas;
2303 47317 : } else if (has(UC_ResourceType, "COOL")) {
2304 1963 : CodeForIPUnits = RT_IPUnits::Cooling;
2305 : }
2306 93065 : if (MtrUnits == OutputProcessor::Unit::m3 && has(UC_ResourceType, "WATER")) {
2307 3421 : CodeForIPUnits = RT_IPUnits::Water;
2308 89644 : } else if (MtrUnits == OutputProcessor::Unit::m3) {
2309 288 : CodeForIPUnits = RT_IPUnits::OtherM3;
2310 : }
2311 93065 : if (MtrUnits == OutputProcessor::Unit::kg) {
2312 5570 : CodeForIPUnits = RT_IPUnits::OtherKG;
2313 : }
2314 93065 : if (MtrUnits == OutputProcessor::Unit::L) {
2315 288 : CodeForIPUnits = RT_IPUnits::OtherL;
2316 : }
2317 : // write(outputfiledebug,*) 'resourcetype=',TRIM(resourcetype)
2318 : // write(outputfiledebug,*) 'ipunits type=',CodeForIPUnits
2319 93065 : if (!(MtrUnits == OutputProcessor::Unit::kg) && !(MtrUnits == OutputProcessor::Unit::J) && !(MtrUnits == OutputProcessor::Unit::m3) &&
2320 : !(MtrUnits == OutputProcessor::Unit::L)) {
2321 3 : ShowWarningError(state,
2322 2 : "DetermineMeterIPUnits: Meter units not recognized for IP Units conversion=[" + unitEnumToString(MtrUnits) + "].");
2323 1 : ErrorsFound = true;
2324 : }
2325 93065 : }
2326 :
2327 299088 : void UpdateMeters(EnergyPlusData &state, int const TimeStamp) // Current TimeStamp (for max/min)
2328 : {
2329 :
2330 : // SUBROUTINE INFORMATION:
2331 : // AUTHOR Linda Lawrie
2332 : // DATE WRITTEN April 2001
2333 : // MODIFIED na
2334 : // RE-ENGINEERED na
2335 :
2336 : // PURPOSE OF THIS SUBROUTINE:
2337 : // This subroutine updates the meters with the current time step value
2338 : // for each meter. Also, sets min/max values for hourly...run period reporting.
2339 :
2340 : // METHODOLOGY EMPLOYED:
2341 : // Goes thru the number of meters, setting min/max as appropriate. Uses timestamp
2342 : // from calling program.
2343 :
2344 : // REFERENCES:
2345 : // na
2346 :
2347 : // USE STATEMENTS:
2348 : // na
2349 :
2350 : // Locals
2351 : // SUBROUTINE ARGUMENT DEFINITIONS:
2352 :
2353 : // SUBROUTINE PARAMETER DEFINITIONS:
2354 : // na
2355 :
2356 : // INTERFACE BLOCK SPECIFICATIONS:
2357 : // na
2358 :
2359 : // DERIVED TYPE DEFINITIONS:
2360 : // na
2361 :
2362 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2363 299088 : auto &op(state.dataOutputProcessor);
2364 :
2365 299088 : if (!op->MeterValue.allocated()) {
2366 0 : return;
2367 : }
2368 :
2369 36180192 : for (int Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
2370 35881104 : if (op->EnergyMeters(Meter).TypeOfMeter != MtrType::CustomDec && op->EnergyMeters(Meter).TypeOfMeter != MtrType::CustomDiff) {
2371 35804160 : op->EnergyMeters(Meter).TSValue += op->MeterValue(Meter);
2372 : } else {
2373 76944 : op->EnergyMeters(Meter).TSValue = op->EnergyMeters(op->EnergyMeters(Meter).SourceMeter).TSValue - op->MeterValue(Meter);
2374 : }
2375 35881104 : op->EnergyMeters(Meter).HRValue += op->EnergyMeters(Meter).TSValue;
2376 35881104 : op->EnergyMeters(Meter).DYValue += op->EnergyMeters(Meter).TSValue;
2377 35881104 : op->EnergyMeters(Meter).MNValue += op->EnergyMeters(Meter).TSValue;
2378 35881104 : op->EnergyMeters(Meter).YRValue += op->EnergyMeters(Meter).TSValue;
2379 35881104 : op->EnergyMeters(Meter).SMValue += op->EnergyMeters(Meter).TSValue;
2380 35881104 : if (op->isFinalYear) op->EnergyMeters(Meter).FinYrSMValue += op->EnergyMeters(Meter).TSValue;
2381 : }
2382 : // Set Max
2383 36180192 : for (int Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
2384 : // Todo - HRMinVal, HRMaxVal not used
2385 69557496 : if (op->EnergyMeters(Meter).TSValue > op->EnergyMeters(Meter).DYMaxVal) {
2386 2204712 : op->EnergyMeters(Meter).DYMaxVal = op->EnergyMeters(Meter).TSValue;
2387 2204712 : op->EnergyMeters(Meter).DYMaxValDate = TimeStamp;
2388 : } else {
2389 33676392 : continue; // Not max val of month or year, if not max of day so far
2390 : }
2391 2204712 : if (op->EnergyMeters(Meter).TSValue > op->EnergyMeters(Meter).MNMaxVal) {
2392 2204712 : op->EnergyMeters(Meter).MNMaxVal = op->EnergyMeters(Meter).TSValue;
2393 2204712 : op->EnergyMeters(Meter).MNMaxValDate = TimeStamp;
2394 : } else {
2395 0 : continue;
2396 : }
2397 2204712 : if (op->EnergyMeters(Meter).TSValue > op->EnergyMeters(Meter).YRMaxVal) {
2398 2204712 : op->EnergyMeters(Meter).YRMaxVal = op->EnergyMeters(Meter).TSValue;
2399 2204712 : op->EnergyMeters(Meter).YRMaxValDate = TimeStamp;
2400 : }
2401 2204712 : if (op->EnergyMeters(Meter).TSValue > op->EnergyMeters(Meter).SMMaxVal) {
2402 2204712 : op->EnergyMeters(Meter).SMMaxVal = op->EnergyMeters(Meter).TSValue;
2403 2204712 : op->EnergyMeters(Meter).SMMaxValDate = TimeStamp;
2404 : }
2405 2204712 : if (op->isFinalYear) {
2406 2163204 : if (op->EnergyMeters(Meter).TSValue > op->EnergyMeters(Meter).FinYrSMMaxVal) {
2407 2163204 : op->EnergyMeters(Meter).FinYrSMMaxVal = op->EnergyMeters(Meter).TSValue;
2408 2163204 : op->EnergyMeters(Meter).FinYrSMMaxValDate = TimeStamp;
2409 : }
2410 : }
2411 : }
2412 : // Set Min
2413 36180192 : for (int Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
2414 70642911 : if (op->EnergyMeters(Meter).TSValue < op->EnergyMeters(Meter).DYMinVal) {
2415 1119297 : op->EnergyMeters(Meter).DYMinVal = op->EnergyMeters(Meter).TSValue;
2416 1119297 : op->EnergyMeters(Meter).DYMinValDate = TimeStamp;
2417 : } else {
2418 34761807 : continue;
2419 : }
2420 1119297 : if (op->EnergyMeters(Meter).TSValue < op->EnergyMeters(Meter).MNMinVal) {
2421 1119297 : op->EnergyMeters(Meter).MNMinVal = op->EnergyMeters(Meter).TSValue;
2422 1119297 : op->EnergyMeters(Meter).MNMinValDate = TimeStamp;
2423 : } else {
2424 0 : continue;
2425 : }
2426 1119297 : if (op->EnergyMeters(Meter).TSValue < op->EnergyMeters(Meter).YRMinVal) {
2427 1119297 : op->EnergyMeters(Meter).YRMinVal = op->EnergyMeters(Meter).TSValue;
2428 1119297 : op->EnergyMeters(Meter).YRMinValDate = TimeStamp;
2429 : }
2430 1119297 : if (op->EnergyMeters(Meter).TSValue < op->EnergyMeters(Meter).SMMinVal) {
2431 1119297 : op->EnergyMeters(Meter).SMMinVal = op->EnergyMeters(Meter).TSValue;
2432 1119297 : op->EnergyMeters(Meter).SMMinValDate = TimeStamp;
2433 : }
2434 1119297 : if (op->isFinalYear) {
2435 1110377 : if (op->EnergyMeters(Meter).TSValue < op->EnergyMeters(Meter).FinYrSMMinVal) {
2436 1110377 : op->EnergyMeters(Meter).FinYrSMMinVal = op->EnergyMeters(Meter).TSValue;
2437 1110377 : op->EnergyMeters(Meter).FinYrSMMinValDate = TimeStamp;
2438 : }
2439 : }
2440 : }
2441 36180192 : for (int Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
2442 35881104 : op->MeterValue(Meter) = 0.0; // Ready for next update
2443 : }
2444 : }
2445 :
2446 1613 : void ResetAccumulationWhenWarmupComplete(EnergyPlusData &state)
2447 : {
2448 : // SUBROUTINE INFORMATION:
2449 : // AUTHOR Jason Glazer
2450 : // DATE WRITTEN June 2015
2451 : // MODIFIED na
2452 : // RE-ENGINEERED na
2453 :
2454 : // PURPOSE OF THIS SUBROUTINE:
2455 : // Resets the accumulating meter values. Needed after warmup period is over to
2456 : // reset the totals on meters so that they are not accumulated over the warmup period
2457 :
2458 : // METHODOLOGY EMPLOYED:
2459 : // Cycle through the meters and reset all accumulating values
2460 :
2461 : // REFERENCES:
2462 : // na
2463 :
2464 : // USE STATEMENTS:
2465 : // na
2466 :
2467 : // Locals
2468 : // SUBROUTINE ARGUMENT DEFINITIONS:
2469 :
2470 : // SUBROUTINE PARAMETER DEFINITIONS:
2471 : // na
2472 :
2473 : // INTERFACE BLOCK SPECIFICATIONS:
2474 : // na
2475 :
2476 : // DERIVED TYPE DEFINITIONS:
2477 : // na
2478 :
2479 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2480 : int Meter; // Loop Control
2481 : int Loop; // Loop Variable
2482 1613 : auto &op(state.dataOutputProcessor);
2483 :
2484 196433 : for (Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
2485 194820 : op->EnergyMeters(Meter).HRValue = 0.0;
2486 :
2487 194820 : op->EnergyMeters(Meter).DYValue = 0.0;
2488 194820 : op->EnergyMeters(Meter).DYMaxVal = MaxSetValue;
2489 194820 : op->EnergyMeters(Meter).DYMaxValDate = 0;
2490 194820 : op->EnergyMeters(Meter).DYMinVal = MinSetValue;
2491 194820 : op->EnergyMeters(Meter).DYMinValDate = 0;
2492 :
2493 194820 : op->EnergyMeters(Meter).MNValue = 0.0;
2494 194820 : op->EnergyMeters(Meter).MNMaxVal = MaxSetValue;
2495 194820 : op->EnergyMeters(Meter).MNMaxValDate = 0;
2496 194820 : op->EnergyMeters(Meter).MNMinVal = MinSetValue;
2497 194820 : op->EnergyMeters(Meter).MNMinValDate = 0;
2498 :
2499 194820 : op->EnergyMeters(Meter).YRValue = 0.0;
2500 194820 : op->EnergyMeters(Meter).YRMaxVal = MaxSetValue;
2501 194820 : op->EnergyMeters(Meter).YRMaxValDate = 0;
2502 194820 : op->EnergyMeters(Meter).YRMinVal = MinSetValue;
2503 194820 : op->EnergyMeters(Meter).YRMinValDate = 0;
2504 :
2505 194820 : op->EnergyMeters(Meter).SMValue = 0.0;
2506 194820 : op->EnergyMeters(Meter).SMMaxVal = MaxSetValue;
2507 194820 : op->EnergyMeters(Meter).SMMaxValDate = 0;
2508 194820 : op->EnergyMeters(Meter).SMMinVal = MinSetValue;
2509 194820 : op->EnergyMeters(Meter).SMMinValDate = 0;
2510 :
2511 194820 : op->EnergyMeters(Meter).FinYrSMValue = 0.0;
2512 194820 : op->EnergyMeters(Meter).FinYrSMMaxVal = MaxSetValue;
2513 194820 : op->EnergyMeters(Meter).FinYrSMMaxValDate = 0;
2514 194820 : op->EnergyMeters(Meter).FinYrSMMinVal = MinSetValue;
2515 194820 : op->EnergyMeters(Meter).FinYrSMMinValDate = 0;
2516 : }
2517 :
2518 394673 : for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
2519 393060 : auto &rVar(op->RVariableTypes(Loop).VarPtr);
2520 739588 : if (rVar.frequency == ReportingFrequency::Monthly || rVar.frequency == ReportingFrequency::Yearly ||
2521 346528 : rVar.frequency == ReportingFrequency::Simulation) {
2522 47264 : rVar.StoreValue = 0.0;
2523 47264 : rVar.NumStored = 0;
2524 : }
2525 : }
2526 :
2527 9913 : for (Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
2528 8300 : auto &iVar(op->IVariableTypes(Loop).VarPtr);
2529 15876 : if (iVar.frequency == ReportingFrequency::Monthly || iVar.frequency == ReportingFrequency::Yearly ||
2530 7576 : iVar.frequency == ReportingFrequency::Simulation) {
2531 724 : iVar.StoreValue = 0;
2532 724 : iVar.NumStored = 0;
2533 : }
2534 : }
2535 1613 : }
2536 :
2537 299088 : void ReportTSMeters(EnergyPlusData &state,
2538 : Real64 const StartMinute, // Start Minute for TimeStep
2539 : Real64 const EndMinute, // End Minute for TimeStep
2540 : bool &PrintESOTimeStamp, // True if the ESO Time Stamp also needs to be printed
2541 : bool PrintTimeStampToSQL // Print Time Stamp to SQL file
2542 : )
2543 : {
2544 :
2545 : // SUBROUTINE INFORMATION:
2546 : // AUTHOR Linda Lawrie
2547 : // DATE WRITTEN January 2001
2548 : // MODIFIED na
2549 : // RE-ENGINEERED na
2550 :
2551 : // PURPOSE OF THIS SUBROUTINE:
2552 : // This subroutine reports on the meters that have been requested for
2553 : // reporting on each time step.
2554 :
2555 : // METHODOLOGY EMPLOYED:
2556 : // na
2557 :
2558 : // REFERENCES:
2559 : // na
2560 :
2561 : // Locals
2562 : // SUBROUTINE ARGUMENT DEFINITIONS:
2563 :
2564 : // SUBROUTINE PARAMETER DEFINITIONS:
2565 : // na
2566 :
2567 : // INTERFACE BLOCK SPECIFICATIONS:
2568 : // na
2569 :
2570 : // DERIVED TYPE DEFINITIONS:
2571 : // na
2572 :
2573 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2574 : int Loop; // Loop Control
2575 : bool PrintTimeStamp;
2576 : int CurDayType;
2577 299088 : auto &op(state.dataOutputProcessor);
2578 :
2579 299088 : if (!state.dataResultsFramework->resultsFramework->TSMeters.rDataFrameEnabled()) {
2580 293532 : state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::TimeStep);
2581 : }
2582 :
2583 299088 : PrintTimeStamp = true;
2584 36180192 : for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
2585 35881104 : op->EnergyMeters(Loop).CurTSValue = op->EnergyMeters(Loop).TSValue;
2586 35881104 : if (!op->EnergyMeters(Loop).RptTS && !op->EnergyMeters(Loop).RptAccTS) continue;
2587 25824 : if (PrintTimeStamp) {
2588 5568 : CurDayType = state.dataEnvrn->DayOfWeek;
2589 5568 : if (state.dataEnvrn->HolidayIndex > 0) {
2590 5568 : CurDayType = state.dataEnvrn->HolidayIndex;
2591 : }
2592 50112 : WriteTimeStampFormatData(state,
2593 : state.files.mtr,
2594 : ReportingFrequency::EachCall,
2595 5568 : op->TimeStepStampReportNbr,
2596 5568 : op->TimeStepStampReportChr,
2597 5568 : state.dataGlobal->DayOfSimChr,
2598 5568 : PrintTimeStamp && PrintTimeStampToSQL,
2599 5568 : state.dataEnvrn->Month,
2600 5568 : state.dataEnvrn->DayOfMonth,
2601 5568 : state.dataGlobal->HourOfDay,
2602 : EndMinute,
2603 : StartMinute,
2604 5568 : state.dataEnvrn->DSTIndicator,
2605 5568 : ScheduleManager::dayTypeNames[CurDayType]);
2606 5568 : if (state.dataResultsFramework->resultsFramework->TSMeters.rDataFrameEnabled()) {
2607 22272 : state.dataResultsFramework->resultsFramework->TSMeters.newRow(
2608 16704 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, EndMinute);
2609 : }
2610 5568 : PrintTimeStamp = false;
2611 5568 : PrintTimeStampToSQL = false;
2612 : }
2613 :
2614 25824 : if (PrintESOTimeStamp && !op->EnergyMeters(Loop).RptTSFO && !op->EnergyMeters(Loop).RptAccTSFO) {
2615 0 : CurDayType = state.dataEnvrn->DayOfWeek;
2616 0 : if (state.dataEnvrn->HolidayIndex > 0) {
2617 0 : CurDayType = state.dataEnvrn->HolidayIndex;
2618 : }
2619 0 : WriteTimeStampFormatData(state,
2620 : state.files.eso,
2621 : ReportingFrequency::EachCall,
2622 0 : op->TimeStepStampReportNbr,
2623 0 : op->TimeStepStampReportChr,
2624 0 : state.dataGlobal->DayOfSimChr,
2625 0 : PrintTimeStamp && PrintESOTimeStamp && PrintTimeStampToSQL,
2626 0 : state.dataEnvrn->Month,
2627 0 : state.dataEnvrn->DayOfMonth,
2628 0 : state.dataGlobal->HourOfDay,
2629 : EndMinute,
2630 : StartMinute,
2631 0 : state.dataEnvrn->DSTIndicator,
2632 0 : ScheduleManager::dayTypeNames[CurDayType]);
2633 0 : PrintESOTimeStamp = false;
2634 : }
2635 :
2636 25824 : if (op->EnergyMeters(Loop).RptTS) {
2637 206592 : WriteReportMeterData(state,
2638 25824 : op->EnergyMeters(Loop).TSRptNum,
2639 25824 : op->EnergyMeters(Loop).TSRptNumChr,
2640 25824 : op->EnergyMeters(Loop).TSValue,
2641 : ReportingFrequency::TimeStep,
2642 25824 : state.dataOutputProcessor->rDummy1TS,
2643 25824 : state.dataOutputProcessor->iDummy1TS,
2644 25824 : state.dataOutputProcessor->rDummy2TS,
2645 25824 : state.dataOutputProcessor->iDummy2TS,
2646 25824 : op->EnergyMeters(Loop).RptTSFO);
2647 51648 : state.dataResultsFramework->resultsFramework->TSMeters.pushVariableValue(op->EnergyMeters(Loop).TSRptNum,
2648 25824 : op->EnergyMeters(Loop).TSValue);
2649 : }
2650 :
2651 25824 : if (op->EnergyMeters(Loop).RptAccTS) {
2652 0 : WriteCumulativeReportMeterData(state,
2653 0 : op->EnergyMeters(Loop).TSAccRptNum,
2654 0 : fmt::to_string(op->EnergyMeters(Loop).TSAccRptNum),
2655 0 : op->EnergyMeters(Loop).SMValue,
2656 0 : op->EnergyMeters(Loop).RptAccTSFO);
2657 0 : state.dataResultsFramework->resultsFramework->TSMeters.pushVariableValue(op->EnergyMeters(Loop).TSAccRptNum,
2658 0 : op->EnergyMeters(Loop).SMValue);
2659 : }
2660 : }
2661 :
2662 299088 : if (op->NumEnergyMeters > 0) {
2663 36180192 : for (auto &e : op->EnergyMeters)
2664 35881104 : e.TSValue = 0.0;
2665 : }
2666 299088 : }
2667 :
2668 57768 : void ReportHRMeters(EnergyPlusData &state, bool PrintTimeStampToSQL // Print Time Stamp to SQL file
2669 : )
2670 : {
2671 :
2672 : // SUBROUTINE INFORMATION:
2673 : // AUTHOR Linda Lawrie
2674 : // DATE WRITTEN January 2001
2675 : // MODIFIED na
2676 : // RE-ENGINEERED na
2677 :
2678 : // PURPOSE OF THIS SUBROUTINE:
2679 : // This subroutine reports on the meters that have been requested for
2680 : // reporting on each hour.
2681 :
2682 : // METHODOLOGY EMPLOYED:
2683 : // na
2684 :
2685 : // REFERENCES:
2686 : // na
2687 :
2688 : // Locals
2689 : // SUBROUTINE ARGUMENT DEFINITIONS:
2690 : // na
2691 :
2692 : // SUBROUTINE PARAMETER DEFINITIONS:
2693 : // na
2694 :
2695 : // INTERFACE BLOCK SPECIFICATIONS:
2696 : // na
2697 :
2698 : // DERIVED TYPE DEFINITIONS:
2699 : // na
2700 :
2701 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2702 : int Loop; // Loop Control
2703 : bool PrintTimeStamp;
2704 : int CurDayType;
2705 57768 : auto &op(state.dataOutputProcessor);
2706 :
2707 57768 : if (!state.dataResultsFramework->resultsFramework->HRMeters.rDataFrameEnabled()) {
2708 49894 : state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::Hourly);
2709 : }
2710 :
2711 57768 : PrintTimeStamp = true;
2712 7095912 : for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
2713 7038144 : if (!op->EnergyMeters(Loop).RptHR && !op->EnergyMeters(Loop).RptAccHR) continue;
2714 39504 : if (PrintTimeStamp) {
2715 8016 : CurDayType = state.dataEnvrn->DayOfWeek;
2716 8016 : if (state.dataEnvrn->HolidayIndex > 0) {
2717 7944 : CurDayType = state.dataEnvrn->HolidayIndex;
2718 : }
2719 72144 : WriteTimeStampFormatData(state,
2720 : state.files.mtr,
2721 : ReportingFrequency::Hourly,
2722 8016 : op->TimeStepStampReportNbr,
2723 8016 : op->TimeStepStampReportChr,
2724 8016 : state.dataGlobal->DayOfSimChr,
2725 8016 : PrintTimeStamp && PrintTimeStampToSQL,
2726 8016 : state.dataEnvrn->Month,
2727 8016 : state.dataEnvrn->DayOfMonth,
2728 8016 : state.dataGlobal->HourOfDay,
2729 : _,
2730 : _,
2731 8016 : state.dataEnvrn->DSTIndicator,
2732 8016 : ScheduleManager::dayTypeNames[CurDayType]);
2733 8016 : if (state.dataResultsFramework->resultsFramework->HRMeters.rDataFrameEnabled()) {
2734 32064 : state.dataResultsFramework->resultsFramework->HRMeters.newRow(
2735 24048 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
2736 : }
2737 8016 : PrintTimeStamp = false;
2738 8016 : PrintTimeStampToSQL = false;
2739 : }
2740 :
2741 39504 : if (op->EnergyMeters(Loop).RptHR) {
2742 316032 : WriteReportMeterData(state,
2743 39504 : op->EnergyMeters(Loop).HRRptNum,
2744 39504 : op->EnergyMeters(Loop).HRRptNumChr,
2745 39504 : op->EnergyMeters(Loop).HRValue,
2746 : ReportingFrequency::Hourly,
2747 39504 : state.dataOutputProcessor->rDummy1,
2748 39504 : state.dataOutputProcessor->iDummy1,
2749 39504 : state.dataOutputProcessor->rDummy2,
2750 39504 : state.dataOutputProcessor->iDummy2,
2751 39504 : op->EnergyMeters(Loop).RptHRFO); // EnergyMeters(Loop)%HRMinVal, EnergyMeters(Loop)%HRMinValDate, & |
2752 : // EnergyMeters(Loop)%HRMaxVal, EnergyMeters(Loop)%HRMaxValDate, &
2753 79008 : state.dataResultsFramework->resultsFramework->HRMeters.pushVariableValue(op->EnergyMeters(Loop).HRRptNum,
2754 39504 : op->EnergyMeters(Loop).HRValue);
2755 39504 : op->EnergyMeters(Loop).HRValue = 0.0;
2756 : }
2757 :
2758 39504 : if (op->EnergyMeters(Loop).RptAccHR) {
2759 0 : WriteCumulativeReportMeterData(state,
2760 0 : op->EnergyMeters(Loop).HRAccRptNum,
2761 0 : fmt::to_string(op->EnergyMeters(Loop).HRAccRptNum),
2762 0 : op->EnergyMeters(Loop).SMValue,
2763 0 : op->EnergyMeters(Loop).RptAccHRFO);
2764 0 : state.dataResultsFramework->resultsFramework->HRMeters.pushVariableValue(op->EnergyMeters(Loop).HRAccRptNum,
2765 0 : op->EnergyMeters(Loop).SMValue);
2766 : }
2767 : }
2768 57768 : }
2769 :
2770 2407 : void ReportDYMeters(EnergyPlusData &state, bool PrintTimeStampToSQL // Print Time Stamp to SQL file
2771 : )
2772 : {
2773 :
2774 : // SUBROUTINE INFORMATION:
2775 : // AUTHOR Linda Lawrie
2776 : // DATE WRITTEN January 2001
2777 : // MODIFIED na
2778 : // RE-ENGINEERED na
2779 :
2780 : // PURPOSE OF THIS SUBROUTINE:
2781 : // This subroutine reports on the meters that have been requested for
2782 : // reporting on each day.
2783 :
2784 : // METHODOLOGY EMPLOYED:
2785 : // na
2786 :
2787 : // REFERENCES:
2788 : // na
2789 :
2790 : // Locals
2791 : // SUBROUTINE ARGUMENT DEFINITIONS:
2792 : // na
2793 :
2794 : // SUBROUTINE PARAMETER DEFINITIONS:
2795 : // na
2796 :
2797 : // INTERFACE BLOCK SPECIFICATIONS:
2798 : // na
2799 :
2800 : // DERIVED TYPE DEFINITIONS:
2801 : // na
2802 :
2803 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2804 : int Loop; // Loop Control
2805 : bool PrintTimeStamp;
2806 : int CurDayType;
2807 2407 : auto &op(state.dataOutputProcessor);
2808 :
2809 2407 : if (!state.dataResultsFramework->resultsFramework->DYMeters.rVariablesScanned()) {
2810 769 : state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::Daily);
2811 : }
2812 :
2813 2407 : PrintTimeStamp = true;
2814 295663 : for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
2815 293256 : if (!op->EnergyMeters(Loop).RptDY && !op->EnergyMeters(Loop).RptAccDY) continue;
2816 158 : if (PrintTimeStamp) {
2817 48 : CurDayType = state.dataEnvrn->DayOfWeek;
2818 48 : if (state.dataEnvrn->HolidayIndex > 0) {
2819 48 : CurDayType = state.dataEnvrn->HolidayIndex;
2820 : }
2821 384 : WriteTimeStampFormatData(state,
2822 : state.files.mtr,
2823 : ReportingFrequency::Daily,
2824 48 : op->DailyStampReportNbr,
2825 48 : op->DailyStampReportChr,
2826 48 : state.dataGlobal->DayOfSimChr,
2827 48 : PrintTimeStamp && PrintTimeStampToSQL,
2828 48 : state.dataEnvrn->Month,
2829 48 : state.dataEnvrn->DayOfMonth,
2830 : _,
2831 : _,
2832 : _,
2833 48 : state.dataEnvrn->DSTIndicator,
2834 48 : ScheduleManager::dayTypeNames[CurDayType]);
2835 48 : if (state.dataResultsFramework->resultsFramework->DYMeters.rDataFrameEnabled()) {
2836 192 : state.dataResultsFramework->resultsFramework->DYMeters.newRow(
2837 144 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
2838 : }
2839 48 : PrintTimeStamp = false;
2840 48 : PrintTimeStampToSQL = false;
2841 : }
2842 :
2843 158 : if (op->EnergyMeters(Loop).RptDY) {
2844 1264 : WriteReportMeterData(state,
2845 158 : op->EnergyMeters(Loop).DYRptNum,
2846 158 : op->EnergyMeters(Loop).DYRptNumChr,
2847 158 : op->EnergyMeters(Loop).DYValue,
2848 : ReportingFrequency::Daily,
2849 158 : op->EnergyMeters(Loop).DYMinVal,
2850 158 : op->EnergyMeters(Loop).DYMinValDate,
2851 158 : op->EnergyMeters(Loop).DYMaxVal,
2852 158 : op->EnergyMeters(Loop).DYMaxValDate,
2853 158 : op->EnergyMeters(Loop).RptDYFO);
2854 316 : state.dataResultsFramework->resultsFramework->DYMeters.pushVariableValue(op->EnergyMeters(Loop).DYRptNum,
2855 158 : op->EnergyMeters(Loop).DYValue);
2856 158 : op->EnergyMeters(Loop).DYValue = 0.0;
2857 158 : op->EnergyMeters(Loop).DYMinVal = MinSetValue;
2858 158 : op->EnergyMeters(Loop).DYMaxVal = MaxSetValue;
2859 : }
2860 :
2861 158 : if (op->EnergyMeters(Loop).RptAccDY) {
2862 0 : WriteCumulativeReportMeterData(state,
2863 0 : op->EnergyMeters(Loop).DYAccRptNum,
2864 0 : fmt::to_string(op->EnergyMeters(Loop).DYAccRptNum),
2865 0 : op->EnergyMeters(Loop).SMValue,
2866 0 : op->EnergyMeters(Loop).RptAccDYFO);
2867 0 : state.dataResultsFramework->resultsFramework->DYMeters.pushVariableValue(op->EnergyMeters(Loop).DYAccRptNum,
2868 0 : op->EnergyMeters(Loop).SMValue);
2869 : }
2870 : }
2871 2407 : }
2872 :
2873 1669 : void ReportMNMeters(EnergyPlusData &state, bool PrintTimeStampToSQL // Print Time Stamp to SQL file
2874 : )
2875 : {
2876 :
2877 : // SUBROUTINE INFORMATION:
2878 : // AUTHOR Linda Lawrie
2879 : // DATE WRITTEN January 2001
2880 : // MODIFIED na
2881 : // RE-ENGINEERED na
2882 :
2883 : // PURPOSE OF THIS SUBROUTINE:
2884 : // This subroutine reports on the meters that have been requested for
2885 : // reporting on each month.
2886 :
2887 : // METHODOLOGY EMPLOYED:
2888 : // na
2889 :
2890 : // REFERENCES:
2891 : // na
2892 :
2893 : // Locals
2894 : // SUBROUTINE ARGUMENT DEFINITIONS:
2895 : // na
2896 :
2897 : // SUBROUTINE PARAMETER DEFINITIONS:
2898 : // na
2899 :
2900 : // INTERFACE BLOCK SPECIFICATIONS:
2901 : // na
2902 :
2903 : // DERIVED TYPE DEFINITIONS:
2904 : // na
2905 :
2906 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2907 : int Loop; // Loop Control
2908 : bool PrintTimeStamp;
2909 1669 : auto &op(state.dataOutputProcessor);
2910 :
2911 1669 : if (!state.dataResultsFramework->resultsFramework->MNMeters.rVariablesScanned()) {
2912 769 : state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::Monthly);
2913 : }
2914 :
2915 1669 : PrintTimeStamp = true;
2916 208990 : for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
2917 207321 : if (!op->EnergyMeters(Loop).RptMN && !op->EnergyMeters(Loop).RptAccMN) continue;
2918 10388 : if (PrintTimeStamp) {
2919 7308 : WriteTimeStampFormatData(state,
2920 : state.files.mtr,
2921 : ReportingFrequency::Monthly,
2922 1218 : op->MonthlyStampReportNbr,
2923 1218 : op->MonthlyStampReportChr,
2924 1218 : state.dataGlobal->DayOfSimChr,
2925 1218 : PrintTimeStamp && PrintTimeStampToSQL,
2926 1218 : state.dataEnvrn->Month);
2927 1218 : if (state.dataResultsFramework->resultsFramework->MNMeters.rDataFrameEnabled()) {
2928 4872 : state.dataResultsFramework->resultsFramework->MNMeters.newRow(
2929 3654 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
2930 : }
2931 1218 : PrintTimeStamp = false;
2932 1218 : PrintTimeStampToSQL = false;
2933 : }
2934 :
2935 10388 : if (op->EnergyMeters(Loop).RptMN) {
2936 83104 : WriteReportMeterData(state,
2937 10388 : op->EnergyMeters(Loop).MNRptNum,
2938 10388 : op->EnergyMeters(Loop).MNRptNumChr,
2939 10388 : op->EnergyMeters(Loop).MNValue,
2940 : ReportingFrequency::Monthly,
2941 10388 : op->EnergyMeters(Loop).MNMinVal,
2942 10388 : op->EnergyMeters(Loop).MNMinValDate,
2943 10388 : op->EnergyMeters(Loop).MNMaxVal,
2944 10388 : op->EnergyMeters(Loop).MNMaxValDate,
2945 10388 : op->EnergyMeters(Loop).RptMNFO);
2946 20776 : state.dataResultsFramework->resultsFramework->MNMeters.pushVariableValue(op->EnergyMeters(Loop).MNRptNum,
2947 10388 : op->EnergyMeters(Loop).MNValue);
2948 10388 : op->EnergyMeters(Loop).MNValue = 0.0;
2949 10388 : op->EnergyMeters(Loop).MNMinVal = MinSetValue;
2950 10388 : op->EnergyMeters(Loop).MNMaxVal = MaxSetValue;
2951 : }
2952 :
2953 10388 : if (op->EnergyMeters(Loop).RptAccMN) {
2954 30 : WriteCumulativeReportMeterData(state,
2955 10 : op->EnergyMeters(Loop).MNAccRptNum,
2956 20 : fmt::to_string(op->EnergyMeters(Loop).MNAccRptNum),
2957 10 : op->EnergyMeters(Loop).SMValue,
2958 10 : op->EnergyMeters(Loop).RptAccMNFO);
2959 20 : state.dataResultsFramework->resultsFramework->MNMeters.pushVariableValue(op->EnergyMeters(Loop).MNAccRptNum,
2960 10 : op->EnergyMeters(Loop).SMValue);
2961 : }
2962 : }
2963 1669 : }
2964 :
2965 2 : void ReportYRMeters(EnergyPlusData &state, bool PrintTimeStampToSQL)
2966 : {
2967 :
2968 : // SUBROUTINE INFORMATION:
2969 : // AUTHOR Jason DeGraw
2970 : // DATE WRITTEN January 2018
2971 : // MODIFIED na
2972 : // RE-ENGINEERED na
2973 :
2974 : // PURPOSE OF THIS SUBROUTINE:
2975 : // This subroutine reports on the meters that have been requested for
2976 : // reporting on each year.
2977 :
2978 : // METHODOLOGY EMPLOYED:
2979 : // na
2980 :
2981 : // REFERENCES:
2982 : // na
2983 :
2984 : // Locals
2985 : // SUBROUTINE ARGUMENT DEFINITIONS:
2986 : // na
2987 :
2988 : // SUBROUTINE PARAMETER DEFINITIONS:
2989 : // na
2990 :
2991 : // INTERFACE BLOCK SPECIFICATIONS:
2992 : // na
2993 :
2994 : // DERIVED TYPE DEFINITIONS:
2995 : // na
2996 :
2997 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2998 : int Loop; // Loop Control
2999 : bool PrintTimeStamp;
3000 2 : auto &op(state.dataOutputProcessor);
3001 :
3002 2 : if (!state.dataResultsFramework->resultsFramework->YRMeters.rVariablesScanned()) {
3003 2 : state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::Yearly);
3004 : }
3005 :
3006 2 : PrintTimeStamp = true;
3007 236 : for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
3008 234 : if (!op->EnergyMeters(Loop).RptYR && !op->EnergyMeters(Loop).RptAccYR) continue;
3009 0 : if (PrintTimeStamp) {
3010 0 : WriteYearlyTimeStamp(
3011 0 : state, state.files.mtr, op->YearlyStampReportChr, state.dataGlobal->CalendarYearChr, PrintTimeStamp && PrintTimeStampToSQL);
3012 0 : if (state.dataResultsFramework->resultsFramework->YRMeters.rDataFrameEnabled()) {
3013 0 : state.dataResultsFramework->resultsFramework->YRMeters.newRow(
3014 0 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
3015 : }
3016 0 : PrintTimeStamp = false;
3017 0 : PrintTimeStampToSQL = false;
3018 : }
3019 :
3020 0 : if (op->EnergyMeters(Loop).RptYR) {
3021 0 : WriteReportMeterData(state,
3022 0 : op->EnergyMeters(Loop).YRRptNum,
3023 0 : op->EnergyMeters(Loop).YRRptNumChr,
3024 0 : op->EnergyMeters(Loop).YRValue,
3025 : ReportingFrequency::Yearly,
3026 0 : op->EnergyMeters(Loop).YRMinVal,
3027 0 : op->EnergyMeters(Loop).YRMinValDate,
3028 0 : op->EnergyMeters(Loop).YRMaxVal,
3029 0 : op->EnergyMeters(Loop).YRMaxValDate,
3030 0 : op->EnergyMeters(Loop).RptYRFO);
3031 0 : state.dataResultsFramework->resultsFramework->YRMeters.pushVariableValue(op->EnergyMeters(Loop).YRRptNum,
3032 0 : op->EnergyMeters(Loop).YRValue);
3033 0 : op->EnergyMeters(Loop).YRValue = 0.0;
3034 0 : op->EnergyMeters(Loop).YRMinVal = MinSetValue;
3035 0 : op->EnergyMeters(Loop).YRMaxVal = MaxSetValue;
3036 : }
3037 :
3038 0 : if (op->EnergyMeters(Loop).RptAccYR) {
3039 0 : WriteCumulativeReportMeterData(state,
3040 0 : op->EnergyMeters(Loop).YRAccRptNum,
3041 0 : fmt::to_string(op->EnergyMeters(Loop).YRAccRptNum),
3042 0 : op->EnergyMeters(Loop).YRValue,
3043 0 : op->EnergyMeters(Loop).RptAccYRFO);
3044 0 : state.dataResultsFramework->resultsFramework->YRMeters.pushVariableValue(op->EnergyMeters(Loop).YRAccRptNum,
3045 0 : op->EnergyMeters(Loop).SMValue);
3046 : }
3047 : }
3048 2 : }
3049 :
3050 1645 : void ReportSMMeters(EnergyPlusData &state, bool PrintTimeStampToSQL // Print Time Stamp to SQL file
3051 : )
3052 : {
3053 :
3054 : // SUBROUTINE INFORMATION:
3055 : // AUTHOR Linda Lawrie
3056 : // DATE WRITTEN January 2001
3057 : // MODIFIED na
3058 : // RE-ENGINEERED na
3059 :
3060 : // PURPOSE OF THIS SUBROUTINE:
3061 : // This subroutine reports on the meters that have been requested for
3062 : // reporting on each environment/run period.
3063 :
3064 : // METHODOLOGY EMPLOYED:
3065 : // na
3066 :
3067 : // REFERENCES:
3068 : // na
3069 :
3070 : // Using/Aliasing
3071 : // using namespace OutputReportPredefined;
3072 :
3073 : // Locals
3074 : // SUBROUTINE ARGUMENT DEFINITIONS:
3075 : // na
3076 :
3077 : // SUBROUTINE PARAMETER DEFINITIONS:
3078 :
3079 : // INTERFACE BLOCK SPECIFICATIONS:
3080 : // na
3081 :
3082 : // DERIVED TYPE DEFINITIONS:
3083 : // na
3084 :
3085 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3086 : int Loop; // Loop Control
3087 : bool PrintTimeStamp;
3088 1645 : auto &op(state.dataOutputProcessor);
3089 :
3090 1645 : if (!state.dataResultsFramework->resultsFramework->SMMeters.rVariablesScanned()) {
3091 769 : state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::Simulation);
3092 : }
3093 :
3094 1645 : PrintTimeStamp = true;
3095 206219 : for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
3096 204574 : op->EnergyMeters(Loop).LastSMValue = op->EnergyMeters(Loop).SMValue;
3097 204574 : op->EnergyMeters(Loop).LastSMMinVal = op->EnergyMeters(Loop).SMMinVal;
3098 204574 : op->EnergyMeters(Loop).LastSMMinValDate = op->EnergyMeters(Loop).SMMinValDate;
3099 204574 : op->EnergyMeters(Loop).LastSMMaxVal = op->EnergyMeters(Loop).SMMaxVal;
3100 204574 : op->EnergyMeters(Loop).LastSMMaxValDate = op->EnergyMeters(Loop).SMMaxValDate;
3101 204574 : if (!op->EnergyMeters(Loop).RptSM && !op->EnergyMeters(Loop).RptAccSM) continue;
3102 5836 : if (PrintTimeStamp) {
3103 5305 : WriteTimeStampFormatData(state,
3104 : state.files.mtr,
3105 : ReportingFrequency::Simulation,
3106 1061 : op->RunPeriodStampReportNbr,
3107 1061 : op->RunPeriodStampReportChr,
3108 1061 : state.dataGlobal->DayOfSimChr,
3109 1061 : PrintTimeStamp && PrintTimeStampToSQL);
3110 1061 : if (state.dataResultsFramework->resultsFramework->SMMeters.rDataFrameEnabled()) {
3111 4244 : state.dataResultsFramework->resultsFramework->SMMeters.newRow(
3112 3183 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
3113 : }
3114 1061 : PrintTimeStamp = false;
3115 1061 : PrintTimeStampToSQL = false;
3116 : }
3117 :
3118 5836 : if (op->EnergyMeters(Loop).RptSM) {
3119 46688 : WriteReportMeterData(state,
3120 5836 : op->EnergyMeters(Loop).SMRptNum,
3121 5836 : op->EnergyMeters(Loop).SMRptNumChr,
3122 5836 : op->EnergyMeters(Loop).SMValue,
3123 : ReportingFrequency::Simulation,
3124 5836 : op->EnergyMeters(Loop).SMMinVal,
3125 5836 : op->EnergyMeters(Loop).SMMinValDate,
3126 5836 : op->EnergyMeters(Loop).SMMaxVal,
3127 5836 : op->EnergyMeters(Loop).SMMaxValDate,
3128 5836 : op->EnergyMeters(Loop).RptSMFO);
3129 11672 : state.dataResultsFramework->resultsFramework->SMMeters.pushVariableValue(op->EnergyMeters(Loop).SMRptNum,
3130 5836 : op->EnergyMeters(Loop).SMValue);
3131 : }
3132 :
3133 5836 : if (op->EnergyMeters(Loop).RptAccSM) {
3134 0 : WriteCumulativeReportMeterData(state,
3135 0 : op->EnergyMeters(Loop).SMAccRptNum,
3136 0 : fmt::to_string(op->EnergyMeters(Loop).SMAccRptNum),
3137 0 : op->EnergyMeters(Loop).SMValue,
3138 0 : op->EnergyMeters(Loop).RptAccSMFO);
3139 0 : state.dataResultsFramework->resultsFramework->SMMeters.pushVariableValue(op->EnergyMeters(Loop).SMAccRptNum,
3140 0 : op->EnergyMeters(Loop).SMValue);
3141 : }
3142 : }
3143 :
3144 1645 : if (op->NumEnergyMeters > 0) {
3145 206219 : for (auto &e : op->EnergyMeters) {
3146 204574 : e.SMValue = 0.0;
3147 204574 : e.SMMinVal = MinSetValue;
3148 204574 : e.SMMaxVal = MaxSetValue;
3149 : }
3150 : }
3151 1645 : }
3152 :
3153 769 : void ReportForTabularReports(EnergyPlusData &state)
3154 : {
3155 :
3156 : // SUBROUTINE INFORMATION:
3157 : // AUTHOR Linda Lawrie
3158 : // DATE WRITTEN August 2013
3159 : // MODIFIED na
3160 : // RE-ENGINEERED na
3161 :
3162 : // PURPOSE OF THIS SUBROUTINE:
3163 : // This subroutine is called after all the simulation is done and before
3164 : // tabular reports in order to reduce the number of calls to the predefined routine
3165 : // for SM (Simulation period) meters, the value of the last calculation is stored
3166 : // in the data structure.
3167 :
3168 : // Using/Aliasing
3169 : using namespace OutputReportPredefined;
3170 :
3171 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3172 : int Loop; // Loop Control
3173 769 : auto &op(state.dataOutputProcessor);
3174 :
3175 93658 : for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
3176 92889 : OutputProcessor::RT_IPUnits const RT_forIPUnits(op->EnergyMeters(Loop).RT_forIPUnits);
3177 92889 : if (RT_forIPUnits == RT_IPUnits::Electricity) {
3178 172652 : PreDefTableEntry(state,
3179 43163 : state.dataOutRptPredefined->pdchEMelecannual,
3180 43163 : op->EnergyMeters(Loop).Name,
3181 43163 : op->EnergyMeters(Loop).FinYrSMValue * DataGlobalConstants::convertJtoGJ);
3182 172652 : PreDefTableEntry(state,
3183 43163 : state.dataOutRptPredefined->pdchEMelecminvalue,
3184 43163 : op->EnergyMeters(Loop).Name,
3185 43163 : op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec);
3186 129489 : PreDefTableEntry(state,
3187 43163 : state.dataOutRptPredefined->pdchEMelecminvaluetime,
3188 43163 : op->EnergyMeters(Loop).Name,
3189 86326 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
3190 172652 : PreDefTableEntry(state,
3191 43163 : state.dataOutRptPredefined->pdchEMelecmaxvalue,
3192 43163 : op->EnergyMeters(Loop).Name,
3193 43163 : op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec);
3194 129489 : PreDefTableEntry(state,
3195 43163 : state.dataOutRptPredefined->pdchEMelecmaxvaluetime,
3196 43163 : op->EnergyMeters(Loop).Name,
3197 86326 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
3198 49726 : } else if (RT_forIPUnits == RT_IPUnits::Gas) {
3199 9956 : PreDefTableEntry(state,
3200 2489 : state.dataOutRptPredefined->pdchEMgasannual,
3201 2489 : op->EnergyMeters(Loop).Name,
3202 2489 : op->EnergyMeters(Loop).FinYrSMValue * DataGlobalConstants::convertJtoGJ);
3203 9956 : PreDefTableEntry(state,
3204 2489 : state.dataOutRptPredefined->pdchEMgasminvalue,
3205 2489 : op->EnergyMeters(Loop).Name,
3206 2489 : op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec);
3207 7467 : PreDefTableEntry(state,
3208 2489 : state.dataOutRptPredefined->pdchEMgasminvaluetime,
3209 2489 : op->EnergyMeters(Loop).Name,
3210 4978 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
3211 9956 : PreDefTableEntry(state,
3212 2489 : state.dataOutRptPredefined->pdchEMgasmaxvalue,
3213 2489 : op->EnergyMeters(Loop).Name,
3214 2489 : op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec);
3215 7467 : PreDefTableEntry(state,
3216 2489 : state.dataOutRptPredefined->pdchEMgasmaxvaluetime,
3217 2489 : op->EnergyMeters(Loop).Name,
3218 4978 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
3219 47237 : } else if (RT_forIPUnits == RT_IPUnits::Cooling) {
3220 7852 : PreDefTableEntry(state,
3221 1963 : state.dataOutRptPredefined->pdchEMcoolannual,
3222 1963 : op->EnergyMeters(Loop).Name,
3223 1963 : op->EnergyMeters(Loop).FinYrSMValue * DataGlobalConstants::convertJtoGJ);
3224 7852 : PreDefTableEntry(state,
3225 1963 : state.dataOutRptPredefined->pdchEMcoolminvalue,
3226 1963 : op->EnergyMeters(Loop).Name,
3227 1963 : op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec);
3228 5889 : PreDefTableEntry(state,
3229 1963 : state.dataOutRptPredefined->pdchEMcoolminvaluetime,
3230 1963 : op->EnergyMeters(Loop).Name,
3231 3926 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
3232 7852 : PreDefTableEntry(state,
3233 1963 : state.dataOutRptPredefined->pdchEMcoolmaxvalue,
3234 1963 : op->EnergyMeters(Loop).Name,
3235 1963 : op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec);
3236 5889 : PreDefTableEntry(state,
3237 1963 : state.dataOutRptPredefined->pdchEMcoolmaxvaluetime,
3238 1963 : op->EnergyMeters(Loop).Name,
3239 3926 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
3240 45274 : } else if (RT_forIPUnits == RT_IPUnits::Water) {
3241 13684 : PreDefTableEntry(
3242 10263 : state, state.dataOutRptPredefined->pdchEMwaterannual, op->EnergyMeters(Loop).Name, op->EnergyMeters(Loop).FinYrSMValue);
3243 13684 : PreDefTableEntry(state,
3244 3421 : state.dataOutRptPredefined->pdchEMwaterminvalue,
3245 3421 : op->EnergyMeters(Loop).Name,
3246 3421 : op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec);
3247 10263 : PreDefTableEntry(state,
3248 3421 : state.dataOutRptPredefined->pdchEMwaterminvaluetime,
3249 3421 : op->EnergyMeters(Loop).Name,
3250 6842 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
3251 13684 : PreDefTableEntry(state,
3252 3421 : state.dataOutRptPredefined->pdchEMwatermaxvalue,
3253 3421 : op->EnergyMeters(Loop).Name,
3254 3421 : op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec);
3255 10263 : PreDefTableEntry(state,
3256 3421 : state.dataOutRptPredefined->pdchEMwatermaxvaluetime,
3257 3421 : op->EnergyMeters(Loop).Name,
3258 6842 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
3259 41853 : } else if (RT_forIPUnits == RT_IPUnits::OtherKG) {
3260 22280 : PreDefTableEntry(
3261 16710 : state, state.dataOutRptPredefined->pdchEMotherKGannual, op->EnergyMeters(Loop).Name, op->EnergyMeters(Loop).FinYrSMValue);
3262 22280 : PreDefTableEntry(state,
3263 5570 : state.dataOutRptPredefined->pdchEMotherKGminvalue,
3264 5570 : op->EnergyMeters(Loop).Name,
3265 5570 : op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec,
3266 : 3);
3267 16710 : PreDefTableEntry(state,
3268 5570 : state.dataOutRptPredefined->pdchEMotherKGminvaluetime,
3269 5570 : op->EnergyMeters(Loop).Name,
3270 11140 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
3271 22280 : PreDefTableEntry(state,
3272 5570 : state.dataOutRptPredefined->pdchEMotherKGmaxvalue,
3273 5570 : op->EnergyMeters(Loop).Name,
3274 5570 : op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec,
3275 : 3);
3276 16710 : PreDefTableEntry(state,
3277 5570 : state.dataOutRptPredefined->pdchEMotherKGmaxvaluetime,
3278 5570 : op->EnergyMeters(Loop).Name,
3279 11140 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
3280 36283 : } else if (RT_forIPUnits == RT_IPUnits::OtherM3) {
3281 1152 : PreDefTableEntry(
3282 864 : state, state.dataOutRptPredefined->pdchEMotherM3annual, op->EnergyMeters(Loop).Name, op->EnergyMeters(Loop).FinYrSMValue, 3);
3283 1152 : PreDefTableEntry(state,
3284 288 : state.dataOutRptPredefined->pdchEMotherM3minvalue,
3285 288 : op->EnergyMeters(Loop).Name,
3286 288 : op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec,
3287 : 3);
3288 864 : PreDefTableEntry(state,
3289 288 : state.dataOutRptPredefined->pdchEMotherM3minvaluetime,
3290 288 : op->EnergyMeters(Loop).Name,
3291 576 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
3292 1152 : PreDefTableEntry(state,
3293 288 : state.dataOutRptPredefined->pdchEMotherM3maxvalue,
3294 288 : op->EnergyMeters(Loop).Name,
3295 288 : op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec,
3296 : 3);
3297 864 : PreDefTableEntry(state,
3298 288 : state.dataOutRptPredefined->pdchEMotherM3maxvaluetime,
3299 288 : op->EnergyMeters(Loop).Name,
3300 576 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
3301 35995 : } else if (RT_forIPUnits == RT_IPUnits::OtherL) {
3302 1152 : PreDefTableEntry(
3303 864 : state, state.dataOutRptPredefined->pdchEMotherLannual, op->EnergyMeters(Loop).Name, op->EnergyMeters(Loop).FinYrSMValue, 3);
3304 1152 : PreDefTableEntry(state,
3305 288 : state.dataOutRptPredefined->pdchEMotherLminvalue,
3306 288 : op->EnergyMeters(Loop).Name,
3307 288 : op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec,
3308 : 3);
3309 864 : PreDefTableEntry(state,
3310 288 : state.dataOutRptPredefined->pdchEMotherLminvaluetime,
3311 288 : op->EnergyMeters(Loop).Name,
3312 576 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
3313 1152 : PreDefTableEntry(state,
3314 288 : state.dataOutRptPredefined->pdchEMotherLmaxvalue,
3315 288 : op->EnergyMeters(Loop).Name,
3316 288 : op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec,
3317 : 3);
3318 864 : PreDefTableEntry(state,
3319 288 : state.dataOutRptPredefined->pdchEMotherLmaxvaluetime,
3320 288 : op->EnergyMeters(Loop).Name,
3321 576 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
3322 : } else {
3323 142828 : PreDefTableEntry(state,
3324 35707 : state.dataOutRptPredefined->pdchEMotherJannual,
3325 35707 : op->EnergyMeters(Loop).Name,
3326 35707 : op->EnergyMeters(Loop).FinYrSMValue * DataGlobalConstants::convertJtoGJ);
3327 142828 : PreDefTableEntry(state,
3328 35707 : state.dataOutRptPredefined->pdchEMotherJminvalue,
3329 35707 : op->EnergyMeters(Loop).Name,
3330 35707 : op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec);
3331 107121 : PreDefTableEntry(state,
3332 35707 : state.dataOutRptPredefined->pdchEMotherJminvaluetime,
3333 35707 : op->EnergyMeters(Loop).Name,
3334 71414 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
3335 142828 : PreDefTableEntry(state,
3336 35707 : state.dataOutRptPredefined->pdchEMotherJmaxvalue,
3337 35707 : op->EnergyMeters(Loop).Name,
3338 35707 : op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec);
3339 107121 : PreDefTableEntry(state,
3340 35707 : state.dataOutRptPredefined->pdchEMotherJmaxvaluetime,
3341 35707 : op->EnergyMeters(Loop).Name,
3342 71414 : DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
3343 : }
3344 : }
3345 769 : }
3346 :
3347 185778 : std::string DateToStringWithMonth(int const codedDate) // word containing encoded month, day, hour, minute
3348 : {
3349 : // SUBROUTINE INFORMATION:
3350 : // AUTHOR Jason Glazer
3351 : // DATE WRITTEN August 2003
3352 : // MODIFIED na
3353 : // RE-ENGINEERED na
3354 :
3355 : // PURPOSE OF THIS SUBROUTINE:
3356 : // Convert the coded date format into a usable
3357 : // string
3358 :
3359 185778 : if (codedDate == 0) return "-";
3360 :
3361 : static constexpr std::string_view DateFmt("{:02}-{:3}-{:02}:{:02}");
3362 :
3363 : // ((month*100 + day)*100 + hour)*100 + minute
3364 : int Month; // month in integer format (1-12)
3365 : int Day; // day in integer format (1-31)
3366 : int Hour; // hour in integer format (1-24)
3367 : int Minute; // minute in integer format (0:59)
3368 :
3369 185778 : General::DecodeMonDayHrMin(codedDate, Month, Day, Hour, Minute);
3370 :
3371 185778 : if (Month < 1 || Month > 12) return "-";
3372 185778 : if (Day < 1 || Day > 31) return "-";
3373 185778 : if (Hour < 1 || Hour > 24) return "-";
3374 185778 : if (Minute < 0 || Minute > 60) return "-";
3375 :
3376 185778 : --Hour;
3377 185778 : if (Minute == 60) {
3378 24606 : ++Hour;
3379 24606 : Minute = 0;
3380 : }
3381 :
3382 371556 : std::string monthName;
3383 185778 : switch (Month) {
3384 9072 : case 1:
3385 9072 : monthName = "JAN";
3386 9072 : break;
3387 41 : case 2:
3388 41 : monthName = "FEB";
3389 41 : break;
3390 22 : case 3:
3391 22 : monthName = "MAR";
3392 22 : break;
3393 272 : case 4:
3394 272 : monthName = "APR";
3395 272 : break;
3396 0 : case 5:
3397 0 : monthName = "MAY";
3398 0 : break;
3399 37 : case 6:
3400 37 : monthName = "JUN";
3401 37 : break;
3402 174392 : case 7:
3403 174392 : monthName = "JUL";
3404 174392 : break;
3405 24 : case 8:
3406 24 : monthName = "AUG";
3407 24 : break;
3408 880 : case 9:
3409 880 : monthName = "SEP";
3410 880 : break;
3411 3 : case 10:
3412 3 : monthName = "OCT";
3413 3 : break;
3414 0 : case 11:
3415 0 : monthName = "NOV";
3416 0 : break;
3417 1035 : case 12:
3418 1035 : monthName = "DEC";
3419 1035 : break;
3420 0 : default:
3421 0 : assert(false);
3422 : }
3423 :
3424 185778 : return format(DateFmt, Day, monthName, Hour, Minute);
3425 : }
3426 :
3427 769 : void ReportMeterDetails(EnergyPlusData &state)
3428 : {
3429 :
3430 : // SUBROUTINE INFORMATION:
3431 : // AUTHOR Linda Lawrie
3432 : // DATE WRITTEN January 2006
3433 : // MODIFIED na
3434 : // RE-ENGINEERED na
3435 :
3436 : // PURPOSE OF THIS SUBROUTINE:
3437 : // Writes the meter details report. This shows which variables are on
3438 : // meters as well as the meter contents.
3439 :
3440 : // METHODOLOGY EMPLOYED:
3441 : // na
3442 :
3443 : // REFERENCES:
3444 : // na
3445 :
3446 : // USE STATEMENTS:
3447 : // na
3448 :
3449 : // Locals
3450 : // SUBROUTINE ARGUMENT DEFINITIONS:
3451 : // na
3452 :
3453 : // SUBROUTINE PARAMETER DEFINITIONS:
3454 : // na
3455 :
3456 : // INTERFACE BLOCK SPECIFICATIONS:
3457 : // na
3458 :
3459 : // DERIVED TYPE DEFINITIONS:
3460 : // na
3461 :
3462 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3463 769 : auto &op(state.dataOutputProcessor);
3464 :
3465 56940 : for (int VarMeter = 1; VarMeter <= op->NumVarMeterArrays; ++VarMeter) {
3466 :
3467 112342 : const std::string mtrUnitString = unitEnumToStringBrackets(op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).units);
3468 :
3469 112342 : std::string Multipliers;
3470 56171 : const auto ZoneMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneMult;
3471 56171 : const auto ZoneListMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneListMult;
3472 :
3473 56171 : if (ZoneMult > 1 || ZoneListMult > 1) {
3474 1131 : Multipliers = format(" * {} (Zone Multiplier = {}, Zone List Multiplier = {})", ZoneMult * ZoneListMult, ZoneMult, ZoneListMult);
3475 : }
3476 :
3477 168513 : print(state.files.mtd,
3478 : "\n Meters for {},{}{}{}\n",
3479 56171 : op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ReportIDChr,
3480 56171 : op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarName,
3481 : mtrUnitString,
3482 56171 : Multipliers);
3483 :
3484 338329 : for (int I = 1; I <= op->VarMeterArrays(VarMeter).NumOnMeters; ++I) {
3485 282158 : print(state.files.mtd, " OnMeter={}{}\n", op->EnergyMeters(op->VarMeterArrays(VarMeter).OnMeters(I)).Name, mtrUnitString);
3486 : }
3487 :
3488 56982 : for (int I = 1; I <= op->VarMeterArrays(VarMeter).NumOnCustomMeters; ++I) {
3489 1622 : print(
3490 1622 : state.files.mtd, " OnCustomMeter={}{}\n", op->EnergyMeters(op->VarMeterArrays(VarMeter).OnCustomMeters(I)).Name, mtrUnitString);
3491 : }
3492 : }
3493 :
3494 93658 : for (int Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
3495 92889 : print(state.files.mtd, "\n For Meter={}{}", op->EnergyMeters(Meter).Name, unitEnumToStringBrackets(op->EnergyMeters(Meter).Units));
3496 92889 : if (!op->EnergyMeters(Meter).ResourceType.empty()) {
3497 92889 : print(state.files.mtd, ", ResourceType={}", op->EnergyMeters(Meter).ResourceType);
3498 : }
3499 92889 : if (!op->EnergyMeters(Meter).EndUse.empty()) {
3500 66639 : print(state.files.mtd, ", EndUse={}", op->EnergyMeters(Meter).EndUse);
3501 : }
3502 92889 : if (!op->EnergyMeters(Meter).Group.empty()) {
3503 56608 : print(state.files.mtd, ", Group={}", op->EnergyMeters(Meter).Group);
3504 : }
3505 92889 : print(state.files.mtd, ", contents are:\n");
3506 :
3507 92889 : bool CustDecWritten = false;
3508 :
3509 20132138 : for (int VarMeter = 1; VarMeter <= op->NumVarMeterArrays; ++VarMeter) {
3510 20039249 : if (op->EnergyMeters(Meter).TypeOfMeter == MtrType::Normal) {
3511 20024036 : if (any_eq(op->VarMeterArrays(VarMeter).OnMeters, Meter)) {
3512 2072266 : for (int VarMeter1 = 1; VarMeter1 <= op->VarMeterArrays(VarMeter).NumOnMeters; ++VarMeter1) {
3513 1790108 : if (op->VarMeterArrays(VarMeter).OnMeters(VarMeter1) != Meter) continue;
3514 :
3515 564316 : std::string Multipliers;
3516 282158 : const auto ZoneMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneMult;
3517 282158 : const auto ZoneListMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneListMult;
3518 :
3519 282158 : if (ZoneMult > 1 || ZoneListMult > 1) {
3520 9540 : Multipliers = format(
3521 19080 : " * {} (Zone Multiplier = {}, Zone List Multiplier = {})", ZoneMult * ZoneListMult, ZoneMult, ZoneListMult);
3522 : }
3523 :
3524 282158 : print(state.files.mtd, " {}{}\n", op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarName, Multipliers);
3525 : }
3526 : }
3527 : }
3528 20039249 : if (op->EnergyMeters(Meter).TypeOfMeter != MtrType::Normal) {
3529 15213 : if (op->VarMeterArrays(VarMeter).NumOnCustomMeters > 0) {
3530 2002 : if (any_eq(op->VarMeterArrays(VarMeter).OnCustomMeters, Meter)) {
3531 811 : if (!CustDecWritten && op->EnergyMeters(Meter).TypeOfMeter == MtrType::CustomDec) {
3532 76 : print(state.files.mtd,
3533 : " Values for this meter will be Source Meter={}; but will be decremented by:\n",
3534 76 : op->EnergyMeters(op->EnergyMeters(Meter).SourceMeter).Name);
3535 38 : CustDecWritten = true;
3536 : }
3537 2540 : for (int VarMeter1 = 1; VarMeter1 <= op->VarMeterArrays(VarMeter).NumOnCustomMeters; ++VarMeter1) {
3538 1729 : if (op->VarMeterArrays(VarMeter).OnCustomMeters(VarMeter1) != Meter) continue;
3539 :
3540 1622 : std::string Multipliers;
3541 811 : const auto ZoneMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneMult;
3542 811 : const auto ZoneListMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneListMult;
3543 :
3544 811 : if (ZoneMult > 1 || ZoneListMult > 1) {
3545 24 : Multipliers = format(
3546 48 : " * {} (Zone Multiplier = {}, Zone List Multiplier = {})", ZoneMult * ZoneListMult, ZoneMult, ZoneListMult);
3547 : }
3548 :
3549 811 : print(state.files.mtd, " {}{}\n", op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarName, Multipliers);
3550 : }
3551 : }
3552 : }
3553 : }
3554 : }
3555 : }
3556 769 : }
3557 :
3558 : // *****************************************************************************
3559 : // End of routines for Energy Meters implementation in EnergyPlus.
3560 : // *****************************************************************************
3561 :
3562 39049 : void addEndUseSubcategory(EnergyPlusData &state, std::string const &EndUseName, std::string const &EndUseSubName)
3563 : {
3564 :
3565 : // SUBROUTINE INFORMATION:
3566 : // AUTHOR Peter Graham Ellis
3567 : // DATE WRITTEN February 2006
3568 : // MODIFIED na
3569 : // RE-ENGINEERED na
3570 :
3571 : // PURPOSE OF THIS SUBROUTINE:
3572 : // This subroutine manages the list of subcategories for each end-use category.
3573 :
3574 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3575 : int EndUseSubNum;
3576 : int NumSubs;
3577 39049 : auto &op(state.dataOutputProcessor);
3578 :
3579 39049 : bool Found = false;
3580 204811 : for (size_t EndUseNum = 1; EndUseNum <= state.dataGlobalConst->iEndUse.size(); ++EndUseNum) {
3581 204811 : if (UtilityRoutines::SameString(op->EndUseCategory(EndUseNum).Name, EndUseName)) {
3582 :
3583 44223 : for (EndUseSubNum = 1; EndUseSubNum <= op->EndUseCategory(EndUseNum).NumSubcategories; ++EndUseSubNum) {
3584 38007 : if (UtilityRoutines::SameString(op->EndUseCategory(EndUseNum).SubcategoryName(EndUseSubNum), EndUseSubName)) {
3585 : // Subcategory already exists, no further action required
3586 32833 : Found = true;
3587 32833 : break;
3588 : }
3589 : }
3590 :
3591 39049 : if (!Found) {
3592 : // Add the subcategory by reallocating the array
3593 6216 : NumSubs = op->EndUseCategory(EndUseNum).NumSubcategories;
3594 6216 : op->EndUseCategory(EndUseNum).SubcategoryName.redimension(NumSubs + 1);
3595 :
3596 6216 : op->EndUseCategory(EndUseNum).NumSubcategories = NumSubs + 1;
3597 6216 : op->EndUseCategory(EndUseNum).SubcategoryName(NumSubs + 1) = EndUseSubName;
3598 :
3599 6216 : if (op->EndUseCategory(EndUseNum).NumSubcategories > op->MaxNumSubcategories) {
3600 656 : op->MaxNumSubcategories = op->EndUseCategory(EndUseNum).NumSubcategories;
3601 : }
3602 :
3603 6216 : Found = true;
3604 : }
3605 39049 : break;
3606 : }
3607 : }
3608 :
3609 39049 : if (!Found) {
3610 0 : ShowSevereError(state, "Nonexistent end use passed to AddEndUseSubcategory=" + EndUseName);
3611 : }
3612 39049 : }
3613 8348 : void addEndUseSpaceType(EnergyPlusData &state, std::string const &EndUseName, std::string const &EndUseSpaceTypeName)
3614 : {
3615 :
3616 8348 : auto &op(state.dataOutputProcessor);
3617 :
3618 8348 : bool Found = false;
3619 33638 : for (size_t EndUseNum = 1; EndUseNum <= state.dataGlobalConst->iEndUse.size(); ++EndUseNum) {
3620 33638 : if (UtilityRoutines::SameString(op->EndUseCategory(EndUseNum).Name, EndUseName)) {
3621 :
3622 8364 : for (int endUseSpTypeNum = 1; endUseSpTypeNum <= op->EndUseCategory(EndUseNum).numSpaceTypes; ++endUseSpTypeNum) {
3623 7083 : if (UtilityRoutines::SameString(op->EndUseCategory(EndUseNum).spaceTypeName(endUseSpTypeNum), EndUseSpaceTypeName)) {
3624 : // Space type already exists, no further action required
3625 7067 : Found = true;
3626 7067 : break;
3627 : }
3628 : }
3629 :
3630 8348 : if (!Found) {
3631 : // Add the space type by reallocating the array
3632 1281 : int numSpTypes = op->EndUseCategory(EndUseNum).numSpaceTypes;
3633 1281 : op->EndUseCategory(EndUseNum).spaceTypeName.redimension(numSpTypes + 1);
3634 :
3635 1281 : op->EndUseCategory(EndUseNum).numSpaceTypes = numSpTypes + 1;
3636 1281 : op->EndUseCategory(EndUseNum).spaceTypeName(numSpTypes + 1) = EndUseSpaceTypeName;
3637 :
3638 1281 : if (op->EndUseCategory(EndUseNum).numSpaceTypes > op->maxNumEndUseSpaceTypes) {
3639 4 : op->maxNumEndUseSpaceTypes = op->EndUseCategory(EndUseNum).numSpaceTypes;
3640 : }
3641 :
3642 1281 : Found = true;
3643 : }
3644 8348 : break;
3645 : }
3646 : }
3647 :
3648 8348 : if (!Found) {
3649 0 : ShowSevereError(state, "Nonexistent end use passed to addEndUseSpaceType=" + EndUseName);
3650 : }
3651 8348 : }
3652 178102 : void WriteTimeStampFormatData(
3653 : EnergyPlusData &state,
3654 : InputOutputFile &outputFile,
3655 : ReportingFrequency const reportingInterval, // See Module Parameter Definitions for ReportEach, ReportTimeStep, ReportHourly, etc.
3656 : int const reportID, // The ID of the time stamp
3657 : std::string const &reportIDString, // The ID of the time stamp
3658 : std::string const &DayOfSimChr, // the number of days simulated so far
3659 : bool writeToSQL,
3660 : Optional_int_const Month, // the month of the reporting interval
3661 : Optional_int_const DayOfMonth, // The day of the reporting interval
3662 : Optional_int_const Hour, // The hour of the reporting interval
3663 : Optional<Real64 const> EndMinute, // The last minute in the reporting interval
3664 : Optional<Real64 const> StartMinute, // The starting minute of the reporting interval
3665 : Optional_int_const DST, // A flag indicating whether daylight savings time is observed
3666 : Optional_string_const DayType // The day tied for the data (e.g., Monday)
3667 : )
3668 : {
3669 :
3670 : // FUNCTION INFORMATION:
3671 : // AUTHOR Greg Stark
3672 : // DATE WRITTEN July 2008
3673 : // MODIFIED na
3674 : // RE-ENGINEERED na
3675 :
3676 : // PURPOSE OF THIS FUNCTION:
3677 : // This function reports the timestamp data for the output processor
3678 : // Much of the code in this function was embedded in earlier versions of EnergyPlus
3679 : // and was moved to this location to simplify maintenance and to allow for data output
3680 : // to the SQL database
3681 :
3682 : // METHODOLOGY EMPLOYED:
3683 : // na
3684 :
3685 : // REFERENCES:
3686 : // na
3687 :
3688 : // Using/Aliasing
3689 : // Locals
3690 : // FUNCTION ARGUMENT DEFINITIONS:
3691 :
3692 : // FUNCTION PARAMETER DEFINITIONS:
3693 : // na
3694 :
3695 : // INTERFACE BLOCK SPECIFICATIONS:
3696 : // na
3697 :
3698 : // DERIVED TYPE DEFINITIONS:
3699 : // na
3700 :
3701 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3702 :
3703 178102 : assert(reportIDString.length() + DayOfSimChr.length() + (DayType.present() ? DayType().length() : 0u) + 26 <
3704 : N_WriteTimeStampFormatData); // Check will fit in stamp size
3705 :
3706 178102 : if (!outputFile.good()) return;
3707 :
3708 178102 : switch (reportingInterval) {
3709 127081 : case ReportingFrequency::EachCall:
3710 : case ReportingFrequency::TimeStep:
3711 254162 : print<FormatSyntax::FMT>(outputFile,
3712 : "{},{},{:2d},{:2d},{:2d},{:2d},{:5.2f},{:5.2f},{}\n",
3713 254162 : reportIDString.c_str(),
3714 254162 : DayOfSimChr.c_str(),
3715 : Month(),
3716 : DayOfMonth(),
3717 : DST(),
3718 : Hour(),
3719 : StartMinute(),
3720 : EndMinute(),
3721 381243 : DayType().c_str());
3722 127081 : if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
3723 85440 : state.dataSQLiteProcedures->sqlite->createSQLiteTimeIndexRecord(static_cast<int>(reportingInterval),
3724 : reportID,
3725 17088 : state.dataGlobal->DayOfSim,
3726 17088 : state.dataEnvrn->CurEnvirNum,
3727 17088 : state.dataGlobal->CalendarYear,
3728 : Month,
3729 : DayOfMonth,
3730 : Hour,
3731 : EndMinute,
3732 : StartMinute,
3733 : DST,
3734 : DayType,
3735 17088 : state.dataGlobal->WarmupFlag);
3736 : }
3737 127081 : break;
3738 48288 : case ReportingFrequency::Hourly:
3739 144864 : print<FormatSyntax::FMT>(outputFile,
3740 : "{},{},{:2d},{:2d},{:2d},{:2d},{:5.2f},{:5.2f},{}\n",
3741 96576 : reportIDString.c_str(),
3742 96576 : DayOfSimChr.c_str(),
3743 : Month(),
3744 : DayOfMonth(),
3745 : DST(),
3746 : Hour(),
3747 : 0.0,
3748 : 60.0,
3749 144864 : DayType().c_str());
3750 48288 : if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
3751 24840 : state.dataSQLiteProcedures->sqlite->createSQLiteTimeIndexRecord(static_cast<int>(reportingInterval),
3752 : reportID,
3753 4968 : state.dataGlobal->DayOfSim,
3754 4968 : state.dataEnvrn->CurEnvirNum,
3755 4968 : state.dataGlobal->CalendarYear,
3756 : Month,
3757 : DayOfMonth,
3758 : Hour,
3759 : _,
3760 : _,
3761 : DST,
3762 : DayType,
3763 4968 : state.dataGlobal->WarmupFlag);
3764 : }
3765 48288 : break;
3766 142 : case ReportingFrequency::Daily:
3767 284 : print<FormatSyntax::FMT>(outputFile,
3768 : "{},{},{:2d},{:2d},{:2d},{}\n",
3769 284 : reportIDString.c_str(),
3770 284 : DayOfSimChr.c_str(),
3771 : Month(),
3772 : DayOfMonth(),
3773 : DST(),
3774 426 : DayType().c_str());
3775 142 : if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
3776 85 : state.dataSQLiteProcedures->sqlite->createSQLiteTimeIndexRecord(static_cast<int>(reportingInterval),
3777 : reportID,
3778 17 : state.dataGlobal->DayOfSim,
3779 17 : state.dataEnvrn->CurEnvirNum,
3780 17 : state.dataGlobal->CalendarYear,
3781 : Month,
3782 : DayOfMonth,
3783 : _,
3784 : _,
3785 : _,
3786 : DST,
3787 : DayType,
3788 17 : state.dataGlobal->WarmupFlag);
3789 : }
3790 142 : break;
3791 1445 : case ReportingFrequency::Monthly:
3792 1445 : print<FormatSyntax::FMT>(outputFile, "{},{},{:2d}\n", reportIDString.c_str(), DayOfSimChr.c_str(), Month());
3793 1445 : if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
3794 460 : state.dataSQLiteProcedures->sqlite->createSQLiteTimeIndexRecord(static_cast<int>(reportingInterval),
3795 : reportID,
3796 115 : state.dataGlobal->DayOfSim,
3797 115 : state.dataEnvrn->CurEnvirNum,
3798 115 : state.dataGlobal->CalendarYear,
3799 : Month);
3800 : }
3801 1445 : break;
3802 1146 : case ReportingFrequency::Simulation:
3803 1146 : print<FormatSyntax::FMT>(outputFile, "{},{}\n", reportIDString.c_str(), DayOfSimChr.c_str());
3804 1146 : if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
3805 32 : state.dataSQLiteProcedures->sqlite->createSQLiteTimeIndexRecord(static_cast<int>(reportingInterval),
3806 : reportID,
3807 8 : state.dataGlobal->DayOfSim,
3808 8 : state.dataEnvrn->CurEnvirNum,
3809 8 : state.dataGlobal->CalendarYear);
3810 : }
3811 1146 : break;
3812 0 : default:
3813 0 : if (state.dataSQLiteProcedures->sqlite) {
3814 0 : state.dataSQLiteProcedures->sqlite->sqliteWriteMessage(format<FormatSyntax::FMT>(
3815 0 : "Illegal reportingInterval passed to WriteTimeStampFormatData: {}", static_cast<int>(reportingInterval)));
3816 : }
3817 0 : break;
3818 : }
3819 : }
3820 :
3821 0 : void WriteYearlyTimeStamp(EnergyPlusData &state,
3822 : InputOutputFile &outputFile,
3823 : std::string const &reportIDString, // The ID of the time stamp
3824 : std::string const &yearOfSimChr, // the year of the simulation
3825 : bool writeToSQL)
3826 : {
3827 0 : print(outputFile, "{},{}\n", reportIDString, yearOfSimChr);
3828 0 : if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
3829 0 : state.dataSQLiteProcedures->sqlite->createYearlyTimeIndexRecord(state.dataGlobal->CalendarYear, state.dataEnvrn->CurEnvirNum);
3830 : }
3831 0 : }
3832 :
3833 58444 : void WriteReportVariableDictionaryItem(EnergyPlusData &state,
3834 : ReportingFrequency const reportingInterval, // The reporting interval (e.g., hourly, daily)
3835 : StoreType const storeType,
3836 : int const reportID, // The reporting ID for the data
3837 : [[maybe_unused]] int const indexGroupKey, // The reporting group (e.g., Zone, Plant Loop, etc.)
3838 : std::string const &indexGroup, // The reporting group (e.g., Zone, Plant Loop, etc.)
3839 : std::string const &reportIDChr, // The reporting ID for the data
3840 : std::string_view const keyedValue, // The key name for the data
3841 : std::string_view const variableName, // The variable's actual name
3842 : TimeStepType const timeStepType,
3843 : OutputProcessor::Unit const unitsForVar, // The variables units
3844 : Optional_string_const customUnitName,
3845 : std::string_view const ScheduleName)
3846 : {
3847 :
3848 : // SUBROUTINE INFORMATION:
3849 : // AUTHOR Greg Stark
3850 : // DATE WRITTEN August 2008
3851 : // MODIFIED April 2011; Linda Lawrie
3852 : // RE-ENGINEERED na
3853 :
3854 : // PURPOSE OF THIS SUBROUTINE:
3855 : // This subroutine writes the ESO data dictionary information to the output files
3856 : // and the SQL database
3857 :
3858 : // METHODOLOGY EMPLOYED:
3859 :
3860 : // REFERENCES:
3861 : // na
3862 :
3863 : // Using/Aliasing
3864 :
3865 : // Locals
3866 : // SUBROUTINE ARGUMENT DEFINITIONS:
3867 :
3868 : // SUBROUTINE PARAMETER DEFINITIONS:
3869 : // na
3870 :
3871 : // INTERFACE BLOCK SPECIFICATIONS:
3872 : // na
3873 :
3874 : // DERIVED TYPE DEFINITIONS:
3875 : // na
3876 :
3877 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3878 116888 : std::string FreqString;
3879 58444 : auto &op(state.dataOutputProcessor);
3880 :
3881 58444 : FreqString = frequencyNotice(storeType, reportingInterval);
3882 :
3883 58444 : if (!ScheduleName.empty()) {
3884 2150 : FreqString = fmt::format("{},{}", FreqString, ScheduleName);
3885 : }
3886 :
3887 116888 : std::string UnitsString;
3888 58444 : if (unitsForVar == OutputProcessor::Unit::customEMS && present(customUnitName)) {
3889 10 : UnitsString = customUnitName;
3890 : } else {
3891 58434 : UnitsString = unitEnumToString(unitsForVar);
3892 : }
3893 :
3894 58444 : const auto write = [&](InputOutputFile &file, const int interval) {
3895 58444 : if (file.good()) {
3896 58444 : print(file, "{},{},{},{} [{}]{}\n", reportIDChr, interval, keyedValue, variableName, UnitsString, FreqString);
3897 : }
3898 116888 : };
3899 58444 : switch (reportingInterval) {
3900 22019 : case ReportingFrequency::EachCall:
3901 : case ReportingFrequency::TimeStep:
3902 22019 : write(state.files.eso, 1);
3903 22019 : break;
3904 28427 : case ReportingFrequency::Hourly:
3905 28427 : op->TrackingHourlyVariables = true;
3906 28427 : write(state.files.eso, 1);
3907 28427 : break;
3908 4762 : case ReportingFrequency::Daily:
3909 4762 : op->TrackingDailyVariables = true;
3910 4762 : write(state.files.eso, 7);
3911 4762 : break;
3912 1599 : case ReportingFrequency::Monthly:
3913 1599 : op->TrackingMonthlyVariables = true;
3914 1599 : write(state.files.eso, 9);
3915 1599 : break;
3916 276 : case ReportingFrequency::Simulation:
3917 276 : op->TrackingRunPeriodVariables = true;
3918 276 : write(state.files.eso, 11);
3919 276 : break;
3920 1361 : case ReportingFrequency::Yearly:
3921 1361 : op->TrackingYearlyVariables = true;
3922 1361 : write(state.files.eso, 11);
3923 1361 : break;
3924 0 : default:
3925 0 : assert(false);
3926 : }
3927 :
3928 58444 : if (state.dataSQLiteProcedures->sqlite) {
3929 12811 : state.dataSQLiteProcedures->sqlite->createSQLiteReportDictionaryRecord(reportID,
3930 : static_cast<int>(storeType),
3931 : indexGroup,
3932 : keyedValue,
3933 : variableName,
3934 : static_cast<int>(timeStepType),
3935 : UnitsString,
3936 : static_cast<int>(reportingInterval),
3937 : false,
3938 : ScheduleName);
3939 : }
3940 :
3941 58444 : state.dataResultsFramework->resultsFramework->addReportVariable(keyedValue, variableName, UnitsString, reportingInterval);
3942 :
3943 : // add to ResultsFramework for output variable list, need to check RVI/MVI later
3944 58444 : }
3945 :
3946 7818 : void WriteMeterDictionaryItem(EnergyPlusData &state,
3947 : ReportingFrequency const reportingInterval, // The reporting interval (e.g., hourly, daily)
3948 : StoreType const storeType,
3949 : int const reportID, // The reporting ID in for the variable
3950 : [[maybe_unused]] int const indexGroupKey, // The reporting group for the variable
3951 : std::string const &indexGroup, // The reporting group for the variable
3952 : std::string const &reportIDChr, // The reporting ID in for the variable
3953 : std::string const &meterName, // The variable's meter name
3954 : OutputProcessor::Unit const unit, // The variables units
3955 : bool const cumulativeMeterFlag, // A flag indicating cumulative data
3956 : bool const meterFileOnlyFlag // A flag indicating whether the data is to be written to standard output
3957 : )
3958 : {
3959 :
3960 : // SUBROUTINE INFORMATION:
3961 : // AUTHOR Greg Stark
3962 : // DATE WRITTEN August 2008
3963 : // MODIFIED April 2011; Linda Lawrie
3964 : // RE-ENGINEERED na
3965 :
3966 : // PURPOSE OF THIS SUBROUTINE:
3967 : // The subroutine writes meter data dictionary information to the output files
3968 : // and the SQL database. Much of the code here was embedded in other subroutines
3969 : // and was moved here for the purposes of ease of maintenance and to allow easy
3970 : // data reporting to the SQL database
3971 :
3972 : // METHODOLOGY EMPLOYED:
3973 : // na
3974 :
3975 : // REFERENCES:
3976 : // na
3977 :
3978 : // Using/Aliasing
3979 :
3980 : // Locals
3981 : // SUBROUTINE ARGUMENT DEFINITIONS:
3982 :
3983 : // SUBROUTINE PARAMETER DEFINITIONS:
3984 : // na
3985 :
3986 : // INTERFACE BLOCK SPECIFICATIONS:
3987 : // na
3988 :
3989 : // DERIVED TYPE DEFINITIONS:
3990 : // na
3991 :
3992 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3993 15636 : std::string UnitsString = unitEnumToString(unit);
3994 :
3995 15636 : std::string const FreqString(frequencyNotice(storeType, reportingInterval));
3996 :
3997 7818 : const auto print_meter = [&](EnergyPlusData &state, const int frequency) {
3998 9868 : const auto out = [&](InputOutputFile &of) {
3999 9868 : if (of.good()) {
4000 17686 : if (cumulativeMeterFlag) {
4001 : static constexpr std::string_view fmt{"{},{},Cumulative {} [{}]{}\n"};
4002 17686 : const auto lenString = index(FreqString, '[');
4003 43184 : print(of, fmt, reportIDChr, 1, meterName, UnitsString, FreqString.substr(0, lenString));
4004 : } else {
4005 : static constexpr std::string_view fmt{"{},{},{} [{}]{}\n"};
4006 19724 : print(of, fmt, reportIDChr, frequency, meterName, UnitsString, FreqString);
4007 : }
4008 : }
4009 48958 : };
4010 :
4011 7818 : out(state.files.mtr);
4012 7818 : if (!meterFileOnlyFlag) {
4013 2050 : out(state.files.eso);
4014 : }
4015 15636 : };
4016 :
4017 7818 : switch (reportingInterval) {
4018 749 : case ReportingFrequency::EachCall:
4019 : case ReportingFrequency::TimeStep:
4020 : case ReportingFrequency::Hourly: // -1, 0, 1
4021 749 : print_meter(state, 1);
4022 749 : break;
4023 71 : case ReportingFrequency::Daily: // 2
4024 71 : print_meter(state, 7);
4025 71 : break;
4026 4090 : case ReportingFrequency::Monthly: // 3
4027 4090 : print_meter(state, 9);
4028 4090 : break;
4029 2908 : case ReportingFrequency::Yearly: // 5
4030 : case ReportingFrequency::Simulation: // 4
4031 2908 : print_meter(state, 11);
4032 2908 : break;
4033 0 : default:
4034 0 : assert(false);
4035 : }
4036 :
4037 : static constexpr std::string_view keyedValueStringCum("Cumulative ");
4038 : static constexpr std::string_view keyedValueStringNon;
4039 7818 : std::string_view const keyedValueString(cumulativeMeterFlag ? keyedValueStringCum : keyedValueStringNon);
4040 :
4041 7818 : if (state.dataSQLiteProcedures->sqlite) {
4042 3244 : state.dataSQLiteProcedures->sqlite->createSQLiteReportDictionaryRecord(reportID,
4043 : static_cast<int>(storeType),
4044 : indexGroup,
4045 : keyedValueString,
4046 : meterName,
4047 : 1,
4048 : UnitsString,
4049 : static_cast<int>(reportingInterval),
4050 1622 : true);
4051 : }
4052 :
4053 7818 : state.dataResultsFramework->resultsFramework->addReportMeter(meterName, UnitsString, reportingInterval);
4054 : // add to ResultsFramework for output variable list, need to check RVI/MVI later
4055 7818 : }
4056 :
4057 1303999 : void WriteRealVariableOutput(EnergyPlusData &state,
4058 : RealVariables &realVar, // Real variable to write out
4059 : ReportingFrequency const reportType // The report type or interval (e.g., hourly)
4060 : )
4061 : {
4062 :
4063 : // SUBROUTINE INFORMATION:
4064 : // AUTHOR Greg Stark
4065 : // DATE WRITTEN August 2008
4066 : // MODIFIED April 2011; Linda Lawrie, December 2017; Jason DeGraw
4067 : // RE-ENGINEERED na
4068 :
4069 : // PURPOSE OF THIS SUBROUTINE:
4070 : // This subroutine writes real report variable data to the output file and
4071 : // SQL database. Much of the code here was an included in earlier versions
4072 : // of the UpdateDataandReport subroutine. The code was moved to facilitate
4073 : // easier maintenance and writing of data to the SQL database.
4074 :
4075 : // METHODOLOGY EMPLOYED:
4076 : // na
4077 :
4078 : // REFERENCES:
4079 : // na
4080 :
4081 : // USE STATEMENTS:
4082 :
4083 : // Locals
4084 : // SUBROUTINE ARGUMENT DEFINITIONS:
4085 :
4086 : // SUBROUTINE PARAMETER DEFINITIONS:
4087 : // na
4088 :
4089 : // INTERFACE BLOCK SPECIFICATIONS:
4090 : // na
4091 :
4092 : // DERIVED TYPE DEFINITIONS:
4093 : // na
4094 :
4095 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4096 : // na
4097 :
4098 1303999 : if (realVar.Report && realVar.frequency == reportType && realVar.Stored) {
4099 34277 : if (realVar.NumStored > 0.0) {
4100 34271 : WriteReportRealData(state,
4101 : realVar.ReportID,
4102 : realVar.ReportIDChr,
4103 : realVar.StoreValue,
4104 : realVar.storeType,
4105 : realVar.NumStored,
4106 : realVar.frequency,
4107 : realVar.MinValue,
4108 : realVar.minValueDate,
4109 : realVar.MaxValue,
4110 : realVar.maxValueDate);
4111 34271 : ++state.dataGlobal->StdOutputRecordCount;
4112 : }
4113 :
4114 34277 : realVar.StoreValue = 0.0;
4115 34277 : realVar.NumStored = 0.0;
4116 34277 : realVar.MinValue = MinSetValue;
4117 34277 : realVar.MaxValue = MaxSetValue;
4118 34277 : realVar.Stored = false;
4119 : }
4120 1303999 : }
4121 :
4122 34271 : void WriteReportRealData(EnergyPlusData &state,
4123 : int const reportID,
4124 : std::string const &creportID,
4125 : Real64 const repValue,
4126 : StoreType const storeType,
4127 : Real64 const numOfItemsStored,
4128 : ReportingFrequency const reportingInterval,
4129 : Real64 const minValue,
4130 : int const minValueDate,
4131 : Real64 const MaxValue,
4132 : int const maxValueDate)
4133 : {
4134 :
4135 : // SUBROUTINE INFORMATION:
4136 : // AUTHOR Greg Stark
4137 : // DATE WRITTEN July 2008
4138 : // MODIFIED April 2011; Linda Lawrie
4139 : // RE-ENGINEERED na
4140 :
4141 : // PURPOSE OF THIS SUBROUTINE:
4142 : // This subroutine writes the average real data to the output files and
4143 : // SQL database. It supports the WriteRealVariableOutput subroutine.
4144 : // Much of the code here was an included in earlier versions
4145 : // of the UpdateDataandReport subroutine. The code was moved to facilitate
4146 : // easier maintenance and writing of data to the SQL database.
4147 :
4148 68542 : std::string NumberOut; // Character for producing "number out"
4149 34271 : Real64 repVal(repValue); // The variable's value
4150 :
4151 34271 : if (storeType == StoreType::Averaged) {
4152 29353 : repVal /= numOfItemsStored;
4153 : }
4154 34271 : if (repVal == 0.0) {
4155 6088 : NumberOut = "0.0";
4156 : } else {
4157 28183 : dtoa(repVal, state.dataOutputProcessor->s_WriteReportRealData);
4158 28183 : NumberOut = std::string(state.dataOutputProcessor->s_WriteReportRealData);
4159 : }
4160 :
4161 34271 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
4162 : //// The others (<= hourly) are handled inline with the code
4163 : // add to daily TS data store
4164 0 : if (reportingInterval == ReportingFrequency::Daily) {
4165 0 : state.dataResultsFramework->resultsFramework->RIDailyTSData.pushVariableValue(reportID, repVal);
4166 : }
4167 : // add to monthly TS data store
4168 0 : if (reportingInterval == ReportingFrequency::Monthly) {
4169 0 : state.dataResultsFramework->resultsFramework->RIMonthlyTSData.pushVariableValue(reportID, repVal);
4170 : }
4171 : // add to run period TS data store
4172 0 : if (reportingInterval == ReportingFrequency::Simulation) {
4173 0 : state.dataResultsFramework->resultsFramework->RIRunPeriodTSData.pushVariableValue(reportID, repVal);
4174 : }
4175 : // add to annual TS data store
4176 0 : if (reportingInterval == ReportingFrequency::Yearly) {
4177 0 : state.dataResultsFramework->resultsFramework->RIYearlyTSData.pushVariableValue(reportID, repVal);
4178 : }
4179 : }
4180 :
4181 34271 : if (state.dataSQLiteProcedures->sqlite) {
4182 5100 : state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(
4183 3400 : reportID, repVal, static_cast<int>(reportingInterval), minValue, minValueDate, MaxValue, maxValueDate);
4184 : }
4185 :
4186 34271 : if ((reportingInterval == ReportingFrequency::EachCall) || (reportingInterval == ReportingFrequency::TimeStep) ||
4187 : (reportingInterval == ReportingFrequency::Hourly)) { // -1, 0, 1
4188 0 : if (state.files.eso.good()) {
4189 0 : print(state.files.eso, "{},{}\n", creportID, NumberOut);
4190 : }
4191 :
4192 : } else { // if ( ( reportingInterval == ReportingFrequency::Daily ) || ( reportingInterval == ReportingFrequency::Monthly ) || (
4193 : // reportingInterval == ReportingFrequency::Simulation ) ) { // 2, 3, 4, 5
4194 68542 : std::string MaxOut; // Character for Max out string
4195 68542 : std::string MinOut; // Character for Min out string
4196 :
4197 34271 : if (MaxValue == 0.0) {
4198 6132 : MaxOut = "0.0";
4199 : } else {
4200 28139 : dtoa(MaxValue, state.dataOutputProcessor->s_WriteReportRealData);
4201 28139 : MaxOut = std::string(state.dataOutputProcessor->s_WriteReportRealData);
4202 : }
4203 :
4204 34271 : if (minValue == 0.0) {
4205 15867 : MinOut = "0.0";
4206 : } else {
4207 18404 : dtoa(minValue, state.dataOutputProcessor->s_WriteReportRealData);
4208 18404 : MinOut = std::string(state.dataOutputProcessor->s_WriteReportRealData);
4209 : }
4210 :
4211 : // Append the min and max strings with date information
4212 34271 : ProduceMinMaxString(MinOut, minValueDate, reportingInterval);
4213 34271 : ProduceMinMaxString(MaxOut, maxValueDate, reportingInterval);
4214 :
4215 34271 : if (state.files.eso.good()) {
4216 34271 : print(state.files.eso, "{},{},{},{}\n", creportID, NumberOut, MinOut, MaxOut);
4217 : }
4218 : }
4219 34271 : }
4220 :
4221 10 : void WriteCumulativeReportMeterData(EnergyPlusData &state,
4222 : int const reportID, // The variable's report ID
4223 : std::string const &creportID, // variable ID in characters
4224 : Real64 const repValue, // The variable's value
4225 : bool const meterOnlyFlag // A flag that indicates if the data should be written to standard output
4226 : )
4227 : {
4228 :
4229 : // SUBROUTINE INFORMATION:
4230 : // AUTHOR Greg Stark
4231 : // DATE WRITTEN July 2008
4232 : // MODIFIED na
4233 : // RE-ENGINEERED na
4234 :
4235 : // PURPOSE OF THIS SUBROUTINE:
4236 : // This subroutine writes the cumulative meter data to the output files and
4237 : // SQL database.
4238 :
4239 20 : std::string NumberOut; // Character for producing "number out"
4240 :
4241 10 : if (repValue == 0.0) {
4242 0 : NumberOut = "0.0";
4243 : } else {
4244 10 : dtoa(repValue, state.dataOutputProcessor->s_WriteCumulativeReportMeterData);
4245 10 : NumberOut = std::string(state.dataOutputProcessor->s_WriteCumulativeReportMeterData);
4246 : }
4247 :
4248 10 : if (state.dataSQLiteProcedures->sqlite) {
4249 4 : state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(reportID, repValue);
4250 : }
4251 :
4252 10 : if (state.files.mtr.good()) print(state.files.mtr, "{},{}\n", creportID, NumberOut);
4253 10 : ++state.dataGlobal->StdMeterRecordCount;
4254 :
4255 10 : if (!meterOnlyFlag) {
4256 2 : if (state.files.eso.good()) print(state.files.eso, "{},{}\n", creportID, NumberOut);
4257 2 : ++state.dataGlobal->StdOutputRecordCount;
4258 : }
4259 10 : }
4260 :
4261 81710 : void WriteReportMeterData(EnergyPlusData &state,
4262 : int const reportID, // The variable's report ID
4263 : std::string const &creportID, // variable ID in characters
4264 : Real64 const repValue, // The variable's value
4265 : ReportingFrequency const reportingInterval, // The variable's reporting interval (e.g., hourly)
4266 : Real64 const minValue, // The variable's minimum value during the reporting interval
4267 : int const minValueDate, // The date the minimum value occurred
4268 : Real64 const MaxValue, // The variable's maximum value during the reporting interval
4269 : int const maxValueDate, // The date of the maximum value
4270 : bool const meterOnlyFlag // Indicates whether the data is for the meter file only
4271 : )
4272 : {
4273 :
4274 : // SUBROUTINE INFORMATION:
4275 : // AUTHOR Greg Stark
4276 : // DATE WRITTEN July 2008
4277 : // MODIFIED na
4278 : // RE-ENGINEERED na
4279 :
4280 : // PURPOSE OF THIS SUBROUTINE:
4281 : // This subroutine writes for the non-cumulative meter data to the output files and
4282 : // SQL database.
4283 :
4284 163420 : std::string NumberOut; // Character for producing "number out"
4285 :
4286 81710 : if (repValue == 0.0) {
4287 28018 : NumberOut = "0.0";
4288 : } else {
4289 53692 : dtoa(repValue, state.dataOutputProcessor->s_WriteReportMeterData);
4290 53692 : NumberOut = std::string(state.dataOutputProcessor->s_WriteReportMeterData);
4291 : }
4292 :
4293 81710 : if (state.dataSQLiteProcedures->sqlite) {
4294 167568 : state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(reportID,
4295 : repValue,
4296 83784 : static_cast<int>(reportingInterval),
4297 : minValue,
4298 : minValueDate,
4299 : MaxValue,
4300 : maxValueDate,
4301 41892 : state.dataGlobal->MinutesPerTimeStep);
4302 : }
4303 :
4304 81710 : if ((reportingInterval == ReportingFrequency::EachCall) || (reportingInterval == ReportingFrequency::TimeStep) ||
4305 : (reportingInterval == ReportingFrequency::Hourly)) { // -1, 0, 1
4306 65328 : if (state.files.mtr.good()) {
4307 65328 : print(state.files.mtr, "{},{}\n", creportID, NumberOut);
4308 : }
4309 65328 : ++state.dataGlobal->StdMeterRecordCount;
4310 130656 : if (state.files.eso.good() && !meterOnlyFlag) {
4311 55200 : print(state.files.eso, "{},{}\n", creportID, NumberOut);
4312 55200 : ++state.dataGlobal->StdOutputRecordCount;
4313 : }
4314 : } else { // if ( ( reportingInterval == ReportDaily ) || ( reportingInterval == ReportMonthly ) || ( reportingInterval == ReportSim ) ) {
4315 : // // 2, 3, 4
4316 32764 : std::string MaxOut; // Character for Max out string
4317 32764 : std::string MinOut; // Character for Min out string
4318 :
4319 16382 : if (MaxValue == 0.0) {
4320 1900 : MaxOut = "0.0";
4321 : } else {
4322 14482 : dtoa(MaxValue, state.dataOutputProcessor->s_WriteReportMeterData);
4323 14482 : MaxOut = std::string(state.dataOutputProcessor->s_WriteReportMeterData);
4324 : }
4325 :
4326 16382 : if (minValue == 0.0) {
4327 3813 : MinOut = "0.0";
4328 : } else {
4329 12569 : dtoa(minValue, state.dataOutputProcessor->s_WriteReportMeterData);
4330 12569 : MinOut = std::string(state.dataOutputProcessor->s_WriteReportMeterData);
4331 : }
4332 :
4333 : // Append the min and max strings with date information
4334 16382 : ProduceMinMaxString(MinOut, minValueDate, reportingInterval);
4335 16382 : ProduceMinMaxString(MaxOut, maxValueDate, reportingInterval);
4336 :
4337 16382 : if (state.files.mtr.good()) {
4338 16382 : print(state.files.mtr, "{},{},{},{}\n", creportID, NumberOut, MinOut, MaxOut);
4339 : }
4340 :
4341 16382 : ++state.dataGlobal->StdMeterRecordCount;
4342 16382 : if (state.files.eso.good() && !meterOnlyFlag) {
4343 3382 : print(state.files.eso, "{},{},{},{}\n", creportID, NumberOut, MinOut, MaxOut);
4344 3382 : ++state.dataGlobal->StdOutputRecordCount;
4345 : }
4346 : }
4347 81710 : }
4348 :
4349 9860796 : void WriteNumericData(EnergyPlusData &state,
4350 : int const reportID, // The variable's reporting ID
4351 : std::string const &creportID, // variable ID in characters
4352 : Real64 const repValue // The variable's value
4353 : )
4354 : {
4355 : // SUBROUTINE INFORMATION:
4356 : // AUTHOR Mark Adams
4357 : // DATE WRITTEN May 2016
4358 : // MODIFIED na
4359 : // RE-ENGINEERED na
4360 :
4361 : // PURPOSE:
4362 : // This subroutine writes real data to the output files and
4363 : // SQL database.
4364 : // This is a refactor of WriteRealData.
4365 : //
4366 : // Much of the code here was an included in earlier versions
4367 : // of the UpdateDataandReport subroutine. The code was moved to facilitate
4368 : // easier maintenance and writing of data to the SQL database.
4369 :
4370 9860796 : if (state.dataSysVars->UpdateDataDuringWarmupExternalInterface && !state.dataSysVars->ReportDuringWarmup) return;
4371 :
4372 9860796 : dtoa(repValue, state.dataOutputProcessor->s_WriteNumericData);
4373 :
4374 9860796 : if (state.dataSQLiteProcedures->sqlite) {
4375 1935519 : state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(reportID, repValue);
4376 : }
4377 :
4378 9860796 : if (state.files.eso.good()) {
4379 9860796 : print<FormatSyntax::FMT>(state.files.eso, "{},{}\n", creportID, state.dataOutputProcessor->s_WriteNumericData);
4380 : }
4381 : }
4382 :
4383 7320 : void WriteNumericData(EnergyPlusData &state,
4384 : int const reportID, // The variable's reporting ID
4385 : std::string const &creportID, // variable ID in characters
4386 : int32_t const repValue // The variable's value
4387 : )
4388 : {
4389 : // SUBROUTINE INFORMATION:
4390 : // AUTHOR Mark Adams
4391 : // DATE WRITTEN May 2016
4392 : // MODIFIED na
4393 : // RE-ENGINEERED na
4394 :
4395 : // PURPOSE:
4396 : // This subroutine writes real data to the output files and
4397 : // SQL database.
4398 : // This is a refactor of WriteIntegerData.
4399 : //
4400 : // Much of the code here was an included in earlier versions
4401 : // of the UpdateDataandReport subroutine. The code was moved to facilitate
4402 : // easier maintenance and writing of data to the SQL database.
4403 :
4404 : // i32toa(repValue, state.dataOutputProcessor->s_WriteNumericData);
4405 :
4406 7320 : if (state.dataSQLiteProcedures->sqlite) {
4407 259 : state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(reportID, repValue);
4408 : }
4409 :
4410 7320 : if (state.files.eso.good()) {
4411 7320 : print<FormatSyntax::FMT>(state.files.eso, "{},{}\n", creportID, fmt::format_int(repValue).c_str());
4412 : }
4413 7320 : }
4414 :
4415 26479 : void WriteIntegerVariableOutput(EnergyPlusData &state,
4416 : IntegerVariables &intVar, // Integer variable to write out
4417 : ReportingFrequency const reportType // The report type (i.e., the reporting interval)
4418 : )
4419 : {
4420 :
4421 : // SUBROUTINE INFORMATION:
4422 : // AUTHOR Greg Stark
4423 : // DATE WRITTEN August 2008
4424 : // MODIFIED April 2011; Linda Lawrie, December 2017; Jason DeGraw
4425 : // RE-ENGINEERED na
4426 :
4427 : // PURPOSE OF THIS SUBROUTINE:
4428 : // This subroutine writes integer report variable data to the output file and
4429 : // SQL database. Much of the code here was an included in earlier versions
4430 : // of the UpdateDataandReport subroutine. The code was moved to facilitate
4431 : // easier maintenance and writing of data to the SQL database.
4432 :
4433 : // METHODOLOGY EMPLOYED:
4434 : // na
4435 :
4436 : // REFERENCES:
4437 : // na
4438 :
4439 : // Using/Aliasing
4440 :
4441 : // Locals
4442 : // SUBROUTINE ARGUMENT DEFINITIONS:
4443 :
4444 : // SUBROUTINE PARAMETER DEFINITIONS:
4445 : // na
4446 :
4447 : // INTERFACE BLOCK SPECIFICATIONS:
4448 : // na
4449 :
4450 : // DERIVED TYPE DEFINITIONS:
4451 : // na
4452 :
4453 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4454 : // na
4455 :
4456 26479 : if (state.dataSysVars->UpdateDataDuringWarmupExternalInterface && !state.dataSysVars->ReportDuringWarmup) return;
4457 :
4458 26479 : if (intVar.Report && intVar.frequency == reportType && intVar.Stored) {
4459 404 : if (intVar.NumStored > 0.0) {
4460 404 : WriteReportIntegerData(state,
4461 : intVar.ReportID,
4462 : intVar.ReportIDChr,
4463 : intVar.StoreValue,
4464 : intVar.storeType,
4465 : intVar.NumStored,
4466 : intVar.frequency,
4467 : intVar.MinValue,
4468 : intVar.minValueDate,
4469 : intVar.MaxValue,
4470 : intVar.maxValueDate);
4471 404 : ++state.dataGlobal->StdOutputRecordCount;
4472 : }
4473 :
4474 404 : intVar.StoreValue = 0.0;
4475 404 : intVar.NumStored = 0.0;
4476 404 : intVar.MinValue = IMinSetValue;
4477 404 : intVar.MaxValue = IMaxSetValue;
4478 404 : intVar.Stored = false;
4479 : }
4480 : }
4481 :
4482 404 : void WriteReportIntegerData(EnergyPlusData &state,
4483 : int const reportID, // The variable's reporting ID
4484 : std::string const &reportIDString, // The variable's reporting ID (character)
4485 : Real64 const repValue, // The variable's value
4486 : StoreType const storeType, // Type of item (averaged or summed)
4487 : Real64 const numOfItemsStored, // The number of items (hours or timesteps) of data stored
4488 : ReportingFrequency const reportingInterval, // The reporting interval (e.g., monthly)
4489 : int const minValue, // The variable's minimum value during the reporting interval
4490 : int const minValueDate, // The date the minimum value occurred
4491 : int const MaxValue, // The variable's maximum value during the reporting interval
4492 : int const maxValueDate // The date the maximum value occurred
4493 : )
4494 : {
4495 :
4496 : // SUBROUTINE INFORMATION:
4497 : // AUTHOR Greg Stark
4498 : // DATE WRITTEN July 2008
4499 : // MODIFIED April 2011; Linda Lawrie
4500 : // RE-ENGINEERED na
4501 :
4502 : // PURPOSE OF THIS SUBROUTINE:
4503 : // This subroutine writes averaged integer data to the output files and
4504 : // SQL database. It supports the WriteIntegerVariableOutput subroutine.
4505 : // Much of the code here was an included in earlier versions
4506 : // of the UpdateDataandReport subroutine. The code was moved to facilitate
4507 : // easier maintenance and writing of data to the SQL database.
4508 :
4509 : // METHODOLOGY EMPLOYED:
4510 : // na
4511 :
4512 : // REFERENCES:
4513 : // na
4514 :
4515 : // Using/Aliasing
4516 : using General::strip_trailing_zeros;
4517 :
4518 : // Locals
4519 :
4520 : // SUBROUTINE ARGUMENT DEFINITIONS:
4521 :
4522 : // SUBROUTINE PARAMETER DEFINITIONS:
4523 :
4524 : // INTERFACE BLOCK SPECIFICATIONS:
4525 : // na
4526 :
4527 : // DERIVED TYPE DEFINITIONS:
4528 : // na
4529 :
4530 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4531 808 : std::string NumberOut; // Character for producing "number out"
4532 808 : std::string MaxOut; // Character for Max out string
4533 808 : std::string MinOut; // Character for Min out string
4534 : Real64 rmaxValue;
4535 : Real64 rminValue;
4536 : Real64 repVal; // The variable's value
4537 :
4538 404 : repVal = repValue;
4539 404 : if (storeType == StoreType::Averaged) {
4540 364 : repVal /= numOfItemsStored;
4541 : }
4542 404 : if (repValue == 0.0) {
4543 74 : NumberOut = "0.0";
4544 : } else {
4545 330 : NumberOut = format("{:N}", repVal);
4546 330 : strip_trailing_zeros(strip(NumberOut));
4547 : }
4548 :
4549 : // Append the min and max strings with date information
4550 404 : MinOut = fmt::to_string(minValue);
4551 404 : MaxOut = fmt::to_string(MaxValue);
4552 404 : ProduceMinMaxString(MinOut, minValueDate, reportingInterval);
4553 404 : ProduceMinMaxString(MaxOut, maxValueDate, reportingInterval);
4554 :
4555 404 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
4556 : // add to daily TS data store
4557 0 : if (reportingInterval == ReportingFrequency::Daily) {
4558 0 : state.dataResultsFramework->resultsFramework->RIDailyTSData.pushVariableValue(reportID, repVal);
4559 : }
4560 : // add to monthly TS data store
4561 0 : if (reportingInterval == ReportingFrequency::Monthly) {
4562 0 : state.dataResultsFramework->resultsFramework->RIMonthlyTSData.pushVariableValue(reportID, repVal);
4563 : }
4564 : // add to run period TS data store
4565 0 : if (reportingInterval == ReportingFrequency::Simulation) {
4566 0 : state.dataResultsFramework->resultsFramework->RIRunPeriodTSData.pushVariableValue(reportID, repVal);
4567 : }
4568 : // add to annual TS data store
4569 0 : if (reportingInterval == ReportingFrequency::Yearly) {
4570 0 : state.dataResultsFramework->resultsFramework->RIYearlyTSData.pushVariableValue(reportID, repVal);
4571 : }
4572 : }
4573 :
4574 404 : rminValue = minValue;
4575 404 : rmaxValue = MaxValue;
4576 404 : if (state.dataSQLiteProcedures->sqlite) {
4577 12 : state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(
4578 8 : reportID, repVal, static_cast<int>(reportingInterval), rminValue, minValueDate, rmaxValue, maxValueDate);
4579 : }
4580 :
4581 404 : if ((reportingInterval == ReportingFrequency::EachCall) || (reportingInterval == ReportingFrequency::TimeStep) ||
4582 : (reportingInterval == ReportingFrequency::Hourly)) { // -1, 0, 1
4583 0 : if (state.files.eso.good()) {
4584 0 : print(state.files.eso, "{},{}\n", reportIDString, NumberOut);
4585 : }
4586 : } else { // if ( ( reportingInterval == ReportDaily ) || ( reportingInterval == ReportMonthly ) || ( reportingInterval == ReportSim ) ) {
4587 : // // 2, 3, 4
4588 404 : if (state.files.eso.good()) {
4589 404 : print(state.files.eso, "{},{},{},{}\n", reportIDString, NumberOut, MinOut, MaxOut);
4590 : }
4591 : }
4592 404 : }
4593 :
4594 7880 : int DetermineIndexGroupKeyFromMeterName(EnergyPlusData &state, std::string const &meterName) // the meter name
4595 : {
4596 :
4597 : // FUNCTION INFORMATION:
4598 : // AUTHOR Greg Stark
4599 : // DATE WRITTEN May 2009
4600 : // MODIFIED na
4601 : // RE-ENGINEERED na
4602 :
4603 : // PURPOSE OF THIS FUNCTION:
4604 : // This function attemps to guess determine how a meter variable should be
4605 : // grouped. It does this by parsing the meter name and then assigns a
4606 : // indexGroupKey based on the name
4607 :
4608 : // METHODOLOGY EMPLOYED:
4609 : // na
4610 :
4611 : // REFERENCES:
4612 : // na
4613 :
4614 : // USE STATEMENTS:
4615 : // na
4616 :
4617 : // Return value
4618 : int DetermineIndexGroupKeyFromMeterName;
4619 :
4620 : // Locals
4621 : // FUNCTION ARGUMENT DEFINITIONS:
4622 :
4623 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4624 :
4625 : // Facility indices are in the 100s
4626 7880 : if (has(meterName, "Electricity:Facility")) {
4627 1140 : state.dataOutputProcessor->indexGroupKey = 100;
4628 6740 : } else if (has(meterName, "NaturalGas:Facility")) {
4629 686 : state.dataOutputProcessor->indexGroupKey = 101;
4630 6054 : } else if (has(meterName, "DistricHeating:Facility")) {
4631 0 : state.dataOutputProcessor->indexGroupKey = 102;
4632 6054 : } else if (has(meterName, "DistricCooling:Facility")) {
4633 0 : state.dataOutputProcessor->indexGroupKey = 103;
4634 6054 : } else if (has(meterName, "ElectricityNet:Facility")) {
4635 18 : state.dataOutputProcessor->indexGroupKey = 104;
4636 :
4637 : // Building indices are in the 200s
4638 6036 : } else if (has(meterName, "Electricity:Building")) {
4639 943 : state.dataOutputProcessor->indexGroupKey = 201;
4640 5093 : } else if (has(meterName, "NaturalGas:Building")) {
4641 8 : state.dataOutputProcessor->indexGroupKey = 202;
4642 :
4643 : // HVAC indices are in the 300s
4644 5085 : } else if (has(meterName, "Electricity:HVAC")) {
4645 836 : state.dataOutputProcessor->indexGroupKey = 301;
4646 :
4647 : // InteriorLights:Electricity:Zone indices are in the 500s
4648 4249 : } else if (has(meterName, "InteriorLights:Electricity:Zone")) {
4649 14 : state.dataOutputProcessor->indexGroupKey = 501;
4650 :
4651 : // InteriorLights:Electricity indices are in the 400s
4652 4235 : } else if (has(meterName, "InteriorLights:Electricity")) {
4653 958 : state.dataOutputProcessor->indexGroupKey = 401;
4654 :
4655 : // Unknown items have negative indices
4656 : } else {
4657 3277 : state.dataOutputProcessor->indexGroupKey = -11;
4658 : }
4659 :
4660 7880 : DetermineIndexGroupKeyFromMeterName = state.dataOutputProcessor->indexGroupKey;
4661 :
4662 7880 : return DetermineIndexGroupKeyFromMeterName;
4663 : }
4664 :
4665 7880 : std::string DetermineIndexGroupFromMeterGroup(MeterType const &meter) // the meter
4666 : {
4667 :
4668 : // FUNCTION INFORMATION:
4669 : // AUTHOR Greg Stark
4670 : // DATE WRITTEN May 2009
4671 : // MODIFIED na
4672 : // RE-ENGINEERED na
4673 :
4674 : // PURPOSE OF THIS FUNCTION:
4675 : // This function attemps to determine how a meter variable should be
4676 : // grouped. It does this by parsing the meter group
4677 :
4678 : // METHODOLOGY EMPLOYED:
4679 : // na
4680 :
4681 : // REFERENCES:
4682 : // na
4683 :
4684 : // USE STATEMENTS:
4685 : // na
4686 :
4687 : // Return value
4688 7880 : std::string indexGroup;
4689 :
4690 : // Locals
4691 : // FUNCTION ARGUMENT DEFINITIONS:
4692 :
4693 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4694 :
4695 7880 : if (len(meter.Group) > 0) {
4696 3077 : indexGroup = meter.Group;
4697 : } else {
4698 4803 : indexGroup = "Facility";
4699 : }
4700 :
4701 7880 : if (len(meter.ResourceType) > 0) {
4702 7880 : indexGroup += ":" + meter.ResourceType;
4703 : }
4704 :
4705 7880 : if (len(meter.EndUse) > 0) {
4706 1615 : indexGroup += ":" + meter.EndUse;
4707 : }
4708 :
4709 7880 : if (len(meter.EndUseSub) > 0) {
4710 51 : indexGroup += ":" + meter.EndUseSub;
4711 : }
4712 :
4713 7880 : return indexGroup;
4714 : }
4715 :
4716 6069 : void SetInternalVariableValue(EnergyPlusData &state,
4717 : OutputProcessor::VariableType const varType, // 1=integer, 2=real, 3=meter
4718 : int const keyVarIndex, // Array index
4719 : Real64 const SetRealVal, // real value to set, if type is real or meter
4720 : int const SetIntVal // integer value to set if type is integer
4721 : )
4722 : {
4723 :
4724 : // SUBROUTINE INFORMATION:
4725 : // AUTHOR B. Griffith
4726 : // DATE WRITTEN August 2012
4727 : // MODIFIED na
4728 : // RE-ENGINEERED na
4729 :
4730 : // PURPOSE OF THIS SUBROUTINE:
4731 : // This is a simple set routine for output pointers
4732 : // It is intended for special use to reinitializations those pointers used for EMS sensors
4733 :
4734 : // METHODOLOGY EMPLOYED:
4735 : // given a variable type and variable index,
4736 : // assign the pointers the values passed in.
4737 :
4738 : // REFERENCES:
4739 : // na
4740 :
4741 : // USE STATEMENTS:
4742 : // na
4743 :
4744 : // Locals
4745 : // SUBROUTINE ARGUMENT DEFINITIONS:
4746 :
4747 : // SUBROUTINE PARAMETER DEFINITIONS:
4748 : // na
4749 :
4750 : // INTERFACE BLOCK SPECIFICATIONS:
4751 : // na
4752 :
4753 : // DERIVED TYPE DEFINITIONS:
4754 : // na
4755 :
4756 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4757 6069 : auto &op(state.dataOutputProcessor);
4758 :
4759 6069 : if (varType == VariableType::Integer) {
4760 15 : *op->IVariableTypes(keyVarIndex).VarPtr.Which = SetIntVal;
4761 6054 : } else if (varType == VariableType::Real) {
4762 6009 : *op->RVariableTypes(keyVarIndex).VarPtr.Which = SetRealVal;
4763 45 : } else if (varType == VariableType::Meter) {
4764 45 : op->EnergyMeters(keyVarIndex).CurTSValue = SetRealVal;
4765 : }
4766 6069 : }
4767 :
4768 : // returns the string corresponding to the OutputProcessor::Unit enum in brackets
4769 1296884 : std::string unitEnumToStringBrackets(EnergyPlus::OutputProcessor::Unit const unitIn)
4770 : {
4771 : // J.Glazer - August/September 2017
4772 1296884 : return " [" + unitEnumToString(unitIn) + "]";
4773 : }
4774 :
4775 : // returns the unit string for a DDVariableTypes item and custom string when customEMS is used
4776 875230 : std::string unitStringFromDDitem(EnergyPlusData &state, int const ddItemPtr // index provided for DDVariableTypes
4777 : )
4778 : {
4779 : // J.Glazer - August/September 2017
4780 875230 : OutputProcessor::Unit ddUnit = state.dataOutputProcessor->DDVariableTypes(ddItemPtr).units;
4781 875230 : if (ddUnit != OutputProcessor::Unit::customEMS) {
4782 875212 : return unitEnumToStringBrackets(ddUnit);
4783 : } else {
4784 18 : return " [" + state.dataOutputProcessor->DDVariableTypes(ddItemPtr).unitNameCustomEMS + "]";
4785 : }
4786 : }
4787 :
4788 : // returns the string corresponding to the OutputProcessor::Unit enum
4789 1363727 : std::string unitEnumToString(EnergyPlus::OutputProcessor::Unit const unitIn)
4790 : {
4791 : // J.Glazer - August/September 2017
4792 1363727 : switch (unitIn) {
4793 619607 : case OutputProcessor::Unit::J:
4794 619607 : return "J";
4795 : break;
4796 249843 : case OutputProcessor::Unit::W:
4797 249843 : return "W";
4798 : break;
4799 87176 : case OutputProcessor::Unit::C:
4800 87176 : return "C";
4801 : break;
4802 101741 : case OutputProcessor::Unit::None:
4803 101741 : return "";
4804 : break;
4805 45021 : case OutputProcessor::Unit::kg:
4806 45021 : return "kg";
4807 : break;
4808 45885 : case OutputProcessor::Unit::W_m2:
4809 45885 : return "W/m2";
4810 : break;
4811 30533 : case OutputProcessor::Unit::m3:
4812 30533 : return "m3";
4813 : break;
4814 46558 : case OutputProcessor::Unit::hr:
4815 46558 : return "hr";
4816 : break;
4817 19673 : case OutputProcessor::Unit::kg_s:
4818 19673 : return "kg/s";
4819 : break;
4820 15908 : case OutputProcessor::Unit::deg:
4821 15908 : return "deg";
4822 : break;
4823 19454 : case OutputProcessor::Unit::m3_s:
4824 19454 : return "m3/s";
4825 : break;
4826 10254 : case OutputProcessor::Unit::W_m2K:
4827 10254 : return "W/m2-K";
4828 : break;
4829 10037 : case OutputProcessor::Unit::kgWater_kgDryAir:
4830 10037 : return "kgWater/kgDryAir";
4831 : break;
4832 7482 : case OutputProcessor::Unit::Perc:
4833 7482 : return "%";
4834 : break;
4835 7452 : case OutputProcessor::Unit::m_s:
4836 7452 : return "m/s";
4837 : break;
4838 4908 : case OutputProcessor::Unit::lux:
4839 4908 : return "lux";
4840 : break;
4841 8933 : case OutputProcessor::Unit::kgWater_s:
4842 8933 : return "kgWater/s";
4843 : break;
4844 2884 : case OutputProcessor::Unit::rad:
4845 2884 : return "rad";
4846 : break;
4847 3451 : case OutputProcessor::Unit::Pa:
4848 3451 : return "Pa";
4849 : break;
4850 3043 : case OutputProcessor::Unit::J_kg:
4851 3043 : return "J/kg";
4852 : break;
4853 4542 : case OutputProcessor::Unit::m:
4854 4542 : return "m";
4855 : break;
4856 3026 : case OutputProcessor::Unit::lum_W:
4857 3026 : return "lum/W";
4858 : break;
4859 2912 : case OutputProcessor::Unit::kg_m3:
4860 2912 : return "kg/m3";
4861 : break;
4862 2069 : case OutputProcessor::Unit::L:
4863 2069 : return "L";
4864 : break;
4865 3184 : case OutputProcessor::Unit::ach:
4866 3184 : return "ach";
4867 : break;
4868 1764 : case OutputProcessor::Unit::m2:
4869 1764 : return "m2";
4870 : break;
4871 1361 : case OutputProcessor::Unit::deltaC:
4872 1361 : return "deltaC";
4873 : break;
4874 1631 : case OutputProcessor::Unit::J_kgK:
4875 1631 : return "J/kg-K";
4876 : break;
4877 802 : case OutputProcessor::Unit::W_W:
4878 802 : return "W/W";
4879 : break;
4880 737 : case OutputProcessor::Unit::clo:
4881 737 : return "clo";
4882 : break;
4883 251 : case OutputProcessor::Unit::W_mK:
4884 251 : return "W/m-K";
4885 : break;
4886 612 : case OutputProcessor::Unit::W_K:
4887 612 : return "W/K";
4888 : break;
4889 4 : case OutputProcessor::Unit::K_W:
4890 4 : return "K/W";
4891 : break;
4892 313 : case OutputProcessor::Unit::ppm:
4893 313 : return "ppm";
4894 : break;
4895 274 : case OutputProcessor::Unit::kg_kg:
4896 274 : return "kg/kg";
4897 : break;
4898 106 : case OutputProcessor::Unit::s:
4899 106 : return "s";
4900 : break;
4901 164 : case OutputProcessor::Unit::cd_m2:
4902 164 : return "cd/m2";
4903 : break;
4904 33 : case OutputProcessor::Unit::kmol_s:
4905 33 : return "kmol/s";
4906 : break;
4907 22 : case OutputProcessor::Unit::K_m:
4908 22 : return "K/m";
4909 : break;
4910 14 : case OutputProcessor::Unit::min:
4911 14 : return "min";
4912 : break;
4913 13 : case OutputProcessor::Unit::J_kgWater:
4914 13 : return "J/kgWater";
4915 : break;
4916 6 : case OutputProcessor::Unit::rev_min:
4917 6 : return "rev/min";
4918 : break;
4919 8 : case OutputProcessor::Unit::kg_m2s:
4920 8 : return "kg/m2-s";
4921 : break;
4922 6 : case OutputProcessor::Unit::J_m2:
4923 6 : return "J/m2";
4924 : break;
4925 8 : case OutputProcessor::Unit::A:
4926 8 : return "A";
4927 : break;
4928 8 : case OutputProcessor::Unit::V:
4929 8 : return "V";
4930 : break;
4931 4 : case OutputProcessor::Unit::W_m2C:
4932 4 : return "W/m2-C";
4933 : break;
4934 6 : case OutputProcessor::Unit::Ah:
4935 6 : return "Ah";
4936 : break;
4937 4 : case OutputProcessor::Unit::Btu_h_W:
4938 4 : return "Btu/h-W";
4939 : break;
4940 0 : default:
4941 0 : return "unknown";
4942 : break;
4943 : }
4944 : }
4945 :
4946 : // returns the OutputProcessor::Unit enum value when a string containing the units is provided without brackets
4947 360 : OutputProcessor::Unit unitStringToEnum(std::string const &unitIn)
4948 : {
4949 : // J.Glazer - August/September 2017
4950 720 : std::string unitUpper = UtilityRoutines::MakeUPPERCase(unitIn);
4951 360 : if (unitUpper == "J") {
4952 194 : return OutputProcessor::Unit::J;
4953 166 : } else if (unitUpper == "DELTAC") {
4954 31 : return OutputProcessor::Unit::deltaC;
4955 135 : } else if (unitUpper.empty()) {
4956 78 : return OutputProcessor::Unit::None;
4957 57 : } else if (unitUpper == "W") {
4958 35 : return OutputProcessor::Unit::W;
4959 22 : } else if (unitUpper == "C") {
4960 9 : return OutputProcessor::Unit::C;
4961 13 : } else if (unitUpper == "KG/S") {
4962 0 : return OutputProcessor::Unit::kg_s;
4963 13 : } else if (unitUpper == "KGWATER/KGDRYAIR") {
4964 0 : return OutputProcessor::Unit::kgWater_kgDryAir;
4965 13 : } else if (unitUpper == "PPM") {
4966 0 : return OutputProcessor::Unit::ppm;
4967 13 : } else if (unitUpper == "PA") {
4968 0 : return OutputProcessor::Unit::Pa;
4969 13 : } else if (unitUpper == "M3/S") {
4970 0 : return OutputProcessor::Unit::m3_s;
4971 13 : } else if (unitUpper == "MIN") {
4972 0 : return OutputProcessor::Unit::min;
4973 13 : } else if (unitUpper == "M3") {
4974 0 : return OutputProcessor::Unit::m3;
4975 13 : } else if (unitUpper == "KG") {
4976 0 : return OutputProcessor::Unit::kg;
4977 13 : } else if (unitUpper == "ACH") {
4978 0 : return OutputProcessor::Unit::ach;
4979 13 : } else if (unitUpper == "W/W") {
4980 0 : return OutputProcessor::Unit::W_W;
4981 13 : } else if (unitUpper == "LUX") {
4982 0 : return OutputProcessor::Unit::lux;
4983 13 : } else if (unitUpper == "LUM/W") {
4984 0 : return OutputProcessor::Unit::lum_W;
4985 13 : } else if (unitUpper == "HR") {
4986 0 : return OutputProcessor::Unit::hr;
4987 13 : } else if (unitUpper == "CD/M2") {
4988 0 : return OutputProcessor::Unit::cd_m2;
4989 13 : } else if (unitUpper == "J/KGWATER") {
4990 0 : return OutputProcessor::Unit::J_kgWater;
4991 13 : } else if (unitUpper == "M/S") {
4992 0 : return OutputProcessor::Unit::m_s;
4993 13 : } else if (unitUpper == "W/M2") {
4994 0 : return OutputProcessor::Unit::W_m2;
4995 13 : } else if (unitUpper == "M") {
4996 0 : return OutputProcessor::Unit::m;
4997 13 : } else if (unitUpper == "AH") {
4998 0 : return OutputProcessor::Unit::Ah;
4999 13 : } else if (unitUpper == "A") {
5000 0 : return OutputProcessor::Unit::A;
5001 13 : } else if (unitUpper == "V") {
5002 0 : return OutputProcessor::Unit::V;
5003 13 : } else if (unitUpper == "KMOL/S") {
5004 0 : return OutputProcessor::Unit::kmol_s;
5005 13 : } else if (unitUpper == "KG/S") {
5006 0 : return OutputProcessor::Unit::rev_min;
5007 13 : } else if (unitUpper == "W/M2-K") {
5008 0 : return OutputProcessor::Unit::W_m2K;
5009 13 : } else if (unitUpper == "J/KG") {
5010 0 : return OutputProcessor::Unit::J_kg;
5011 13 : } else if (unitUpper == "KG/KG") {
5012 0 : return OutputProcessor::Unit::kg_kg;
5013 13 : } else if (unitUpper == "%") {
5014 0 : return OutputProcessor::Unit::Perc;
5015 13 : } else if (unitUpper == "DEG") {
5016 3 : return OutputProcessor::Unit::deg;
5017 10 : } else if (unitUpper == "S") {
5018 0 : return OutputProcessor::Unit::s;
5019 10 : } else if (unitUpper == "KG/M3") {
5020 0 : return OutputProcessor::Unit::kg_m3;
5021 10 : } else if (unitUpper == "KG/M2-S") {
5022 0 : return OutputProcessor::Unit::kg_m2s;
5023 10 : } else if (unitUpper == "J/KG-K") {
5024 0 : return OutputProcessor::Unit::J_kgK;
5025 10 : } else if (unitUpper == "L") {
5026 0 : return OutputProcessor::Unit::L;
5027 10 : } else if (unitUpper == "K/M") {
5028 0 : return OutputProcessor::Unit::K_m;
5029 10 : } else if (unitUpper == "M2") {
5030 0 : return OutputProcessor::Unit::m2;
5031 10 : } else if (unitUpper == "W/M2-C") {
5032 0 : return OutputProcessor::Unit::W_m2C;
5033 10 : } else if (unitUpper == "RAD") {
5034 0 : return OutputProcessor::Unit::rad;
5035 10 : } else if (unitUpper == "J/M2") {
5036 0 : return OutputProcessor::Unit::J_m2;
5037 10 : } else if (unitUpper == "CLO") {
5038 0 : return OutputProcessor::Unit::clo;
5039 10 : } else if (unitUpper == "W/M-K") {
5040 0 : return OutputProcessor::Unit::W_mK;
5041 10 : } else if (unitUpper == "W/K") {
5042 0 : return OutputProcessor::Unit::W_K;
5043 10 : } else if (unitUpper == "K/W") {
5044 0 : return OutputProcessor::Unit::K_W;
5045 10 : } else if (unitUpper == "KGWATER/S") {
5046 0 : return OutputProcessor::Unit::kgWater_s;
5047 : } else {
5048 10 : return OutputProcessor::Unit::unknown;
5049 : }
5050 : }
5051 :
5052 : } // namespace OutputProcessor
5053 :
5054 : //==============================================================================================
5055 : // *****************************************************************************
5056 : // These routines are available outside the OutputProcessor Module (i.e. calling
5057 : // routines do not have to "USE OutputProcessor". But each of these routines
5058 : // will use the OutputProcessor and take advantage that everything is PUBLIC
5059 : // within the OutputProcessor.
5060 : // *****************************************************************************
5061 :
5062 5829124 : void SetupOutputVariable(EnergyPlusData &state,
5063 : std::string_view const VariableName, // String Name of variable (with units)
5064 : OutputProcessor::Unit const VariableUnit, // Actual units corresponding to the actual variable
5065 : Real64 &ActualVariable, // Actual Variable, used to set up pointer
5066 : OutputProcessor::SOVTimeStepType const TimeStepTypeKey, // Zone, HeatBalance=1, HVAC, System, Plant=2
5067 : OutputProcessor::SOVStoreType const VariableTypeKey, // State, Average=1, NonState, Sum=2
5068 : std::string_view const KeyedValue, // Associated Key for this variable
5069 : Optional_string_const ReportFreq, // Internal use -- causes reporting at this frequency
5070 : Optional_string_const ResourceTypeKey, // Meter Resource Type (Electricity, Gas, etc)
5071 : Optional_string_const EndUseKey, // Meter End Use Key (Lights, Heating, Cooling, etc)
5072 : Optional_string_const EndUseSubKey, // Meter End Use Sub Key (General Lights, Task Lights, etc)
5073 : Optional_string_const GroupKey, // Meter Super Group Key (Building, System, Plant)
5074 : Optional_string_const ZoneKey, // Meter Zone Key (zone name)
5075 : Optional_int_const ZoneMult, // Zone Multiplier, defaults to 1
5076 : Optional_int_const ZoneListMult, // Zone List Multiplier, defaults to 1
5077 : Optional_int_const indexGroupKey, // Group identifier for SQL output
5078 : Optional_string_const customUnitName, // the custom name for the units from EMS definition of units
5079 : Optional_string_const SpaceType // Space type (applicable for Building group only)
5080 : )
5081 : {
5082 :
5083 : // SUBROUTINE INFORMATION:
5084 : // AUTHOR Linda K. Lawrie
5085 : // DATE WRITTEN December 1998
5086 : // MODIFIED January 2001; Implement Meters
5087 : // August 2008; Implement SQL output
5088 : // RE-ENGINEERED na
5089 :
5090 : // PURPOSE OF THIS SUBROUTINE:
5091 : // This subroutine sets up the variable data structure that will be used
5092 : // to track values of the output variables of EnergyPlus.
5093 :
5094 : // METHODOLOGY EMPLOYED:
5095 : // Pointers (as pointers), pointers (as indices), and lots of other KEWL data stuff.
5096 :
5097 : // Using/Aliasing
5098 : using namespace OutputProcessor;
5099 :
5100 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5101 : int CV;
5102 : TimeStepType TimeStepType; // 1=TimeStepZone, 2=TimeStepSys
5103 : StoreType VariableType; // 1=Average, 2=Sum, 3=Min/Max
5104 : int Loop;
5105 5829124 : ReportingFrequency RepFreq(ReportingFrequency::Hourly);
5106 11658248 : std::string ResourceType; // Will hold value of ResourceTypeKey
5107 11658248 : std::string EndUse; // Will hold value of EndUseKey
5108 11658248 : std::string EndUseSub; // Will hold value of EndUseSubKey
5109 11658248 : std::string Group; // Will hold value of GroupKey
5110 11658248 : std::string zoneName; // Will hold value of ZoneKey
5111 11658248 : std::string spaceType; // Will hold value of SpaceType
5112 : int localIndexGroupKey;
5113 5829124 : auto &op(state.dataOutputProcessor);
5114 :
5115 5829124 : if (!op->OutputInitialized) InitializeOutput(state);
5116 :
5117 : // Variable name without units
5118 5829124 : const std::string_view VarName = VariableName;
5119 :
5120 : // Determine whether to Report or not
5121 5829124 : CheckReportVariable(state, KeyedValue, VarName);
5122 :
5123 5829124 : if (op->NumExtraVars == 0) {
5124 5773926 : op->NumExtraVars = 1;
5125 5773926 : op->ReportList = -1;
5126 : }
5127 :
5128 : // If ReportFreq present, overrides input
5129 5829124 : if (present(ReportFreq)) {
5130 1 : RepFreq = determineFrequency(state, ReportFreq);
5131 1 : op->NumExtraVars = 1;
5132 1 : op->ReportList = 0;
5133 : }
5134 :
5135 : // DataOutputs::OutputVariablesForSimulation is case-insensitive
5136 5829124 : bool const ThisOneOnTheList = DataOutputs::FindItemInVariableList(state, KeyedValue, VarName);
5137 5829124 : bool OnMeter = false; // True if this variable is on a meter
5138 :
5139 11659904 : for (Loop = 1; Loop <= op->NumExtraVars; ++Loop) {
5140 :
5141 5830780 : if (Loop == 1) ++op->NumOfRVariable_Setup;
5142 :
5143 5830780 : if (Loop == 1) {
5144 5829124 : OnMeter = false;
5145 5829124 : if (present(ResourceTypeKey)) {
5146 56062 : ResourceType = ResourceTypeKey;
5147 56062 : OnMeter = true;
5148 : } else {
5149 5773062 : ResourceType = "";
5150 : }
5151 5829124 : if (present(EndUseKey)) {
5152 56048 : EndUse = EndUseKey;
5153 56048 : OnMeter = true;
5154 : } else {
5155 5773076 : EndUse = "";
5156 : }
5157 5829124 : if (present(EndUseSubKey)) {
5158 18135 : EndUseSub = EndUseSubKey;
5159 18135 : OnMeter = true;
5160 : } else {
5161 5810989 : EndUseSub = "";
5162 5810989 : if (present(EndUseKey)) {
5163 75826 : if (std::find(endUseCategoryNames.begin(), endUseCategoryNames.end(), UtilityRoutines::MakeUPPERCase(std::string{EndUseKey})) !=
5164 37913 : endUseCategoryNames.end()) {
5165 20935 : EndUseSub = "General";
5166 : }
5167 : }
5168 : }
5169 5829124 : if (present(GroupKey)) {
5170 55821 : Group = GroupKey;
5171 55821 : OnMeter = true;
5172 : } else {
5173 5773303 : Group = "";
5174 : }
5175 5829124 : if (present(ZoneKey)) {
5176 18825 : zoneName = ZoneKey;
5177 18825 : OnMeter = true;
5178 : } else {
5179 5810299 : zoneName = "";
5180 : }
5181 5829124 : if (present(SpaceType)) {
5182 8348 : spaceType = SpaceType;
5183 8348 : OnMeter = true;
5184 : } else {
5185 5820776 : spaceType = "";
5186 : }
5187 : }
5188 :
5189 5830780 : TimeStepType = ValidateTimeStepType(state, TimeStepTypeKey);
5190 5830780 : VariableType = validateVariableType(state, VariableTypeKey);
5191 :
5192 5830780 : if (present(customUnitName)) {
5193 10 : AddToOutputVariableList(state, VarName, TimeStepType, VariableType, VariableType::Real, VariableUnit, customUnitName);
5194 : } else {
5195 5830770 : AddToOutputVariableList(state, VarName, TimeStepType, VariableType, VariableType::Real, VariableUnit);
5196 : }
5197 5830780 : ++op->NumTotalRVariable;
5198 :
5199 11604706 : if (!OnMeter && !ThisOneOnTheList) continue;
5200 :
5201 171003 : ++op->NumOfRVariable;
5202 171003 : if (Loop == 1 && VariableType == StoreType::Summed) {
5203 94683 : ++op->NumOfRVariable_Sum;
5204 94683 : if (present(ResourceTypeKey)) {
5205 56062 : if (!ResourceTypeKey().empty()) ++op->NumOfRVariable_Meter;
5206 : }
5207 : }
5208 171003 : if (op->NumOfRVariable > op->MaxRVariable) {
5209 59 : ReallocateRVar(state);
5210 : }
5211 171003 : CV = op->NumOfRVariable;
5212 171003 : auto &thisRvar = op->RVariableTypes(CV);
5213 171003 : thisRvar.timeStepType = TimeStepType;
5214 171003 : thisRvar.storeType = VariableType;
5215 171003 : thisRvar.VarName = fmt::format("{}:{}", KeyedValue, VarName);
5216 171003 : thisRvar.VarNameOnly = VarName;
5217 171003 : thisRvar.VarNameOnlyUC = UtilityRoutines::MakeUPPERCase(VarName);
5218 171003 : thisRvar.VarNameUC = UtilityRoutines::MakeUPPERCase(thisRvar.VarName);
5219 171003 : thisRvar.KeyNameOnlyUC = UtilityRoutines::MakeUPPERCase(KeyedValue);
5220 171003 : thisRvar.units = VariableUnit;
5221 171003 : if (VariableUnit == OutputProcessor::Unit::customEMS) {
5222 10 : thisRvar.unitNameCustomEMS = customUnitName;
5223 : }
5224 171003 : AssignReportNumber(state, op->CurrentReportNumber);
5225 227857 : const auto IDOut = fmt::to_string(op->CurrentReportNumber);
5226 171003 : thisRvar.ReportID = op->CurrentReportNumber;
5227 171003 : auto &thisVarPtr = thisRvar.VarPtr;
5228 171003 : thisVarPtr.Value = 0.0;
5229 171003 : thisVarPtr.TSValue = 0.0;
5230 171003 : thisVarPtr.StoreValue = 0.0;
5231 171003 : thisVarPtr.NumStored = 0.0;
5232 171003 : thisVarPtr.MaxValue = MaxSetValue;
5233 171003 : thisVarPtr.maxValueDate = 0;
5234 171003 : thisVarPtr.MinValue = MinSetValue;
5235 171003 : thisVarPtr.minValueDate = 0;
5236 171003 : thisVarPtr.Which = &ActualVariable;
5237 171003 : thisVarPtr.ReportID = op->CurrentReportNumber;
5238 171003 : thisVarPtr.ReportIDChr = IDOut.substr(0, 15);
5239 171003 : thisVarPtr.storeType = VariableType;
5240 171003 : thisVarPtr.Stored = false;
5241 171003 : thisVarPtr.Report = false;
5242 171003 : thisVarPtr.frequency = ReportingFrequency::Hourly;
5243 171003 : thisVarPtr.SchedPtr = 0;
5244 171003 : thisVarPtr.MeterArrayPtr = 0;
5245 171003 : thisVarPtr.ZoneMult = 1;
5246 171003 : thisVarPtr.ZoneListMult = 1;
5247 171003 : if (present(ZoneMult) && present(ZoneListMult)) {
5248 17986 : thisVarPtr.ZoneMult = ZoneMult;
5249 17986 : thisVarPtr.ZoneListMult = ZoneListMult;
5250 : }
5251 :
5252 171003 : if (Loop == 1) {
5253 169347 : if (OnMeter) {
5254 56062 : if (VariableType == StoreType::Averaged) {
5255 0 : ShowSevereError(state, "Meters can only be \"Summed\" variables");
5256 0 : ShowContinueError(state, fmt::format("..reference variable={}:{}", KeyedValue, VariableName));
5257 : } else {
5258 56062 : Unit mtrUnits = op->RVariableTypes(CV).units;
5259 56062 : bool ErrorsFound = false;
5260 56062 : AttachMeters(
5261 : state, mtrUnits, ResourceType, EndUse, EndUseSub, Group, zoneName, spaceType, CV, thisVarPtr.MeterArrayPtr, ErrorsFound);
5262 56062 : if (ErrorsFound) {
5263 0 : ShowContinueError(state, fmt::format("Invalid Meter spec for variable={}:{}", KeyedValue, VariableName));
5264 0 : op->ErrorsLogged = true;
5265 : }
5266 : }
5267 : }
5268 : }
5269 :
5270 171003 : if (op->ReportList(Loop) == -1) continue;
5271 :
5272 56854 : thisVarPtr.Report = true;
5273 :
5274 56854 : if (op->ReportList(Loop) == 0) {
5275 1 : thisVarPtr.frequency = RepFreq;
5276 1 : thisVarPtr.SchedPtr = 0;
5277 : } else {
5278 56853 : thisVarPtr.frequency = op->ReqRepVars(op->ReportList(Loop)).frequency;
5279 56853 : thisVarPtr.SchedPtr = op->ReqRepVars(op->ReportList(Loop)).SchedPtr;
5280 : }
5281 :
5282 56854 : if (thisVarPtr.Report) {
5283 56854 : if (present(indexGroupKey)) {
5284 0 : localIndexGroupKey = indexGroupKey;
5285 : } else {
5286 56854 : localIndexGroupKey = -999; // Unknown Group
5287 : }
5288 :
5289 56854 : if (thisVarPtr.SchedPtr != 0) {
5290 6450 : WriteReportVariableDictionaryItem(state,
5291 : thisVarPtr.frequency,
5292 : thisVarPtr.storeType,
5293 : thisVarPtr.ReportID,
5294 : localIndexGroupKey,
5295 4300 : std::string(sovTimeStepTypeStrings[(int)TimeStepTypeKey]),
5296 : thisVarPtr.ReportIDChr,
5297 : KeyedValue,
5298 : VarName,
5299 : thisRvar.timeStepType,
5300 : thisRvar.units,
5301 : thisRvar.unitNameCustomEMS,
5302 2150 : op->ReqRepVars(op->ReportList(Loop)).SchedName);
5303 : } else {
5304 164112 : WriteReportVariableDictionaryItem(state,
5305 : thisVarPtr.frequency,
5306 : thisVarPtr.storeType,
5307 : thisVarPtr.ReportID,
5308 : localIndexGroupKey,
5309 109408 : std::string(sovTimeStepTypeStrings[(int)TimeStepTypeKey]),
5310 : thisVarPtr.ReportIDChr,
5311 : KeyedValue,
5312 : VarName,
5313 : thisRvar.timeStepType,
5314 : thisRvar.units,
5315 54704 : thisRvar.unitNameCustomEMS);
5316 : }
5317 : }
5318 : }
5319 5829124 : }
5320 :
5321 253776 : void SetupOutputVariable(EnergyPlusData &state,
5322 : std::string_view const VariableName, // String Name of variable
5323 : OutputProcessor::Unit const VariableUnit, // Actual units corresponding to the actual variable
5324 : int &ActualVariable, // Actual Variable, used to set up pointer
5325 : OutputProcessor::SOVTimeStepType const TimeStepTypeKey, // Zone, HeatBalance=1, HVAC, System, Plant=2
5326 : OutputProcessor::SOVStoreType const VariableTypeKey, // State, Average=1, NonState, Sum=2
5327 : std::string_view const KeyedValue, // Associated Key for this variable
5328 : Optional_string_const ReportFreq, // Internal use -- causes reporting at this freqency
5329 : Optional_int_const indexGroupKey // Group identifier for SQL output
5330 : )
5331 : {
5332 :
5333 : // SUBROUTINE INFORMATION:
5334 : // AUTHOR Linda K. Lawrie
5335 : // DATE WRITTEN December 1998
5336 : // MODIFIED August 2008; Added SQL output capability
5337 : // RE-ENGINEERED na
5338 :
5339 : // PURPOSE OF THIS SUBROUTINE:
5340 : // This subroutine sets up the variable data structure that will be used
5341 : // to track values of the output variables of EnergyPlus.
5342 :
5343 : // METHODOLOGY EMPLOYED:
5344 : // Pointers (as pointers), pointers (as indices), and lots of other KEWL data stuff.
5345 :
5346 : // Using/Aliasing
5347 : using namespace OutputProcessor;
5348 :
5349 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5350 : int CV;
5351 : TimeStepType TimeStepType; // 1=TimeStepZone, 2=TimeStepSys
5352 : StoreType VariableType; // 1=Average, 2=Sum, 3=Min/Max
5353 : int localIndexGroupKey;
5354 : int Loop;
5355 253776 : ReportingFrequency RepFreq(ReportingFrequency::Hourly);
5356 253776 : auto &op(state.dataOutputProcessor);
5357 :
5358 253776 : if (!op->OutputInitialized) InitializeOutput(state);
5359 :
5360 : // Variable name without units
5361 253776 : const std::string_view VarName = VariableName;
5362 :
5363 : // Determine whether to Report or not
5364 253776 : CheckReportVariable(state, KeyedValue, VarName);
5365 :
5366 253776 : if (op->NumExtraVars == 0) {
5367 252206 : op->NumExtraVars = 1;
5368 252206 : op->ReportList = -1;
5369 : }
5370 :
5371 : // If ReportFreq present, overrides input
5372 253776 : if (present(ReportFreq)) {
5373 0 : RepFreq = determineFrequency(state, ReportFreq);
5374 0 : op->NumExtraVars = 1;
5375 0 : op->ReportList = 0;
5376 : }
5377 :
5378 : // DataOutputs::OutputVariablesForSimulation is case-insentitive
5379 253776 : bool const ThisOneOnTheList = DataOutputs::FindItemInVariableList(state, KeyedValue, VarName);
5380 :
5381 507572 : for (Loop = 1; Loop <= op->NumExtraVars; ++Loop) {
5382 :
5383 253796 : if (Loop == 1) ++op->NumOfIVariable_Setup;
5384 :
5385 253796 : TimeStepType = ValidateTimeStepType(state, TimeStepTypeKey);
5386 253796 : VariableType = validateVariableType(state, VariableTypeKey);
5387 :
5388 253796 : AddToOutputVariableList(state, VarName, TimeStepType, VariableType, VariableType::Integer, VariableUnit);
5389 253796 : ++op->NumTotalIVariable;
5390 :
5391 506002 : if (!ThisOneOnTheList) continue;
5392 :
5393 3829 : ++op->NumOfIVariable;
5394 3829 : if (Loop == 1 && VariableType == StoreType::Summed) {
5395 143 : ++op->NumOfIVariable_Sum;
5396 : }
5397 3829 : if (op->NumOfIVariable > op->MaxIVariable) {
5398 302 : ReallocateIVar(state);
5399 : }
5400 :
5401 3829 : CV = op->NumOfIVariable;
5402 3829 : auto &thisIVar = op->IVariableTypes(CV);
5403 3829 : thisIVar.timeStepType = TimeStepType;
5404 3829 : thisIVar.storeType = VariableType;
5405 3829 : thisIVar.VarName = fmt::format("{}:{}", KeyedValue, VarName);
5406 3829 : thisIVar.VarNameOnly = VarName;
5407 3829 : thisIVar.VarNameOnlyUC = UtilityRoutines::MakeUPPERCase(VarName);
5408 3829 : thisIVar.VarNameUC = UtilityRoutines::MakeUPPERCase(thisIVar.VarName);
5409 3829 : thisIVar.KeyNameOnlyUC = UtilityRoutines::MakeUPPERCase(KeyedValue);
5410 3829 : thisIVar.units = VariableUnit;
5411 3829 : AssignReportNumber(state, op->CurrentReportNumber);
5412 5419 : const auto IDOut = fmt::to_string(op->CurrentReportNumber);
5413 3829 : thisIVar.ReportID = op->CurrentReportNumber;
5414 3829 : auto &thisVarPtr = thisIVar.VarPtr;
5415 3829 : thisVarPtr.Value = 0.0;
5416 3829 : thisVarPtr.StoreValue = 0.0;
5417 3829 : thisVarPtr.TSValue = 0.0;
5418 3829 : thisVarPtr.NumStored = 0.0;
5419 : // IVariable%LastTSValue=0
5420 3829 : thisVarPtr.MaxValue = IMaxSetValue;
5421 3829 : thisVarPtr.maxValueDate = 0;
5422 3829 : thisVarPtr.MinValue = IMinSetValue;
5423 3829 : thisVarPtr.minValueDate = 0;
5424 3829 : thisVarPtr.Which = &ActualVariable;
5425 3829 : thisVarPtr.ReportID = op->CurrentReportNumber;
5426 3829 : thisVarPtr.ReportIDChr = IDOut.substr(0, 15);
5427 3829 : thisVarPtr.storeType = VariableType;
5428 3829 : thisVarPtr.Stored = false;
5429 3829 : thisVarPtr.Report = false;
5430 3829 : thisVarPtr.frequency = ReportingFrequency::Hourly;
5431 3829 : thisVarPtr.SchedPtr = 0;
5432 :
5433 3829 : if (op->ReportList(Loop) == -1) continue;
5434 :
5435 1590 : thisVarPtr.Report = true;
5436 :
5437 1590 : if (op->ReportList(Loop) == 0) {
5438 0 : thisVarPtr.frequency = RepFreq;
5439 0 : thisVarPtr.SchedPtr = 0;
5440 : } else {
5441 1590 : thisVarPtr.frequency = op->ReqRepVars(op->ReportList(Loop)).frequency;
5442 1590 : thisVarPtr.SchedPtr = op->ReqRepVars(op->ReportList(Loop)).SchedPtr;
5443 : }
5444 :
5445 1590 : if (thisVarPtr.Report) {
5446 1590 : if (present(indexGroupKey)) {
5447 0 : localIndexGroupKey = indexGroupKey;
5448 : } else {
5449 1590 : localIndexGroupKey = -999; // Unknown Group
5450 : }
5451 :
5452 1590 : if (thisVarPtr.SchedPtr != 0) {
5453 36 : WriteReportVariableDictionaryItem(state,
5454 : thisVarPtr.frequency,
5455 : thisVarPtr.storeType,
5456 : thisVarPtr.ReportID,
5457 : localIndexGroupKey,
5458 24 : std::string(sovTimeStepTypeStrings[(int)TimeStepTypeKey]),
5459 : thisVarPtr.ReportIDChr,
5460 : KeyedValue,
5461 : VarName,
5462 : thisIVar.timeStepType,
5463 : thisIVar.units,
5464 12 : op->ReqRepVars(op->ReportList(Loop)).SchedName);
5465 : } else {
5466 4734 : WriteReportVariableDictionaryItem(state,
5467 : thisVarPtr.frequency,
5468 : thisVarPtr.storeType,
5469 : thisVarPtr.ReportID,
5470 : localIndexGroupKey,
5471 3156 : std::string(sovTimeStepTypeStrings[(int)TimeStepTypeKey]),
5472 : thisVarPtr.ReportIDChr,
5473 : KeyedValue,
5474 : VarName,
5475 : thisIVar.timeStepType,
5476 1578 : thisIVar.units);
5477 : }
5478 : }
5479 : }
5480 253776 : }
5481 :
5482 690474 : void UpdateDataandReport(EnergyPlusData &state, OutputProcessor::TimeStepType const t_TimeStepTypeKey) // What kind of data to update (Zone, HVAC)
5483 : {
5484 :
5485 : // SUBROUTINE INFORMATION:
5486 : // AUTHOR Linda K. Lawrie
5487 : // DATE WRITTEN December 1998
5488 : // MODIFIED January 2001; Resolution integrated at the Zone TimeStep intervals
5489 : // MODIFIED August 2008; Added SQL output capability
5490 : // RE-ENGINEERED na
5491 :
5492 : // PURPOSE OF THIS SUBROUTINE:
5493 : // This subroutine writes the actual report variable (for user requested
5494 : // Report Variables) strings to the standard output file.
5495 :
5496 : // METHODOLOGY EMPLOYED:
5497 : // na
5498 :
5499 : // REFERENCES:
5500 : // na
5501 :
5502 : // Using/Aliasing
5503 : using namespace OutputProcessor;
5504 : using General::EncodeMonDayHrMin;
5505 : using ScheduleManager::GetCurrentScheduleValue;
5506 :
5507 : // Locals
5508 : // SUBROUTINE ARGUMENT DEFINITIONS:
5509 :
5510 : // SUBROUTINE PARAMETER DEFINITIONS:
5511 : // na
5512 :
5513 : // INTERFACE BLOCK SPECIFICATIONS:
5514 : // na
5515 :
5516 : // DERIVED TYPE DEFINITIONS:
5517 : // na
5518 :
5519 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5520 690474 : bool TimePrint(true); // True if the time needs to be printed
5521 690474 : bool EndTimeStepFlag(false); // True when it's the end of the Zone Time Step
5522 690474 : auto &op(state.dataOutputProcessor);
5523 :
5524 690474 : if (t_TimeStepTypeKey != TimeStepType::Zone && t_TimeStepTypeKey != TimeStepType::System) {
5525 0 : ShowFatalError(state, "Invalid reporting requested -- UpdateDataAndReport");
5526 : }
5527 :
5528 : // Basic record keeping and report out if "detailed"
5529 690474 : Real64 StartMinute = op->TimeValue.at(t_TimeStepTypeKey).CurMinute; // StartMinute for UpdateData call
5530 690474 : op->TimeValue.at(t_TimeStepTypeKey).CurMinute += (*op->TimeValue.at(t_TimeStepTypeKey).TimeStep) * 60.0;
5531 1772334 : if (t_TimeStepTypeKey == TimeStepType::System &&
5532 1081860 : (op->TimeValue.at(TimeStepType::System).CurMinute == op->TimeValue.at(TimeStepType::Zone).CurMinute)) {
5533 0 : EndTimeStepFlag = true;
5534 690474 : } else if (t_TimeStepTypeKey == TimeStepType::Zone) {
5535 299088 : EndTimeStepFlag = true;
5536 : } else {
5537 391386 : EndTimeStepFlag = false;
5538 : }
5539 690474 : Real64 MinuteNow = op->TimeValue.at(t_TimeStepTypeKey).CurMinute; // What minute it is now
5540 :
5541 : int MDHM; // Month,Day,Hour,Minute
5542 690474 : EncodeMonDayHrMin(MDHM, state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, int(MinuteNow));
5543 690474 : TimePrint = true;
5544 :
5545 690474 : Real64 rxTime = (MinuteNow - StartMinute) /
5546 690474 : double(state.dataGlobal->MinutesPerTimeStep); // (MinuteNow-StartMinute)/REAL(MinutesPerTimeStep,r64) - for execution time
5547 :
5548 690474 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
5549 : // R and I data frames for TimeStepType::TimeStepZone
5550 4140 : if (t_TimeStepTypeKey == TimeStepType::Zone && !state.dataResultsFramework->resultsFramework->RIDetailedZoneTSData.rVariablesScanned()) {
5551 21 : state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
5552 14 : ReportingFrequency::EachCall, op->RVariableTypes, op->NumOfRVariable, TimeStepType::Zone);
5553 : }
5554 4140 : if (t_TimeStepTypeKey == TimeStepType::Zone && !state.dataResultsFramework->resultsFramework->RIDetailedZoneTSData.iVariablesScanned()) {
5555 21 : state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
5556 14 : ReportingFrequency::EachCall, op->IVariableTypes, op->NumOfIVariable, TimeStepType::Zone);
5557 : }
5558 :
5559 : // R and I data frames for TimeStepType::TimeStepSystem
5560 4140 : if (t_TimeStepTypeKey == TimeStepType::System && !state.dataResultsFramework->resultsFramework->RIDetailedHVACTSData.rVariablesScanned()) {
5561 21 : state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
5562 14 : ReportingFrequency::EachCall, op->RVariableTypes, op->NumOfRVariable, TimeStepType::System);
5563 : }
5564 4140 : if (t_TimeStepTypeKey == TimeStepType::System && !state.dataResultsFramework->resultsFramework->RIDetailedHVACTSData.iVariablesScanned()) {
5565 21 : state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
5566 14 : ReportingFrequency::EachCall, op->IVariableTypes, op->NumOfIVariable, TimeStepType::System);
5567 : }
5568 : }
5569 :
5570 690474 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
5571 4140 : if (t_TimeStepTypeKey == TimeStepType::Zone) {
5572 8160 : state.dataResultsFramework->resultsFramework->RIDetailedZoneTSData.newRow(
5573 8160 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, op->TimeValue.at(TimeStepType::Zone).CurMinute);
5574 : }
5575 4140 : if (t_TimeStepTypeKey == TimeStepType::System) {
5576 : // TODO this was an error probably, was using TimeValue(1)
5577 12540 : state.dataResultsFramework->resultsFramework->RIDetailedHVACTSData.newRow(
5578 12540 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, op->TimeValue.at(TimeStepType::System).CurMinute);
5579 : }
5580 : }
5581 :
5582 : // Main "Record Keeping" Loops for R and I variables
5583 142459923 : for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
5584 141769449 : if (op->RVariableTypes(Loop).timeStepType != t_TimeStepTypeKey) continue;
5585 :
5586 : // Act on the RVariables variable
5587 73980952 : auto &rVar(op->RVariableTypes(Loop).VarPtr);
5588 73980952 : rVar.Stored = true;
5589 73980952 : if (rVar.storeType == StoreType::Averaged) {
5590 36252282 : Real64 CurVal = (*rVar.Which) * rxTime;
5591 : // CALL SetMinMax(RVar%Which,MDHM,RVar%MaxValue,RVar%maxValueDate,RVar%MinValue,RVar%minValueDate)
5592 36252282 : if ((*rVar.Which) > rVar.MaxValue) {
5593 2450717 : rVar.MaxValue = (*rVar.Which);
5594 2450717 : rVar.maxValueDate = MDHM;
5595 : }
5596 36252282 : if ((*rVar.Which) < rVar.MinValue) {
5597 1628594 : rVar.MinValue = (*rVar.Which);
5598 1628594 : rVar.minValueDate = MDHM;
5599 : }
5600 36252282 : rVar.TSValue += CurVal;
5601 36252282 : rVar.EITSValue = rVar.TSValue; // CR - 8481 fix - 09/06/2011
5602 : } else {
5603 : // CurVal=RVar%Which
5604 37728670 : if ((*rVar.Which) > rVar.MaxValue) {
5605 1353425 : rVar.MaxValue = (*rVar.Which);
5606 1353425 : rVar.maxValueDate = MDHM;
5607 : }
5608 37728670 : if ((*rVar.Which) < rVar.MinValue) {
5609 464896 : rVar.MinValue = (*rVar.Which);
5610 464896 : rVar.minValueDate = MDHM;
5611 : }
5612 37728670 : rVar.TSValue += (*rVar.Which);
5613 37728670 : rVar.EITSValue = rVar.TSValue; // CR - 8481 fix - 09/06/2011
5614 : }
5615 :
5616 : // End of "record keeping" Report if applicable
5617 73980952 : if (!rVar.Report) continue;
5618 35194679 : bool ReportNow = true;
5619 35194679 : if (rVar.SchedPtr > 0) ReportNow = (GetCurrentScheduleValue(state, rVar.SchedPtr) != 0.0); // SetReportNow(RVar%SchedPtr)
5620 35194679 : if (!ReportNow) continue;
5621 35049871 : rVar.tsStored = true;
5622 35049871 : if (!rVar.thisTSStored) {
5623 27059240 : ++rVar.thisTSCount;
5624 27059240 : rVar.thisTSStored = true;
5625 : }
5626 :
5627 35049871 : if (rVar.frequency == ReportingFrequency::EachCall) {
5628 554032 : if (TimePrint) {
5629 23533 : if (op->LHourP != state.dataGlobal->HourOfDay || std::abs(op->LStartMin - StartMinute) > 0.001 ||
5630 2699 : std::abs(op->LEndMin - op->TimeValue.at(t_TimeStepTypeKey).CurMinute) > 0.001) {
5631 18135 : int CurDayType = state.dataEnvrn->DayOfWeek;
5632 18135 : if (state.dataEnvrn->HolidayIndex > 0) {
5633 18135 : CurDayType = state.dataEnvrn->HolidayIndex;
5634 : }
5635 163215 : WriteTimeStampFormatData(state,
5636 : state.files.eso,
5637 : ReportingFrequency::EachCall,
5638 18135 : op->TimeStepStampReportNbr,
5639 18135 : op->TimeStepStampReportChr,
5640 18135 : state.dataGlobal->DayOfSimChr,
5641 : true,
5642 18135 : state.dataEnvrn->Month,
5643 18135 : state.dataEnvrn->DayOfMonth,
5644 18135 : state.dataGlobal->HourOfDay,
5645 18135 : op->TimeValue.at(t_TimeStepTypeKey).CurMinute,
5646 : StartMinute,
5647 18135 : state.dataEnvrn->DSTIndicator,
5648 18135 : ScheduleManager::dayTypeNames[CurDayType]);
5649 18135 : op->LHourP = state.dataGlobal->HourOfDay;
5650 18135 : op->LStartMin = StartMinute;
5651 18135 : op->LEndMin = op->TimeValue.at(t_TimeStepTypeKey).CurMinute;
5652 : }
5653 20834 : TimePrint = false;
5654 : }
5655 554032 : WriteNumericData(state, rVar.ReportID, rVar.ReportIDChr, *rVar.Which);
5656 554032 : ++state.dataGlobal->StdOutputRecordCount;
5657 :
5658 554032 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
5659 7810 : if (t_TimeStepTypeKey == TimeStepType::Zone) {
5660 384 : state.dataResultsFramework->resultsFramework->RIDetailedZoneTSData.pushVariableValue(rVar.ReportID, *rVar.Which);
5661 : }
5662 7810 : if (t_TimeStepTypeKey == TimeStepType::System) {
5663 7426 : state.dataResultsFramework->resultsFramework->RIDetailedHVACTSData.pushVariableValue(rVar.ReportID, *rVar.Which);
5664 : }
5665 : }
5666 : }
5667 : }
5668 :
5669 3601187 : for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
5670 2910713 : if (op->IVariableTypes(Loop).timeStepType != t_TimeStepTypeKey) continue;
5671 :
5672 : // Act on the IVariables variable
5673 1328639 : auto &iVar(op->IVariableTypes(Loop).VarPtr);
5674 1328639 : iVar.Stored = true;
5675 : // ICurVal=IVar%Which
5676 1328639 : if (iVar.storeType == StoreType::Averaged) {
5677 1243022 : Real64 ICurVal = (*iVar.Which) * rxTime;
5678 1243022 : iVar.TSValue += ICurVal;
5679 1243022 : iVar.EITSValue = iVar.TSValue; // CR - 8481 fix - 09/06/2011
5680 1243022 : if (nint(ICurVal) > iVar.MaxValue) {
5681 4993 : iVar.MaxValue = nint(ICurVal); // Record keeping for date and time go here too
5682 4993 : iVar.maxValueDate = MDHM; //+ TimeValue.at(t_TimeStepTypeKey)%TimeStep
5683 : }
5684 1243022 : if (nint(ICurVal) < iVar.MinValue) {
5685 4470 : iVar.MinValue = nint(ICurVal);
5686 4470 : iVar.minValueDate = MDHM; //+ TimeValue.at(t_TimeStepTypeKey)%TimeStep
5687 : }
5688 : } else {
5689 85617 : if ((*iVar.Which) > iVar.MaxValue) {
5690 315 : iVar.MaxValue = (*iVar.Which); // Record keeping for date and time go here too
5691 315 : iVar.maxValueDate = MDHM; //+ TimeValue(TimeStepType)%TimeStep
5692 : }
5693 85617 : if ((*iVar.Which) < iVar.MinValue) {
5694 197 : iVar.MinValue = (*iVar.Which);
5695 197 : iVar.minValueDate = MDHM; //+ TimeValue(TimeStepType)%TimeStep
5696 : }
5697 85617 : iVar.TSValue += (*iVar.Which);
5698 85617 : iVar.EITSValue = iVar.TSValue; // CR - 8481 fix - 09/06/2011
5699 : }
5700 :
5701 1328639 : if (!iVar.Report) continue;
5702 895439 : bool ReportNow = true;
5703 895439 : if (iVar.SchedPtr > 0) ReportNow = (GetCurrentScheduleValue(state, iVar.SchedPtr) != 0.0); // SetReportNow(IVar%SchedPtr)
5704 895439 : if (!ReportNow) continue;
5705 895439 : iVar.tsStored = true;
5706 895439 : if (!iVar.thisTSStored) {
5707 666144 : ++iVar.thisTSCount;
5708 666144 : iVar.thisTSStored = true;
5709 : }
5710 :
5711 895439 : if (iVar.frequency == ReportingFrequency::EachCall) {
5712 7320 : if (TimePrint) {
5713 0 : if (op->LHourP != state.dataGlobal->HourOfDay || std::abs(op->LStartMin - StartMinute) > 0.001 ||
5714 0 : std::abs(op->LEndMin - op->TimeValue.at(t_TimeStepTypeKey).CurMinute) > 0.001) {
5715 0 : int CurDayType = state.dataEnvrn->DayOfWeek;
5716 0 : if (state.dataEnvrn->HolidayIndex > 0) {
5717 0 : CurDayType = state.dataEnvrn->HolidayIndex;
5718 : }
5719 0 : WriteTimeStampFormatData(state,
5720 : state.files.eso,
5721 : ReportingFrequency::EachCall,
5722 0 : op->TimeStepStampReportNbr,
5723 0 : op->TimeStepStampReportChr,
5724 0 : state.dataGlobal->DayOfSimChr,
5725 : true,
5726 0 : state.dataEnvrn->Month,
5727 0 : state.dataEnvrn->DayOfMonth,
5728 0 : state.dataGlobal->HourOfDay,
5729 0 : op->TimeValue.at(t_TimeStepTypeKey).CurMinute,
5730 : StartMinute,
5731 0 : state.dataEnvrn->DSTIndicator,
5732 0 : ScheduleManager::dayTypeNames[CurDayType]);
5733 0 : op->LHourP = state.dataGlobal->HourOfDay;
5734 0 : op->LStartMin = StartMinute;
5735 0 : op->LEndMin = op->TimeValue.at(t_TimeStepTypeKey).CurMinute;
5736 : }
5737 0 : TimePrint = false;
5738 : }
5739 : // only time integer vars actual report as integer only is "detailed"
5740 7320 : WriteNumericData(state, iVar.ReportID, iVar.ReportIDChr, *iVar.Which);
5741 7320 : ++state.dataGlobal->StdOutputRecordCount;
5742 :
5743 7320 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
5744 737 : if (t_TimeStepTypeKey == TimeStepType::Zone) {
5745 0 : state.dataResultsFramework->resultsFramework->RIDetailedZoneTSData.pushVariableValue(iVar.ReportID, *iVar.Which);
5746 : }
5747 737 : if (t_TimeStepTypeKey == TimeStepType::System) {
5748 737 : state.dataResultsFramework->resultsFramework->RIDetailedHVACTSData.pushVariableValue(iVar.ReportID, *iVar.Which);
5749 : }
5750 : }
5751 : }
5752 : }
5753 :
5754 1378541 : if (t_TimeStepTypeKey == TimeStepType::System) return; // All other stuff happens at the "zone" time step call to this routine.
5755 :
5756 : // TimeStep Block (Report on Zone TimeStep)
5757 :
5758 299088 : if (EndTimeStepFlag) {
5759 299088 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
5760 1632 : if (!state.dataResultsFramework->resultsFramework->RITimestepTSData.rVariablesScanned()) {
5761 21 : state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
5762 14 : ReportingFrequency::TimeStep, op->RVariableTypes, op->NumOfRVariable);
5763 : }
5764 1632 : if (!state.dataResultsFramework->resultsFramework->RITimestepTSData.iVariablesScanned()) {
5765 21 : state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
5766 14 : ReportingFrequency::TimeStep, op->IVariableTypes, op->NumOfIVariable);
5767 : }
5768 8160 : state.dataResultsFramework->resultsFramework->RITimestepTSData.newRow(
5769 8160 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, op->TimeValue.at(TimeStepType::Zone).CurMinute);
5770 : }
5771 :
5772 897264 : for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
5773 117964992 : for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
5774 117366816 : if (op->RVariableTypes(Loop).timeStepType != thisTimeStepType) continue;
5775 58683408 : auto &rVar(op->RVariableTypes(Loop).VarPtr);
5776 : // Update meters on the TimeStep (Zone)
5777 58683408 : if (rVar.MeterArrayPtr != 0 && !state.dataOutputProcessor->MeterValue.empty()) {
5778 20327808 : Real64 TimeStepValue = rVar.TSValue * rVar.ZoneMult * rVar.ZoneListMult;
5779 122677296 : for (int i = 1; i <= op->VarMeterArrays(rVar.MeterArrayPtr).NumOnMeters; i++) {
5780 102349488 : int index = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(i);
5781 102349488 : state.dataOutputProcessor->MeterValue(index) += TimeStepValue;
5782 : }
5783 21878208 : for (int i = 1; i <= op->VarMeterArrays(rVar.MeterArrayPtr).NumOnCustomMeters; i++) {
5784 1550400 : int index = op->VarMeterArrays(rVar.MeterArrayPtr).OnCustomMeters(i);
5785 1550400 : state.dataOutputProcessor->MeterValue(index) += TimeStepValue;
5786 : }
5787 : }
5788 :
5789 58683408 : bool ReportNow = true;
5790 58683408 : if (rVar.SchedPtr > 0) ReportNow = (GetCurrentScheduleValue(state, rVar.SchedPtr) != 0.0); // SetReportNow(RVar%SchedPtr)
5791 58683408 : if (!ReportNow || !rVar.Report) {
5792 31624168 : rVar.TSValue = 0.0;
5793 : }
5794 : // IF (RVar%StoreType == AveragedVar) THEN
5795 : // RVar%Value=RVar%Value+RVar%TSValue/NumOfTimeStepInHour
5796 : // ELSE
5797 58683408 : rVar.Value += rVar.TSValue;
5798 : // ENDIF
5799 :
5800 58683408 : if (!ReportNow || !rVar.Report) continue;
5801 :
5802 27059240 : if (rVar.frequency == ReportingFrequency::TimeStep) {
5803 6273024 : if (TimePrint) {
5804 103214 : if (op->LHourP != state.dataGlobal->HourOfDay || std::abs(op->LStartMin - StartMinute) > 0.001 ||
5805 62 : std::abs(op->LEndMin - op->TimeValue.at(thisTimeStepType).CurMinute) > 0.001) {
5806 103090 : int CurDayType = state.dataEnvrn->DayOfWeek;
5807 103090 : if (state.dataEnvrn->HolidayIndex > 0) {
5808 99154 : CurDayType = state.dataEnvrn->HolidayIndex;
5809 : }
5810 927810 : WriteTimeStampFormatData(state,
5811 : state.files.eso,
5812 : ReportingFrequency::EachCall,
5813 103090 : op->TimeStepStampReportNbr,
5814 103090 : op->TimeStepStampReportChr,
5815 103090 : state.dataGlobal->DayOfSimChr,
5816 : true,
5817 103090 : state.dataEnvrn->Month,
5818 103090 : state.dataEnvrn->DayOfMonth,
5819 103090 : state.dataGlobal->HourOfDay,
5820 103090 : op->TimeValue.at(thisTimeStepType).CurMinute,
5821 : StartMinute,
5822 103090 : state.dataEnvrn->DSTIndicator,
5823 103090 : ScheduleManager::dayTypeNames[CurDayType]);
5824 103090 : op->LHourP = state.dataGlobal->HourOfDay;
5825 103090 : op->LStartMin = StartMinute;
5826 103090 : op->LEndMin = op->TimeValue.at(thisTimeStepType).CurMinute;
5827 : }
5828 103152 : TimePrint = false;
5829 : }
5830 :
5831 6273024 : WriteNumericData(state, rVar.ReportID, rVar.ReportIDChr, rVar.TSValue);
5832 6273024 : ++state.dataGlobal->StdOutputRecordCount;
5833 :
5834 6273024 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
5835 0 : state.dataResultsFramework->resultsFramework->RITimestepTSData.pushVariableValue(rVar.ReportID, rVar.TSValue);
5836 : }
5837 : }
5838 27059240 : rVar.TSValue = 0.0;
5839 27059240 : rVar.thisTSStored = false;
5840 : } // Number of R Variables
5841 :
5842 2796864 : for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
5843 2198688 : if (op->IVariableTypes(Loop).timeStepType != thisTimeStepType) continue;
5844 1099344 : auto &iVar(op->IVariableTypes(Loop).VarPtr);
5845 1099344 : bool ReportNow = true;
5846 1099344 : if (iVar.SchedPtr > 0) ReportNow = (GetCurrentScheduleValue(state, iVar.SchedPtr) != 0.0); // SetReportNow(IVar%SchedPtr)
5847 1099344 : if (!ReportNow) {
5848 0 : iVar.TSValue = 0.0;
5849 : }
5850 : // IF (IVar%StoreType == AveragedVar) THEN
5851 : // IVar%Value=IVar%Value+REAL(IVar%TSValue,r64)/REAL(NumOfTimeStepInHour,r64)
5852 : // ELSE
5853 1099344 : iVar.Value += iVar.TSValue;
5854 : // ENDIF
5855 :
5856 1099344 : if (!ReportNow || !iVar.Report) continue;
5857 :
5858 666144 : if (iVar.frequency == ReportingFrequency::TimeStep) {
5859 279264 : if (TimePrint) {
5860 288 : if (op->LHourP != state.dataGlobal->HourOfDay || std::abs(op->LStartMin - StartMinute) > 0.001 ||
5861 0 : std::abs(op->LEndMin - op->TimeValue.at(thisTimeStepType).CurMinute) > 0.001) {
5862 288 : int CurDayType = state.dataEnvrn->DayOfWeek;
5863 288 : if (state.dataEnvrn->HolidayIndex > 0) {
5864 288 : CurDayType = state.dataEnvrn->HolidayIndex;
5865 : }
5866 2592 : WriteTimeStampFormatData(state,
5867 : state.files.eso,
5868 : ReportingFrequency::EachCall,
5869 288 : op->TimeStepStampReportNbr,
5870 288 : op->TimeStepStampReportChr,
5871 288 : state.dataGlobal->DayOfSimChr,
5872 : true,
5873 288 : state.dataEnvrn->Month,
5874 288 : state.dataEnvrn->DayOfMonth,
5875 288 : state.dataGlobal->HourOfDay,
5876 288 : op->TimeValue.at(thisTimeStepType).CurMinute,
5877 : StartMinute,
5878 288 : state.dataEnvrn->DSTIndicator,
5879 288 : ScheduleManager::dayTypeNames[CurDayType]);
5880 288 : op->LHourP = state.dataGlobal->HourOfDay;
5881 288 : op->LStartMin = StartMinute;
5882 288 : op->LEndMin = op->TimeValue.at(thisTimeStepType).CurMinute;
5883 : }
5884 288 : TimePrint = false;
5885 : }
5886 :
5887 279264 : WriteNumericData(state, iVar.ReportID, iVar.ReportIDChr, iVar.TSValue);
5888 279264 : ++state.dataGlobal->StdOutputRecordCount;
5889 :
5890 279264 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
5891 0 : state.dataResultsFramework->resultsFramework->RITimestepTSData.pushVariableValue(iVar.ReportID, iVar.TSValue);
5892 : }
5893 : }
5894 666144 : iVar.TSValue = 0.0;
5895 666144 : iVar.thisTSStored = false;
5896 : } // Number of I Variables
5897 : } // Index Type (Zone or HVAC)
5898 :
5899 299088 : UpdateMeters(state, MDHM);
5900 :
5901 299088 : ReportTSMeters(state, StartMinute, op->TimeValue.at(TimeStepType::Zone).CurMinute, TimePrint, TimePrint);
5902 :
5903 : } // TimeStep Block
5904 :
5905 : // Hour Block
5906 299088 : if (state.dataGlobal->EndHourFlag) {
5907 57768 : if (op->TrackingHourlyVariables) {
5908 40272 : int CurDayType = state.dataEnvrn->DayOfWeek;
5909 40272 : if (state.dataEnvrn->HolidayIndex > 0) {
5910 22584 : CurDayType = state.dataEnvrn->HolidayIndex;
5911 : }
5912 322176 : WriteTimeStampFormatData(state,
5913 : state.files.eso,
5914 : ReportingFrequency::Hourly,
5915 40272 : op->TimeStepStampReportNbr,
5916 40272 : op->TimeStepStampReportChr,
5917 40272 : state.dataGlobal->DayOfSimChr,
5918 : true,
5919 40272 : state.dataEnvrn->Month,
5920 40272 : state.dataEnvrn->DayOfMonth,
5921 40272 : state.dataGlobal->HourOfDay,
5922 : _,
5923 : _,
5924 40272 : state.dataEnvrn->DSTIndicator,
5925 40272 : ScheduleManager::dayTypeNames[CurDayType]);
5926 40272 : TimePrint = false;
5927 : }
5928 :
5929 57768 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
5930 336 : if (!state.dataResultsFramework->resultsFramework->RIHourlyTSData.rVariablesScanned()) {
5931 21 : state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
5932 14 : ReportingFrequency::Hourly, op->RVariableTypes, op->NumOfRVariable);
5933 : }
5934 336 : if (!state.dataResultsFramework->resultsFramework->RIHourlyTSData.iVariablesScanned()) {
5935 21 : state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
5936 14 : ReportingFrequency::Hourly, op->IVariableTypes, op->NumOfIVariable);
5937 : }
5938 1344 : state.dataResultsFramework->resultsFramework->RIHourlyTSData.newRow(
5939 1008 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
5940 : }
5941 :
5942 173304 : for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
5943 115536 : op->TimeValue.at(thisTimeStepType).CurMinute = 0.0;
5944 23999904 : for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
5945 23884368 : if (op->RVariableTypes(Loop).timeStepType != thisTimeStepType) continue;
5946 11942184 : auto &rVar(op->RVariableTypes(Loop).VarPtr);
5947 : // ReportNow=.TRUE.
5948 : // IF (RVar%SchedPtr > 0) &
5949 : // ReportNow=(GetCurrentScheduleValue(state, RVar%SchedPtr) /= 0.0) !SetReportNow(RVar%SchedPtr)
5950 :
5951 : // IF (ReportNow) THEN
5952 11942184 : if (rVar.tsStored) {
5953 5132774 : if (rVar.storeType == StoreType::Averaged) {
5954 4602854 : rVar.Value /= double(rVar.thisTSCount);
5955 : }
5956 5132774 : if (rVar.Report && rVar.frequency == ReportingFrequency::Hourly && rVar.Stored) {
5957 2703140 : WriteNumericData(state, rVar.ReportID, rVar.ReportIDChr, rVar.Value);
5958 2703140 : ++state.dataGlobal->StdOutputRecordCount;
5959 2703140 : rVar.Stored = false;
5960 : // add time series value for hourly to data store
5961 2703140 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
5962 14556 : state.dataResultsFramework->resultsFramework->RIHourlyTSData.pushVariableValue(rVar.ReportID, rVar.Value);
5963 : }
5964 : }
5965 5132774 : rVar.StoreValue += rVar.Value;
5966 5132774 : ++rVar.NumStored;
5967 : }
5968 11942184 : rVar.tsStored = false;
5969 11942184 : rVar.thisTSStored = false;
5970 11942184 : rVar.thisTSCount = 0;
5971 11942184 : rVar.Value = 0.0;
5972 : } // Number of R Variables
5973 :
5974 562944 : for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
5975 447408 : if (op->IVariableTypes(Loop).timeStepType != thisTimeStepType) continue;
5976 223704 : auto &iVar(op->IVariableTypes(Loop).VarPtr);
5977 : // ReportNow=.TRUE.
5978 : // IF (IVar%SchedPtr > 0) &
5979 : // ReportNow=(GetCurrentScheduleValue(state, IVar%SchedPtr) /= 0.0) !SetReportNow(IVar%SchedPtr)
5980 : // IF (ReportNow) THEN
5981 223704 : if (iVar.tsStored) {
5982 116232 : if (iVar.storeType == StoreType::Averaged) {
5983 106872 : iVar.Value /= double(iVar.thisTSCount);
5984 : }
5985 116232 : if (iVar.Report && iVar.frequency == ReportingFrequency::Hourly && iVar.Stored) {
5986 51336 : WriteNumericData(state, iVar.ReportID, iVar.ReportIDChr, iVar.Value);
5987 51336 : ++state.dataGlobal->StdOutputRecordCount;
5988 51336 : iVar.Stored = false;
5989 51336 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
5990 1152 : state.dataResultsFramework->resultsFramework->RIHourlyTSData.pushVariableValue(iVar.ReportID, iVar.Value);
5991 : }
5992 : }
5993 116232 : iVar.StoreValue += iVar.Value;
5994 116232 : ++iVar.NumStored;
5995 : }
5996 223704 : iVar.tsStored = false;
5997 223704 : iVar.thisTSStored = false;
5998 223704 : iVar.thisTSCount = 0;
5999 223704 : iVar.Value = 0.0;
6000 : } // Number of I Variables
6001 : } // thisTimeStepType (Zone or HVAC)
6002 :
6003 57768 : ReportHRMeters(state, TimePrint);
6004 :
6005 : } // Hour Block
6006 :
6007 299088 : if (!state.dataGlobal->EndHourFlag) return;
6008 :
6009 : // Day Block
6010 57768 : if (state.dataGlobal->EndDayFlag) {
6011 2407 : if (op->TrackingDailyVariables) {
6012 94 : int CurDayType = state.dataEnvrn->DayOfWeek;
6013 94 : if (state.dataEnvrn->HolidayIndex > 0) {
6014 90 : CurDayType = state.dataEnvrn->HolidayIndex;
6015 : }
6016 658 : WriteTimeStampFormatData(state,
6017 : state.files.eso,
6018 : ReportingFrequency::Daily,
6019 94 : op->DailyStampReportNbr,
6020 94 : op->DailyStampReportChr,
6021 94 : state.dataGlobal->DayOfSimChr,
6022 : true,
6023 94 : state.dataEnvrn->Month,
6024 94 : state.dataEnvrn->DayOfMonth,
6025 : _,
6026 : _,
6027 : _,
6028 94 : state.dataEnvrn->DSTIndicator,
6029 94 : ScheduleManager::dayTypeNames[CurDayType]);
6030 94 : TimePrint = false;
6031 : }
6032 2407 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
6033 14 : if (!state.dataResultsFramework->resultsFramework->RIDailyTSData.rVariablesScanned()) {
6034 21 : state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
6035 14 : ReportingFrequency::Daily, op->RVariableTypes, op->NumOfRVariable);
6036 : }
6037 14 : if (!state.dataResultsFramework->resultsFramework->RIDailyTSData.iVariablesScanned()) {
6038 21 : state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
6039 14 : ReportingFrequency::Daily, op->IVariableTypes, op->NumOfIVariable);
6040 : }
6041 56 : state.dataResultsFramework->resultsFramework->RIDailyTSData.newRow(
6042 42 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
6043 : }
6044 :
6045 2407 : op->NumHoursInMonth += 24;
6046 7221 : for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
6047 999996 : for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
6048 995182 : if (op->RVariableTypes(Loop).timeStepType == thisTimeStepType) {
6049 497591 : WriteRealVariableOutput(state, op->RVariableTypes(Loop).VarPtr, ReportingFrequency::Daily);
6050 : }
6051 : } // Number of R Variables
6052 :
6053 23456 : for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
6054 18642 : if (op->IVariableTypes(Loop).timeStepType == thisTimeStepType) {
6055 9321 : WriteIntegerVariableOutput(state, op->IVariableTypes(Loop).VarPtr, ReportingFrequency::Daily);
6056 : }
6057 : } // Number of I Variables
6058 : } // thisTimeStepType (Zone or HVAC)
6059 :
6060 2407 : ReportDYMeters(state, TimePrint);
6061 :
6062 : } // Day Block
6063 :
6064 : // Only continue if EndDayFlag is set
6065 57768 : if (!state.dataGlobal->EndDayFlag) return;
6066 :
6067 : // Month Block
6068 2407 : if (state.dataEnvrn->EndMonthFlag || state.dataGlobal->EndEnvrnFlag) {
6069 1669 : if (op->TrackingMonthlyVariables) {
6070 1135 : WriteTimeStampFormatData(state,
6071 : state.files.eso,
6072 : ReportingFrequency::Monthly,
6073 227 : op->MonthlyStampReportNbr,
6074 227 : op->MonthlyStampReportChr,
6075 227 : state.dataGlobal->DayOfSimChr,
6076 : true,
6077 227 : state.dataEnvrn->Month);
6078 227 : TimePrint = false;
6079 : }
6080 :
6081 1669 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
6082 14 : if (!state.dataResultsFramework->resultsFramework->RIMonthlyTSData.rVariablesScanned()) {
6083 21 : state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
6084 14 : ReportingFrequency::Monthly, op->RVariableTypes, op->NumOfRVariable);
6085 : }
6086 14 : if (!state.dataResultsFramework->resultsFramework->RIMonthlyTSData.iVariablesScanned()) {
6087 21 : state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
6088 14 : ReportingFrequency::Monthly, op->IVariableTypes, op->NumOfIVariable);
6089 : }
6090 56 : state.dataResultsFramework->resultsFramework->RIMonthlyTSData.newRow(
6091 42 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
6092 : }
6093 :
6094 1669 : op->NumHoursInSim += op->NumHoursInMonth;
6095 1669 : state.dataEnvrn->EndMonthFlag = false;
6096 5007 : for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
6097 812434 : for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
6098 809096 : if (op->RVariableTypes(Loop).timeStepType == thisTimeStepType) {
6099 404548 : WriteRealVariableOutput(state, op->RVariableTypes(Loop).VarPtr, ReportingFrequency::Monthly);
6100 : }
6101 : } // Number of R Variables
6102 :
6103 20518 : for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
6104 17180 : if (op->IVariableTypes(Loop).timeStepType == thisTimeStepType) {
6105 8590 : WriteIntegerVariableOutput(state, op->IVariableTypes(Loop).VarPtr, ReportingFrequency::Monthly);
6106 : }
6107 : } // Number of I Variables
6108 : } // thisTimeStepType (Zone, HVAC)
6109 :
6110 1669 : ReportMNMeters(state, TimePrint);
6111 :
6112 1669 : op->NumHoursInMonth = 0;
6113 : } // Month Block
6114 :
6115 : // Sim/Environment Block
6116 2407 : if (state.dataGlobal->EndEnvrnFlag) {
6117 1645 : if (op->TrackingRunPeriodVariables) {
6118 340 : WriteTimeStampFormatData(state,
6119 : state.files.eso,
6120 : ReportingFrequency::Simulation,
6121 85 : op->RunPeriodStampReportNbr,
6122 85 : op->RunPeriodStampReportChr,
6123 85 : state.dataGlobal->DayOfSimChr,
6124 : true);
6125 85 : TimePrint = false;
6126 : }
6127 :
6128 1645 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
6129 14 : if (!state.dataResultsFramework->resultsFramework->RIRunPeriodTSData.rVariablesScanned()) {
6130 21 : state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
6131 14 : ReportingFrequency::Simulation, op->RVariableTypes, op->NumOfRVariable);
6132 : }
6133 14 : if (!state.dataResultsFramework->resultsFramework->RIRunPeriodTSData.iVariablesScanned()) {
6134 21 : state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
6135 14 : ReportingFrequency::Simulation, op->IVariableTypes, op->NumOfIVariable);
6136 : }
6137 56 : state.dataResultsFramework->resultsFramework->RIRunPeriodTSData.newRow(
6138 42 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
6139 : }
6140 4935 : for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
6141 806498 : for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
6142 803208 : if (op->RVariableTypes(Loop).timeStepType == thisTimeStepType) {
6143 401604 : WriteRealVariableOutput(state, op->RVariableTypes(Loop).VarPtr, ReportingFrequency::Simulation);
6144 : }
6145 : } // Number of R Variables
6146 :
6147 20422 : for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
6148 17132 : if (op->IVariableTypes(Loop).timeStepType == thisTimeStepType) {
6149 8566 : WriteIntegerVariableOutput(state, op->IVariableTypes(Loop).VarPtr, ReportingFrequency::Simulation);
6150 : }
6151 : } // Number of I Variables
6152 : } // thisTimeStepType (Zone, HVAC)
6153 :
6154 1645 : ReportSMMeters(state, TimePrint);
6155 :
6156 1645 : op->NumHoursInSim = 0;
6157 : }
6158 :
6159 : // Yearly Block
6160 2407 : if (state.dataEnvrn->EndYearFlag) {
6161 2 : if (op->TrackingYearlyVariables) {
6162 0 : WriteYearlyTimeStamp(state, state.files.eso, op->YearlyStampReportChr, state.dataGlobal->CalendarYearChr, true);
6163 0 : TimePrint = false;
6164 : }
6165 2 : if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
6166 0 : if (!state.dataResultsFramework->resultsFramework->RIYearlyTSData.rVariablesScanned()) {
6167 0 : state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
6168 0 : ReportingFrequency::Yearly, op->RVariableTypes, op->NumOfRVariable);
6169 : }
6170 0 : if (!state.dataResultsFramework->resultsFramework->RIYearlyTSData.iVariablesScanned()) {
6171 0 : state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
6172 0 : ReportingFrequency::Yearly, op->IVariableTypes, op->NumOfIVariable);
6173 : }
6174 0 : state.dataResultsFramework->resultsFramework->RIYearlyTSData.newRow(
6175 0 : state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
6176 : }
6177 6 : for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
6178 516 : for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
6179 512 : if (op->RVariableTypes(Loop).timeStepType == thisTimeStepType) {
6180 256 : WriteRealVariableOutput(state, op->RVariableTypes(Loop).VarPtr, ReportingFrequency::Yearly);
6181 : }
6182 : } // Number of R Variables
6183 :
6184 8 : for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
6185 4 : if (op->IVariableTypes(Loop).timeStepType == thisTimeStepType) {
6186 2 : WriteIntegerVariableOutput(state, op->IVariableTypes(Loop).VarPtr, ReportingFrequency::Yearly);
6187 : }
6188 : } // Number of I Variables
6189 : } // thisTimeStepType (Zone, HVAC)
6190 :
6191 2 : ReportYRMeters(state, TimePrint);
6192 :
6193 2 : state.dataGlobal->CalendarYear += 1;
6194 2 : state.dataGlobal->CalendarYearChr = fmt::to_string(state.dataGlobal->CalendarYear);
6195 : }
6196 : }
6197 :
6198 1296238 : void AssignReportNumber(EnergyPlusData &state, int &ReportNumber)
6199 : {
6200 :
6201 : // SUBROUTINE INFORMATION:
6202 : // AUTHOR Linda K. Lawrie
6203 : // DATE WRITTEN December 1997
6204 : // MODIFIED na
6205 : // RE-ENGINEERED na
6206 :
6207 : // PURPOSE OF THIS SUBROUTINE:
6208 : // This subroutine returns the next report number available. The report number
6209 : // is used in output reports as a key.
6210 :
6211 : // METHODOLOGY EMPLOYED:
6212 : // Use internal ReportNumberCounter to maintain current report numbers.
6213 :
6214 : // REFERENCES:
6215 : // na
6216 :
6217 : // USE STATEMENTS:
6218 : using namespace OutputProcessor;
6219 :
6220 : // Locals
6221 : // SUBROUTINE ARGUMENT DEFINITIONS:
6222 :
6223 : // FUNCTION PARAMETER DEFINITIONS:
6224 : // na
6225 :
6226 : // INTERFACE BLOCK SPECIFICATIONS:
6227 : // na
6228 :
6229 : // DERIVED TYPE DEFINITIONS:
6230 : // na
6231 :
6232 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
6233 :
6234 1296238 : ++state.dataOutputProcessor->ReportNumberCounter;
6235 1296238 : ReportNumber = state.dataOutputProcessor->ReportNumberCounter;
6236 1296238 : }
6237 :
6238 769 : void GenOutputVariablesAuditReport(EnergyPlusData &state)
6239 : {
6240 :
6241 : // SUBROUTINE INFORMATION:
6242 : // AUTHOR Linda Lawrie
6243 : // DATE WRITTEN February 2000
6244 : // MODIFIED na
6245 : // RE-ENGINEERED na
6246 :
6247 : // PURPOSE OF THIS SUBROUTINE:
6248 : // This subroutine reports (to the .err file) any report variables
6249 : // which were requested but not "setup" during the run. These will
6250 : // either be items that were not used in the IDF file or misspellings
6251 : // of report variable names.
6252 :
6253 : // METHODOLOGY EMPLOYED:
6254 : // Use flagged data structure in OutputProcessor.
6255 :
6256 : // Using/Aliasing
6257 : using namespace OutputProcessor;
6258 :
6259 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6260 : int Loop;
6261 769 : auto &op(state.dataOutputProcessor);
6262 : std::map<ReportingFrequency, std::string> reportFrequency({{ReportingFrequency::EachCall, "Detailed"},
6263 : {ReportingFrequency::TimeStep, "TimeStep"},
6264 : {ReportingFrequency::Hourly, "Hourly"},
6265 : {ReportingFrequency::Daily, "Daily"},
6266 : {ReportingFrequency::Monthly, "Monthly"},
6267 1538 : {ReportingFrequency::Yearly, "Annual"}});
6268 :
6269 21119 : for (Loop = 1; Loop <= op->NumOfReqVariables; ++Loop) {
6270 20350 : if (op->ReqRepVars(Loop).Used) continue;
6271 77 : if (op->ReqRepVars(Loop).Key.empty()) op->ReqRepVars(Loop).Key = "*";
6272 77 : if (has(op->ReqRepVars(Loop).VarName, "OPAQUE SURFACE INSIDE FACE CONDUCTION") && !state.dataGlobal->DisplayAdvancedReportVariables &&
6273 0 : !state.dataOutputProcessor->OpaqSurfWarned) {
6274 0 : ShowWarningError(state, R"(Variables containing "Opaque Surface Inside Face Conduction" are now "advanced" variables.)");
6275 0 : ShowContinueError(state, "You must enter the \"Output:Diagnostics,DisplayAdvancedReportVariables;\" statement to view.");
6276 0 : ShowContinueError(state, "First, though, read cautionary statements in the \"InputOutputReference\" document.");
6277 0 : state.dataOutputProcessor->OpaqSurfWarned = true;
6278 : }
6279 77 : if (!state.dataOutputProcessor->Rept) {
6280 19 : ShowWarningError(state, "The following Report Variables were requested but not generated -- check.rdd file");
6281 19 : ShowContinueError(state, "Either the IDF did not contain these elements, the variable name is misspelled,");
6282 19 : ShowContinueError(state,
6283 : "or the requested variable is an advanced output which requires Output : Diagnostics, DisplayAdvancedReportVariables;");
6284 19 : state.dataOutputProcessor->Rept = true;
6285 : }
6286 231 : ShowMessage(state,
6287 154 : "Key=" + op->ReqRepVars(Loop).Key + ", VarName=" + op->ReqRepVars(Loop).VarName +
6288 231 : ", Frequency=" + reportFrequency[op->ReqRepVars(Loop).frequency]);
6289 : }
6290 769 : }
6291 :
6292 769 : void UpdateMeterReporting(EnergyPlusData &state)
6293 : {
6294 :
6295 : // SUBROUTINE INFORMATION:
6296 : // AUTHOR Linda Lawrie
6297 : // DATE WRITTEN January 2001
6298 : // MODIFIED February 2007 -- add cumulative meter reporting
6299 : // January 2012 -- add predefined tabular meter reporting
6300 : // RE-ENGINEERED na
6301 :
6302 : // PURPOSE OF THIS SUBROUTINE:
6303 : // This subroutine is called at the end of the first HVAC iteration and
6304 : // sets up the reporting for the Energy Meters. It also may show a fatal error
6305 : // if errors occurred during initial SetupOutputVariable processing. It "gets"
6306 : // the Report Meter input:
6307 : // Report Meter,
6308 : // \memo Meters requested here show up on eplusout.eso and eplusout.mtr
6309 : // A1 , \field Meter_Name
6310 : // \required-field
6311 : // \note Form is EnergyUseType:..., e.g. Electricity:* for all Electricity meters
6312 : // \note or EndUse:..., e.g. InteriorLights:* for all interior lights
6313 : // \note Report MeterFileOnly puts results on the eplusout.mtr file only
6314 : // A2 ; \field Reporting_Frequency
6315 : // \type choice
6316 : // \key timestep
6317 : // \note timestep refers to the zone timestep/timestep in hour value
6318 : // \note runperiod, environment, and annual are the same
6319 : // \key hourly
6320 : // \key daily
6321 : // \key monthly
6322 : // \key runperiod
6323 : // \key environment
6324 : // \key annual
6325 : // \note runperiod, environment, and annual are synonymous
6326 : // Report MeterFileOnly,
6327 : // \memo same reporting as Report Meter -- goes to eplusout.mtr only
6328 : // A1 , \field Meter_Name
6329 : // \required-field
6330 : // \note Form is EnergyUseType:..., e.g. Electricity:* for all Electricity meters
6331 : // \note or EndUse:..., e.g. InteriorLights:* for all interior lights
6332 : // \note Report MeterFileOnly puts results on the eplusout.mtr file only
6333 : // A2 ; \field Reporting_Frequency
6334 : // \type choice
6335 : // \key timestep
6336 : // \note timestep refers to the zone timestep/timestep in hour value
6337 : // \note runperiod, environment, and annual are the same
6338 : // \key hourly
6339 : // \key daily
6340 : // \key monthly
6341 : // \key runperiod
6342 : // \key environment
6343 : // \key annual
6344 : // \note runperiod, environment, and annual are synonymous
6345 :
6346 : // Using/Aliasing
6347 : using namespace OutputProcessor;
6348 :
6349 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6350 : int Loop;
6351 1538 : Array1D_string Alphas(2);
6352 1538 : Array1D<Real64> Numbers(1);
6353 : int NumAlpha;
6354 : int NumNumbers;
6355 : int IOStat;
6356 : int NumReqMeters;
6357 : int NumReqMeterFOs;
6358 :
6359 769 : bool ErrorsFound(false); // If errors detected in input
6360 769 : auto &op(state.dataOutputProcessor);
6361 :
6362 769 : GetCustomMeterInput(state, ErrorsFound);
6363 769 : if (ErrorsFound) {
6364 0 : op->ErrorsLogged = true;
6365 : }
6366 :
6367 : // Helper lambda to locate a meter index from its name. Returns a negative value if not found
6368 : auto setupMeterFromMeterName =
6369 26576 : [&state](std::string &name, std::string const &freqString, bool MeterFileOnlyIndicator, bool CumulativeIndicator) -> bool {
6370 6635 : bool result = false;
6371 :
6372 6635 : auto varnameLen = index(name, '[');
6373 6635 : if (varnameLen != std::string::npos) {
6374 0 : name.erase(varnameLen);
6375 : }
6376 :
6377 6635 : auto &op(state.dataOutputProcessor);
6378 :
6379 6635 : std::string::size_type wildCardPosition = index(name, '*');
6380 :
6381 6635 : if (wildCardPosition == std::string::npos) {
6382 6611 : int meterIndex = UtilityRoutines::FindItem(name, op->EnergyMeters);
6383 6611 : if (meterIndex > 0) {
6384 6549 : ReportingFrequency ReportFreq = determineFrequency(state, freqString);
6385 13098 : SetInitialMeterReportingAndOutputNames(state, meterIndex, MeterFileOnlyIndicator, ReportFreq, CumulativeIndicator);
6386 6549 : result = true;
6387 : }
6388 : } else { // Wildcard input
6389 24 : ReportingFrequency ReportFreq = determineFrequency(state, freqString);
6390 2399 : for (int meterIndex = 1; meterIndex <= op->NumEnergyMeters; ++meterIndex) {
6391 2375 : if (UtilityRoutines::SameString(op->EnergyMeters(meterIndex).Name.substr(0, wildCardPosition), name.substr(0, wildCardPosition))) {
6392 368 : SetInitialMeterReportingAndOutputNames(state, meterIndex, MeterFileOnlyIndicator, ReportFreq, CumulativeIndicator);
6393 184 : result = true;
6394 : }
6395 : }
6396 : }
6397 :
6398 6635 : return result;
6399 769 : };
6400 :
6401 769 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
6402 769 : cCurrentModuleObject = "Output:Meter";
6403 769 : NumReqMeters = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
6404 :
6405 1586 : for (Loop = 1; Loop <= NumReqMeters; ++Loop) {
6406 :
6407 4085 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
6408 : cCurrentModuleObject,
6409 : Loop,
6410 : Alphas,
6411 : NumAlpha,
6412 : Numbers,
6413 : NumNumbers,
6414 : IOStat,
6415 817 : state.dataIPShortCut->lNumericFieldBlanks,
6416 817 : state.dataIPShortCut->lAlphaFieldBlanks,
6417 817 : state.dataIPShortCut->cAlphaFieldNames,
6418 817 : state.dataIPShortCut->cNumericFieldNames);
6419 :
6420 817 : bool meterFileOnlyIndicator = false;
6421 817 : bool cumulativeIndicator = false;
6422 817 : if (!setupMeterFromMeterName(Alphas(1), Alphas(2), meterFileOnlyIndicator, cumulativeIndicator)) {
6423 48 : ShowWarningError(state,
6424 32 : cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(1) + "=\"" + Alphas(1) + "\" - not found.");
6425 : }
6426 : }
6427 :
6428 769 : cCurrentModuleObject = "Output:Meter:MeterFileOnly";
6429 769 : NumReqMeterFOs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
6430 6582 : for (Loop = 1; Loop <= NumReqMeterFOs; ++Loop) {
6431 :
6432 29065 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
6433 : cCurrentModuleObject,
6434 : Loop,
6435 : Alphas,
6436 : NumAlpha,
6437 : Numbers,
6438 : NumNumbers,
6439 : IOStat,
6440 5813 : state.dataIPShortCut->lNumericFieldBlanks,
6441 5813 : state.dataIPShortCut->lAlphaFieldBlanks,
6442 5813 : state.dataIPShortCut->cAlphaFieldNames,
6443 5813 : state.dataIPShortCut->cNumericFieldNames);
6444 :
6445 5813 : bool meterFileOnlyIndicator = true;
6446 5813 : bool cumulativeIndicator = false;
6447 5813 : if (!setupMeterFromMeterName(Alphas(1), Alphas(2), meterFileOnlyIndicator, cumulativeIndicator)) {
6448 138 : ShowWarningError(state,
6449 92 : cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(1) + "=\"" + Alphas(1) + "\" - not found.");
6450 : }
6451 : }
6452 :
6453 769 : cCurrentModuleObject = "Output:Meter:Cumulative";
6454 769 : NumReqMeters = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
6455 :
6456 770 : for (Loop = 1; Loop <= NumReqMeters; ++Loop) {
6457 :
6458 5 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
6459 : cCurrentModuleObject,
6460 : Loop,
6461 : Alphas,
6462 : NumAlpha,
6463 : Numbers,
6464 : NumNumbers,
6465 : IOStat,
6466 1 : state.dataIPShortCut->lNumericFieldBlanks,
6467 1 : state.dataIPShortCut->lAlphaFieldBlanks,
6468 1 : state.dataIPShortCut->cAlphaFieldNames,
6469 1 : state.dataIPShortCut->cNumericFieldNames);
6470 :
6471 1 : bool meterFileOnlyIndicator = false;
6472 1 : bool cumulativeIndicator = true;
6473 1 : if (!setupMeterFromMeterName(Alphas(1), Alphas(2), meterFileOnlyIndicator, cumulativeIndicator)) {
6474 0 : ShowWarningError(state,
6475 0 : cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(1) + "=\"" + Alphas(1) + "\" - not found.");
6476 : }
6477 : }
6478 :
6479 769 : cCurrentModuleObject = "Output:Meter:Cumulative:MeterFileOnly";
6480 769 : NumReqMeterFOs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
6481 773 : for (Loop = 1; Loop <= NumReqMeterFOs; ++Loop) {
6482 :
6483 20 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
6484 : cCurrentModuleObject,
6485 : Loop,
6486 : Alphas,
6487 : NumAlpha,
6488 : Numbers,
6489 : NumNumbers,
6490 : IOStat,
6491 4 : state.dataIPShortCut->lNumericFieldBlanks,
6492 4 : state.dataIPShortCut->lAlphaFieldBlanks,
6493 4 : state.dataIPShortCut->cAlphaFieldNames,
6494 4 : state.dataIPShortCut->cNumericFieldNames);
6495 :
6496 4 : bool meterFileOnlyIndicator = true;
6497 4 : bool cumulativeIndicator = true;
6498 4 : if (!setupMeterFromMeterName(Alphas(1), Alphas(2), meterFileOnlyIndicator, cumulativeIndicator)) {
6499 0 : ShowWarningError(state,
6500 0 : cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(1) + "=\"" + Alphas(1) + "\" - not found.");
6501 : }
6502 : }
6503 :
6504 769 : ReportMeterDetails(state);
6505 :
6506 769 : if (op->ErrorsLogged) {
6507 0 : ShowFatalError(state, "UpdateMeterReporting: Previous Meter Specification errors cause program termination.");
6508 : }
6509 :
6510 769 : op->MeterValue.dimension(op->NumEnergyMeters, 0.0);
6511 769 : }
6512 :
6513 6733 : void SetInitialMeterReportingAndOutputNames(EnergyPlusData &state,
6514 : int const WhichMeter, // Which meter number
6515 : bool const MeterFileOnlyIndicator, // true if this is a meter file only reporting
6516 : OutputProcessor::ReportingFrequency const FrequencyIndicator, // at what frequency is the meter reported
6517 : bool const CumulativeIndicator // true if this is a Cumulative meter reporting
6518 : )
6519 : {
6520 :
6521 : // SUBROUTINE INFORMATION:
6522 : // AUTHOR Linda Lawrie
6523 : // DATE WRITTEN February 2007
6524 : // MODIFIED na
6525 : // RE-ENGINEERED na
6526 :
6527 : // PURPOSE OF THIS SUBROUTINE:
6528 : // Set values and output initial names to output files.
6529 :
6530 : // Using/Aliasing
6531 : using namespace OutputProcessor;
6532 :
6533 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6534 : int indexGroupKey;
6535 13466 : std::string indexGroup;
6536 6733 : auto &op(state.dataOutputProcessor);
6537 :
6538 6733 : if ((FrequencyIndicator == ReportingFrequency::EachCall) ||
6539 : (FrequencyIndicator == ReportingFrequency::TimeStep)) { // roll "detailed" into TimeStep
6540 100 : if (!CumulativeIndicator) {
6541 50 : if (MeterFileOnlyIndicator) {
6542 8 : if (op->EnergyMeters(WhichMeter).RptTS) {
6543 0 : ShowWarningError(state,
6544 0 : "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
6545 0 : R"(" (TimeStep), already on "Output:Meter". Will report to both )" +
6546 0 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6547 : }
6548 : }
6549 50 : if (!op->EnergyMeters(WhichMeter).RptTS) {
6550 50 : op->EnergyMeters(WhichMeter).RptTS = true;
6551 50 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptTSFO = true;
6552 50 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6553 50 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6554 250 : WriteMeterDictionaryItem(state,
6555 : FrequencyIndicator,
6556 : StoreType::Summed,
6557 50 : op->EnergyMeters(WhichMeter).TSRptNum,
6558 : indexGroupKey,
6559 : indexGroup,
6560 50 : op->EnergyMeters(WhichMeter).TSRptNumChr,
6561 50 : op->EnergyMeters(WhichMeter).Name,
6562 50 : op->EnergyMeters(WhichMeter).Units,
6563 : false,
6564 : MeterFileOnlyIndicator);
6565 : }
6566 : } else {
6567 0 : if (MeterFileOnlyIndicator) {
6568 0 : if (op->EnergyMeters(WhichMeter).RptAccTS) {
6569 0 : ShowWarningError(state,
6570 0 : "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
6571 0 : R"(" (TimeStep), already on "Output:Meter". Will report to both )" +
6572 0 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6573 : }
6574 : }
6575 0 : if (!op->EnergyMeters(WhichMeter).RptAccTS) {
6576 0 : op->EnergyMeters(WhichMeter).RptAccTS = true;
6577 0 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccTSFO = true;
6578 0 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6579 0 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6580 0 : WriteMeterDictionaryItem(state,
6581 : FrequencyIndicator,
6582 : StoreType::Summed,
6583 0 : op->EnergyMeters(WhichMeter).TSAccRptNum,
6584 : indexGroupKey,
6585 : indexGroup,
6586 0 : fmt::to_string(op->EnergyMeters(WhichMeter).TSAccRptNum),
6587 0 : op->EnergyMeters(WhichMeter).Name,
6588 0 : op->EnergyMeters(WhichMeter).Units,
6589 : true,
6590 : MeterFileOnlyIndicator);
6591 : }
6592 : }
6593 6683 : } else if (FrequencyIndicator == ReportingFrequency::Hourly) {
6594 702 : if (!CumulativeIndicator) {
6595 702 : if (MeterFileOnlyIndicator) {
6596 151 : if (op->EnergyMeters(WhichMeter).RptHR) {
6597 9 : ShowWarningError(state,
6598 6 : "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
6599 6 : R"(" (Hourly), already on "Output:Meter". Will report to both )" +
6600 12 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6601 : }
6602 : }
6603 702 : if (!op->EnergyMeters(WhichMeter).RptHR) {
6604 699 : op->EnergyMeters(WhichMeter).RptHR = true;
6605 699 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptHRFO = true;
6606 699 : if (!MeterFileOnlyIndicator) op->TrackingHourlyVariables = true;
6607 699 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6608 699 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6609 3495 : WriteMeterDictionaryItem(state,
6610 : FrequencyIndicator,
6611 : StoreType::Summed,
6612 699 : op->EnergyMeters(WhichMeter).HRRptNum,
6613 : indexGroupKey,
6614 : indexGroup,
6615 699 : op->EnergyMeters(WhichMeter).HRRptNumChr,
6616 699 : op->EnergyMeters(WhichMeter).Name,
6617 699 : op->EnergyMeters(WhichMeter).Units,
6618 : false,
6619 : MeterFileOnlyIndicator);
6620 : }
6621 : } else {
6622 0 : if (MeterFileOnlyIndicator) {
6623 0 : if (op->EnergyMeters(WhichMeter).RptAccHR) {
6624 0 : ShowWarningError(state,
6625 0 : "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
6626 0 : R"(" (Hourly), already on "Output:Meter". Will report to both )" +
6627 0 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6628 : }
6629 : }
6630 0 : if (!op->EnergyMeters(WhichMeter).RptAccHR) {
6631 0 : op->EnergyMeters(WhichMeter).RptAccHR = true;
6632 0 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccHRFO = true;
6633 0 : if (!MeterFileOnlyIndicator) op->TrackingHourlyVariables = true;
6634 0 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6635 0 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6636 0 : WriteMeterDictionaryItem(state,
6637 : FrequencyIndicator,
6638 : StoreType::Summed,
6639 0 : op->EnergyMeters(WhichMeter).HRAccRptNum,
6640 : indexGroupKey,
6641 : indexGroup,
6642 0 : fmt::to_string(op->EnergyMeters(WhichMeter).HRAccRptNum),
6643 0 : op->EnergyMeters(WhichMeter).Name,
6644 0 : op->EnergyMeters(WhichMeter).Units,
6645 : true,
6646 : MeterFileOnlyIndicator);
6647 : }
6648 : }
6649 5981 : } else if (FrequencyIndicator == ReportingFrequency::Daily) {
6650 71 : if (!CumulativeIndicator) {
6651 71 : if (MeterFileOnlyIndicator) {
6652 1 : if (op->EnergyMeters(WhichMeter).RptDY) {
6653 0 : ShowWarningError(state,
6654 0 : "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
6655 0 : R"(" (Daily), already on "Output:Meter". Will report to both )" +
6656 0 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6657 : }
6658 : }
6659 71 : if (!op->EnergyMeters(WhichMeter).RptDY) {
6660 71 : op->EnergyMeters(WhichMeter).RptDY = true;
6661 71 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptDYFO = true;
6662 71 : if (!MeterFileOnlyIndicator) op->TrackingDailyVariables = true;
6663 71 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6664 71 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6665 355 : WriteMeterDictionaryItem(state,
6666 : FrequencyIndicator,
6667 : StoreType::Summed,
6668 71 : op->EnergyMeters(WhichMeter).DYRptNum,
6669 : indexGroupKey,
6670 : indexGroup,
6671 71 : op->EnergyMeters(WhichMeter).DYRptNumChr,
6672 71 : op->EnergyMeters(WhichMeter).Name,
6673 71 : op->EnergyMeters(WhichMeter).Units,
6674 : false,
6675 : MeterFileOnlyIndicator);
6676 : }
6677 : } else {
6678 0 : if (MeterFileOnlyIndicator) {
6679 0 : if (op->EnergyMeters(WhichMeter).RptAccDY) {
6680 0 : ShowWarningError(state,
6681 0 : "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
6682 0 : R"(" (Hourly), already on "Output:Meter". Will report to both )" +
6683 0 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6684 : }
6685 : }
6686 0 : if (!op->EnergyMeters(WhichMeter).RptAccDY) {
6687 0 : op->EnergyMeters(WhichMeter).RptAccDY = true;
6688 0 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccDYFO = true;
6689 0 : if (!MeterFileOnlyIndicator) op->TrackingDailyVariables = true;
6690 0 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6691 0 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6692 0 : WriteMeterDictionaryItem(state,
6693 : FrequencyIndicator,
6694 : StoreType::Summed,
6695 0 : op->EnergyMeters(WhichMeter).DYAccRptNum,
6696 : indexGroupKey,
6697 : indexGroup,
6698 0 : fmt::to_string(op->EnergyMeters(WhichMeter).DYAccRptNum),
6699 0 : op->EnergyMeters(WhichMeter).Name,
6700 0 : op->EnergyMeters(WhichMeter).Units,
6701 : true,
6702 : MeterFileOnlyIndicator);
6703 : }
6704 : }
6705 5910 : } else if (FrequencyIndicator == ReportingFrequency::Monthly) {
6706 3003 : if (!CumulativeIndicator) {
6707 2998 : if (MeterFileOnlyIndicator) {
6708 2862 : if (op->EnergyMeters(WhichMeter).RptMN) {
6709 0 : ShowWarningError(state,
6710 0 : "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
6711 0 : R"(" (Monthly), already on "Output:Meter". Will report to both )" +
6712 0 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6713 : }
6714 : }
6715 2998 : if (!op->EnergyMeters(WhichMeter).RptMN) {
6716 2998 : op->EnergyMeters(WhichMeter).RptMN = true;
6717 2998 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptMNFO = true;
6718 2998 : if (!MeterFileOnlyIndicator) op->TrackingMonthlyVariables = true;
6719 2998 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6720 2998 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6721 14990 : WriteMeterDictionaryItem(state,
6722 : FrequencyIndicator,
6723 : StoreType::Summed,
6724 2998 : op->EnergyMeters(WhichMeter).MNRptNum,
6725 : indexGroupKey,
6726 : indexGroup,
6727 2998 : op->EnergyMeters(WhichMeter).MNRptNumChr,
6728 2998 : op->EnergyMeters(WhichMeter).Name,
6729 2998 : op->EnergyMeters(WhichMeter).Units,
6730 : false,
6731 : MeterFileOnlyIndicator);
6732 : }
6733 : } else {
6734 5 : if (MeterFileOnlyIndicator) {
6735 4 : if (op->EnergyMeters(WhichMeter).RptAccMN) {
6736 0 : ShowWarningError(state,
6737 0 : "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
6738 0 : R"(" (Monthly), already on "Output:Meter". Will report to both )" +
6739 0 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6740 : }
6741 : }
6742 5 : if (!op->EnergyMeters(WhichMeter).RptAccMN) {
6743 5 : op->EnergyMeters(WhichMeter).RptAccMN = true;
6744 5 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccMNFO = true;
6745 5 : if (!MeterFileOnlyIndicator) op->TrackingMonthlyVariables = true;
6746 5 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6747 5 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6748 20 : WriteMeterDictionaryItem(state,
6749 : FrequencyIndicator,
6750 : StoreType::Summed,
6751 5 : op->EnergyMeters(WhichMeter).MNAccRptNum,
6752 : indexGroupKey,
6753 : indexGroup,
6754 10 : fmt::to_string(op->EnergyMeters(WhichMeter).MNAccRptNum),
6755 5 : op->EnergyMeters(WhichMeter).Name,
6756 5 : op->EnergyMeters(WhichMeter).Units,
6757 : true,
6758 : MeterFileOnlyIndicator);
6759 : }
6760 : }
6761 2907 : } else if (FrequencyIndicator == ReportingFrequency::Yearly) {
6762 83 : if (!CumulativeIndicator) {
6763 83 : if (MeterFileOnlyIndicator) {
6764 83 : if (op->EnergyMeters(WhichMeter).RptYR) {
6765 0 : ShowWarningError(state,
6766 0 : "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
6767 0 : R"(" (Annual), already on "Output:Meter". Will report to both )" +
6768 0 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6769 : }
6770 : }
6771 83 : if (!op->EnergyMeters(WhichMeter).RptYR) {
6772 83 : op->EnergyMeters(WhichMeter).RptYR = true;
6773 83 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptYRFO = true;
6774 83 : if (!MeterFileOnlyIndicator) op->TrackingYearlyVariables = true;
6775 83 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6776 83 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6777 415 : WriteMeterDictionaryItem(state,
6778 : FrequencyIndicator,
6779 : StoreType::Summed,
6780 83 : op->EnergyMeters(WhichMeter).YRRptNum,
6781 : indexGroupKey,
6782 : indexGroup,
6783 83 : op->EnergyMeters(WhichMeter).YRRptNumChr,
6784 83 : op->EnergyMeters(WhichMeter).Name,
6785 83 : op->EnergyMeters(WhichMeter).Units,
6786 : false,
6787 : MeterFileOnlyIndicator);
6788 : }
6789 : } else {
6790 0 : if (MeterFileOnlyIndicator) {
6791 0 : if (op->EnergyMeters(WhichMeter).RptAccYR) {
6792 0 : ShowWarningError(state,
6793 0 : "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
6794 0 : R"(" (Annual), already on "Output:Meter". Will report to both )" +
6795 0 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6796 : }
6797 : }
6798 0 : if (!op->EnergyMeters(WhichMeter).RptAccYR) {
6799 0 : op->EnergyMeters(WhichMeter).RptAccYR = true;
6800 0 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccYRFO = true;
6801 0 : if (!MeterFileOnlyIndicator) op->TrackingYearlyVariables = true;
6802 0 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6803 0 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6804 0 : WriteMeterDictionaryItem(state,
6805 : FrequencyIndicator,
6806 : StoreType::Summed,
6807 0 : op->EnergyMeters(WhichMeter).YRAccRptNum,
6808 : indexGroupKey,
6809 : indexGroup,
6810 0 : fmt::to_string(op->EnergyMeters(WhichMeter).YRAccRptNum),
6811 0 : op->EnergyMeters(WhichMeter).Name,
6812 0 : op->EnergyMeters(WhichMeter).Units,
6813 : true,
6814 : MeterFileOnlyIndicator);
6815 : }
6816 : }
6817 2824 : } else if (FrequencyIndicator == ReportingFrequency::Simulation) {
6818 2824 : if (!CumulativeIndicator) {
6819 2824 : if (MeterFileOnlyIndicator) {
6820 2662 : if (op->EnergyMeters(WhichMeter).RptSM) {
6821 0 : ShowWarningError(state,
6822 0 : "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
6823 0 : R"(" (RunPeriod), already on "Output:Meter". Will report to both )" +
6824 0 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6825 : }
6826 : }
6827 2824 : if (!op->EnergyMeters(WhichMeter).RptSM) {
6828 2824 : op->EnergyMeters(WhichMeter).RptSM = true;
6829 2824 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptSMFO = true;
6830 2824 : if (!MeterFileOnlyIndicator) op->TrackingRunPeriodVariables = true;
6831 2824 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6832 2824 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6833 14120 : WriteMeterDictionaryItem(state,
6834 : FrequencyIndicator,
6835 : StoreType::Summed,
6836 2824 : op->EnergyMeters(WhichMeter).SMRptNum,
6837 : indexGroupKey,
6838 : indexGroup,
6839 2824 : op->EnergyMeters(WhichMeter).SMRptNumChr,
6840 2824 : op->EnergyMeters(WhichMeter).Name,
6841 2824 : op->EnergyMeters(WhichMeter).Units,
6842 : false,
6843 : MeterFileOnlyIndicator);
6844 : }
6845 : } else {
6846 0 : if (MeterFileOnlyIndicator) {
6847 0 : if (op->EnergyMeters(WhichMeter).RptAccSM) {
6848 0 : ShowWarningError(state,
6849 0 : "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
6850 0 : R"(" (RunPeriod), already on "Output:Meter". Will report to both )" +
6851 0 : state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
6852 : }
6853 : }
6854 0 : if (!op->EnergyMeters(WhichMeter).RptAccSM) {
6855 0 : op->EnergyMeters(WhichMeter).RptAccSM = true;
6856 0 : if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccSMFO = true;
6857 0 : if (!MeterFileOnlyIndicator) op->TrackingRunPeriodVariables = true;
6858 0 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
6859 0 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
6860 0 : WriteMeterDictionaryItem(state,
6861 : FrequencyIndicator,
6862 : StoreType::Summed,
6863 0 : op->EnergyMeters(WhichMeter).SMAccRptNum,
6864 : indexGroupKey,
6865 : indexGroup,
6866 0 : fmt::to_string(op->EnergyMeters(WhichMeter).SMAccRptNum),
6867 0 : op->EnergyMeters(WhichMeter).Name,
6868 0 : op->EnergyMeters(WhichMeter).Units,
6869 : true,
6870 : MeterFileOnlyIndicator);
6871 : }
6872 : }
6873 : } else {
6874 : }
6875 6733 : }
6876 :
6877 412682 : int GetMeterIndex(EnergyPlusData &state, std::string const &MeterName)
6878 : {
6879 :
6880 : // FUNCTION INFORMATION:
6881 : // AUTHOR Linda K. Lawrie
6882 : // DATE WRITTEN August 2002
6883 : // MODIFIED na
6884 : // RE-ENGINEERED na
6885 :
6886 : // PURPOSE OF THIS FUNCTION:
6887 : // This function returns a index to the meter "number" (aka assigned report number)
6888 : // for the meter name. If none active for this run, a zero is returned. This is used later to
6889 : // obtain a meter "value".
6890 :
6891 : // Using/Aliasing
6892 : using namespace OutputProcessor;
6893 : using SortAndStringUtilities::SetupAndSort;
6894 :
6895 : // Return value
6896 : int MeterIndex;
6897 :
6898 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
6899 : // Valid Meter names because matching case insensitive
6900 : //////////// hoisted into namespace changed to GetMeterIndexFirstCall////////////
6901 : // static bool FirstCall( true );
6902 : ////////////////////////////////////////////////
6903 : int Found;
6904 412682 : auto &op(state.dataOutputProcessor);
6905 :
6906 412682 : if (op->GetMeterIndexFirstCall || (state.dataOutputProcessor->NumValidMeters != op->NumEnergyMeters)) {
6907 2471 : state.dataOutputProcessor->NumValidMeters = op->NumEnergyMeters;
6908 2471 : state.dataOutputProcessor->ValidMeterNames.allocate(state.dataOutputProcessor->NumValidMeters);
6909 292854 : for (Found = 1; Found <= state.dataOutputProcessor->NumValidMeters; ++Found) {
6910 290383 : state.dataOutputProcessor->ValidMeterNames(Found) = UtilityRoutines::MakeUPPERCase(op->EnergyMeters(Found).Name);
6911 : }
6912 2471 : state.dataOutputProcessor->iValidMeterNames.allocate(state.dataOutputProcessor->NumValidMeters);
6913 2471 : SetupAndSort(state.dataOutputProcessor->ValidMeterNames, state.dataOutputProcessor->iValidMeterNames);
6914 2471 : op->GetMeterIndexFirstCall = false;
6915 : }
6916 :
6917 412682 : MeterIndex =
6918 825364 : UtilityRoutines::FindItemInSortedList(MeterName, state.dataOutputProcessor->ValidMeterNames, state.dataOutputProcessor->NumValidMeters);
6919 412682 : if (MeterIndex != 0) MeterIndex = state.dataOutputProcessor->iValidMeterNames(MeterIndex);
6920 :
6921 412682 : return MeterIndex;
6922 : }
6923 :
6924 23 : std::string GetMeterResourceType(EnergyPlusData &state, int const MeterNumber) // Which Meter Number (from GetMeterIndex)
6925 : {
6926 :
6927 : // FUNCTION INFORMATION:
6928 : // AUTHOR Linda K. Lawrie
6929 : // DATE WRITTEN August 2002
6930 : // MODIFIED na
6931 : // RE-ENGINEERED na
6932 :
6933 : // PURPOSE OF THIS FUNCTION:
6934 : // This function returns the character string of Resource Type for the
6935 : // given meter number/index. If MeterNumber is 0, ResourceType=Invalid/Unknown.
6936 :
6937 : // METHODOLOGY EMPLOYED:
6938 : // na
6939 :
6940 : // REFERENCES:
6941 : // na
6942 :
6943 : // Using/Aliasing
6944 : using namespace OutputProcessor;
6945 :
6946 : // Return value
6947 23 : std::string ResourceType;
6948 :
6949 : // Locals
6950 : // FUNCTION ARGUMENT DEFINITIONS:
6951 :
6952 : // FUNCTION PARAMETER DEFINITIONS:
6953 : // na
6954 :
6955 : // INTERFACE BLOCK SPECIFICATIONS:
6956 : // na
6957 :
6958 : // DERIVED TYPE DEFINITIONS:
6959 : // na
6960 :
6961 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
6962 23 : if (MeterNumber > 0) {
6963 23 : ResourceType = state.dataOutputProcessor->EnergyMeters(MeterNumber).ResourceType;
6964 : } else {
6965 0 : ResourceType = "Invalid/Unknown";
6966 : }
6967 :
6968 23 : return ResourceType;
6969 : }
6970 :
6971 5032315 : Real64 GetCurrentMeterValue(EnergyPlusData &state, int const MeterNumber) // Which Meter Number (from GetMeterIndex)
6972 : {
6973 :
6974 : // FUNCTION INFORMATION:
6975 : // AUTHOR Linda K. Lawrie
6976 : // DATE WRITTEN August 2002
6977 : // MODIFIED na
6978 : // RE-ENGINEERED na
6979 :
6980 : // PURPOSE OF THIS FUNCTION:
6981 : // This function returns the current meter value (timestep) for the meter number indicated.
6982 :
6983 : // METHODOLOGY EMPLOYED:
6984 : // Uses internal EnergyMeters structure to get value.
6985 :
6986 : // REFERENCES:
6987 : // na
6988 :
6989 : // Using/Aliasing
6990 : using namespace OutputProcessor;
6991 :
6992 : // Return value
6993 : Real64 CurrentMeterValue;
6994 :
6995 : // Locals
6996 : // FUNCTION ARGUMENT DEFINITIONS:
6997 :
6998 : // FUNCTION PARAMETER DEFINITIONS:
6999 : // na
7000 :
7001 : // INTERFACE BLOCK SPECIFICATIONS:
7002 : // na
7003 :
7004 : // DERIVED TYPE DEFINITIONS:
7005 : // na
7006 :
7007 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
7008 : // na
7009 :
7010 5032315 : if (MeterNumber > 0) {
7011 3769147 : CurrentMeterValue = state.dataOutputProcessor->EnergyMeters(MeterNumber).CurTSValue;
7012 : } else {
7013 1263168 : CurrentMeterValue = 0.0;
7014 : }
7015 :
7016 5032315 : return CurrentMeterValue;
7017 : }
7018 :
7019 253370806 : Real64 GetInstantMeterValue(EnergyPlusData &state,
7020 : int const MeterNumber, // Which Meter Number (from GetMeterIndex)
7021 : OutputProcessor::TimeStepType const t_timeStepType // Whether this is zone of HVAC
7022 : )
7023 : {
7024 :
7025 : // FUNCTION INFORMATION:
7026 : // AUTHOR Richard Liesen
7027 : // DATE WRITTEN February 2003
7028 : // MODIFIED na
7029 : // RE-ENGINEERED na
7030 :
7031 : // PURPOSE OF THIS FUNCTION:
7032 : // This function returns the Instantaneous meter value (timestep) for the meter number indicated
7033 : // using TimeStepType to differentiate between Zone and HVAC values.
7034 :
7035 : // METHODOLOGY EMPLOYED:
7036 : // Uses internal EnergyMeters structure to get value.
7037 :
7038 : // REFERENCES:
7039 : // na
7040 :
7041 : // Using/Aliasing
7042 : using namespace OutputProcessor;
7043 :
7044 : // Return value
7045 253370806 : Real64 InstantMeterValue(0.0);
7046 :
7047 : // Locals
7048 : // FUNCTION ARGUMENT DEFINITIONS:
7049 :
7050 : // FUNCTION PARAMETER DEFINITIONS:
7051 : // na
7052 :
7053 : // INTERFACE BLOCK SPECIFICATIONS:
7054 : // na
7055 :
7056 : // DERIVED TYPE DEFINITIONS:
7057 : // na
7058 :
7059 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
7060 :
7061 : // EnergyMeters(Meter)%TSValue=EnergyMeters(EnergyMeters(Meter)%SourceMeter)%TSValue-MeterValue(Meter)
7062 :
7063 253370806 : if (MeterNumber == 0) return InstantMeterValue;
7064 60242367 : auto &op(state.dataOutputProcessor);
7065 :
7066 60242367 : auto &energy_meter(op->EnergyMeters(MeterNumber));
7067 60242367 : auto &cache_beg(energy_meter.InstMeterCacheStart);
7068 60242367 : auto &cache_end(energy_meter.InstMeterCacheEnd);
7069 60242367 : if (energy_meter.TypeOfMeter != MtrType::CustomDec) {
7070 : // section added to speed up the execution of this routine
7071 : // instead of looping through all the VarMeterArrays to see if a RVariableType is used for a
7072 : // specific meter, create a list of all the indexes for RVariableType that are used for that
7073 : // meter.
7074 60105151 : if (cache_beg == 0) { // not yet added to the cache
7075 244772 : for (int Loop = 1; Loop <= op->NumVarMeterArrays; ++Loop) {
7076 241671 : auto const &var_meter_on(op->VarMeterArrays(Loop).OnMeters);
7077 1309367 : for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnMeters; Meter <= Meter_end; ++Meter) {
7078 1091037 : if (var_meter_on(Meter) == MeterNumber) {
7079 23341 : IncrementInstMeterCache(state);
7080 23341 : cache_end = op->InstMeterCacheLastUsed;
7081 23341 : if (cache_beg == 0) cache_beg = op->InstMeterCacheLastUsed;
7082 23341 : op->InstMeterCache(op->InstMeterCacheLastUsed) = op->VarMeterArrays(Loop).RepVariable;
7083 23341 : break;
7084 : }
7085 : }
7086 241671 : auto const &var_meter_on_custom(op->VarMeterArrays(Loop).OnCustomMeters);
7087 245153 : for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnCustomMeters; Meter <= Meter_end; ++Meter) {
7088 3493 : if (var_meter_on_custom(Meter) == MeterNumber) {
7089 11 : IncrementInstMeterCache(state);
7090 11 : cache_end = op->InstMeterCacheLastUsed;
7091 11 : if (cache_beg == 0) cache_beg = op->InstMeterCacheLastUsed;
7092 11 : op->InstMeterCache(op->InstMeterCacheLastUsed) = op->VarMeterArrays(Loop).RepVariable;
7093 11 : break;
7094 : }
7095 : } // End Number of Meters Loop
7096 : }
7097 : }
7098 1702291435 : for (int Loop = cache_beg; Loop <= cache_end; ++Loop) {
7099 1642186284 : auto &r_var_loop(op->RVariableTypes(op->InstMeterCache(Loop)));
7100 : // Separate the Zone variables from the HVAC variables using TimeStepType
7101 1642186284 : if (r_var_loop.timeStepType == t_timeStepType) {
7102 822750953 : auto &rVar(r_var_loop.VarPtr);
7103 : // Add to the total all of the appropriate variables
7104 822750953 : InstantMeterValue += (*rVar.Which) * rVar.ZoneMult * rVar.ZoneListMult;
7105 : }
7106 : }
7107 : } else { // MeterType_CustomDec
7108 : // Get Source Meter value
7109 : // Loop through all report meters to find correct report variables to add to instant meter total
7110 63570754 : for (int Loop = 1; Loop <= op->NumVarMeterArrays; ++Loop) {
7111 63433538 : auto &r_var_loop(op->RVariableTypes(op->VarMeterArrays(Loop).RepVariable));
7112 :
7113 63433538 : auto const &var_meter_on(op->VarMeterArrays(Loop).OnMeters);
7114 376590132 : for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnMeters; Meter <= Meter_end; ++Meter) {
7115 315335129 : if (var_meter_on(Meter) == energy_meter.SourceMeter) {
7116 : // Separate the Zone variables from the HVAC variables using TimeStepType
7117 4357070 : if (r_var_loop.timeStepType == t_timeStepType) {
7118 2178535 : auto &rVar(r_var_loop.VarPtr);
7119 : // Add to the total all of the appropriate variables
7120 2178535 : InstantMeterValue += (*rVar.Which) * rVar.ZoneMult * rVar.ZoneListMult;
7121 2178535 : break;
7122 : }
7123 : }
7124 : }
7125 :
7126 63433538 : auto const &var_meter_on_custom(op->VarMeterArrays(Loop).OnCustomMeters);
7127 63964194 : for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnCustomMeters; Meter <= Meter_end; ++Meter) {
7128 530656 : if (var_meter_on_custom(Meter) == energy_meter.SourceMeter) {
7129 : // Separate the Zone variables from the HVAC variables using TimeStepType
7130 0 : if (r_var_loop.timeStepType == t_timeStepType) {
7131 0 : auto &rVar(r_var_loop.VarPtr);
7132 : // Add to the total all of the appropriate variables
7133 0 : InstantMeterValue += (*rVar.Which) * rVar.ZoneMult * rVar.ZoneListMult;
7134 0 : break;
7135 : }
7136 : }
7137 : }
7138 :
7139 : } // End Number of Meters Loop
7140 63570754 : for (int Loop = 1; Loop <= op->NumVarMeterArrays; ++Loop) {
7141 63433538 : auto &r_var_loop(op->RVariableTypes(op->VarMeterArrays(Loop).RepVariable));
7142 :
7143 63433538 : auto const &var_meter_on(op->VarMeterArrays(Loop).OnMeters);
7144 389661342 : for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnMeters; Meter <= Meter_end; ++Meter) {
7145 326227804 : if (var_meter_on(Meter) == MeterNumber) {
7146 : // Separate the Zone variables from the HVAC variables using TimeStepType
7147 0 : if (r_var_loop.timeStepType == t_timeStepType) {
7148 0 : auto &rVar(r_var_loop.VarPtr);
7149 : // Add to the total all of the appropriate variables
7150 0 : InstantMeterValue -= (*rVar.Which) * rVar.ZoneMult * rVar.ZoneListMult;
7151 0 : break;
7152 : }
7153 : }
7154 : }
7155 :
7156 63433538 : auto const &var_meter_on_custom(op->VarMeterArrays(Loop).OnCustomMeters);
7157 63767474 : for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnCustomMeters; Meter <= Meter_end; ++Meter) {
7158 530656 : if (var_meter_on_custom(Meter) == MeterNumber) {
7159 : // Separate the Zone variables from the HVAC variables using TimeStepType
7160 393440 : if (r_var_loop.timeStepType == t_timeStepType) {
7161 196720 : auto &rVar(r_var_loop.VarPtr);
7162 : // Add to the total all of the appropriate variables
7163 196720 : InstantMeterValue -= (*rVar.Which) * rVar.ZoneMult * rVar.ZoneListMult;
7164 196720 : break;
7165 : }
7166 : }
7167 : }
7168 :
7169 : } // End Number of Meters Loop
7170 : }
7171 :
7172 60242367 : return InstantMeterValue;
7173 : }
7174 :
7175 23352 : void IncrementInstMeterCache(EnergyPlusData &state)
7176 : {
7177 : // SUBROUTINE INFORMATION:
7178 : // AUTHOR Jason Glazer
7179 : // DATE WRITTEN January 2013
7180 : // MODIFIED
7181 : // RE-ENGINEERED na
7182 :
7183 : // PURPOSE OF THIS FUNCTION:
7184 : // Manage the InstMeterCache array
7185 :
7186 : // METHODOLOGY EMPLOYED:
7187 : // When the array grows to large, double it.
7188 :
7189 23352 : auto &op(state.dataOutputProcessor);
7190 :
7191 23352 : if (!allocated(op->InstMeterCache)) {
7192 746 : op->InstMeterCache.dimension(op->InstMeterCacheSizeInc, 0); // zero the entire array
7193 746 : op->InstMeterCacheLastUsed = 1;
7194 : } else {
7195 22606 : ++op->InstMeterCacheLastUsed;
7196 : // if larger than current size grow the array
7197 22606 : if (op->InstMeterCacheLastUsed > op->InstMeterCacheSize) {
7198 0 : op->InstMeterCache.redimension(op->InstMeterCacheSize += op->InstMeterCacheSizeInc, 0);
7199 : }
7200 : }
7201 23352 : }
7202 :
7203 89026344 : Real64 GetInternalVariableValue(EnergyPlusData &state,
7204 : OutputProcessor::VariableType const varType, // 1=integer, 2=real, 3=meter
7205 : int const keyVarIndex // Array index
7206 : )
7207 : {
7208 : // FUNCTION INFORMATION:
7209 : // AUTHOR Linda K. Lawrie
7210 : // DATE WRITTEN December 2000
7211 : // MODIFIED August 2003, M. J. Witte
7212 : // RE-ENGINEERED na
7213 :
7214 : // PURPOSE OF THIS FUNCTION:
7215 : // This function returns the current value of the Internal Variable assigned to
7216 : // the varType and keyVarIndex. Values may be accessed for REAL(r64) and integer
7217 : // report variables and meter variables. The variable type (varType) may be
7218 : // determined by calling subroutine and GetVariableKeyCountandType. The
7219 : // index (keyVarIndex) may be determined by calling subroutine GetVariableKeys.
7220 :
7221 : // METHODOLOGY EMPLOYED:
7222 : // Uses Internal OutputProcessor data structure to return value.
7223 :
7224 : // REFERENCES:
7225 : // na
7226 :
7227 : // Using/Aliasing
7228 : using namespace OutputProcessor;
7229 : using ScheduleManager::GetCurrentScheduleValue;
7230 :
7231 : // Return value
7232 : Real64 resultVal; // value returned
7233 :
7234 : // Locals
7235 : // FUNCTION ARGUMENT DEFINITIONS:
7236 :
7237 : // FUNCTION PARAMETER DEFINITIONS:
7238 : // na
7239 :
7240 : // INTERFACE BLOCK SPECIFICATIONS:
7241 : // na
7242 :
7243 : // DERIVED TYPE DEFINITIONS:
7244 : // na
7245 :
7246 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
7247 : // na
7248 :
7249 89026344 : auto &op(state.dataOutputProcessor);
7250 :
7251 : // Select based on variable type: integer, real, or meter
7252 89026344 : if (varType == VariableType::NotFound) { // Variable not a found variable
7253 0 : resultVal = 0.0;
7254 89026344 : } else if (varType == VariableType::Integer) {
7255 24135 : if (keyVarIndex > op->NumOfIVariable) {
7256 0 : ShowFatalError(state, "GetInternalVariableValue: Integer variable passed index beyond range of array.");
7257 0 : ShowContinueError(state, format("Index = {} Number of integer variables = {}", keyVarIndex, op->NumOfIVariable));
7258 : }
7259 24135 : if (keyVarIndex < 1) {
7260 0 : ShowFatalError(state, format("GetInternalVariableValue: Integer variable passed index <1. Index = {}", keyVarIndex));
7261 : }
7262 :
7263 : // must use %Which, %Value is always zero if variable is not a requested report variable
7264 24135 : resultVal = double(*op->IVariableTypes(keyVarIndex).VarPtr.Which);
7265 89002209 : } else if (varType == VariableType::Real) {
7266 88609601 : if (keyVarIndex > op->NumOfRVariable) {
7267 0 : ShowFatalError(state, "GetInternalVariableValue: Real variable passed index beyond range of array.");
7268 0 : ShowContinueError(state, format("Index = {} Number of real variables = {}", keyVarIndex, op->NumOfRVariable));
7269 : }
7270 88609601 : if (keyVarIndex < 1) {
7271 0 : ShowFatalError(state, format("GetInternalVariableValue: Integer variable passed index <1. Index = {}", keyVarIndex));
7272 : }
7273 :
7274 : // must use %Which, %Value is always zero if variable is not a requested report variable
7275 88609601 : resultVal = *op->RVariableTypes(keyVarIndex).VarPtr.Which;
7276 392608 : } else if (varType == VariableType::Meter) {
7277 392608 : resultVal = GetCurrentMeterValue(state, keyVarIndex);
7278 0 : } else if (varType == VariableType::Schedule) {
7279 0 : resultVal = GetCurrentScheduleValue(state, keyVarIndex);
7280 : } else {
7281 0 : resultVal = 0.0;
7282 : }
7283 :
7284 89026344 : return resultVal;
7285 : }
7286 :
7287 0 : Real64 GetInternalVariableValueExternalInterface(EnergyPlusData &state,
7288 : OutputProcessor::VariableType const varType, // 1=integer, 2=REAL(r64), 3=meter
7289 : int const keyVarIndex // Array index
7290 : )
7291 : {
7292 : // FUNCTION INFORMATION:
7293 : // AUTHOR Thierry S. Nouidui
7294 : // DATE WRITTEN August 2011
7295 : // MODIFIED na
7296 : // RE-ENGINEERED na
7297 :
7298 : // PURPOSE OF THIS FUNCTION:
7299 : // This function returns the last zone-timestep value of the Internal Variable assigned to
7300 : // the varType and keyVarIndex. Values may be accessed for REAL(r64) and integer
7301 : // report variables and meter variables. The variable type (varType) may be
7302 : // determined by calling subroutine and GetVariableKeyCountandType. The
7303 : // index (keyVarIndex) may be determined by calling subroutine GetVariableKeys.
7304 :
7305 : // METHODOLOGY EMPLOYED:
7306 : // Uses Internal OutputProcessor data structure to return value.
7307 :
7308 : // REFERENCES:
7309 : // na
7310 :
7311 : // Using/Aliasing
7312 : using namespace OutputProcessor;
7313 : using ScheduleManager::GetCurrentScheduleValue;
7314 :
7315 : // Return value
7316 : Real64 resultVal; // value returned
7317 :
7318 : // Locals
7319 : // FUNCTION ARGUMENT DEFINITIONS:
7320 :
7321 : // FUNCTION PARAMETER DEFINITIONS:
7322 : // na
7323 :
7324 : // INTERFACE BLOCK SPECIFICATIONS:
7325 : // na
7326 :
7327 : // DERIVED TYPE DEFINITIONS:
7328 : // na
7329 :
7330 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
7331 : // na
7332 :
7333 0 : auto &op(state.dataOutputProcessor);
7334 :
7335 : // Select based on variable type: integer, REAL(r64), or meter
7336 0 : if (varType == VariableType::NotFound) { // Variable not a found variable
7337 0 : resultVal = 0.0;
7338 0 : } else if (varType == VariableType::Integer) {
7339 0 : if (keyVarIndex > op->NumOfIVariable) {
7340 0 : ShowFatalError(state, "GetInternalVariableValueExternalInterface: passed index beyond range of array.");
7341 : }
7342 0 : if (keyVarIndex < 1) {
7343 0 : ShowFatalError(state, "GetInternalVariableValueExternalInterface: passed index beyond range of array.");
7344 : }
7345 :
7346 : // must use %EITSValue, %This is the last-zonetimestep value
7347 0 : resultVal = double(op->IVariableTypes(keyVarIndex).VarPtr.EITSValue);
7348 0 : } else if (varType == VariableType::Real) {
7349 0 : if (keyVarIndex > op->NumOfRVariable) {
7350 0 : ShowFatalError(state, "GetInternalVariableValueExternalInterface: passed index beyond range of array.");
7351 : }
7352 0 : if (keyVarIndex < 1) {
7353 0 : ShowFatalError(state, "GetInternalVariableValueExternalInterface: passed index beyond range of array.");
7354 : }
7355 :
7356 : // must use %EITSValue, %This is the last-zonetimestep value
7357 0 : resultVal = op->RVariableTypes(keyVarIndex).VarPtr.EITSValue;
7358 0 : } else if (varType == VariableType::Meter) {
7359 0 : resultVal = GetCurrentMeterValue(state, keyVarIndex);
7360 0 : } else if (varType == VariableType::Schedule) {
7361 0 : resultVal = GetCurrentScheduleValue(state, keyVarIndex);
7362 : } else {
7363 0 : resultVal = 0.0;
7364 : }
7365 :
7366 0 : return resultVal;
7367 : }
7368 :
7369 32429 : int GetNumMeteredVariables(EnergyPlusData &state,
7370 : [[maybe_unused]] std::string const &ComponentType, // Given Component Type
7371 : std::string const &ComponentName // Given Component Name (user defined)
7372 : )
7373 : {
7374 :
7375 : // FUNCTION INFORMATION:
7376 : // AUTHOR Linda Lawrie
7377 : // DATE WRITTEN May 2005
7378 : // MODIFIED na
7379 : // RE-ENGINEERED na
7380 :
7381 : // PURPOSE OF THIS FUNCTION:
7382 : // This function counts the number of metered variables associated with the
7383 : // given ComponentType/Name. This resultant number would then be used to
7384 : // allocate arrays for a call the GetMeteredVariables routine.
7385 :
7386 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
7387 : int Loop;
7388 32429 : int NumVariables = 0;
7389 32429 : auto &op(state.dataOutputProcessor);
7390 :
7391 36392179 : for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
7392 : // Pos=INDEX(RVariableTypes(Loop)%VarName,':')
7393 : // IF (ComponentName /= RVariableTypes(Loop)%VarNameUC(1:Pos-1)) CYCLE
7394 36359750 : if (ComponentName != op->RVariableTypes(Loop).KeyNameOnlyUC) continue;
7395 61167 : auto &rVar(op->RVariableTypes(Loop).VarPtr);
7396 61167 : if (rVar.MeterArrayPtr == 0) {
7397 24232 : continue;
7398 : }
7399 36935 : if (op->VarMeterArrays(rVar.MeterArrayPtr).NumOnMeters > 0) {
7400 36935 : ++NumVariables;
7401 : }
7402 : }
7403 :
7404 32429 : return NumVariables;
7405 : }
7406 :
7407 16539 : void GetMeteredVariables(EnergyPlusData &state,
7408 : std::string const &ComponentType, // Given Component Type
7409 : std::string const &ComponentName, // Given Component Name (user defined)
7410 : Array1D_int &VarIndexes, // Variable Numbers
7411 : Array1D<OutputProcessor::VariableType> &VarTypes, // Variable Types (1=integer, 2=real, 3=meter)
7412 : Array1D<OutputProcessor::TimeStepType> &TimeStepTypes, // Variable Index Types (1=Zone,2=HVAC)
7413 : Array1D<OutputProcessor::Unit> &unitsForVar, // units from enum for each variable
7414 : std::map<int, DataGlobalConstants::ResourceType> &ResourceTypes, // ResourceTypes for each variable
7415 : Array1D_string &EndUses, // EndUses for each variable
7416 : Array1D_string &Groups, // Groups for each variable
7417 : Array1D_string &Names, // Variable Names for each variable
7418 : int &NumFound // Number Found
7419 : )
7420 : {
7421 :
7422 : // SUBROUTINE INFORMATION:
7423 : // AUTHOR Linda Lawrie
7424 : // DATE WRITTEN May 2005
7425 : // MODIFIED Jason DeGraw 2/12/2020, de-optionalized
7426 : // RE-ENGINEERED na
7427 :
7428 : // PURPOSE OF THIS SUBROUTINE:
7429 : // This routine gets the variable names and other associated information
7430 : // for metered variables associated with the given ComponentType/Name.
7431 :
7432 : // Using/Aliasing
7433 : using namespace DataGlobalConstants;
7434 : using namespace OutputProcessor;
7435 :
7436 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7437 : int Loop;
7438 : int NumVariables;
7439 : int MeterPtr;
7440 : int NumOnMeterPtr;
7441 : int MeterNum;
7442 16539 : auto &op(state.dataOutputProcessor);
7443 :
7444 16539 : NumVariables = 0;
7445 :
7446 20875959 : for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
7447 : // Pos=INDEX(RVariableTypes(Loop)%VarName,':')
7448 : // IF (ComponentName /= RVariableTypes(Loop)%VarNameUC(1:Pos-1)) CYCLE
7449 20859420 : if (ComponentName != op->RVariableTypes(Loop).KeyNameOnlyUC) continue;
7450 59074 : auto &rVar(op->RVariableTypes(Loop).VarPtr);
7451 59074 : if (rVar.MeterArrayPtr == 0) continue;
7452 36935 : NumOnMeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).NumOnMeters;
7453 36935 : MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(1);
7454 36935 : if (MeterPtr) {
7455 36935 : ++NumVariables;
7456 36935 : VarIndexes(NumVariables) = Loop;
7457 36935 : VarTypes(NumVariables) = VariableType::Real;
7458 36935 : TimeStepTypes(NumVariables) = op->RVariableTypes(Loop).timeStepType;
7459 36935 : unitsForVar(NumVariables) = op->RVariableTypes(Loop).units;
7460 :
7461 36935 : ResourceTypes.at(NumVariables) = AssignResourceTypeNum(UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).ResourceType));
7462 :
7463 36935 : Names(NumVariables) = op->RVariableTypes(Loop).VarNameUC;
7464 :
7465 110805 : for (MeterNum = 1; MeterNum <= NumOnMeterPtr; ++MeterNum) {
7466 110792 : MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(MeterNum);
7467 110792 : if (!op->EnergyMeters(MeterPtr).EndUse.empty()) {
7468 36922 : EndUses(NumVariables) = UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).EndUse);
7469 36922 : break;
7470 : }
7471 : }
7472 :
7473 73870 : for (MeterNum = 1; MeterNum <= NumOnMeterPtr; ++MeterNum) {
7474 73870 : MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(MeterNum);
7475 73870 : if (!op->EnergyMeters(MeterPtr).Group.empty()) {
7476 36935 : Groups(NumVariables) = UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).Group);
7477 36935 : break;
7478 : }
7479 : }
7480 :
7481 : } else {
7482 0 : ShowWarningError(state,
7483 0 : "Referenced variable or meter used in the wrong context \"" + ComponentName + "\" of type \"" + ComponentType + "\"");
7484 : }
7485 : }
7486 :
7487 16539 : NumFound = NumVariables; // Should just return this
7488 16539 : }
7489 :
7490 0 : void GetMeteredVariables(EnergyPlusData &state,
7491 : std::string const &ComponentType, // Given Component Type
7492 : std::string const &ComponentName, // Given Component Name (user defined)
7493 : Array1D_int &VarIndexes, // Variable Numbers
7494 : Array1D<OutputProcessor::VariableType> &VarTypes, // Variable Types (1=integer, 2=real, 3=meter)
7495 : Array1D<OutputProcessor::TimeStepType> &TimeStepTypes, // Variable Index Types (1=Zone,2=HVAC)
7496 : Array1D<OutputProcessor::Unit> &unitsForVar, // units from enum for each variable
7497 : std::map<int, DataGlobalConstants::ResourceType> &ResourceTypes, // ResourceTypes for each variable
7498 : Array1D_string &EndUses, // EndUses for each variable
7499 : Array1D_string &Groups, // Groups for each variable
7500 : Array1D_string &Names, // Variable Names for each variable
7501 : Array1D_int &VarIDs // Variable Report Numbers
7502 : )
7503 : {
7504 :
7505 : // SUBROUTINE INFORMATION:
7506 : // AUTHOR Linda Lawrie
7507 : // DATE WRITTEN May 2005
7508 : // MODIFIED Jason DeGraw 2/12/2020, de-optionalized
7509 : // RE-ENGINEERED na
7510 :
7511 : // PURPOSE OF THIS SUBROUTINE:
7512 : // This routine gets the variable names and other associated information
7513 : // for metered variables associated with the given ComponentType/Name.
7514 :
7515 : // Using/Aliasing
7516 : using namespace DataGlobalConstants;
7517 : using namespace OutputProcessor;
7518 :
7519 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7520 : int Loop;
7521 : int NumVariables;
7522 : int MeterPtr;
7523 : int NumOnMeterPtr;
7524 : int MeterNum;
7525 0 : auto &op(state.dataOutputProcessor);
7526 :
7527 0 : NumVariables = 0;
7528 :
7529 0 : for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
7530 : // Pos=INDEX(RVariableTypes(Loop)%VarName,':')
7531 : // IF (ComponentName /= RVariableTypes(Loop)%VarNameUC(1:Pos-1)) CYCLE
7532 0 : if (ComponentName != op->RVariableTypes(Loop).KeyNameOnlyUC) continue;
7533 0 : auto &rVar(op->RVariableTypes(Loop).VarPtr);
7534 0 : if (rVar.MeterArrayPtr == 0) continue;
7535 0 : NumOnMeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).NumOnMeters;
7536 0 : MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(1);
7537 0 : if (MeterPtr) {
7538 0 : ++NumVariables;
7539 0 : VarIndexes(NumVariables) = Loop;
7540 0 : VarTypes(NumVariables) = VariableType::Real;
7541 0 : TimeStepTypes(NumVariables) = op->RVariableTypes(Loop).timeStepType;
7542 0 : unitsForVar(NumVariables) = op->RVariableTypes(Loop).units;
7543 :
7544 0 : ResourceTypes.at(NumVariables) = AssignResourceTypeNum(UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).ResourceType));
7545 0 : Names(NumVariables) = op->RVariableTypes(Loop).VarNameUC;
7546 :
7547 0 : for (MeterNum = 1; MeterNum <= NumOnMeterPtr; ++MeterNum) {
7548 0 : MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(MeterNum);
7549 0 : if (!op->EnergyMeters(MeterPtr).EndUse.empty()) {
7550 0 : EndUses(NumVariables) = UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).EndUse);
7551 0 : break;
7552 : }
7553 : }
7554 :
7555 0 : for (MeterNum = 1; MeterNum <= NumOnMeterPtr; ++MeterNum) {
7556 0 : MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(MeterNum);
7557 0 : if (!op->EnergyMeters(MeterPtr).Group.empty()) {
7558 0 : Groups(NumVariables) = UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).Group);
7559 0 : break;
7560 : }
7561 : }
7562 :
7563 0 : VarIDs(NumVariables) = rVar.ReportID;
7564 :
7565 : } else {
7566 0 : ShowWarningError(state,
7567 0 : "Referenced variable or meter used in the wrong context \"" + ComponentName + "\" of type \"" + ComponentType + "\"");
7568 : }
7569 : }
7570 0 : }
7571 :
7572 58393 : void GetVariableKeyCountandType(EnergyPlusData &state,
7573 : std::string const &varName, // Standard variable name
7574 : int &numKeys, // Number of keys found
7575 : OutputProcessor::VariableType &varType,
7576 : OutputProcessor::StoreType &varAvgSum, // Variable is Averaged=1 or Summed=2
7577 : OutputProcessor::TimeStepType &varStepType, // Variable time step is Zone=1 or HVAC=2
7578 : OutputProcessor::Unit &varUnits // Units enumeration
7579 : )
7580 : {
7581 :
7582 : // SUBROUTINE INFORMATION:
7583 : // AUTHOR Michael J. Witte
7584 : // DATE WRITTEN August 2003
7585 : // MODIFIED na
7586 : // RE-ENGINEERED na
7587 :
7588 : // PURPOSE OF THIS SUBROUTINE:
7589 : // This subroutine returns the variable TYPE (Real, integer, meter, schedule, etc.)
7590 : // (varType) whether it is an averaged or summed variable (varAvgSum),
7591 : // whether it is a zone or HVAC time step (varStepType),
7592 : // and the number of keynames for a given report variable or report meter name
7593 : // (varName). The variable type (varType) and number of keys (numKeys) are
7594 : // used when calling subroutine GetVariableKeys to obtain a list of the
7595 : // keynames for a particular variable and a corresponding list of indexes.
7596 :
7597 : // METHODOLOGY EMPLOYED:
7598 : // Uses Internal OutputProcessor data structure to search for varName
7599 : // in each of the three output data arrays:
7600 : // RVariableTypes - real report variables
7601 : // IVariableTypes - integer report variables
7602 : // EnergyMeters - report meters (via GetMeterIndex function)
7603 : // Schedules - specific schedule values
7604 : // When the variable is found, the variable type (varType) is set and the
7605 : // number of associated keys is counted.
7606 : // varType is assigned as follows:
7607 : // 0 = not found
7608 : // 1 = integer
7609 : // 2 = real
7610 : // 3 = meter
7611 : // 4 = schedule
7612 : // varAvgSum is assigned as follows:
7613 : // 1 = averaged
7614 : // 2 = summed
7615 : // varStepType is assigned as follows:
7616 : // 1 = zone time step
7617 : // 2 = HVAC time step
7618 :
7619 : // Using/Aliasing
7620 : using namespace OutputProcessor;
7621 : using ScheduleManager::GetScheduleIndex;
7622 : using ScheduleManager::GetScheduleType;
7623 : using SortAndStringUtilities::SetupAndSort;
7624 :
7625 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7626 : int Loop; // Loop counters
7627 : int Loop2;
7628 : std::string::size_type Position; // Starting point of search string
7629 : int VFound; // Found integer/real variable attributes
7630 : bool Found; // True if varName is found
7631 : bool Duplicate; // True if keyname is a duplicate
7632 116786 : std::string VarKeyPlusName; // Full variable name including keyname and units
7633 116786 : std::string varNameUpper; // varName pushed to all upper case
7634 58393 : auto &op(state.dataOutputProcessor);
7635 :
7636 : // INITIALIZATIONS
7637 58393 : if (op->InitFlag) {
7638 167 : op->curKeyVarIndexLimit = 1000;
7639 167 : op->keyVarIndexes.allocate(op->curKeyVarIndexLimit);
7640 167 : op->numVarNames = op->NumVariablesForOutput;
7641 167 : op->varNames.allocate(op->numVarNames);
7642 91244 : for (Loop = 1; Loop <= op->NumVariablesForOutput; ++Loop) {
7643 91077 : op->varNames(Loop) = UtilityRoutines::MakeUPPERCase(op->DDVariableTypes(Loop).VarNameOnly);
7644 : }
7645 167 : op->ivarNames.allocate(op->numVarNames);
7646 167 : SetupAndSort(op->varNames, op->ivarNames);
7647 167 : op->InitFlag = false;
7648 : }
7649 :
7650 58393 : if (op->numVarNames != op->NumVariablesForOutput) {
7651 349 : op->numVarNames = op->NumVariablesForOutput;
7652 349 : op->varNames.allocate(op->numVarNames);
7653 163272 : for (Loop = 1; Loop <= op->NumVariablesForOutput; ++Loop) {
7654 162923 : op->varNames(Loop) = UtilityRoutines::MakeUPPERCase(op->DDVariableTypes(Loop).VarNameOnly);
7655 : }
7656 349 : op->ivarNames.allocate(op->numVarNames);
7657 349 : SetupAndSort(op->varNames, op->ivarNames);
7658 : }
7659 :
7660 58393 : op->keyVarIndexes = 0;
7661 58393 : varType = VariableType::NotFound;
7662 58393 : numKeys = 0;
7663 58393 : varAvgSum = StoreType::Averaged;
7664 58393 : varStepType = TimeStepType::Zone;
7665 58393 : varUnits = OutputProcessor::Unit::None;
7666 58393 : Found = false;
7667 58393 : Duplicate = false;
7668 58393 : varNameUpper = varName;
7669 :
7670 : // Search Variable List First
7671 58393 : VFound = UtilityRoutines::FindItemInSortedList(varNameUpper, op->varNames, op->numVarNames);
7672 58393 : if (VFound != 0) {
7673 2113 : varType = op->DDVariableTypes(op->ivarNames(VFound)).variableType;
7674 : }
7675 :
7676 58393 : if (varType == VariableType::Integer) {
7677 : // Search Integer Variables
7678 30 : for (Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
7679 25 : VarKeyPlusName = op->IVariableTypes(Loop).VarNameUC;
7680 25 : Position = index(VarKeyPlusName, ':' + varNameUpper, true);
7681 25 : if (Position != std::string::npos) {
7682 25 : if (VarKeyPlusName.substr(Position + 1) == varNameUpper) {
7683 25 : Found = true;
7684 25 : varType = VariableType::Integer;
7685 25 : Duplicate = false;
7686 : // Check if duplicate - duplicates happen if the same report variable/key name
7687 : // combination is requested more than once in the idf at different reporting
7688 : // frequencies
7689 75 : for (Loop2 = 1; Loop2 <= numKeys; ++Loop2) {
7690 50 : if (VarKeyPlusName == op->IVariableTypes(op->keyVarIndexes(Loop2)).VarNameUC) Duplicate = true;
7691 : }
7692 25 : if (!Duplicate) {
7693 25 : ++numKeys;
7694 25 : if (numKeys > op->curKeyVarIndexLimit) {
7695 0 : op->keyVarIndexes.redimension(op->curKeyVarIndexLimit += 500, 0);
7696 : }
7697 25 : op->keyVarIndexes(numKeys) = Loop;
7698 25 : varAvgSum = op->DDVariableTypes(op->ivarNames(VFound)).storeType;
7699 25 : varStepType = op->DDVariableTypes(op->ivarNames(VFound)).timeStepType;
7700 25 : varUnits = op->DDVariableTypes(op->ivarNames(VFound)).units;
7701 : }
7702 : }
7703 : }
7704 : }
7705 58388 : } else if (varType == VariableType::Real) {
7706 : // Search real Variables Next
7707 2193293 : for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
7708 2191185 : if (op->RVariableTypes(Loop).VarNameOnlyUC == varNameUpper) {
7709 152072 : Found = true;
7710 152072 : varType = VariableType::Real;
7711 152072 : Duplicate = false;
7712 : // Check if duplicate - duplicates happen if the same report variable/key name
7713 : // combination is requested more than once in the idf at different reporting
7714 : // frequencies
7715 152072 : VarKeyPlusName = op->RVariableTypes(Loop).VarNameUC;
7716 14364330 : for (Loop2 = 1; Loop2 <= numKeys; ++Loop2) {
7717 14212258 : if (VarKeyPlusName == op->RVariableTypes(op->keyVarIndexes(Loop2)).VarNameUC) Duplicate = true;
7718 : }
7719 152072 : if (!Duplicate) {
7720 152072 : ++numKeys;
7721 152072 : if (numKeys > op->curKeyVarIndexLimit) {
7722 0 : op->keyVarIndexes.redimension(op->curKeyVarIndexLimit += 500, 0);
7723 : }
7724 152072 : op->keyVarIndexes(numKeys) = Loop;
7725 152072 : varAvgSum = op->DDVariableTypes(op->ivarNames(VFound)).storeType;
7726 152072 : varStepType = op->DDVariableTypes(op->ivarNames(VFound)).timeStepType;
7727 152072 : varUnits = op->DDVariableTypes(op->ivarNames(VFound)).units;
7728 : }
7729 : }
7730 : }
7731 : }
7732 :
7733 : // Search Meters if not found in integers or reals
7734 : // Use the GetMeterIndex function
7735 : // Meters do not have keys, so only one will be found
7736 58393 : if (!Found) {
7737 56280 : op->keyVarIndexes(1) = GetMeterIndex(state, varName);
7738 56280 : if (op->keyVarIndexes(1) > 0) {
7739 367 : Found = true;
7740 367 : numKeys = 1;
7741 367 : varType = VariableType::Meter;
7742 367 : varUnits = op->EnergyMeters(op->keyVarIndexes(1)).Units;
7743 367 : varAvgSum = StoreType::Summed;
7744 367 : varStepType = TimeStepType::Zone;
7745 : }
7746 : }
7747 :
7748 : // Search schedules if not found in integers, reals, or meters
7749 : // Use the GetScheduleIndex function
7750 : // Schedules do not have keys, so only one will be found
7751 58393 : if (!Found) {
7752 55913 : op->keyVarIndexes(1) = GetScheduleIndex(state, varName);
7753 55913 : if (op->keyVarIndexes(1) > 0) {
7754 0 : Found = true;
7755 0 : numKeys = 1;
7756 0 : varType = VariableType::Schedule;
7757 0 : varUnits = unitStringToEnum(GetScheduleType(state, op->keyVarIndexes(1)));
7758 0 : varAvgSum = StoreType::Averaged;
7759 0 : varStepType = TimeStepType::Zone;
7760 : }
7761 : }
7762 58393 : }
7763 :
7764 2480 : void GetVariableKeys(EnergyPlusData &state,
7765 : std::string const &varName, // Standard variable name
7766 : OutputProcessor::VariableType const varType, // 1=integer, 2=real, 3=meter
7767 : Array1D_string &keyNames, // Specific key name
7768 : Array1D_int &keyVarIndexes // Array index for
7769 : )
7770 : {
7771 :
7772 : // SUBROUTINE INFORMATION:
7773 : // AUTHOR Michael J. Witte
7774 : // DATE WRITTEN August 2003
7775 : // MODIFIED na
7776 : // RE-ENGINEERED na
7777 :
7778 : // PURPOSE OF THIS SUBROUTINE:
7779 : // This subroutine returns a list of keynames and indexes associated
7780 : // with a particular report variable or report meter name (varName).
7781 : // This routine assumes that the variable TYPE (Real, integer, meter, etc.)
7782 : // may be determined by calling GetVariableKeyCountandType. The variable type
7783 : // and index can then be used with function GetInternalVariableValue to
7784 : // to retrieve the current value of a particular variable/keyname combination.
7785 :
7786 : // METHODOLOGY EMPLOYED:
7787 : // Uses Internal OutputProcessor data structure to search for varName
7788 : // and build list of keynames and indexes. The indexes are the array index
7789 : // in the data array for the
7790 :
7791 : // Using/Aliasing
7792 : using namespace OutputProcessor;
7793 : using ScheduleManager::GetScheduleIndex;
7794 :
7795 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7796 : int Loop; // Loop counters
7797 : int Loop2;
7798 : std::string::size_type Position; // Starting point of search string
7799 : bool Duplicate; // True if keyname is a duplicate
7800 : int maxKeyNames; // Max allowable # of key names=size of keyNames array
7801 : int maxkeyVarIndexes; // Max allowable # of key indexes=size of keyVarIndexes array
7802 : int numKeys; // Number of keys found
7803 4960 : std::string VarKeyPlusName; // Full variable name including keyname and units
7804 4960 : std::string varNameUpper; // varName pushed to all upper case
7805 :
7806 : // INITIALIZATIONS
7807 2480 : keyNames = "";
7808 2480 : keyVarIndexes = 0;
7809 2480 : numKeys = 0;
7810 2480 : Duplicate = false;
7811 2480 : maxKeyNames = size(keyNames);
7812 2480 : maxkeyVarIndexes = size(keyVarIndexes);
7813 2480 : varNameUpper = UtilityRoutines::MakeUPPERCase(varName);
7814 2480 : auto &op(state.dataOutputProcessor);
7815 :
7816 : // Select based on variable type: integer, real, or meter
7817 2480 : if (varType == VariableType::Integer) { // Integer
7818 30 : for (Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
7819 25 : VarKeyPlusName = op->IVariableTypes(Loop).VarNameUC;
7820 25 : Position = index(VarKeyPlusName, ':' + varNameUpper, true);
7821 25 : if (Position != std::string::npos) {
7822 25 : if (VarKeyPlusName.substr(Position + 1) == varNameUpper) {
7823 25 : Duplicate = false;
7824 : // Check if duplicate - duplicates happen if the same report variable/key name
7825 : // combination is requested more than once in the idf at different reporting
7826 : // frequencies
7827 75 : for (Loop2 = 1; Loop2 <= numKeys; ++Loop2) {
7828 50 : if (VarKeyPlusName == op->IVariableTypes(keyVarIndexes(Loop2)).VarNameUC) Duplicate = true;
7829 : }
7830 25 : if (!Duplicate) {
7831 25 : ++numKeys;
7832 25 : if ((numKeys > maxKeyNames) || (numKeys > maxkeyVarIndexes)) {
7833 0 : ShowFatalError(state, "Invalid array size in GetVariableKeys");
7834 : }
7835 25 : keyNames(numKeys) = op->IVariableTypes(Loop).VarNameUC.substr(0, Position);
7836 25 : keyVarIndexes(numKeys) = Loop;
7837 : }
7838 : }
7839 : }
7840 : }
7841 2475 : } else if (varType == VariableType::Real) { // Real
7842 2193293 : for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
7843 2191185 : if (op->RVariableTypes(Loop).VarNameOnlyUC == varNameUpper) {
7844 152072 : Duplicate = false;
7845 : // Check if duplicate - duplicates happen if the same report variable/key name
7846 : // combination is requested more than once in the idf at different reporting
7847 : // frequencies
7848 152072 : VarKeyPlusName = op->RVariableTypes(Loop).VarNameUC;
7849 14364330 : for (Loop2 = 1; Loop2 <= numKeys; ++Loop2) {
7850 14212258 : if (VarKeyPlusName == op->RVariableTypes(keyVarIndexes(Loop2)).VarNameUC) Duplicate = true;
7851 : }
7852 152072 : if (!Duplicate) {
7853 152072 : ++numKeys;
7854 152072 : if ((numKeys > maxKeyNames) || (numKeys > maxkeyVarIndexes)) {
7855 0 : ShowFatalError(state, "Invalid array size in GetVariableKeys");
7856 : }
7857 152072 : keyNames(numKeys) = op->RVariableTypes(Loop).KeyNameOnlyUC;
7858 152072 : keyVarIndexes(numKeys) = Loop;
7859 : }
7860 : }
7861 : }
7862 367 : } else if (varType == VariableType::Meter) { // Meter
7863 367 : numKeys = 1;
7864 367 : if ((numKeys > maxKeyNames) || (numKeys > maxkeyVarIndexes)) {
7865 0 : ShowFatalError(state, "Invalid array size in GetVariableKeys");
7866 : }
7867 367 : keyNames(1) = "Meter";
7868 367 : keyVarIndexes(1) = GetMeterIndex(state, varName);
7869 0 : } else if (varType == VariableType::Schedule) { // Schedule
7870 0 : numKeys = 1;
7871 0 : if ((numKeys > maxKeyNames) || (numKeys > maxkeyVarIndexes)) {
7872 0 : ShowFatalError(state, "Invalid array size in GetVariableKeys");
7873 : }
7874 0 : keyNames(1) = "Environment";
7875 0 : keyVarIndexes(1) = GetScheduleIndex(state, varName);
7876 : } else {
7877 : // do nothing
7878 : }
7879 2480 : }
7880 :
7881 8113 : bool ReportingThisVariable(EnergyPlusData &state, std::string const &RepVarName)
7882 : {
7883 :
7884 : // FUNCTION INFORMATION:
7885 : // AUTHOR Linda Lawrie
7886 : // DATE WRITTEN October 2008
7887 : // MODIFIED na
7888 : // RE-ENGINEERED na
7889 :
7890 : // PURPOSE OF THIS FUNCTION:
7891 : // This function scans the report variables and reports back
7892 : // if user has requested this variable be reported.
7893 :
7894 : // METHODOLOGY EMPLOYED:
7895 : // na
7896 :
7897 : // REFERENCES:
7898 : // na
7899 :
7900 : // Using/Aliasing
7901 : using namespace OutputProcessor;
7902 :
7903 : // Return value
7904 : bool BeingReported;
7905 :
7906 : // Locals
7907 : // FUNCTION ARGUMENT DEFINITIONS:
7908 :
7909 : // FUNCTION PARAMETER DEFINITIONS:
7910 : // na
7911 :
7912 : // INTERFACE BLOCK SPECIFICATIONS:
7913 : // na
7914 :
7915 : // DERIVED TYPE DEFINITIONS:
7916 : // na
7917 :
7918 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
7919 : int Found;
7920 8113 : auto &op(state.dataOutputProcessor);
7921 :
7922 8113 : BeingReported = false;
7923 8113 : Found = UtilityRoutines::FindItem(RepVarName, op->ReqRepVars, &ReqReportVariables::VarName);
7924 8113 : if (Found > 0) {
7925 0 : BeingReported = true;
7926 : }
7927 :
7928 8113 : if (!BeingReported) { // check meter names too
7929 8113 : Found = UtilityRoutines::FindItem(RepVarName, op->EnergyMeters);
7930 8113 : if (Found > 0) {
7931 5569 : if (op->EnergyMeters(Found).RptTS || op->EnergyMeters(Found).RptHR || op->EnergyMeters(Found).RptDY || op->EnergyMeters(Found).RptMN ||
7932 4170 : op->EnergyMeters(Found).RptSM || op->EnergyMeters(Found).RptTSFO || op->EnergyMeters(Found).RptHRFO ||
7933 4170 : op->EnergyMeters(Found).RptDYFO || op->EnergyMeters(Found).RptMNFO || op->EnergyMeters(Found).RptSMFO ||
7934 4170 : op->EnergyMeters(Found).RptAccTS || op->EnergyMeters(Found).RptAccHR || op->EnergyMeters(Found).RptAccDY ||
7935 4170 : op->EnergyMeters(Found).RptAccMN || op->EnergyMeters(Found).RptAccSM || op->EnergyMeters(Found).RptAccTSFO ||
7936 5563 : op->EnergyMeters(Found).RptAccHRFO || op->EnergyMeters(Found).RptAccDYFO || op->EnergyMeters(Found).RptAccMNFO ||
7937 1390 : op->EnergyMeters(Found).RptAccSMFO) {
7938 3 : BeingReported = true;
7939 : }
7940 : }
7941 : }
7942 :
7943 8113 : return BeingReported;
7944 : }
7945 :
7946 60 : void InitPollutionMeterReporting(EnergyPlusData &state, std::string const &ReportFreqName)
7947 : {
7948 :
7949 : // SUBROUTINE INFORMATION:Richard Liesen
7950 : // DATE WRITTEN July 2002
7951 : // MODIFIED na
7952 : // RE-ENGINEERED na
7953 :
7954 : // PURPOSE OF THIS SUBROUTINE:
7955 : // This subroutine is called at the end of the first HVAC iteration and
7956 : // sets up the reporting for the Pollution Meters.
7957 : // ReportPollutionOutput,
7958 : // A1 ; \field Reporting_Frequency
7959 : // \type choice
7960 : // \key timestep
7961 : // \key hourly
7962 : // \key daily
7963 : // \key monthly
7964 : // \key runperiod
7965 : // METHODOLOGY EMPLOYED:
7966 : // The program tries to setup all of the following meters if the Pollution Report is initiated.
7967 : // Electricity:Facility [J]
7968 : // Diesel:Facility [J]
7969 : // DistrictCooling:Facility [J]
7970 : // DistrictHeating:Facility [J]
7971 : // Gas:Facility [J]
7972 : // GASOLINE:Facility [J]
7973 : // COAL:Facility [J]
7974 : // FuelOilNo1:Facility [J]
7975 : // FuelOilNo2:Facility [J]
7976 : // Propane:Facility [J]
7977 : // ElectricityProduced:Facility [J]
7978 : // Pollutant:CO2
7979 : // Pollutant:CO
7980 : // Pollutant:CH4
7981 : // Pollutant:NOx
7982 : // Pollutant:N2O
7983 : // Pollutant:SO2
7984 : // Pollutant:PM
7985 : // Pollutant:PM10
7986 : // Pollutant:PM2.5
7987 : // Pollutant:NH3
7988 : // Pollutant:NMVOC
7989 : // Pollutant:Hg
7990 : // Pollutant:Pb
7991 : // Pollutant:WaterEnvironmentalFactors
7992 : // Pollutant:Nuclear High
7993 : // Pollutant:Nuclear Low
7994 : // Pollutant:Carbon Equivalent
7995 :
7996 : // Using/Aliasing
7997 : using namespace OutputProcessor;
7998 : // SUBROUTINE PARAMETER DEFINITIONS:
7999 : // Now for the Pollution Meters
8000 : static Array1D_string const PollutionMeters({1, 29},
8001 : {"Electricity:Facility",
8002 : "Diesel:Facility",
8003 : "DistrictCooling:Facility",
8004 : "DistrictHeating:Facility",
8005 : "NaturalGas:Facility",
8006 : "GASOLINE:Facility",
8007 : "COAL:Facility",
8008 : "FuelOilNo1:Facility",
8009 : "FuelOilNo2:Facility",
8010 : "Propane:Facility",
8011 : "ElectricityProduced:Facility",
8012 : "Steam:Facility",
8013 : "CO2:Facility",
8014 : "CO:Facility",
8015 : "CH4:Facility",
8016 : "NOx:Facility",
8017 : "N2O:Facility",
8018 : "SO2:Facility",
8019 : "PM:Facility",
8020 : "PM10:Facility",
8021 : "PM2.5:Facility",
8022 : "NH3:Facility",
8023 : "NMVOC:Facility",
8024 : "Hg:Facility",
8025 : "Pb:Facility",
8026 : "WaterEnvironmentalFactors:Facility",
8027 : "Nuclear High:Facility",
8028 : "Nuclear Low:Facility",
8029 60 : "Carbon Equivalent:Facility"});
8030 :
8031 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8032 : int Loop;
8033 : int NumReqMeters;
8034 : int Meter;
8035 60 : ReportingFrequency ReportFreq(determineFrequency(state, ReportFreqName));
8036 :
8037 : int indexGroupKey;
8038 120 : std::string indexGroup;
8039 60 : auto &op(state.dataOutputProcessor);
8040 :
8041 60 : NumReqMeters = 29;
8042 :
8043 1800 : for (Loop = 1; Loop <= NumReqMeters; ++Loop) {
8044 :
8045 1740 : Meter = UtilityRoutines::FindItem(PollutionMeters(Loop), op->EnergyMeters);
8046 1740 : if (Meter > 0) { // All the active meters for this run are set, but all are still searched for.
8047 :
8048 1150 : indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(Meter).Name);
8049 1150 : indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(Meter));
8050 : // All of the specified meters are checked and the headers printed to the meter file if this
8051 : // has not been done previously
8052 1150 : if (ReportFreq == ReportingFrequency::TimeStep) {
8053 0 : if (op->EnergyMeters(Meter).RptTS) {
8054 0 : op->EnergyMeters(Meter).RptTS = true;
8055 : } else {
8056 0 : op->EnergyMeters(Meter).RptTS = true;
8057 0 : WriteMeterDictionaryItem(state,
8058 : ReportFreq,
8059 : StoreType::Summed,
8060 0 : op->EnergyMeters(Meter).TSRptNum,
8061 : indexGroupKey,
8062 : indexGroup,
8063 0 : op->EnergyMeters(Meter).TSRptNumChr,
8064 0 : op->EnergyMeters(Meter).Name,
8065 0 : op->EnergyMeters(Meter).Units,
8066 : false,
8067 : false);
8068 : }
8069 1150 : } else if (ReportFreq == ReportingFrequency::Hourly) {
8070 0 : if (op->EnergyMeters(Meter).RptHR) {
8071 0 : op->EnergyMeters(Meter).RptHR = true;
8072 0 : op->TrackingHourlyVariables = true;
8073 : } else {
8074 0 : op->EnergyMeters(Meter).RptHR = true;
8075 0 : op->TrackingHourlyVariables = true;
8076 0 : WriteMeterDictionaryItem(state,
8077 : ReportFreq,
8078 : StoreType::Summed,
8079 0 : op->EnergyMeters(Meter).HRRptNum,
8080 : indexGroupKey,
8081 : indexGroup,
8082 0 : op->EnergyMeters(Meter).HRRptNumChr,
8083 0 : op->EnergyMeters(Meter).Name,
8084 0 : op->EnergyMeters(Meter).Units,
8085 : false,
8086 : false);
8087 : }
8088 1150 : } else if (ReportFreq == ReportingFrequency::Daily) {
8089 0 : if (op->EnergyMeters(Meter).RptDY) {
8090 0 : op->EnergyMeters(Meter).RptDY = true;
8091 0 : op->TrackingDailyVariables = true;
8092 : } else {
8093 0 : op->EnergyMeters(Meter).RptDY = true;
8094 0 : op->TrackingDailyVariables = true;
8095 0 : WriteMeterDictionaryItem(state,
8096 : ReportFreq,
8097 : StoreType::Summed,
8098 0 : op->EnergyMeters(Meter).DYRptNum,
8099 : indexGroupKey,
8100 : indexGroup,
8101 0 : op->EnergyMeters(Meter).DYRptNumChr,
8102 0 : op->EnergyMeters(Meter).Name,
8103 0 : op->EnergyMeters(Meter).Units,
8104 : false,
8105 : false);
8106 : }
8107 1150 : } else if (ReportFreq == ReportingFrequency::Monthly) {
8108 1131 : if (op->EnergyMeters(Meter).RptMN) {
8109 44 : op->EnergyMeters(Meter).RptMN = true;
8110 44 : op->TrackingMonthlyVariables = true;
8111 : } else {
8112 1087 : op->EnergyMeters(Meter).RptMN = true;
8113 1087 : op->TrackingMonthlyVariables = true;
8114 4348 : WriteMeterDictionaryItem(state,
8115 : ReportFreq,
8116 : StoreType::Summed,
8117 1087 : op->EnergyMeters(Meter).MNRptNum,
8118 : indexGroupKey,
8119 : indexGroup,
8120 1087 : op->EnergyMeters(Meter).MNRptNumChr,
8121 1087 : op->EnergyMeters(Meter).Name,
8122 1087 : op->EnergyMeters(Meter).Units,
8123 : false,
8124 : false);
8125 : }
8126 19 : } else if (ReportFreq == ReportingFrequency::Yearly) {
8127 19 : if (op->EnergyMeters(Meter).RptYR) {
8128 18 : op->EnergyMeters(Meter).RptYR = true;
8129 18 : op->TrackingYearlyVariables = true;
8130 : } else {
8131 1 : op->EnergyMeters(Meter).RptYR = true;
8132 1 : op->TrackingMonthlyVariables = true;
8133 4 : WriteMeterDictionaryItem(state,
8134 : ReportFreq,
8135 : StoreType::Summed,
8136 1 : op->EnergyMeters(Meter).YRRptNum,
8137 : indexGroupKey,
8138 : indexGroup,
8139 1 : op->EnergyMeters(Meter).YRRptNumChr,
8140 1 : op->EnergyMeters(Meter).Name,
8141 1 : op->EnergyMeters(Meter).Units,
8142 : false,
8143 : false);
8144 : }
8145 0 : } else if (ReportFreq == ReportingFrequency::Simulation) {
8146 0 : if (op->EnergyMeters(Meter).RptSM) {
8147 0 : op->EnergyMeters(Meter).RptSM = true;
8148 0 : op->TrackingRunPeriodVariables = true;
8149 : } else {
8150 0 : op->EnergyMeters(Meter).RptSM = true;
8151 0 : op->TrackingRunPeriodVariables = true;
8152 0 : WriteMeterDictionaryItem(state,
8153 : ReportFreq,
8154 : StoreType::Summed,
8155 0 : op->EnergyMeters(Meter).SMRptNum,
8156 : indexGroupKey,
8157 : indexGroup,
8158 0 : op->EnergyMeters(Meter).SMRptNumChr,
8159 0 : op->EnergyMeters(Meter).Name,
8160 0 : op->EnergyMeters(Meter).Units,
8161 : false,
8162 : false);
8163 : }
8164 : } else {
8165 : }
8166 : }
8167 : }
8168 60 : }
8169 :
8170 769 : void ProduceRDDMDD(EnergyPlusData &state)
8171 : {
8172 :
8173 : // SUBROUTINE INFORMATION:
8174 : // AUTHOR Linda Lawrie
8175 : // DATE WRITTEN March 2009
8176 : // MODIFIED na
8177 : // RE-ENGINEERED na
8178 :
8179 : // PURPOSE OF THIS SUBROUTINE:
8180 : // provide a single call for writing out the Report Data Dictionary and Meter Data Dictionary.
8181 :
8182 : // Using/Aliasing
8183 : using namespace OutputProcessor;
8184 : using General::ScanForReports;
8185 : using SortAndStringUtilities::SetupAndSort;
8186 :
8187 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8188 1538 : std::string VarOption1;
8189 1538 : std::string VarOption2;
8190 : bool DoReport;
8191 : int Item;
8192 : bool SortByName;
8193 : int ItemPtr;
8194 :
8195 : struct VariableTypes
8196 : {
8197 : // Members
8198 : int RealIntegerType; // Real= 1, Integer=2
8199 : int VarPtr; // pointer to real/integer VariableTypes structures
8200 : int TimeStepType;
8201 : int StoreType;
8202 : std::string UnitsString;
8203 :
8204 : // Default Constructor
8205 : VariableTypes() : RealIntegerType(0), VarPtr(0), TimeStepType(0), StoreType(0)
8206 : {
8207 : }
8208 : };
8209 :
8210 769 : auto &op(state.dataOutputProcessor);
8211 :
8212 : // See if Report Variables should be turned on
8213 769 : SortByName = false;
8214 769 : ScanForReports(state, "VariableDictionary", DoReport, _, VarOption1, VarOption2);
8215 : // IF (.not. DoReport) RETURN
8216 :
8217 769 : if (DoReport) {
8218 755 : op->ProduceReportVDD = ReportVDD::Yes;
8219 755 : if (VarOption1 == std::string("IDF")) {
8220 248 : op->ProduceReportVDD = ReportVDD::IDF;
8221 : }
8222 755 : if (!VarOption2.empty()) {
8223 67 : if (UtilityRoutines::SameString(VarOption2, "Name") || UtilityRoutines::SameString(VarOption2, "AscendingName")) {
8224 3 : SortByName = true;
8225 : }
8226 : }
8227 : }
8228 :
8229 769 : state.files.rdd.ensure_open(state, "ProduceRDDMDD", state.files.outputControl.rdd);
8230 769 : state.files.mdd.ensure_open(state, "ProduceRDDMDD", state.files.outputControl.mdd);
8231 769 : if (op->ProduceReportVDD == ReportVDD::Yes) {
8232 507 : print(state.files.rdd, "Program Version,{},{}{}", state.dataStrGlobals->VerStringVar, state.dataStrGlobals->IDDVerString, '\n');
8233 507 : print(state.files.rdd, "Var Type (reported time step),Var Report Type,Variable Name [Units]{}", '\n');
8234 :
8235 507 : print(state.files.mdd, "Program Version,{},{}{}", state.dataStrGlobals->VerStringVar, state.dataStrGlobals->IDDVerString, '\n');
8236 507 : print(state.files.mdd, "Var Type (reported time step),Var Report Type,Variable Name [Units]{}", '\n');
8237 262 : } else if (op->ProduceReportVDD == ReportVDD::IDF) {
8238 248 : print(state.files.rdd, "! Program Version,{},{}{}", state.dataStrGlobals->VerStringVar, state.dataStrGlobals->IDDVerString, '\n');
8239 248 : print(state.files.rdd, "! Output:Variable Objects (applicable to this run){}", '\n');
8240 :
8241 248 : print(state.files.mdd, "! Program Version,{},{}{}", state.dataStrGlobals->VerStringVar, state.dataStrGlobals->IDDVerString, '\n');
8242 248 : print(state.files.mdd, "! Output:Meter Objects (applicable to this run){}", '\n');
8243 : }
8244 :
8245 1538 : Array1D_string VariableNames(op->NumVariablesForOutput);
8246 446578 : for (int i = 1; i <= op->NumVariablesForOutput; ++i)
8247 445809 : VariableNames(i) = op->DDVariableTypes(i).VarNameOnly;
8248 1538 : Array1D_int iVariableNames(op->NumVariablesForOutput);
8249 :
8250 769 : if (SortByName) {
8251 3 : SetupAndSort(VariableNames, iVariableNames);
8252 : } else {
8253 445371 : for (Item = 1; Item <= op->NumVariablesForOutput; ++Item) {
8254 444605 : iVariableNames(Item) = Item;
8255 : }
8256 : }
8257 :
8258 446578 : for (Item = 1; Item <= op->NumVariablesForOutput; ++Item) {
8259 445809 : if (op->ProduceReportVDD == ReportVDD::Yes) {
8260 289235 : ItemPtr = iVariableNames(Item);
8261 289235 : if (!op->DDVariableTypes(ItemPtr).ReportedOnDDFile) {
8262 1156924 : print(state.files.rdd,
8263 : "{},{},{}{}{}",
8264 578462 : StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType),
8265 578462 : standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType),
8266 : VariableNames(Item),
8267 578462 : unitStringFromDDitem(state, ItemPtr),
8268 289231 : '\n');
8269 1156924 : state.dataResultsFramework->resultsFramework->RDD.push_back(StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType) + "," +
8270 1156924 : standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType) + "," +
8271 1156924 : VariableNames(Item) + unitStringFromDDitem(state, ItemPtr));
8272 289231 : op->DDVariableTypes(ItemPtr).ReportedOnDDFile = true;
8273 289239 : while (op->DDVariableTypes(ItemPtr).Next != 0) {
8274 4 : if (SortByName) {
8275 0 : ++ItemPtr;
8276 : } else {
8277 4 : ItemPtr = op->DDVariableTypes(ItemPtr).Next;
8278 : }
8279 16 : print(state.files.rdd,
8280 : "{},{},{}{}{}",
8281 8 : StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType),
8282 8 : standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType),
8283 : VariableNames(Item),
8284 8 : unitStringFromDDitem(state, ItemPtr),
8285 4 : '\n');
8286 16 : state.dataResultsFramework->resultsFramework->RDD.push_back(StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType) +
8287 8 : "," +
8288 16 : standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType) +
8289 16 : "," + VariableNames(Item) + unitStringFromDDitem(state, ItemPtr));
8290 4 : op->DDVariableTypes(ItemPtr).ReportedOnDDFile = true;
8291 : }
8292 : }
8293 156574 : } else if (op->ProduceReportVDD == ReportVDD::IDF) {
8294 148380 : ItemPtr = iVariableNames(Item);
8295 148380 : if (!op->DDVariableTypes(ItemPtr).ReportedOnDDFile) {
8296 593516 : print(state.files.rdd,
8297 : "Output:Variable,*,{},hourly; !- {} {}{}{}",
8298 : VariableNames(Item),
8299 296758 : StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType),
8300 296758 : standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType),
8301 296758 : unitStringFromDDitem(state, ItemPtr),
8302 148379 : '\n');
8303 593516 : state.dataResultsFramework->resultsFramework->RDD.push_back(StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType) + "," +
8304 593516 : standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType) + "," +
8305 593516 : VariableNames(Item) + unitStringFromDDitem(state, ItemPtr));
8306 148379 : op->DDVariableTypes(ItemPtr).ReportedOnDDFile = true;
8307 148381 : while (op->DDVariableTypes(ItemPtr).Next != 0) {
8308 1 : if (SortByName) {
8309 0 : ++ItemPtr;
8310 : } else {
8311 1 : ItemPtr = op->DDVariableTypes(ItemPtr).Next;
8312 : }
8313 4 : print(state.files.rdd,
8314 : "Output:Variable,*,{},hourly; !- {} {}{}{}",
8315 : VariableNames(Item),
8316 2 : StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType),
8317 2 : standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType),
8318 2 : unitStringFromDDitem(state, ItemPtr),
8319 1 : '\n');
8320 4 : state.dataResultsFramework->resultsFramework->RDD.push_back(StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType) +
8321 2 : "," +
8322 4 : standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType) +
8323 4 : "," + VariableNames(Item) + unitStringFromDDitem(state, ItemPtr));
8324 1 : op->DDVariableTypes(ItemPtr).ReportedOnDDFile = true;
8325 : }
8326 : }
8327 : }
8328 : }
8329 769 : state.files.rdd.close();
8330 :
8331 : // Now EnergyMeter variables
8332 769 : VariableNames.allocate(op->NumEnergyMeters);
8333 769 : iVariableNames.allocate(op->NumEnergyMeters);
8334 769 : if (SortByName) {
8335 202 : for (Item = 1; Item <= op->NumEnergyMeters; ++Item) {
8336 199 : VariableNames(Item) = op->EnergyMeters(Item).Name;
8337 : }
8338 3 : SetupAndSort(VariableNames, iVariableNames);
8339 : } else {
8340 93456 : for (Item = 1; Item <= op->NumEnergyMeters; ++Item) {
8341 92690 : VariableNames(Item) = op->EnergyMeters(Item).Name;
8342 92690 : iVariableNames(Item) = Item;
8343 : }
8344 : }
8345 :
8346 93658 : for (Item = 1; Item <= op->NumEnergyMeters; ++Item) {
8347 92889 : ItemPtr = iVariableNames(Item);
8348 92889 : if (op->ProduceReportVDD == ReportVDD::Yes) {
8349 185544 : print(state.files.mdd,
8350 : "Zone,Meter,{}{}{}",
8351 46386 : op->EnergyMeters(ItemPtr).Name,
8352 92772 : unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units),
8353 46386 : '\n');
8354 92772 : state.dataResultsFramework->resultsFramework->MDD.push_back("Zone,Meter," + op->EnergyMeters(ItemPtr).Name +
8355 92772 : unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units));
8356 46503 : } else if (op->ProduceReportVDD == ReportVDD::IDF) {
8357 179840 : print(state.files.mdd,
8358 : "Output:Meter,{},hourly; !-{}{}",
8359 44960 : op->EnergyMeters(ItemPtr).Name,
8360 89920 : unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units),
8361 44960 : '\n');
8362 89920 : state.dataResultsFramework->resultsFramework->MDD.push_back("Output:Meter," + op->EnergyMeters(ItemPtr).Name +
8363 89920 : unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units));
8364 179840 : print(state.files.mdd,
8365 : "Output:Meter:Cumulative,{},hourly; !-{}{}",
8366 44960 : op->EnergyMeters(ItemPtr).Name,
8367 89920 : unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units),
8368 44960 : '\n');
8369 89920 : state.dataResultsFramework->resultsFramework->MDD.push_back("Output:Meter:Cumulative," + op->EnergyMeters(ItemPtr).Name +
8370 89920 : unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units));
8371 : }
8372 : }
8373 769 : state.files.mdd.close();
8374 769 : }
8375 :
8376 6084576 : void AddToOutputVariableList(EnergyPlusData &state,
8377 : std::string_view const VarName, // Variable Name
8378 : OutputProcessor::TimeStepType const TimeStepType,
8379 : OutputProcessor::StoreType const StateType,
8380 : OutputProcessor::VariableType const VariableType,
8381 : OutputProcessor::Unit const unitsForVar,
8382 : Optional_string_const customUnitName // the custom name for the units from EMS definition of units
8383 : )
8384 : {
8385 :
8386 : // SUBROUTINE INFORMATION:
8387 : // AUTHOR Linda Lawrie
8388 : // DATE WRITTEN August 2010
8389 : // MODIFIED na
8390 : // RE-ENGINEERED na
8391 :
8392 : // PURPOSE OF THIS SUBROUTINE:
8393 : // This routine maintains a unique list of Output Variables for the
8394 : // Variable Dictionary output.
8395 :
8396 : // METHODOLOGY EMPLOYED:
8397 : // na
8398 :
8399 : // REFERENCES:
8400 : // na
8401 :
8402 : // Using/Aliasing
8403 : using namespace OutputProcessor;
8404 :
8405 : // Locals
8406 : // SUBROUTINE ARGUMENT DEFINITIONS:
8407 :
8408 : // SUBROUTINE PARAMETER DEFINITIONS:
8409 : // na
8410 :
8411 : // INTERFACE BLOCK SPECIFICATIONS:
8412 : // na
8413 :
8414 : // DERIVED TYPE DEFINITIONS:
8415 : // na
8416 :
8417 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8418 6084576 : auto &op(state.dataOutputProcessor);
8419 :
8420 6084576 : int dup = 0; // for duplicate variable name
8421 6084576 : if (op->NumVariablesForOutput > 0) {
8422 6083805 : dup = UtilityRoutines::FindItemInList(VarName, op->DDVariableTypes, &VariableTypeForDDOutput::VarNameOnly, op->NumVariablesForOutput);
8423 : } else {
8424 771 : op->DDVariableTypes.allocate(LVarAllocInc);
8425 771 : op->MaxVariablesForOutput = LVarAllocInc;
8426 : }
8427 6084576 : if (dup == 0) {
8428 446765 : ++op->NumVariablesForOutput;
8429 446765 : if (op->NumVariablesForOutput > op->MaxVariablesForOutput) {
8430 1 : op->DDVariableTypes.redimension(op->MaxVariablesForOutput += LVarAllocInc);
8431 : }
8432 446765 : op->DDVariableTypes(op->NumVariablesForOutput).timeStepType = TimeStepType;
8433 446765 : op->DDVariableTypes(op->NumVariablesForOutput).storeType = StateType;
8434 446765 : op->DDVariableTypes(op->NumVariablesForOutput).variableType = VariableType;
8435 446765 : op->DDVariableTypes(op->NumVariablesForOutput).VarNameOnly = VarName;
8436 446765 : op->DDVariableTypes(op->NumVariablesForOutput).units = unitsForVar;
8437 446765 : if (present(customUnitName) && unitsForVar == OutputProcessor::Unit::customEMS) {
8438 10 : op->DDVariableTypes(op->NumVariablesForOutput).unitNameCustomEMS = customUnitName;
8439 : }
8440 5637811 : } else if (unitsForVar != op->DDVariableTypes(dup).units) { // not the same as first units
8441 6 : int dup2 = 0; // for duplicate variable name
8442 8 : while (op->DDVariableTypes(dup).Next != 0) {
8443 3 : if (unitsForVar != op->DDVariableTypes(op->DDVariableTypes(dup).Next).units) {
8444 1 : dup = op->DDVariableTypes(dup).Next;
8445 1 : continue;
8446 : }
8447 1 : dup2 = op->DDVariableTypes(dup).Next;
8448 1 : break;
8449 : }
8450 6 : if (dup2 == 0) {
8451 5 : ++op->NumVariablesForOutput;
8452 5 : if (op->NumVariablesForOutput > op->MaxVariablesForOutput) {
8453 0 : op->DDVariableTypes.redimension(op->MaxVariablesForOutput += LVarAllocInc);
8454 : }
8455 5 : op->DDVariableTypes(op->NumVariablesForOutput).timeStepType = TimeStepType;
8456 5 : op->DDVariableTypes(op->NumVariablesForOutput).storeType = StateType;
8457 5 : op->DDVariableTypes(op->NumVariablesForOutput).variableType = VariableType;
8458 5 : op->DDVariableTypes(op->NumVariablesForOutput).VarNameOnly = VarName;
8459 5 : op->DDVariableTypes(op->NumVariablesForOutput).units = unitsForVar;
8460 5 : if (present(customUnitName) && unitsForVar == OutputProcessor::Unit::customEMS) {
8461 0 : op->DDVariableTypes(op->NumVariablesForOutput).unitNameCustomEMS = customUnitName;
8462 : }
8463 5 : op->DDVariableTypes(dup).Next = op->NumVariablesForOutput;
8464 : }
8465 : }
8466 6084576 : }
8467 :
8468 771 : int initErrorFile(EnergyPlusData &state)
8469 : {
8470 771 : state.files.err_stream = std::make_unique<std::ofstream>(state.files.outputErrFilePath);
8471 771 : if (state.files.err_stream->bad()) {
8472 0 : DisplayString(state, "ERROR: Could not open file " + state.files.outputErrFilePath.string() + " for output (write).");
8473 0 : return EXIT_FAILURE;
8474 : }
8475 771 : return EXIT_SUCCESS;
8476 : }
8477 :
8478 2313 : } // namespace EnergyPlus
|