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 <map>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 : #include <ObjexxFCL/ArrayS.functions.hh>
54 : #include <ObjexxFCL/Fmath.hh>
55 : #include <ObjexxFCL/string.functions.hh>
56 :
57 : // EnergyPlus Headers
58 : #include <EnergyPlus/CommandLineInterface.hh>
59 : #include <EnergyPlus/Data/EnergyPlusData.hh>
60 : #include <EnergyPlus/DataEnvironment.hh>
61 : #include <EnergyPlus/DataStringGlobals.hh>
62 : #include <EnergyPlus/DataSystemVariables.hh>
63 : #include <EnergyPlus/EMSManager.hh>
64 : #include <EnergyPlus/FileSystem.hh>
65 : #include <EnergyPlus/General.hh>
66 : #include <EnergyPlus/GlobalNames.hh>
67 : #include <EnergyPlus/InputProcessing/CsvParser.hh>
68 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
69 : #include <EnergyPlus/OutputProcessor.hh>
70 : #include <EnergyPlus/ScheduleManager.hh>
71 : #include <EnergyPlus/StringUtilities.hh>
72 : #include <EnergyPlus/UtilityRoutines.hh>
73 : #include <EnergyPlus/WeatherManager.hh>
74 :
75 : namespace EnergyPlus {
76 :
77 : namespace ScheduleManager {
78 : // Module containing the Schedule Manager routines
79 :
80 : // MODULE INFORMATION:
81 : // AUTHOR Linda K. Lawrie
82 : // DATE WRITTEN September 1997
83 : // MODIFIED January 2003 -- added sub-hourly schedule possibility (and interval scheduling)
84 : // J. Glazer January 2005 -- added Schedule:File
85 : // Michael Wetter February 2010 -- added Schedule for external Interface
86 : // L Lawrie - October 2012 - added sub-hourly option for Schedule:File
87 :
88 : // PURPOSE OF THIS MODULE:
89 : // To provide the capabilities of getting the schedule data from the input,
90 : // validating it, and storing it in such a manner that the schedule manager
91 : // can provide the scheduling value needs for the simulation.
92 :
93 : // REFERENCES:
94 : // Proposal for Schedule Manager in EnergyPlus (Rick Strand)
95 :
96 : // MODULE PARAMETER DEFINITIONS
97 : static constexpr std::string_view BlankString;
98 : // Day types are 1-based for EMS and output and other uses, so add a dummy
99 : constexpr std::array<std::string_view, static_cast<int>(DayType::Num)> dayTypeNames{"dummy",
100 : "Sunday",
101 : "Monday",
102 : "Tuesday",
103 : "Wednesday",
104 : "Thursday",
105 : "Friday",
106 : "Saturday",
107 : "Holiday",
108 : "SummerDesignDay",
109 : "WinterDesignDay",
110 : "CustomDay1",
111 : "CustomDay2"};
112 :
113 : constexpr std::array<std::string_view, static_cast<int>(DayType::Num)> dayTypeNamesUC{"dummy",
114 : "SUNDAY",
115 : "MONDAY",
116 : "TUESDAY",
117 : "WEDNESDAY",
118 : "THURSDAY",
119 : "FRIDAY",
120 : "SATURDAY",
121 : "HOLIDAY",
122 : "SUMMERDESIGNDAY",
123 : "WINTERDESIGNDAY",
124 : "CUSTOMDAY1",
125 : "CUSTOMDAY2"};
126 :
127 : int constexpr numScheduleTypeLimitUnitTypes = 14;
128 : static constexpr std::array<std::string_view, static_cast<int>(numScheduleTypeLimitUnitTypes)> scheduleTypeLimitUnitTypes{"DIMENSIONLESS",
129 : "TEMPERATURE",
130 : "DELTATEMPERATURE",
131 : "PRECIPITATIONRATE",
132 : "ANGLE",
133 : "CONVECTIONCOEFFICIENT",
134 : "ACTIVITYLEVEL",
135 : "VELOCITY",
136 : "CAPACITY",
137 : "POWER",
138 : "AVAILABILITY",
139 : "PERCENT",
140 : "CONTROL",
141 : "MODE"};
142 :
143 : constexpr std::array<std::string_view, static_cast<int>(OutputReportLevel::Num)> outputScheduleReportLevelNames = {"Hourly", "Timestep"};
144 : constexpr std::array<std::string_view, static_cast<int>(OutputReportLevel::Num)> outputScheduleReportLevelNamesUC = {"HOURLY", "TIMESTEP"};
145 : constexpr std::array<std::string_view, static_cast<int>(ScheduleInterpolation::Num)> interpolationTypes = {"No", "Average", "Linear"};
146 : constexpr std::array<std::string_view, static_cast<int>(ScheduleInterpolation::Num)> interpolationTypesUC = {"NO", "AVERAGE", "LINEAR"};
147 :
148 771 : void ProcessScheduleInput(EnergyPlusData &state)
149 : {
150 : // SUBROUTINE INFORMATION:
151 : // AUTHOR Linda K. Lawrie
152 : // DATE WRITTEN September 1997
153 : // MODIFIED Rui Zhang February 2010
154 : // RE-ENGINEERED na
155 :
156 : // PURPOSE OF THIS SUBROUTINE:
157 : // This subroutine processes the schedules input for EnergyPlus.
158 :
159 : // METHODOLOGY EMPLOYED:
160 : // Uses the standard get routines in the InputProcessor.
161 :
162 : // Using/Aliasing
163 : using DataStringGlobals::CharComma;
164 : using DataStringGlobals::CharSemicolon;
165 : using DataStringGlobals::CharSpace;
166 : using DataStringGlobals::CharTab;
167 : using DataSystemVariables::CheckForActualFilePath;
168 : using General::ProcessDateString;
169 :
170 : // Locals
171 : // SUBROUTINE PARAMETER DEFINITIONS:
172 771 : auto constexpr RoutineName("ProcessScheduleInput: ");
173 :
174 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
175 :
176 1542 : Array1D_int DaysInYear(366);
177 : int LoopIndex;
178 : int InLoopIndex;
179 : int DayIndex;
180 : int WeekIndex;
181 1542 : Array1D_string Alphas;
182 1542 : Array1D_string cAlphaFields;
183 1542 : Array1D_string cNumericFields;
184 1542 : Array1D<Real64> Numbers;
185 1542 : Array1D_bool lAlphaBlanks;
186 1542 : Array1D_bool lNumericBlanks;
187 : int NumAlphas;
188 : int NumNumbers;
189 : int Status;
190 : int StartMonth;
191 : int StartDay;
192 : int EndMonth;
193 : int EndDay;
194 : int StartPointer;
195 : int EndPointer;
196 : int NumPointer;
197 : int Count;
198 : int CheckIndex;
199 771 : bool ErrorsFound(false);
200 : bool NumErrorFlag;
201 : int SchedTypePtr;
202 1542 : std::string CFld; // Character field for error message
203 : // CHARACTER(len=20) CFld1 ! Character field for error message
204 : int NumHrDaySchedules; // Number of "hourly" dayschedules
205 : int NumIntDaySchedules; // Number of "interval" dayschedules
206 : int NumExternalInterfaceSchedules; // Number of "PtolemyServer ExternalInterface" "compact" Schedules
207 : int NumExternalInterfaceFunctionalMockupUnitImportSchedules; // Number of "FunctionalMockupUnitImport ExternalInterface"
208 : // "compact" Schedules ! added for FMU Import
209 : int NumExternalInterfaceFunctionalMockupUnitExportSchedules; // Number of "FunctionalMockupUnitExport ExternalInterface"
210 : // "compact" Schedules ! added for FMU Export
211 : int NumLstDaySchedules; // Number of "list" dayschedules
212 : int NumRegDaySchedules; // Number of hourly+interval+list dayschedules
213 : int NumRegWeekSchedules; // Number of "regular" Weekschedules
214 : int NumRegSchedules; // Number of "regular" Schedules
215 : int NumCptWeekSchedules; // Number of "compact" WeekSchedules
216 : int NumCptSchedules; // Number of "compact" Schedules
217 : int NumCommaFileSchedules; // Number of Schedule:File schedules
218 : int NumConstantSchedules; // Number of "constant" schedules
219 771 : int NumCSVAllColumnsSchedules = 0; // Number of imported shading schedules
220 : int NumCommaFileShading; // Number of shading csv schedules
221 : int TS; // Counter for Num Of Time Steps in Hour
222 : int Hr; // Hour Counter
223 1542 : Array2D<Real64> MinuteValue; // Temporary for processing interval schedules
224 1542 : Array2D_bool SetMinuteValue; // Temporary for processing interval schedules
225 : int NumFields;
226 : int SCount;
227 : // LOGICAL RptSchedule
228 : int RptLevel;
229 : int CurMinute;
230 : int MinutesPerItem;
231 : int NumExpectedItems;
232 : int MaxNums;
233 : int MaxAlps;
234 : int AddWeekSch;
235 : int AddDaySch;
236 1542 : Array1D_bool AllDays(maxDayTypes);
237 1542 : Array1D_bool TheseDays(maxDayTypes);
238 : bool ErrorHere;
239 : int SchNum;
240 : int WkCount;
241 : int DyCount;
242 : int NumField;
243 : WeatherManager::DateType PDateType;
244 : int PWeekDay;
245 : int ThruField;
246 : int UntilFld;
247 : int xxcount;
248 : // REAL(r64) tempval
249 1542 : std::string CurrentThrough;
250 1542 : std::string LastFor;
251 1542 : std::string errmsg;
252 : int kdy;
253 : // for SCHEDULE:FILE
254 : int rowCnt;
255 1542 : std::string subString;
256 : int iDay;
257 : int hDay;
258 : int jHour;
259 : int kDayType;
260 : Real64 curHrVal;
261 : std::string::size_type sPos;
262 1542 : std::string CurrentModuleObject; // for ease in getting objects
263 : int MaxNums1;
264 : char ColumnSep;
265 : bool FileIntervalInterpolated;
266 : int rowLimitCount;
267 : int skiprowCount;
268 : int curcolCount;
269 : int numHourlyValues;
270 771 : int numerrors = 0;
271 : int ifld;
272 : int hrLimitCount;
273 :
274 771 : if (state.dataScheduleMgr->ScheduleInputProcessed) {
275 0 : return;
276 : }
277 771 : state.dataScheduleMgr->ScheduleInputProcessed = true;
278 :
279 771 : MaxNums = 1; // Need at least 1 number because it's used as a local variable in the Schedule Types loop
280 771 : MaxAlps = 0;
281 :
282 771 : CurrentModuleObject = "ScheduleTypeLimits";
283 771 : state.dataScheduleMgr->NumScheduleTypes = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
284 771 : if (state.dataScheduleMgr->NumScheduleTypes > 0) {
285 769 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
286 769 : MaxNums = max(MaxNums, NumNumbers);
287 769 : MaxAlps = max(MaxAlps, NumAlphas);
288 : }
289 771 : CurrentModuleObject = "Schedule:Day:Hourly";
290 771 : NumHrDaySchedules = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
291 771 : if (NumHrDaySchedules > 0) {
292 16 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
293 16 : MaxNums = max(MaxNums, NumNumbers);
294 16 : MaxAlps = max(MaxAlps, NumAlphas);
295 : }
296 771 : CurrentModuleObject = "Schedule:Day:Interval";
297 771 : NumIntDaySchedules = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
298 771 : if (NumIntDaySchedules > 0) {
299 6 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
300 6 : MaxNums = max(MaxNums, NumNumbers);
301 6 : MaxAlps = max(MaxAlps, NumAlphas);
302 : }
303 771 : CurrentModuleObject = "Schedule:Day:List";
304 771 : NumLstDaySchedules = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
305 771 : if (NumLstDaySchedules > 0) {
306 1 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
307 1 : MaxNums = max(MaxNums, NumNumbers);
308 1 : MaxAlps = max(MaxAlps, NumAlphas);
309 : }
310 771 : CurrentModuleObject = "Schedule:Week:Daily";
311 771 : NumRegWeekSchedules = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
312 771 : if (NumRegWeekSchedules > 0) {
313 16 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
314 16 : MaxNums = max(MaxNums, NumNumbers);
315 16 : MaxAlps = max(MaxAlps, NumAlphas);
316 : }
317 771 : CurrentModuleObject = "Schedule:Week:Compact";
318 771 : NumCptWeekSchedules = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
319 771 : if (NumCptWeekSchedules > 0) {
320 3 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
321 3 : MaxNums = max(MaxNums, NumNumbers);
322 3 : MaxAlps = max(MaxAlps, NumAlphas);
323 : }
324 771 : CurrentModuleObject = "Schedule:Year";
325 771 : NumRegSchedules = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
326 771 : if (NumRegSchedules > 0) {
327 19 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
328 19 : MaxNums = max(MaxNums, NumNumbers);
329 19 : MaxAlps = max(MaxAlps, NumAlphas);
330 : }
331 771 : CurrentModuleObject = "Schedule:Compact";
332 771 : NumCptSchedules = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
333 771 : if (NumCptSchedules > 0) {
334 743 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
335 743 : MaxNums = max(MaxNums, NumNumbers);
336 743 : MaxAlps = max(MaxAlps, NumAlphas + 1);
337 : }
338 771 : CurrentModuleObject = "Schedule:File";
339 771 : NumCommaFileSchedules = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
340 771 : if (NumCommaFileSchedules > 0) {
341 8 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
342 8 : MaxNums = max(MaxNums, NumNumbers);
343 8 : MaxAlps = max(MaxAlps, NumAlphas);
344 : }
345 :
346 771 : CurrentModuleObject = "Schedule:Constant";
347 771 : NumConstantSchedules = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
348 771 : if (NumConstantSchedules > 0) {
349 87 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
350 87 : MaxNums = max(MaxNums, NumNumbers);
351 87 : MaxAlps = max(MaxAlps, NumAlphas);
352 : }
353 771 : CurrentModuleObject = "ExternalInterface:Schedule";
354 771 : NumExternalInterfaceSchedules = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
355 : // added for FMI
356 771 : if (NumExternalInterfaceSchedules > 0) {
357 0 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
358 0 : MaxNums = max(MaxNums, NumNumbers);
359 0 : MaxAlps = max(MaxAlps, NumAlphas + 1);
360 : }
361 : // added for FMU Import
362 771 : CurrentModuleObject = "ExternalInterface:FunctionalMockupUnitImport:To:Schedule";
363 771 : NumExternalInterfaceFunctionalMockupUnitImportSchedules =
364 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
365 771 : if (NumExternalInterfaceFunctionalMockupUnitImportSchedules > 0) {
366 1 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
367 1 : MaxNums = max(MaxNums, NumNumbers);
368 1 : MaxAlps = max(MaxAlps, NumAlphas + 1);
369 : }
370 : // added for FMU Export
371 771 : CurrentModuleObject = "ExternalInterface:FunctionalMockupUnitExport:To:Schedule";
372 771 : NumExternalInterfaceFunctionalMockupUnitExportSchedules =
373 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
374 771 : if (NumExternalInterfaceFunctionalMockupUnitExportSchedules > 0) {
375 0 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
376 0 : MaxNums = max(MaxNums, NumNumbers);
377 0 : MaxAlps = max(MaxAlps, NumAlphas + 1);
378 : }
379 771 : CurrentModuleObject = "Output:Schedules";
380 771 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Count, NumAlphas, NumNumbers);
381 771 : MaxNums = max(MaxNums, NumNumbers);
382 771 : MaxAlps = max(MaxAlps, NumAlphas);
383 :
384 771 : Alphas.allocate(MaxAlps); // Maximum Alphas possible
385 771 : cAlphaFields.allocate(MaxAlps);
386 771 : cNumericFields.allocate(MaxNums);
387 771 : Numbers.dimension(MaxNums, 0.0); // Maximum Numbers possible
388 771 : lAlphaBlanks.dimension(MaxAlps, true);
389 771 : lNumericBlanks.dimension(MaxNums, true);
390 :
391 : // Prescan to determine extra day and week schedules due to compact schedule input
392 771 : AddWeekSch = 0;
393 771 : AddDaySch = 0;
394 771 : CurrentModuleObject = "Schedule:Compact";
395 771 : MaxNums1 = 0;
396 16195 : for (LoopIndex = 1; LoopIndex <= NumCptSchedules; ++LoopIndex) {
397 15424 : state.dataInputProcessing->inputProcessor->getObjectItem(
398 : state, CurrentModuleObject, LoopIndex, Alphas, NumAlphas, Numbers, NumNumbers, Status);
399 : // # 'THROUGH" => Number of additional week schedules
400 : // # 'FOR' => Number of additional day schedules
401 221410 : for (Count = 3; Count <= NumAlphas; ++Count) {
402 205986 : if (has_prefix(Alphas(Count), "THROUGH")) ++AddWeekSch;
403 205986 : if (has_prefix(Alphas(Count), "FOR")) ++AddDaySch;
404 205986 : if (has_prefix(Alphas(Count), "UNTIL")) ++MaxNums1;
405 : }
406 : }
407 771 : if (MaxNums1 > MaxNums) {
408 722 : MaxNums = MaxNums1;
409 722 : cNumericFields.deallocate();
410 722 : Numbers.deallocate();
411 722 : lNumericBlanks.deallocate();
412 722 : cNumericFields.allocate(MaxNums);
413 722 : Numbers.dimension(MaxNums, 0.0); // Maximum Numbers possible
414 722 : lNumericBlanks.dimension(MaxNums, true);
415 : }
416 : // add week and day schedules for each FILE:COMMA schedule
417 771 : AddWeekSch += NumCommaFileSchedules * 366; // number of days/year because need a week for each day
418 771 : AddDaySch += NumCommaFileSchedules * 366; // number of days/year
419 771 : AddWeekSch += NumConstantSchedules;
420 771 : AddDaySch += NumConstantSchedules;
421 : // add week and day schedules for each ExternalInterface:Schedule schedule
422 771 : AddWeekSch += NumExternalInterfaceSchedules * 366; // number of days/year because need a week for each day
423 771 : AddDaySch += NumExternalInterfaceSchedules; // one day schedule for ExternalInterface to update during run time
424 : // added for FMU Import
425 : // add week and day schedules for each ExternalInterface:FunctionalMockupUnitImport:Schedule
426 771 : AddWeekSch += NumExternalInterfaceFunctionalMockupUnitImportSchedules * 366; // number of days/year
427 : // because need a week for each day
428 771 : AddDaySch += NumExternalInterfaceFunctionalMockupUnitImportSchedules; // one day schedule for ExternalInterface
429 : // to update during run time
430 : // added for FMU Export
431 : // add week and day schedules for each ExternalInterface:FunctionalMockupUnitExport:Schedule
432 771 : AddWeekSch += NumExternalInterfaceFunctionalMockupUnitExportSchedules * 366; // number of days/year
433 : // because need a week for each day
434 771 : AddDaySch += NumExternalInterfaceFunctionalMockupUnitExportSchedules; // one day schedule for ExternalInterface
435 : // to update during run time
436 :
437 771 : CurrentModuleObject = "Schedule:File:Shading";
438 771 : NumCommaFileShading = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
439 771 : NumAlphas = 0;
440 771 : NumNumbers = 0;
441 771 : if (NumCommaFileShading > 1) {
442 0 : ShowWarningError(state, CurrentModuleObject + ": More than 1 occurrence of this object found, only first will be used.");
443 : }
444 :
445 1542 : std::map<fs::path, nlohmann::json>::iterator schedule_file_shading_result;
446 771 : if (NumCommaFileShading != 0) {
447 1 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
448 : CurrentModuleObject,
449 : 1,
450 : Alphas,
451 : NumAlphas,
452 : Numbers,
453 : NumNumbers,
454 : Status,
455 : lNumericBlanks,
456 : lAlphaBlanks,
457 : cAlphaFields,
458 : cNumericFields);
459 2 : std::string ShadingSunlitFracFileName = Alphas(1);
460 :
461 2 : std::string contextString = CurrentModuleObject + ", " + cAlphaFields(1) + ": ";
462 1 : state.files.TempFullFilePath.filePath = CheckForActualFilePath(state, ShadingSunlitFracFileName, contextString);
463 :
464 1 : if (state.files.TempFullFilePath.filePath.empty()) {
465 0 : ShowFatalError(state, "Program terminates due to previous condition.");
466 : }
467 :
468 1 : if (state.dataEnvrn->CurrentYearIsLeapYear) {
469 0 : rowLimitCount = 366 * 24 * state.dataGlobal->NumOfTimeStepInHour;
470 : } else {
471 1 : rowLimitCount = 365 * 24 * state.dataGlobal->NumOfTimeStepInHour;
472 : }
473 1 : ColumnSep = CharComma;
474 :
475 1 : schedule_file_shading_result = state.dataScheduleMgr->UniqueProcessedExternalFiles.find(state.files.TempFullFilePath.filePath);
476 1 : if (schedule_file_shading_result == state.dataScheduleMgr->UniqueProcessedExternalFiles.end()) {
477 :
478 1 : auto const ext = FileSystem::getFileType(state.files.TempFullFilePath.filePath);
479 1 : if (FileSystem::is_flat_file_type(ext)) {
480 2 : auto const schedule_data = FileSystem::readFile(state.files.TempFullFilePath.filePath);
481 2 : CsvParser csvParser;
482 1 : skiprowCount = 1; // make sure to parse header row only for Schedule:File:Shading
483 1 : auto it = state.dataScheduleMgr->UniqueProcessedExternalFiles.emplace(state.files.TempFullFilePath.filePath,
484 2 : csvParser.decode(schedule_data, ColumnSep, skiprowCount));
485 1 : schedule_file_shading_result = it.first;
486 0 : } else if (FileSystem::is_all_json_type(ext)) {
487 0 : auto schedule_data = FileSystem::readJSON(state.files.TempFullFilePath.filePath);
488 : auto it =
489 0 : state.dataScheduleMgr->UniqueProcessedExternalFiles.emplace(state.files.TempFullFilePath.filePath, std::move(schedule_data));
490 0 : schedule_file_shading_result = it.first;
491 : } else {
492 0 : ShowSevereError(state,
493 0 : fmt::format(R"({}{}="{}", {}="{}" has an unknown file extension and cannot be read by this program.)",
494 : RoutineName,
495 : CurrentModuleObject,
496 : Alphas(1),
497 : cAlphaFields(3),
498 : Alphas(3)));
499 0 : ShowFatalError(state, "Program terminates due to previous condition.");
500 : }
501 : }
502 :
503 1 : auto const &column_json = schedule_file_shading_result->second["values"].at(0); // assume there is at least 1 column
504 1 : rowCnt = column_json.size();
505 1 : NumCSVAllColumnsSchedules =
506 2 : schedule_file_shading_result->second["header"].get<std::set<std::string>>().size() - 1; // -1 to account for timestamp column
507 :
508 1 : if (rowCnt != rowLimitCount) {
509 0 : if (rowCnt < rowLimitCount) {
510 0 : ShowSevereError(state, format("{}{}=\"{}\" {} data values read.", RoutineName, CurrentModuleObject, Alphas(1), rowCnt));
511 0 : } else if (rowCnt > rowLimitCount) {
512 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\" too many data values read.");
513 : }
514 0 : ShowContinueError(
515 : state,
516 0 : format("Number of rows in the shading file must be a full year multiplied by the simulation TimeStep: {}.", rowLimitCount));
517 0 : ShowFatalError(state, "Program terminates due to previous condition.");
518 : }
519 :
520 : // schedule values have been filled into the CSVAllColumnNameAndValues map.
521 1 : state.dataScheduleMgr->ScheduleFileShadingProcessed = true;
522 :
523 1 : if (numerrors > 0) {
524 0 : ShowWarningError(
525 : state,
526 0 : format("{}{}=\"{}\" {} records had errors - these values are set to 0.", RoutineName, CurrentModuleObject, Alphas(1), numerrors));
527 : }
528 : }
529 :
530 : // add week and day schedules for each ExternalInterface:FunctionalMockupUnitExport:Schedule
531 771 : AddWeekSch += NumCSVAllColumnsSchedules * 366; // number of days/year
532 : // because need a week for each day
533 771 : AddDaySch += NumCSVAllColumnsSchedules * 366;
534 : // to update during run time
535 :
536 : // include additional schedules in with count
537 771 : NumRegDaySchedules = NumHrDaySchedules + NumIntDaySchedules + NumLstDaySchedules;
538 771 : state.dataScheduleMgr->NumDaySchedules = NumRegDaySchedules + AddDaySch;
539 771 : state.dataScheduleMgr->NumWeekSchedules = NumRegWeekSchedules + NumCptWeekSchedules + AddWeekSch;
540 1542 : state.dataScheduleMgr->NumSchedules = NumRegSchedules + NumCptSchedules + NumCommaFileSchedules + NumConstantSchedules +
541 771 : NumExternalInterfaceSchedules + NumExternalInterfaceFunctionalMockupUnitImportSchedules +
542 771 : NumExternalInterfaceFunctionalMockupUnitExportSchedules + NumCSVAllColumnsSchedules;
543 :
544 : //! Most initializations in the schedule data structures are taken care of in
545 : //! the definitions (see above)
546 :
547 771 : state.dataScheduleMgr->ScheduleType.allocate({0, state.dataScheduleMgr->NumScheduleTypes});
548 :
549 771 : state.dataScheduleMgr->DaySchedule.allocate({0, state.dataScheduleMgr->NumDaySchedules});
550 771 : state.dataScheduleMgr->UniqueDayScheduleNames.reserve(static_cast<unsigned>(state.dataScheduleMgr->NumDaySchedules));
551 : // Initialize
552 124474 : for (LoopIndex = 0; LoopIndex <= state.dataScheduleMgr->NumDaySchedules; ++LoopIndex) {
553 123703 : state.dataScheduleMgr->DaySchedule(LoopIndex).TSValue.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
554 3092575 : for (Count = 1; Count <= 24; ++Count) {
555 16664688 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
556 13695816 : state.dataScheduleMgr->DaySchedule(LoopIndex).TSValue(TS, Count) = 0.0;
557 : }
558 : }
559 : }
560 :
561 771 : state.dataScheduleMgr->WeekSchedule.allocate({0, state.dataScheduleMgr->NumWeekSchedules});
562 771 : state.dataScheduleMgr->UniqueWeekScheduleNames.reserve(static_cast<unsigned>(state.dataScheduleMgr->NumWeekSchedules));
563 :
564 771 : state.dataScheduleMgr->Schedule.allocate({-1, state.dataScheduleMgr->NumSchedules});
565 771 : state.dataScheduleMgr->UniqueScheduleNames.reserve(static_cast<unsigned>(state.dataScheduleMgr->NumSchedules));
566 771 : state.dataScheduleMgr->Schedule(-1).ScheduleTypePtr = -1;
567 771 : state.dataScheduleMgr->Schedule(-1).WeekSchedulePointer = 1;
568 771 : state.dataScheduleMgr->Schedule(0).ScheduleTypePtr = 0;
569 771 : state.dataScheduleMgr->Schedule(0).WeekSchedulePointer = 0;
570 :
571 771 : print(state.files.audit.ensure_open(state, "ProcessScheduleInput", state.files.outputControl.audit),
572 : "{}\n",
573 771 : " Processing Schedule Input -- Start");
574 :
575 : //!! Get Schedule Types
576 :
577 771 : CurrentModuleObject = "ScheduleTypeLimits";
578 4826 : for (LoopIndex = 1; LoopIndex <= state.dataScheduleMgr->NumScheduleTypes; ++LoopIndex) {
579 4055 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
580 : CurrentModuleObject,
581 : LoopIndex,
582 : Alphas,
583 : NumAlphas,
584 : Numbers,
585 : NumNumbers,
586 : Status,
587 : lNumericBlanks,
588 : lAlphaBlanks,
589 : cAlphaFields,
590 : cNumericFields);
591 4055 : UtilityRoutines::IsNameEmpty(state, Alphas(1), CurrentModuleObject, ErrorsFound);
592 :
593 4055 : state.dataScheduleMgr->ScheduleType(LoopIndex).Name = Alphas(1);
594 4055 : if (lNumericBlanks(1) || lNumericBlanks(2)) {
595 951 : state.dataScheduleMgr->ScheduleType(LoopIndex).Limited = false;
596 3104 : } else if (!lNumericBlanks(1) && !lNumericBlanks(2)) {
597 3104 : state.dataScheduleMgr->ScheduleType(LoopIndex).Limited = true;
598 : }
599 4055 : if (!lNumericBlanks(1)) {
600 3110 : state.dataScheduleMgr->ScheduleType(LoopIndex).Minimum = Numbers(1);
601 : }
602 4055 : if (!lNumericBlanks(2)) {
603 3104 : state.dataScheduleMgr->ScheduleType(LoopIndex).Maximum = Numbers(2);
604 : }
605 4055 : if (state.dataScheduleMgr->ScheduleType(LoopIndex).Limited) {
606 3104 : if (Alphas(2) == "DISCRETE" || Alphas(2) == "INTEGER") {
607 1325 : state.dataScheduleMgr->ScheduleType(LoopIndex).IsReal = false;
608 : } else {
609 1779 : if (Alphas(2) != "CONTINUOUS" && Alphas(2) != "REAL") {
610 0 : ShowWarningError(state,
611 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" +
612 0 : state.dataScheduleMgr->ScheduleType(LoopIndex).Name + "\", invalid " + cAlphaFields(2) + '=' +
613 0 : Alphas(2));
614 0 : ErrorsFound = true;
615 : }
616 1779 : state.dataScheduleMgr->ScheduleType(LoopIndex).IsReal = true;
617 : }
618 : }
619 4055 : if (NumAlphas >= 3) {
620 563 : if (!lAlphaBlanks(3)) {
621 563 : state.dataScheduleMgr->ScheduleType(LoopIndex).UnitType = getEnumerationValue(scheduleTypeLimitUnitTypes, Alphas(3)) + 1;
622 563 : if (state.dataScheduleMgr->ScheduleType(LoopIndex).UnitType == 0) {
623 0 : ShowWarningError(state,
624 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(3) + "=\"" +
625 0 : Alphas(3) + "\" is invalid.");
626 : }
627 : }
628 : }
629 4055 : if (state.dataScheduleMgr->ScheduleType(LoopIndex).Limited) {
630 3104 : if (state.dataScheduleMgr->ScheduleType(LoopIndex).Minimum > state.dataScheduleMgr->ScheduleType(LoopIndex).Maximum) {
631 0 : if (state.dataScheduleMgr->ScheduleType(LoopIndex).IsReal) {
632 0 : ShowSevereError(state,
633 0 : format("{}{}=\"{}\", {} [{:.2R}] > {} [{:.2R}].",
634 : RoutineName,
635 : CurrentModuleObject,
636 : Alphas(1),
637 : cNumericFields(1),
638 0 : state.dataScheduleMgr->ScheduleType(LoopIndex).Minimum,
639 : cNumericFields(2),
640 0 : state.dataScheduleMgr->ScheduleType(LoopIndex).Maximum));
641 0 : ShowContinueError(state, " Other warning/severes about schedule values may appear.");
642 : } else {
643 0 : ShowSevereError(state,
644 0 : format("{}{}=\"{}\", {} [{:.0R}] > {} [{:.0R}].",
645 : RoutineName,
646 : CurrentModuleObject,
647 : Alphas(1),
648 : cNumericFields(1),
649 0 : state.dataScheduleMgr->ScheduleType(LoopIndex).Minimum,
650 : cNumericFields(2),
651 0 : state.dataScheduleMgr->ScheduleType(LoopIndex).Maximum));
652 0 : ShowContinueError(state, " Other warning/severes about schedule values may appear.");
653 : }
654 : }
655 : }
656 : }
657 :
658 : //!! Get Day Schedules (all types)
659 :
660 : //!!=> Get "DAYSCHEDULE" (Hourly)
661 :
662 771 : Count = 0;
663 771 : CurrentModuleObject = "Schedule:Day:Hourly";
664 913 : for (LoopIndex = 1; LoopIndex <= NumHrDaySchedules; ++LoopIndex) {
665 142 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
666 : CurrentModuleObject,
667 : LoopIndex,
668 : Alphas,
669 : NumAlphas,
670 : Numbers,
671 : NumNumbers,
672 : Status,
673 : lNumericBlanks,
674 : lAlphaBlanks,
675 : cAlphaFields,
676 : cNumericFields);
677 284 : GlobalNames::VerifyUniqueInterObjectName(
678 284 : state, state.dataScheduleMgr->UniqueDayScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
679 142 : ++Count;
680 142 : state.dataScheduleMgr->DaySchedule(Count).Name = Alphas(1);
681 : // Validate ScheduleType
682 142 : if (state.dataScheduleMgr->NumScheduleTypes > 0) {
683 142 : CheckIndex =
684 284 : UtilityRoutines::FindItemInList(Alphas(2), state.dataScheduleMgr->ScheduleType({1, state.dataScheduleMgr->NumScheduleTypes}));
685 142 : if (CheckIndex == 0) {
686 0 : if (!lAlphaBlanks(2)) {
687 0 : ShowWarningError(state,
688 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(2) + "=\"" +
689 0 : Alphas(2) + "\" not found -- will not be validated");
690 : } else {
691 0 : ShowWarningError(state,
692 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Blank " + cAlphaFields(2) +
693 : " input -- will not be validated.");
694 : }
695 : } else {
696 142 : state.dataScheduleMgr->DaySchedule(Count).ScheduleTypePtr = CheckIndex;
697 : }
698 : }
699 3550 : for (Hr = 1; Hr <= 24; ++Hr) {
700 3408 : state.dataScheduleMgr->DaySchedule(Count).TSValue({1, state.dataGlobal->NumOfTimeStepInHour}, Hr) = Numbers(Hr);
701 : }
702 142 : state.dataScheduleMgr->DaySchedule(Count).IntervalInterpolated = ScheduleInterpolation::No;
703 142 : SchedTypePtr = state.dataScheduleMgr->DaySchedule(Count).ScheduleTypePtr;
704 142 : if (state.dataScheduleMgr->ScheduleType(SchedTypePtr).Limited) {
705 268 : if (any_lt(state.dataScheduleMgr->DaySchedule(Count).TSValue, state.dataScheduleMgr->ScheduleType(SchedTypePtr).Minimum) ||
706 134 : any_gt(state.dataScheduleMgr->DaySchedule(Count).TSValue, state.dataScheduleMgr->ScheduleType(SchedTypePtr).Maximum)) {
707 0 : ShowWarningError(state,
708 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Values are outside of range for " +
709 0 : cAlphaFields(2) + '=' + Alphas(2));
710 : }
711 : }
712 142 : if (!state.dataScheduleMgr->ScheduleType(SchedTypePtr).IsReal) {
713 : // Make sure each is integer
714 12 : NumErrorFlag = false; // only show error message once
715 300 : for (Hr = 1; Hr <= 24; ++Hr) {
716 2304 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
717 4032 : if (state.dataScheduleMgr->DaySchedule(Count).TSValue(TS, Hr) !=
718 2016 : int(state.dataScheduleMgr->DaySchedule(Count).TSValue(TS, Hr))) {
719 0 : if (!NumErrorFlag) {
720 0 : ShowWarningError(state,
721 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
722 0 : "\", One or more values are not integer as required by " + cAlphaFields(2) + '=' + Alphas(2));
723 0 : NumErrorFlag = true;
724 : }
725 : }
726 : }
727 : }
728 : }
729 : }
730 :
731 771 : MinuteValue.allocate(60, 24);
732 771 : SetMinuteValue.allocate(60, 24);
733 :
734 : //!! Get "DaySchedule:Interval"
735 :
736 771 : CurrentModuleObject = "Schedule:Day:Interval";
737 947 : for (LoopIndex = 1; LoopIndex <= NumIntDaySchedules; ++LoopIndex) {
738 176 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
739 : CurrentModuleObject,
740 : LoopIndex,
741 : Alphas,
742 : NumAlphas,
743 : Numbers,
744 : NumNumbers,
745 : Status,
746 : lNumericBlanks,
747 : lAlphaBlanks,
748 : cAlphaFields,
749 : cNumericFields);
750 352 : GlobalNames::VerifyUniqueInterObjectName(
751 352 : state, state.dataScheduleMgr->UniqueDayScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
752 176 : ++Count;
753 176 : state.dataScheduleMgr->DaySchedule(Count).Name = Alphas(1);
754 : // Validate ScheduleType
755 176 : if (state.dataScheduleMgr->NumScheduleTypes > 0) {
756 176 : CheckIndex =
757 352 : UtilityRoutines::FindItemInList(Alphas(2), state.dataScheduleMgr->ScheduleType({1, state.dataScheduleMgr->NumScheduleTypes}));
758 176 : if (CheckIndex == 0) {
759 0 : if (!lAlphaBlanks(2)) {
760 0 : ShowWarningError(state,
761 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(2) + "=\"" +
762 0 : Alphas(2) + "\" not found -- will not be validated");
763 : } else {
764 0 : ShowWarningError(state,
765 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Blank " + cAlphaFields(2) +
766 : " input -- will not be validated.");
767 : }
768 : } else {
769 176 : state.dataScheduleMgr->DaySchedule(Count).ScheduleTypePtr = CheckIndex;
770 : }
771 : }
772 176 : NumFields = NumAlphas - 3;
773 : // check to see if numfield=0
774 176 : if (NumFields == 0) {
775 0 : ShowSevereError(state,
776 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
777 : "\", Insufficient data entered for a full schedule day.");
778 0 : ShowContinueError(state, format("...Number of interval fields = = [{}].", NumFields));
779 0 : ErrorsFound = true;
780 : }
781 :
782 : // Depending on value of "Interpolate" field, the value for each time step in each hour gets processed:
783 176 : state.dataScheduleMgr->DaySchedule(Count).IntervalInterpolated =
784 352 : static_cast<ScheduleInterpolation>(getEnumerationValue(interpolationTypesUC, Alphas(3)));
785 176 : if (state.dataScheduleMgr->DaySchedule(Count).IntervalInterpolated == ScheduleInterpolation::Invalid) {
786 0 : ShowSevereError(state,
787 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "Invalid value for \"" + cAlphaFields(3) +
788 0 : "\" field=\"" + Alphas(3) + "\"");
789 0 : ErrorsFound = true;
790 : }
791 704 : ProcessIntervalFields(state,
792 352 : Alphas({4, _}),
793 : Numbers,
794 : NumFields,
795 : NumNumbers,
796 : MinuteValue,
797 : SetMinuteValue,
798 : ErrorsFound,
799 176 : Alphas(1),
800 : CurrentModuleObject,
801 176 : state.dataScheduleMgr->DaySchedule(Count).IntervalInterpolated);
802 176 : if (state.dataScheduleMgr->DaySchedule(Count).IntervalInterpolated == ScheduleInterpolation::Average) {
803 25 : for (Hr = 1; Hr <= 24; ++Hr) {
804 24 : SCount = 1;
805 24 : CurMinute = state.dataGlobal->MinutesPerTimeStep;
806 120 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
807 96 : state.dataScheduleMgr->DaySchedule(Count).TSValue(TS, Hr) =
808 192 : sum(MinuteValue({SCount, CurMinute}, Hr)) / double(state.dataGlobal->MinutesPerTimeStep);
809 96 : SCount = CurMinute + 1;
810 96 : CurMinute += state.dataGlobal->MinutesPerTimeStep;
811 : }
812 : }
813 : } else {
814 4375 : for (Hr = 1; Hr <= 24; ++Hr) {
815 4200 : CurMinute = state.dataGlobal->MinutesPerTimeStep;
816 21768 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
817 17568 : state.dataScheduleMgr->DaySchedule(Count).TSValue(TS, Hr) = MinuteValue(CurMinute, Hr);
818 17568 : CurMinute += state.dataGlobal->MinutesPerTimeStep;
819 : }
820 : }
821 : }
822 :
823 176 : SchedTypePtr = state.dataScheduleMgr->DaySchedule(Count).ScheduleTypePtr;
824 176 : if (!state.dataScheduleMgr->ScheduleType(SchedTypePtr).IsReal) {
825 : // Make sure each is integer
826 3 : NumErrorFlag = false; // only show error message once
827 75 : for (Hr = 1; Hr <= 24; ++Hr) {
828 360 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
829 576 : if (state.dataScheduleMgr->DaySchedule(Count).TSValue(TS, Hr) !=
830 288 : int(state.dataScheduleMgr->DaySchedule(Count).TSValue(TS, Hr))) {
831 0 : if (!NumErrorFlag) {
832 0 : ShowWarningError(state,
833 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
834 0 : "\", , One or more values are not integer as required by " + cAlphaFields(2) + '=' + Alphas(2));
835 0 : NumErrorFlag = true;
836 : }
837 : }
838 : }
839 : }
840 : }
841 : }
842 :
843 : //!! Get "DaySchedule:List"
844 :
845 771 : CurrentModuleObject = "Schedule:Day:List";
846 777 : for (LoopIndex = 1; LoopIndex <= NumLstDaySchedules; ++LoopIndex) {
847 6 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
848 : CurrentModuleObject,
849 : LoopIndex,
850 : Alphas,
851 : NumAlphas,
852 : Numbers,
853 : NumNumbers,
854 : Status,
855 : lNumericBlanks,
856 : lAlphaBlanks,
857 : cAlphaFields,
858 : cNumericFields);
859 12 : GlobalNames::VerifyUniqueInterObjectName(
860 12 : state, state.dataScheduleMgr->UniqueDayScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
861 6 : ++Count;
862 6 : state.dataScheduleMgr->DaySchedule(Count).Name = Alphas(1);
863 : // Validate ScheduleType
864 6 : if (state.dataScheduleMgr->NumScheduleTypes > 0) {
865 6 : CheckIndex =
866 12 : UtilityRoutines::FindItemInList(Alphas(2), state.dataScheduleMgr->ScheduleType({1, state.dataScheduleMgr->NumScheduleTypes}));
867 6 : if (CheckIndex == 0) {
868 0 : if (!lAlphaBlanks(2)) {
869 0 : ShowWarningError(state,
870 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(2) + "=\"" +
871 0 : Alphas(2) + "\" not found -- will not be validated");
872 : } else {
873 0 : ShowWarningError(state,
874 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Blank " + cAlphaFields(2) +
875 : " input -- will not be validated.");
876 : }
877 : } else {
878 6 : state.dataScheduleMgr->DaySchedule(Count).ScheduleTypePtr = CheckIndex;
879 : }
880 : }
881 :
882 : // Depending on value of "Interpolate" field, the value for each time step in each hour gets processed:
883 6 : if (UtilityRoutines::SameString(Alphas(3), "NO")) {
884 1 : state.dataScheduleMgr->DaySchedule(Count).IntervalInterpolated = ScheduleInterpolation::No;
885 5 : } else if (UtilityRoutines::SameString(Alphas(3), "AVERAGE")) {
886 5 : state.dataScheduleMgr->DaySchedule(Count).IntervalInterpolated = ScheduleInterpolation::Average;
887 0 : } else if (UtilityRoutines::SameString(Alphas(3), "LINEAR")) {
888 0 : state.dataScheduleMgr->DaySchedule(Count).IntervalInterpolated = ScheduleInterpolation::Linear;
889 : } else {
890 0 : ShowSevereError(state,
891 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "Invalid value for \"" + cAlphaFields(3) +
892 0 : "\" field=\"" + Alphas(3) + "\"");
893 0 : ErrorsFound = true;
894 : }
895 :
896 : // check to see if there are any fields
897 6 : if (Numbers(1) <= 0.0) {
898 0 : ShowSevereError(state,
899 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
900 : "\", Insufficient data entered for a full schedule day.");
901 0 : ShowContinueError(state, format("...Minutes per Item field = [{}].", Numbers(1)));
902 0 : ErrorsFound = true;
903 0 : continue;
904 : }
905 6 : if (NumNumbers < 25) {
906 0 : ShowSevereError(state,
907 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
908 : "\", Insufficient data entered for a full schedule day.");
909 0 : ShowContinueError(state,
910 0 : format("...Minutes per Item field = [{}] and only [{}] to apply to list fields.", Numbers(1), NumNumbers - 1));
911 0 : ErrorsFound = true;
912 0 : continue;
913 : }
914 6 : MinutesPerItem = int(Numbers(1));
915 6 : NumExpectedItems = 1440 / MinutesPerItem;
916 6 : if ((NumNumbers - 1) != NumExpectedItems) {
917 0 : ShowSevereError(state,
918 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + ", Number of Entered Items=" +
919 0 : format("{} not equal number of expected items={}", NumNumbers - 1, NumExpectedItems));
920 0 : ShowContinueError(state, format("based on {} field value={}", cNumericFields(1), MinutesPerItem));
921 0 : ErrorsFound = true;
922 0 : continue;
923 : }
924 :
925 6 : if (mod(60, MinutesPerItem) != 0) {
926 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1));
927 0 : ShowContinueError(state, format("Requested {} field value ({}) not evenly divisible into 60", cNumericFields(1), MinutesPerItem));
928 0 : ErrorsFound = true;
929 0 : continue;
930 : }
931 :
932 : // Number of numbers in the Numbers list okay to process
933 6 : Hr = 1;
934 6 : CurMinute = MinutesPerItem;
935 6 : SCount = 1;
936 438 : for (NumFields = 2; NumFields <= NumNumbers; ++NumFields) {
937 432 : MinuteValue({SCount, CurMinute}, Hr) = Numbers(NumFields);
938 432 : SCount = CurMinute + 1;
939 432 : CurMinute += MinutesPerItem;
940 432 : if (CurMinute > 60) {
941 144 : CurMinute = MinutesPerItem;
942 144 : SCount = 1;
943 144 : ++Hr;
944 : }
945 : }
946 :
947 : // Now parcel into TS Value....
948 :
949 6 : if (state.dataScheduleMgr->DaySchedule(Count).IntervalInterpolated == ScheduleInterpolation::Average) {
950 125 : for (Hr = 1; Hr <= 24; ++Hr) {
951 120 : SCount = 1;
952 120 : CurMinute = state.dataGlobal->MinutesPerTimeStep;
953 600 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
954 480 : state.dataScheduleMgr->DaySchedule(Count).TSValue(TS, Hr) =
955 960 : sum(MinuteValue({SCount, CurMinute}, Hr)) / double(state.dataGlobal->MinutesPerTimeStep);
956 480 : SCount = CurMinute + 1;
957 480 : CurMinute += state.dataGlobal->MinutesPerTimeStep;
958 : }
959 : }
960 : } else {
961 25 : for (Hr = 1; Hr <= 24; ++Hr) {
962 24 : CurMinute = state.dataGlobal->MinutesPerTimeStep;
963 120 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
964 96 : state.dataScheduleMgr->DaySchedule(Count).TSValue(TS, Hr) = MinuteValue(CurMinute, Hr);
965 96 : CurMinute += state.dataGlobal->MinutesPerTimeStep;
966 : }
967 : }
968 : }
969 :
970 6 : SchedTypePtr = state.dataScheduleMgr->DaySchedule(Count).ScheduleTypePtr;
971 6 : if (state.dataScheduleMgr->ScheduleType(SchedTypePtr).Limited) {
972 0 : if (any_lt(state.dataScheduleMgr->DaySchedule(Count).TSValue, state.dataScheduleMgr->ScheduleType(SchedTypePtr).Minimum) ||
973 0 : any_gt(state.dataScheduleMgr->DaySchedule(Count).TSValue, state.dataScheduleMgr->ScheduleType(SchedTypePtr).Maximum)) {
974 0 : ShowWarningError(state,
975 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Values are outside of range for " +
976 0 : cAlphaFields(2) + '=' + Alphas(2));
977 : }
978 : }
979 6 : if (!state.dataScheduleMgr->ScheduleType(SchedTypePtr).IsReal) {
980 : // Make sure each is integer
981 0 : NumErrorFlag = false; // only show error message once
982 0 : for (Hr = 1; Hr <= 24; ++Hr) {
983 0 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
984 0 : if (state.dataScheduleMgr->DaySchedule(Count).TSValue(TS, Hr) !=
985 0 : int(state.dataScheduleMgr->DaySchedule(Count).TSValue(TS, Hr))) {
986 0 : if (!NumErrorFlag) {
987 0 : ShowWarningError(state,
988 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
989 0 : "\", , One or more values are not integer as required by " + cAlphaFields(2) + '=' + Alphas(2));
990 0 : NumErrorFlag = true;
991 : }
992 : }
993 : }
994 : }
995 : }
996 : }
997 :
998 : //!! Get Week Schedules - regular
999 :
1000 771 : CurrentModuleObject = "Schedule:Week:Daily";
1001 963 : for (LoopIndex = 1; LoopIndex <= NumRegWeekSchedules; ++LoopIndex) {
1002 192 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1003 : CurrentModuleObject,
1004 : LoopIndex,
1005 : Alphas,
1006 : NumAlphas,
1007 : Numbers,
1008 : NumNumbers,
1009 : Status,
1010 : lNumericBlanks,
1011 : lAlphaBlanks,
1012 : cAlphaFields,
1013 : cNumericFields);
1014 384 : GlobalNames::VerifyUniqueInterObjectName(
1015 384 : state, state.dataScheduleMgr->UniqueWeekScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
1016 192 : state.dataScheduleMgr->WeekSchedule(LoopIndex).Name = Alphas(1);
1017 : // Rest of Alphas are processed into Pointers
1018 2496 : for (InLoopIndex = 1; InLoopIndex <= maxDayTypes; ++InLoopIndex) {
1019 2304 : DayIndex = UtilityRoutines::FindItemInList(Alphas(InLoopIndex + 1), state.dataScheduleMgr->DaySchedule({1, NumRegDaySchedules}));
1020 2304 : if (DayIndex == 0) {
1021 0 : ShowSevereError(state,
1022 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(InLoopIndex + 1) +
1023 0 : " \"" + Alphas(InLoopIndex + 1) + "\" not Found",
1024 0 : OptionalOutputFileRef{state.files.audit});
1025 0 : ErrorsFound = true;
1026 : } else {
1027 2304 : state.dataScheduleMgr->WeekSchedule(LoopIndex).DaySchedulePointer(InLoopIndex) = DayIndex;
1028 : }
1029 : }
1030 : }
1031 :
1032 : //!! Get Week Schedules - compact
1033 771 : Count = NumRegWeekSchedules;
1034 771 : CurrentModuleObject = "Schedule:Week:Compact";
1035 806 : for (LoopIndex = 1; LoopIndex <= NumCptWeekSchedules; ++LoopIndex) {
1036 35 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1037 : CurrentModuleObject,
1038 : LoopIndex,
1039 : Alphas,
1040 : NumAlphas,
1041 : Numbers,
1042 : NumNumbers,
1043 : Status,
1044 : lNumericBlanks,
1045 : lAlphaBlanks,
1046 : cAlphaFields,
1047 : cNumericFields);
1048 35 : if (Count > 0) {
1049 64 : GlobalNames::VerifyUniqueInterObjectName(
1050 64 : state, state.dataScheduleMgr->UniqueWeekScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
1051 : }
1052 35 : ++Count;
1053 35 : state.dataScheduleMgr->WeekSchedule(Count).Name = Alphas(1);
1054 35 : AllDays = false;
1055 : // Rest of Alphas are processed into Pointers
1056 94 : for (InLoopIndex = 2; InLoopIndex <= NumAlphas; InLoopIndex += 2) {
1057 59 : DayIndex = UtilityRoutines::FindItemInList(Alphas(InLoopIndex + 1), state.dataScheduleMgr->DaySchedule({1, NumRegDaySchedules}));
1058 59 : if (DayIndex == 0) {
1059 0 : ShowSevereError(state,
1060 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(InLoopIndex + 1) +
1061 0 : " \"" + Alphas(InLoopIndex + 1) + "\" not Found",
1062 0 : OptionalOutputFileRef{state.files.audit});
1063 0 : ShowContinueError(state, "ref: " + cAlphaFields(InLoopIndex) + " \"" + Alphas(InLoopIndex) + "\"");
1064 0 : ErrorsFound = true;
1065 : } else {
1066 59 : TheseDays = false;
1067 59 : ErrorHere = false;
1068 59 : ProcessForDayTypes(state, Alphas(InLoopIndex), TheseDays, AllDays, ErrorHere);
1069 59 : if (ErrorHere) {
1070 0 : ShowContinueError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1));
1071 0 : ErrorsFound = true;
1072 : } else {
1073 767 : for (Hr = 1; Hr <= maxDayTypes; ++Hr) {
1074 708 : if (TheseDays(Hr)) {
1075 420 : state.dataScheduleMgr->WeekSchedule(Count).DaySchedulePointer(Hr) = DayIndex;
1076 : }
1077 : }
1078 : }
1079 : }
1080 : }
1081 : // Have processed all named days, check to make sure all given
1082 35 : if (!all(AllDays)) {
1083 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Missing some day assignments");
1084 0 : ErrorsFound = true;
1085 : }
1086 : }
1087 771 : NumRegWeekSchedules = Count;
1088 :
1089 : //!! Get Schedules (all types)
1090 :
1091 : //!! Get Regular Schedules
1092 :
1093 771 : CurrentModuleObject = "Schedule:Year";
1094 884 : for (LoopIndex = 1; LoopIndex <= NumRegSchedules; ++LoopIndex) {
1095 113 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1096 : CurrentModuleObject,
1097 : LoopIndex,
1098 : Alphas,
1099 : NumAlphas,
1100 : Numbers,
1101 : NumNumbers,
1102 : Status,
1103 : lNumericBlanks,
1104 : lAlphaBlanks,
1105 : cAlphaFields,
1106 : cNumericFields);
1107 226 : GlobalNames::VerifyUniqueInterObjectName(
1108 226 : state, state.dataScheduleMgr->UniqueScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
1109 113 : state.dataScheduleMgr->Schedule(LoopIndex).Name = Alphas(1);
1110 113 : state.dataScheduleMgr->Schedule(LoopIndex).SchType = SchedType::ScheduleInput_year;
1111 : // Validate ScheduleType
1112 113 : if (state.dataScheduleMgr->NumScheduleTypes > 0) {
1113 113 : CheckIndex =
1114 226 : UtilityRoutines::FindItemInList(Alphas(2), state.dataScheduleMgr->ScheduleType({1, state.dataScheduleMgr->NumScheduleTypes}));
1115 113 : if (CheckIndex == 0) {
1116 0 : if (!lAlphaBlanks(2)) {
1117 0 : ShowWarningError(state,
1118 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(2) + "=\"" +
1119 0 : Alphas(2) + "\" not found -- will not be validated");
1120 : } else {
1121 0 : ShowWarningError(state,
1122 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Blank " + cAlphaFields(2) +
1123 : " input -- will not be validated.");
1124 : }
1125 : } else {
1126 113 : state.dataScheduleMgr->Schedule(LoopIndex).ScheduleTypePtr = CheckIndex;
1127 : }
1128 : }
1129 113 : NumPointer = 0;
1130 113 : DaysInYear = 0;
1131 : // Rest of Alphas (Weekschedules) are processed into Pointers
1132 347 : for (InLoopIndex = 3; InLoopIndex <= NumAlphas; ++InLoopIndex) {
1133 234 : WeekIndex = UtilityRoutines::FindItemInList(Alphas(InLoopIndex), state.dataScheduleMgr->WeekSchedule({1, NumRegWeekSchedules}));
1134 234 : if (WeekIndex == 0) {
1135 0 : ShowSevereError(state,
1136 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(InLoopIndex) + "=\"" +
1137 0 : Alphas(InLoopIndex) + "\" not found.",
1138 0 : OptionalOutputFileRef{state.files.audit});
1139 0 : ErrorsFound = true;
1140 : } else {
1141 : // Process for month, day
1142 234 : StartMonth = int(Numbers(NumPointer + 1));
1143 234 : StartDay = int(Numbers(NumPointer + 2));
1144 234 : EndMonth = int(Numbers(NumPointer + 3));
1145 234 : EndDay = int(Numbers(NumPointer + 4));
1146 234 : NumPointer += 4;
1147 234 : StartPointer = General::OrdinalDay(StartMonth, StartDay, 1);
1148 234 : EndPointer = General::OrdinalDay(EndMonth, EndDay, 1);
1149 234 : if (StartPointer <= EndPointer) {
1150 41592 : for (Count = StartPointer; Count <= EndPointer; ++Count) {
1151 41358 : ++DaysInYear(Count);
1152 41358 : state.dataScheduleMgr->Schedule(LoopIndex).WeekSchedulePointer(Count) = WeekIndex;
1153 : }
1154 : } else {
1155 0 : for (Count = StartPointer; Count <= 366; ++Count) {
1156 0 : ++DaysInYear(Count);
1157 0 : state.dataScheduleMgr->Schedule(LoopIndex).WeekSchedulePointer(Count) = WeekIndex;
1158 : }
1159 0 : for (Count = 1; Count <= EndPointer; ++Count) {
1160 0 : ++DaysInYear(Count);
1161 0 : state.dataScheduleMgr->Schedule(LoopIndex).WeekSchedulePointer(Count) = WeekIndex;
1162 : }
1163 : }
1164 : }
1165 : }
1166 : // Perform Error checks on this item
1167 : // Do special test for Feb 29. Make equal to Feb 28.
1168 113 : if (DaysInYear(60) == 0) {
1169 0 : DaysInYear(60) = DaysInYear(59);
1170 0 : state.dataScheduleMgr->Schedule(LoopIndex).WeekSchedulePointer(60) =
1171 0 : state.dataScheduleMgr->Schedule(LoopIndex).WeekSchedulePointer(59);
1172 : }
1173 113 : if (any_eq(DaysInYear, 0)) {
1174 0 : ShowSevereError(state,
1175 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + state.dataScheduleMgr->Schedule(LoopIndex).Name +
1176 : "\" has missing days in its schedule pointers",
1177 0 : OptionalOutputFileRef{state.files.audit});
1178 0 : ErrorsFound = true;
1179 : }
1180 113 : if (any_gt(DaysInYear, 1)) {
1181 0 : ShowSevereError(state,
1182 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + state.dataScheduleMgr->Schedule(LoopIndex).Name +
1183 : "\" has overlapping days in its schedule pointers",
1184 0 : OptionalOutputFileRef{state.files.audit});
1185 0 : ErrorsFound = true;
1186 : }
1187 :
1188 113 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) { // setup constant schedules as actuators
1189 144 : SetupEMSActuator(state,
1190 : "Schedule:Year",
1191 36 : state.dataScheduleMgr->Schedule(LoopIndex).Name,
1192 : "Schedule Value",
1193 : "[ ]",
1194 36 : state.dataScheduleMgr->Schedule(LoopIndex).EMSActuatedOn,
1195 108 : state.dataScheduleMgr->Schedule(LoopIndex).EMSValue);
1196 : }
1197 : }
1198 :
1199 : //!! Get Compact Schedules
1200 : // SCHEDULE:COMPACT,
1201 : // \memo Irregular object. Does not follow the usual definition for fields. Fields A3... are:
1202 : // \memo Through: Date
1203 : // \memo For: Applicable days (ref: Weekschedule:Compact)
1204 : // \memo Interpolate: Yes/No (ref: Dayschedule:interval) -- optional, if not used will be "No"
1205 : // \memo Until: <Time> (ref: Dayschedule:Interval)
1206 : // \memo <numeric value>
1207 : // \memo words "Through","For","Interpolate","Until" must be included.
1208 : // A1 , \field Name
1209 : // \required-field
1210 : // \type alpha
1211 : // \reference ScheduleNames
1212 : // A2 , \field ScheduleType
1213 : // \type object-list
1214 : // \object-list ScheduleTypeNames
1215 : // A3 , \field Complex Field #1
1216 : // A4 , \field Complex Field #2
1217 : // A5 , \field Complex Field #3
1218 :
1219 771 : SchNum = NumRegSchedules;
1220 771 : AddWeekSch = NumRegWeekSchedules;
1221 771 : AddDaySch = NumRegDaySchedules;
1222 771 : CurrentModuleObject = "Schedule:Compact";
1223 16195 : for (LoopIndex = 1; LoopIndex <= NumCptSchedules; ++LoopIndex) {
1224 15424 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1225 : CurrentModuleObject,
1226 : LoopIndex,
1227 : Alphas,
1228 : NumAlphas,
1229 : Numbers,
1230 : NumNumbers,
1231 : Status,
1232 : lNumericBlanks,
1233 : lAlphaBlanks,
1234 : cAlphaFields,
1235 : cNumericFields);
1236 30848 : GlobalNames::VerifyUniqueInterObjectName(
1237 30848 : state, state.dataScheduleMgr->UniqueScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
1238 15424 : ++SchNum;
1239 15424 : state.dataScheduleMgr->Schedule(SchNum).Name = Alphas(1);
1240 15424 : state.dataScheduleMgr->Schedule(SchNum).SchType = SchedType::ScheduleInput_compact;
1241 : // Validate ScheduleType
1242 15424 : CheckIndex =
1243 30848 : UtilityRoutines::FindItemInList(Alphas(2), state.dataScheduleMgr->ScheduleType({1, state.dataScheduleMgr->NumScheduleTypes}));
1244 15424 : if (CheckIndex == 0) {
1245 10 : if (!lAlphaBlanks(2)) {
1246 30 : ShowWarningError(state,
1247 20 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(2) + "=\"" +
1248 30 : Alphas(2) + "\" not found -- will not be validated");
1249 : } else {
1250 0 : ShowWarningError(state,
1251 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Blank " + cAlphaFields(2) +
1252 : " input -- will not be validated.");
1253 : }
1254 : } else {
1255 15414 : state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr = CheckIndex;
1256 : }
1257 15424 : NumPointer = 0;
1258 15424 : DaysInYear = 0;
1259 : // Process the "complex" fields -- so named because they are not a 1:1 correspondence
1260 : // as other objects are
1261 15424 : NumField = 3;
1262 15424 : StartPointer = 1;
1263 15424 : WkCount = 0;
1264 15424 : DyCount = 0;
1265 15424 : bool FullYearSet = false;
1266 57648 : while (NumField < NumAlphas) {
1267 : // Process "Through"
1268 21112 : if (!has_prefix(Alphas(NumField), "THROUGH:") && !has_prefix(Alphas(NumField), "THROUGH")) {
1269 0 : ShowSevereError(state,
1270 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + state.dataScheduleMgr->Schedule(SchNum).Name +
1271 : "\", Expecting \"Through:\" date");
1272 0 : ShowContinueError(state, "Instead, found entry=" + Alphas(NumField));
1273 0 : ErrorsFound = true;
1274 0 : goto Through_exit;
1275 : } else {
1276 21112 : if (Alphas(NumField)[7] == ':') {
1277 21105 : sPos = 8;
1278 : } else {
1279 7 : sPos = 7;
1280 : }
1281 21112 : Alphas(NumField).erase(0, sPos);
1282 21112 : strip(Alphas(NumField));
1283 : }
1284 21112 : CurrentThrough = Alphas(NumField);
1285 21112 : ErrorHere = false;
1286 21112 : ProcessDateString(state, Alphas(NumField), EndMonth, EndDay, PWeekDay, PDateType, ErrorHere);
1287 21112 : if (PDateType == WeatherManager::DateType::NthDayInMonth || PDateType == WeatherManager::DateType::LastDayInMonth) {
1288 0 : ShowSevereError(state,
1289 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + state.dataScheduleMgr->Schedule(SchNum).Name +
1290 : "\", Invalid \"Through:\" date");
1291 0 : ShowContinueError(state, "Found entry=" + Alphas(NumField));
1292 0 : ErrorsFound = true;
1293 0 : goto Through_exit;
1294 21112 : } else if (ErrorHere) {
1295 0 : ShowSevereError(state,
1296 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + state.dataScheduleMgr->Schedule(SchNum).Name +
1297 : "\", Invalid \"Through:\" date");
1298 0 : ShowContinueError(state, "Found entry=" + Alphas(NumField));
1299 0 : ErrorsFound = true;
1300 0 : goto Through_exit;
1301 : } else {
1302 21112 : EndPointer = General::OrdinalDay(EndMonth, EndDay, 1);
1303 21112 : if (EndPointer == 366) {
1304 15424 : if (FullYearSet) {
1305 0 : ShowSevereError(state,
1306 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + state.dataScheduleMgr->Schedule(SchNum).Name +
1307 : "\", New \"Through\" entry when \"full year\" already set");
1308 0 : ShowContinueError(state, "\"Through\" field=" + CurrentThrough);
1309 0 : ErrorsFound = true;
1310 : }
1311 15424 : FullYearSet = true;
1312 : }
1313 : }
1314 21112 : ++WkCount;
1315 21112 : ++AddWeekSch;
1316 21112 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).Name = format("{}_wk_{}", Alphas(1), WkCount);
1317 21112 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).Used = true;
1318 5666296 : for (Hr = StartPointer; Hr <= EndPointer; ++Hr) {
1319 5645184 : state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(Hr) = AddWeekSch;
1320 5645184 : ++DaysInYear(Hr);
1321 : }
1322 21112 : StartPointer = EndPointer + 1;
1323 21112 : ThruField = NumField;
1324 21112 : AllDays = false;
1325 21112 : ++NumField;
1326 85826 : while (NumField < NumAlphas) { // Continues until next "Through"
1327 38045 : if (has_prefix(Alphas(NumField), "THROUGH")) goto For_exit;
1328 : // "For" must be next, adds to "# Day Schedules"
1329 32357 : if (has_prefix(Alphas(NumField), "FOR")) {
1330 32357 : ++DyCount;
1331 32357 : ++AddDaySch;
1332 32357 : state.dataScheduleMgr->DaySchedule(AddDaySch).Name = format("{}_dy_{}", Alphas(1), DyCount);
1333 32357 : state.dataScheduleMgr->DaySchedule(AddDaySch).ScheduleTypePtr = state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr;
1334 32357 : state.dataScheduleMgr->DaySchedule(AddDaySch).Used = true;
1335 32357 : TheseDays = false;
1336 32357 : ErrorHere = false;
1337 32357 : LastFor = Alphas(NumField);
1338 32357 : ProcessForDayTypes(state, Alphas(NumField), TheseDays, AllDays, ErrorHere);
1339 32357 : if (ErrorHere) {
1340 0 : ShowContinueError(state, "ref " + CurrentModuleObject + "=\"" + Alphas(1) + "\"");
1341 0 : ShowContinueError(state, "ref Through field=" + Alphas(ThruField));
1342 0 : ErrorsFound = true;
1343 : } else {
1344 420641 : for (Hr = 1; Hr <= maxDayTypes; ++Hr) {
1345 388284 : if (TheseDays(Hr)) {
1346 253344 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).DaySchedulePointer(Hr) = AddDaySch;
1347 : }
1348 : }
1349 : }
1350 : } else {
1351 0 : ShowSevereError(state,
1352 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
1353 0 : "\", Looking for \"For\" field, found=" + Alphas(NumField));
1354 0 : ErrorsFound = true;
1355 : // CALL ShowSevereError(state, RoutineName//TRIM(CurrentModuleObject)//'="'//TRIM(Schedule(SchNum)%Name)// &
1356 : // '", Expecting "For:" day types')
1357 : // CALL ShowContinueError(state, 'Instead, found entry='//TRIM(Alphas(NumField)))
1358 0 : goto Through_exit;
1359 : }
1360 : // Check for "Interpolate"
1361 32357 : ++NumField;
1362 32357 : if (has_prefix(Alphas(NumField), "INTERPOLATE")) {
1363 327 : if (has(Alphas(NumField), "NO")) {
1364 87 : state.dataScheduleMgr->DaySchedule(AddDaySch).IntervalInterpolated = ScheduleInterpolation::No;
1365 240 : } else if (has(Alphas(NumField), "AVERAGE")) {
1366 240 : state.dataScheduleMgr->DaySchedule(AddDaySch).IntervalInterpolated = ScheduleInterpolation::Average;
1367 0 : } else if (has(Alphas(NumField), "LINEAR")) {
1368 0 : state.dataScheduleMgr->DaySchedule(AddDaySch).IntervalInterpolated = ScheduleInterpolation::Linear;
1369 : } else {
1370 0 : ShowSevereError(state,
1371 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "Invalid value for \"" +
1372 0 : cAlphaFields(NumField) + "\" field=\"" + Alphas(NumField) + "\"");
1373 0 : ErrorsFound = true;
1374 : }
1375 327 : ++NumField;
1376 : } else {
1377 32030 : if (!has_prefix(Alphas(NumField), "UNTIL")) {
1378 0 : if (has(Alphas(NumField), "NO")) {
1379 0 : state.dataScheduleMgr->DaySchedule(AddDaySch).IntervalInterpolated = ScheduleInterpolation::No;
1380 0 : } else if (has(Alphas(NumField), "AVERAGE")) {
1381 0 : state.dataScheduleMgr->DaySchedule(AddDaySch).IntervalInterpolated = ScheduleInterpolation::Average;
1382 0 : } else if (has(Alphas(NumField), "LINEAR")) {
1383 0 : state.dataScheduleMgr->DaySchedule(AddDaySch).IntervalInterpolated = ScheduleInterpolation::Linear;
1384 : } else {
1385 0 : ShowSevereError(state,
1386 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
1387 0 : "\", Illegal Field entered =" + Alphas(NumField));
1388 0 : ErrorsFound = true;
1389 : }
1390 0 : ++NumField;
1391 : }
1392 : }
1393 32357 : NumNumbers = 0;
1394 32357 : xxcount = 0;
1395 32357 : UntilFld = NumField;
1396 : while (true) {
1397 153699 : if (has_prefix(Alphas(NumField), "FOR")) break;
1398 81783 : if (has_prefix(Alphas(NumField), "THROUGH")) break;
1399 76095 : if (has_prefix(Alphas(NumField), "UNTIL")) {
1400 : // Process Until/Value pairs for later processing by other routine.
1401 76095 : ++NumField;
1402 76095 : ++xxcount;
1403 76095 : ++NumNumbers;
1404 76095 : Numbers(NumNumbers) = UtilityRoutines::ProcessNumber(Alphas(NumField), ErrorHere);
1405 76095 : if (ErrorHere) {
1406 0 : ShowSevereError(state, CurrentModuleObject + "=\"" + Alphas(1) + "\"");
1407 0 : ShowContinueError(state,
1408 0 : "Until field=[" + Alphas(NumField - 1) + "] has illegal value field=[" + Alphas(NumField) + "].");
1409 0 : ErrorsFound = true;
1410 : }
1411 76095 : ++NumField;
1412 76095 : Alphas(UntilFld + xxcount) = Alphas(NumField); // Incase next is "until"
1413 : } else {
1414 0 : ShowSevereError(state,
1415 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
1416 0 : "\", Looking for \"Until\" field, found=" + Alphas(NumField));
1417 0 : ErrorsFound = true;
1418 0 : goto Through_exit;
1419 : }
1420 76095 : if (Alphas(NumField).empty()) break;
1421 : }
1422 : // Process Untils, Numbers
1423 32357 : if (NumNumbers > 0) {
1424 32357 : NumFields = NumNumbers;
1425 32357 : ErrorHere = false;
1426 129428 : ProcessIntervalFields(state,
1427 64714 : Alphas({UntilFld, _}),
1428 : Numbers,
1429 : NumFields,
1430 : NumNumbers,
1431 : MinuteValue,
1432 : SetMinuteValue,
1433 : ErrorHere,
1434 32357 : state.dataScheduleMgr->DaySchedule(AddDaySch).Name,
1435 64714 : CurrentModuleObject + " DaySchedule Fields",
1436 32357 : state.dataScheduleMgr->DaySchedule(AddDaySch).IntervalInterpolated);
1437 : // Depending on value of "Interpolate" field, the value for each time step in each hour gets processed:
1438 32357 : if (ErrorHere) {
1439 0 : ShowContinueError(state, "ref " + CurrentModuleObject + "=\"" + Alphas(1) + "\"");
1440 0 : ErrorsFound = true;
1441 : }
1442 32357 : if (state.dataScheduleMgr->DaySchedule(AddDaySch).IntervalInterpolated ==
1443 : ScheduleInterpolation::No) { // No validation done on the value of the interpolation field
1444 802925 : for (Hr = 1; Hr <= 24; ++Hr) {
1445 770808 : CurMinute = state.dataGlobal->MinutesPerTimeStep;
1446 5273448 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
1447 4502640 : state.dataScheduleMgr->DaySchedule(AddDaySch).TSValue(TS, Hr) = MinuteValue(CurMinute, Hr);
1448 4502640 : CurMinute += state.dataGlobal->MinutesPerTimeStep;
1449 : }
1450 : }
1451 : } else {
1452 6000 : for (Hr = 1; Hr <= 24; ++Hr) {
1453 5760 : SCount = 1;
1454 5760 : CurMinute = state.dataGlobal->MinutesPerTimeStep;
1455 36240 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
1456 : // tempval=SUM(MinuteValue(Hr,SCount:CurMinute))/REAL(MinutesPerTimeStep,r64)
1457 30480 : state.dataScheduleMgr->DaySchedule(AddDaySch).TSValue(TS, Hr) =
1458 60960 : sum(MinuteValue({SCount, CurMinute}, Hr)) / double(state.dataGlobal->MinutesPerTimeStep);
1459 30480 : SCount = CurMinute + 1;
1460 30480 : CurMinute += state.dataGlobal->MinutesPerTimeStep;
1461 : }
1462 : }
1463 : }
1464 : }
1465 : }
1466 15424 : For_exit:;
1467 21112 : if (!all(AllDays)) {
1468 0 : ShowWarningError(state,
1469 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + state.dataScheduleMgr->Schedule(SchNum).Name +
1470 0 : "\" has missing day types in Through=" + CurrentThrough);
1471 0 : ShowContinueError(state, "Last \"For\" field=" + LastFor);
1472 0 : errmsg = "Missing day types=,";
1473 0 : for (kdy = 1; kdy <= maxDayTypes; ++kdy) {
1474 0 : if (AllDays(kdy)) continue;
1475 0 : errmsg.erase(errmsg.length() - 1);
1476 0 : errmsg += "\"" + static_cast<std::string>(dayTypeNames[kdy]) + "\",-";
1477 : }
1478 0 : errmsg.erase(errmsg.length() - 2);
1479 0 : ShowContinueError(state, errmsg);
1480 0 : ShowContinueError(state, "Missing day types will have 0.0 as Schedule Values");
1481 : }
1482 : }
1483 15424 : Through_exit:;
1484 15424 : if (DaysInYear(60) == 0) {
1485 0 : DaysInYear(60) = DaysInYear(59);
1486 0 : state.dataScheduleMgr->Schedule(LoopIndex).WeekSchedulePointer(60) =
1487 0 : state.dataScheduleMgr->Schedule(LoopIndex).WeekSchedulePointer(59);
1488 : }
1489 15424 : if (any_eq(DaysInYear, 0)) {
1490 0 : ShowSevereError(state,
1491 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + state.dataScheduleMgr->Schedule(SchNum).Name +
1492 : "\" has missing days in its schedule pointers",
1493 0 : OptionalOutputFileRef{state.files.audit});
1494 0 : ErrorsFound = true;
1495 : }
1496 15424 : if (any_gt(DaysInYear, 1)) {
1497 0 : ShowSevereError(state,
1498 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + state.dataScheduleMgr->Schedule(SchNum).Name +
1499 : "\" has overlapping days in its schedule pointers",
1500 0 : OptionalOutputFileRef{state.files.audit});
1501 0 : ErrorsFound = true;
1502 : }
1503 :
1504 15424 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) { // setup constant schedules as actuators
1505 12820 : SetupEMSActuator(state,
1506 : "Schedule:Compact",
1507 3205 : state.dataScheduleMgr->Schedule(SchNum).Name,
1508 : "Schedule Value",
1509 : "[ ]",
1510 3205 : state.dataScheduleMgr->Schedule(SchNum).EMSActuatedOn,
1511 9615 : state.dataScheduleMgr->Schedule(SchNum).EMSValue);
1512 : }
1513 : }
1514 :
1515 : // Schedule:File,
1516 : // \min-fields 5
1517 : // \memo A Schedule:File points to a text computer file that has 8760-8784 hours of data.
1518 : // A1 , \field Name
1519 : // \required-field
1520 : // \type alpha
1521 : // \reference ScheduleNames
1522 : // A2 , \field Schedule Type Limits Name
1523 : // \type object-list
1524 : // \object-list ScheduleTypeLimitsNames
1525 : // A3 , \field File Name
1526 : // \required-field
1527 : // \retaincase
1528 : // N1 , \field Column Number
1529 : // \required-field
1530 : // \type integer
1531 : // \minimum 1
1532 : // N2 , \field Rows to Skip at Top
1533 : // \required-field
1534 : // \type integer
1535 : // \minimum 0
1536 : // N3 , \field Number of Hours of Data
1537 : // \note 8760 hours does not account for leap years, 8784 does.
1538 : // \note should be either 8760 or 8784
1539 : // \default 8760
1540 : // \minimum 8760
1541 : // \maximum 8784
1542 : // A4 , \field Column Separator
1543 : // \type choice
1544 : // \key Comma
1545 : // \key Tab
1546 : // \key Fixed
1547 : // \key Semicolon
1548 : // \default Comma
1549 : // A5 , \field Interpolate to Timestep
1550 : // \note when the interval does not match the user specified timestep a "Yes" choice will average between the intervals request (to
1551 : // \note timestep resolution. a "No" choice will use the interval value at the simulation timestep without regard to if it matches
1552 : // \note the boundary or not.
1553 : // \type choice
1554 : // \key Yes
1555 : // \key No
1556 : // \default No
1557 : // N4 ; \field Minutes per Item
1558 : // \note Must be evenly divisible into 60
1559 : // \type integer
1560 : // \minimum 1
1561 : // \maximum 60
1562 :
1563 : // continue adding to SchNum,AddWeekSch,AddDaySch
1564 771 : CurrentModuleObject = "Schedule:File";
1565 904 : for (LoopIndex = 1; LoopIndex <= NumCommaFileSchedules; ++LoopIndex) {
1566 133 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1567 : CurrentModuleObject,
1568 : LoopIndex,
1569 : Alphas,
1570 : NumAlphas,
1571 : Numbers,
1572 : NumNumbers,
1573 : Status,
1574 : lNumericBlanks,
1575 : lAlphaBlanks,
1576 : cAlphaFields,
1577 : cNumericFields);
1578 266 : GlobalNames::VerifyUniqueInterObjectName(
1579 266 : state, state.dataScheduleMgr->UniqueScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
1580 133 : ++SchNum;
1581 133 : state.dataScheduleMgr->Schedule(SchNum).Name = Alphas(1);
1582 133 : state.dataScheduleMgr->Schedule(SchNum).SchType = SchedType::ScheduleInput_file;
1583 : // Validate ScheduleType
1584 133 : if (state.dataScheduleMgr->NumScheduleTypes > 0) {
1585 133 : CheckIndex = 0;
1586 133 : if (!lAlphaBlanks(2))
1587 133 : CheckIndex =
1588 266 : UtilityRoutines::FindItemInList(Alphas(2), state.dataScheduleMgr->ScheduleType({1, state.dataScheduleMgr->NumScheduleTypes}));
1589 133 : if (CheckIndex == 0) {
1590 0 : if (!lAlphaBlanks(2)) {
1591 0 : ShowWarningError(state,
1592 0 : "ProcessScheduleInput: For " + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(2) + "=\"" +
1593 0 : Alphas(2) + "\" not found -- will not be validated");
1594 : } else {
1595 0 : ShowWarningError(state,
1596 0 : "For " + CurrentModuleObject + "=\"" + Alphas(1) + "\", Blank " + cAlphaFields(2) +
1597 : " input -- will not be validated.");
1598 : }
1599 : } else {
1600 133 : state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr = CheckIndex;
1601 : }
1602 : }
1603 :
1604 : // Numbers(1) - which column
1605 133 : curcolCount = Numbers(1);
1606 : // Numbers(2) - number of rows to skip
1607 133 : skiprowCount = Numbers(2);
1608 133 : if (Numbers(3) == 0) Numbers(3) = 8760.0;
1609 133 : if (Numbers(3) != 8760 && Numbers(3) != 8784) {
1610 0 : ShowSevereError(state,
1611 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cNumericFields(3) +
1612 : " must = 8760 or 8784 (for a leap year)");
1613 0 : ShowContinueError(state, format("..Value for field = {:.0T}, Schedule not processed.", Numbers(3)));
1614 0 : ErrorsFound = true;
1615 0 : continue;
1616 : }
1617 :
1618 133 : if (lAlphaBlanks(4) || UtilityRoutines::SameString(Alphas(4), "comma")) {
1619 133 : ColumnSep = CharComma;
1620 133 : Alphas(4) = "comma";
1621 0 : } else if (UtilityRoutines::SameString(Alphas(4), "semicolon")) {
1622 0 : ColumnSep = CharSemicolon;
1623 0 : } else if (UtilityRoutines::SameString(Alphas(4), "tab")) {
1624 0 : ColumnSep = CharTab;
1625 0 : } else if (UtilityRoutines::SameString(Alphas(4), "space")) {
1626 0 : ColumnSep = CharSpace;
1627 : } else {
1628 0 : ShowSevereError(state,
1629 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(4) + " illegal value=\"" +
1630 0 : Alphas(4) + "\".");
1631 0 : ShowContinueError(state, "..must be Comma, Semicolon, Tab, or Space.");
1632 0 : ErrorsFound = true;
1633 0 : continue;
1634 : }
1635 :
1636 : // Depending on value of "Interpolate" field, the value for each time step in each hour gets processed:
1637 133 : FileIntervalInterpolated = false;
1638 133 : if (lAlphaBlanks(5)) Alphas(5) = "NO";
1639 133 : if (Alphas(5) != "NO" && Alphas(5) != "YES") {
1640 0 : ShowSevereError(state,
1641 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "Invalid value for \"" + cAlphaFields(5) +
1642 0 : "\" field=\"" + Alphas(5) + "\"");
1643 0 : ErrorsFound = true;
1644 133 : } else if (Alphas(5) != "YES") { // No validation done on the value of the interpolation field
1645 133 : FileIntervalInterpolated = false;
1646 : } else {
1647 0 : FileIntervalInterpolated = true;
1648 : }
1649 :
1650 133 : state.dataScheduleMgr->Schedule(SchNum).UseDaylightSaving = true;
1651 133 : if ((Alphas(6)) == "NO") {
1652 2 : state.dataScheduleMgr->Schedule(SchNum).UseDaylightSaving = false;
1653 : }
1654 :
1655 : // is it a sub-hourly schedule or not?
1656 133 : MinutesPerItem = 60;
1657 133 : if (NumNumbers > 3) {
1658 133 : MinutesPerItem = int(Numbers(4));
1659 133 : NumExpectedItems = 1440 / MinutesPerItem;
1660 133 : if (mod(60, MinutesPerItem) != 0) {
1661 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1));
1662 0 : ShowContinueError(state, format("Requested {} field value ({}) not evenly divisible into 60", cNumericFields(4), MinutesPerItem));
1663 0 : ErrorsFound = true;
1664 0 : continue;
1665 : }
1666 : }
1667 :
1668 133 : numHourlyValues = Numbers(3);
1669 133 : rowLimitCount = (Numbers(3) * 60.0) / MinutesPerItem;
1670 133 : hrLimitCount = 60 / MinutesPerItem;
1671 :
1672 266 : std::string contextString = CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(3) + ": ";
1673 :
1674 133 : state.files.TempFullFilePath.filePath = CheckForActualFilePath(state, Alphas(3), contextString);
1675 : // Setup file reading parameters
1676 133 : if (state.files.TempFullFilePath.filePath.empty()) {
1677 0 : ErrorsFound = true;
1678 : } else {
1679 266 : auto result = state.dataScheduleMgr->UniqueProcessedExternalFiles.find(state.files.TempFullFilePath.filePath);
1680 133 : if (result == state.dataScheduleMgr->UniqueProcessedExternalFiles.end()) {
1681 9 : auto const ext = FileSystem::getFileType(state.files.TempFullFilePath.filePath);
1682 9 : if (FileSystem::is_flat_file_type(ext)) {
1683 18 : auto const schedule_data = FileSystem::readFile(state.files.TempFullFilePath.filePath);
1684 18 : CsvParser csvParser;
1685 9 : auto it = state.dataScheduleMgr->UniqueProcessedExternalFiles.emplace(
1686 18 : state.files.TempFullFilePath.filePath, csvParser.decode(schedule_data, ColumnSep, skiprowCount));
1687 9 : result = it.first;
1688 0 : } else if (FileSystem::is_all_json_type(ext)) {
1689 0 : auto it = state.dataScheduleMgr->UniqueProcessedExternalFiles.emplace(
1690 0 : state.files.TempFullFilePath.filePath, FileSystem::readJSON(state.files.TempFullFilePath.filePath));
1691 0 : result = it.first;
1692 : } else {
1693 0 : ShowSevereError(state,
1694 0 : fmt::format(R"({}{}="{}", {}="{}" has an unknown file extension and cannot be read by this program.)",
1695 : RoutineName,
1696 : CurrentModuleObject,
1697 : Alphas(1),
1698 : cAlphaFields(3),
1699 : Alphas(3)));
1700 0 : ShowFatalError(state, "Program terminates due to previous condition.");
1701 : }
1702 : }
1703 :
1704 133 : auto const &column_json = result->second["values"][curcolCount - 1];
1705 133 : rowCnt = column_json.size();
1706 266 : auto const column_values = column_json.get<std::vector<Real64>>();
1707 :
1708 : // schedule values have been filled into the hourlyFileValues array.
1709 :
1710 133 : if (numerrors > 0) {
1711 0 : ShowWarningError(state,
1712 0 : format("{}{}=\"{}\" {} records had errors - these values are set to 0.",
1713 : RoutineName,
1714 : CurrentModuleObject,
1715 : Alphas(1),
1716 0 : numerrors));
1717 0 : ShowContinueError(state, "Use Output:Diagnostics,DisplayExtraWarnings; to see individual records in error.");
1718 : }
1719 133 : if (rowCnt < rowLimitCount) {
1720 0 : ShowWarningError(
1721 : state,
1722 0 : format(
1723 0 : "{}{}=\"{}\" less than {} hourly values read from file.", RoutineName, CurrentModuleObject, Alphas(1), numHourlyValues));
1724 0 : ShowContinueError(state, format("..Number read={}.", (rowCnt * 60) / MinutesPerItem));
1725 : }
1726 133 : if (rowCnt < rowLimitCount) {
1727 0 : ShowWarningError(state,
1728 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
1729 : "\" less than specified hourly values read from file.");
1730 0 : ShowContinueError(state,
1731 0 : format("..Specified Number of Hourly Values={} Actual number of hourly values included={}",
1732 : numHourlyValues,
1733 0 : (rowCnt * 60) / MinutesPerItem));
1734 : }
1735 :
1736 : // process the data into the normal schedule data structures
1737 : // note -- schedules are ALWAYS 366 days so some special measures have to be done at 29 Feb "day of year" (60)
1738 133 : iDay = 0;
1739 133 : hDay = 0;
1740 133 : ifld = 0;
1741 : while (true) {
1742 : // create string of which day of year
1743 97223 : ++iDay;
1744 48678 : ++hDay;
1745 48678 : if (iDay > 366) break;
1746 : // increment both since a week schedule is being defined for each day so that a day is valid
1747 : // no matter what the day type that is used in a design day.
1748 48545 : ++AddWeekSch;
1749 48545 : ++AddDaySch;
1750 : // define week schedule
1751 97090 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).Name = fmt::format("{}_wk_{}", Alphas(1), iDay);
1752 : // for all day types point the week schedule to the newly defined day schedule
1753 631085 : for (kDayType = 1; kDayType <= maxDayTypes; ++kDayType) {
1754 582540 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).DaySchedulePointer(kDayType) = AddDaySch;
1755 : }
1756 : // day schedule
1757 97090 : state.dataScheduleMgr->DaySchedule(AddDaySch).Name = fmt::format("{}_dy_{}", Alphas(1), iDay);
1758 48545 : state.dataScheduleMgr->DaySchedule(AddDaySch).ScheduleTypePtr = state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr;
1759 : // schedule is pointing to the week schedule
1760 48545 : state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay) = AddWeekSch;
1761 48545 : if (MinutesPerItem == 60) {
1762 100375 : for (jHour = 1; jHour <= 24; ++jHour) {
1763 96360 : curHrVal = column_values[ifld]; // hourlyFileValues((hDay - 1) * 24 + jHour)
1764 96360 : ++ifld;
1765 481800 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
1766 385440 : state.dataScheduleMgr->DaySchedule(AddDaySch).TSValue(TS, jHour) = curHrVal;
1767 : }
1768 : }
1769 : } else { // Minutes Per Item < 60
1770 1113250 : for (Hr = 1; Hr <= 24; ++Hr) {
1771 1068720 : CurMinute = MinutesPerItem;
1772 1068720 : SCount = 1;
1773 5694000 : for (NumFields = 1; NumFields <= hrLimitCount; ++NumFields) {
1774 4625280 : MinuteValue({SCount, CurMinute}, Hr) = column_values[ifld];
1775 4625280 : ++ifld;
1776 4625280 : SCount = CurMinute + 1;
1777 4625280 : CurMinute += MinutesPerItem;
1778 : }
1779 : }
1780 44530 : if (FileIntervalInterpolated) {
1781 0 : for (Hr = 1; Hr <= 24; ++Hr) {
1782 0 : SCount = 1;
1783 0 : CurMinute = state.dataGlobal->MinutesPerTimeStep;
1784 0 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
1785 0 : state.dataScheduleMgr->DaySchedule(AddDaySch).TSValue(TS, Hr) =
1786 0 : sum(MinuteValue({SCount, CurMinute}, Hr)) / double(state.dataGlobal->MinutesPerTimeStep);
1787 0 : SCount = CurMinute + 1;
1788 0 : CurMinute += state.dataGlobal->MinutesPerTimeStep;
1789 : }
1790 : }
1791 : } else {
1792 1113250 : for (Hr = 1; Hr <= 24; ++Hr) {
1793 1068720 : CurMinute = state.dataGlobal->MinutesPerTimeStep;
1794 5694000 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
1795 4625280 : state.dataScheduleMgr->DaySchedule(AddDaySch).TSValue(TS, Hr) = MinuteValue(CurMinute, Hr);
1796 4625280 : CurMinute += state.dataGlobal->MinutesPerTimeStep;
1797 : }
1798 : }
1799 : }
1800 : }
1801 48545 : if (iDay == 59 && rowCnt < 8784 * hrLimitCount) { // 28 Feb
1802 : // Dup 28 Feb to 29 Feb (60)
1803 133 : ++iDay;
1804 133 : state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay) =
1805 133 : state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay - 1);
1806 : }
1807 : }
1808 : }
1809 :
1810 133 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) { // setup constant schedules as actuators
1811 0 : SetupEMSActuator(state,
1812 : "Schedule:File",
1813 0 : state.dataScheduleMgr->Schedule(SchNum).Name,
1814 : "Schedule Value",
1815 : "[ ]",
1816 0 : state.dataScheduleMgr->Schedule(SchNum).EMSActuatedOn,
1817 0 : state.dataScheduleMgr->Schedule(SchNum).EMSValue);
1818 : }
1819 : }
1820 :
1821 771 : if (NumCommaFileShading != 0) {
1822 1 : auto const &values_json = schedule_file_shading_result->second["values"];
1823 2 : auto const headers = schedule_file_shading_result->second["header"].get<std::vector<std::string>>();
1824 2 : auto const headers_set = schedule_file_shading_result->second["header"].get<std::set<std::string>>();
1825 :
1826 115 : for (auto const &header : headers_set) {
1827 114 : size_t column = 0;
1828 227 : auto column_it = std::find(headers.begin(), headers.end(), header);
1829 114 : if (column_it != headers.end()) {
1830 114 : column = std::distance(headers.begin(), column_it);
1831 : }
1832 114 : if (column == 0) continue; // Skip timestamp column and any duplicate column, which will be 0 as well since it won't be found.
1833 226 : auto const column_values = values_json.at(column).get<std::vector<Real64>>();
1834 :
1835 226 : std::string curName = fmt::format("{}_shading", header);
1836 226 : GlobalNames::VerifyUniqueInterObjectName(
1837 226 : state, state.dataScheduleMgr->UniqueScheduleNames, curName, CurrentModuleObject, cAlphaFields(1), ErrorsFound);
1838 113 : ++SchNum;
1839 113 : state.dataScheduleMgr->Schedule(SchNum).Name = curName;
1840 113 : state.dataScheduleMgr->Schedule(SchNum).SchType = SchedType::ScheduleInput_file;
1841 :
1842 113 : iDay = 0;
1843 113 : ifld = 0;
1844 : while (true) {
1845 : // create string of which day of year
1846 82603 : ++iDay;
1847 41358 : if (iDay > 366) {
1848 113 : break;
1849 : }
1850 : // increment both since a week schedule is being defined for each day so that a day is valid
1851 : // no matter what the day type that is used in a design day.
1852 41245 : ++AddWeekSch;
1853 41245 : ++AddDaySch;
1854 : // define week schedule
1855 41245 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).Name = fmt::format("{}_wk_{}", curName, iDay);
1856 : // for all day types point the week schedule to the newly defined day schedule
1857 536185 : for (kDayType = 1; kDayType <= maxDayTypes; ++kDayType) {
1858 494940 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).DaySchedulePointer(kDayType) = AddDaySch;
1859 : }
1860 : // day schedule
1861 41245 : state.dataScheduleMgr->DaySchedule(AddDaySch).Name = fmt::format("{}_dy_{}", curName, iDay);
1862 41245 : state.dataScheduleMgr->DaySchedule(AddDaySch).ScheduleTypePtr = state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr;
1863 : // schedule is pointing to the week schedule
1864 41245 : state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay) = AddWeekSch;
1865 :
1866 1031125 : for (jHour = 1; jHour <= 24; ++jHour) {
1867 4949400 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
1868 3959520 : state.dataScheduleMgr->DaySchedule(AddDaySch).TSValue(TS, jHour) = column_values[ifld];
1869 3959520 : ++ifld;
1870 : }
1871 : }
1872 41245 : if (iDay == 59 && !state.dataEnvrn->CurrentYearIsLeapYear) { // 28 Feb
1873 : // Dup 28 Feb to 29 Feb (60)
1874 113 : ++iDay;
1875 113 : state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay) =
1876 113 : state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay - 1);
1877 : }
1878 : }
1879 : }
1880 : }
1881 :
1882 771 : MinuteValue.deallocate();
1883 771 : SetMinuteValue.deallocate();
1884 :
1885 : // Constant Schedules
1886 771 : CurrentModuleObject = "Schedule:Constant";
1887 984 : for (LoopIndex = 1; LoopIndex <= NumConstantSchedules; ++LoopIndex) {
1888 213 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1889 : CurrentModuleObject,
1890 : LoopIndex,
1891 : Alphas,
1892 : NumAlphas,
1893 : Numbers,
1894 : NumNumbers,
1895 : Status,
1896 : lNumericBlanks,
1897 : lAlphaBlanks,
1898 : cAlphaFields,
1899 : cNumericFields);
1900 426 : GlobalNames::VerifyUniqueInterObjectName(
1901 426 : state, state.dataScheduleMgr->UniqueScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
1902 213 : ++SchNum;
1903 213 : state.dataScheduleMgr->Schedule(SchNum).Name = Alphas(1);
1904 213 : state.dataScheduleMgr->Schedule(SchNum).SchType = SchedType::ScheduleInput_constant;
1905 : // Validate ScheduleType
1906 213 : if (state.dataScheduleMgr->NumScheduleTypes > 0) {
1907 211 : CheckIndex =
1908 422 : UtilityRoutines::FindItemInList(Alphas(2), state.dataScheduleMgr->ScheduleType({1, state.dataScheduleMgr->NumScheduleTypes}));
1909 211 : if (CheckIndex == 0) {
1910 34 : if (!lAlphaBlanks(2)) {
1911 0 : ShowWarningError(state,
1912 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(2) + "=\"" +
1913 0 : Alphas(2) + "\" not found -- will not be validated");
1914 : } else {
1915 102 : ShowWarningError(state,
1916 68 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Blank " + cAlphaFields(2) +
1917 : " input -- will not be validated.");
1918 : }
1919 : } else {
1920 177 : state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr = CheckIndex;
1921 : }
1922 : }
1923 213 : ++AddWeekSch;
1924 213 : ++AddDaySch;
1925 : // define week schedule
1926 213 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).Name = Alphas(1) + "_wk_";
1927 : // for all day types point the week schedule to the newly defined day schedule
1928 2769 : for (kDayType = 1; kDayType <= maxDayTypes; ++kDayType) {
1929 2556 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).DaySchedulePointer(kDayType) = AddDaySch;
1930 : }
1931 : // day schedule
1932 213 : state.dataScheduleMgr->DaySchedule(AddDaySch).Name = Alphas(1) + "_dy_";
1933 213 : state.dataScheduleMgr->DaySchedule(AddDaySch).ScheduleTypePtr = state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr;
1934 : // schedule is pointing to the week schedule
1935 213 : state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer = AddWeekSch;
1936 213 : curHrVal = Numbers(1);
1937 213 : state.dataScheduleMgr->DaySchedule(AddDaySch).TSValue = Numbers(1);
1938 :
1939 213 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) { // setup constant schedules as actuators
1940 268 : SetupEMSActuator(state,
1941 : "Schedule:Constant",
1942 67 : state.dataScheduleMgr->Schedule(SchNum).Name,
1943 : "Schedule Value",
1944 : "[ ]",
1945 67 : state.dataScheduleMgr->Schedule(SchNum).EMSActuatedOn,
1946 201 : state.dataScheduleMgr->Schedule(SchNum).EMSValue);
1947 : }
1948 : }
1949 :
1950 771 : CurrentModuleObject = "ExternalInterface:Schedule";
1951 771 : for (LoopIndex = 1; LoopIndex <= NumExternalInterfaceSchedules; ++LoopIndex) {
1952 :
1953 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1954 : CurrentModuleObject,
1955 : LoopIndex,
1956 : Alphas,
1957 : NumAlphas,
1958 : Numbers,
1959 : NumNumbers,
1960 : Status,
1961 : lNumericBlanks,
1962 : lAlphaBlanks,
1963 : cAlphaFields,
1964 : cNumericFields);
1965 0 : GlobalNames::VerifyUniqueInterObjectName(
1966 0 : state, state.dataScheduleMgr->UniqueScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
1967 0 : ++SchNum;
1968 0 : state.dataScheduleMgr->Schedule(SchNum).Name = Alphas(1);
1969 0 : state.dataScheduleMgr->Schedule(SchNum).SchType = SchedType::ScheduleInput_external;
1970 :
1971 : // Validate ScheduleType
1972 0 : CheckIndex =
1973 0 : UtilityRoutines::FindItemInList(Alphas(2), state.dataScheduleMgr->ScheduleType({1, state.dataScheduleMgr->NumScheduleTypes}));
1974 0 : if (CheckIndex == 0) {
1975 0 : if (!lAlphaBlanks(2)) {
1976 0 : ShowWarningError(state,
1977 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(2) + "=\"" +
1978 0 : Alphas(2) + "\" not found -- will not be validated");
1979 : } else {
1980 0 : ShowWarningError(state,
1981 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Blank " + cAlphaFields(2) +
1982 : " input -- will not be validated.");
1983 : }
1984 : } else {
1985 0 : state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr = CheckIndex;
1986 : }
1987 0 : ++AddWeekSch;
1988 0 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).Name = Alphas(1);
1989 0 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).Used = true;
1990 0 : for (Hr = 1; Hr <= 366; ++Hr) {
1991 0 : state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(Hr) = AddWeekSch;
1992 : }
1993 0 : ++AddDaySch;
1994 0 : state.dataScheduleMgr->DaySchedule(AddDaySch).Name = Alphas(1);
1995 0 : state.dataScheduleMgr->DaySchedule(AddDaySch).ScheduleTypePtr = state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr;
1996 0 : state.dataScheduleMgr->DaySchedule(AddDaySch).Used = true;
1997 0 : for (Hr = 1; Hr <= maxDayTypes; ++Hr) {
1998 0 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).DaySchedulePointer(Hr) = AddDaySch;
1999 : }
2000 : // Initialize the ExternalInterface day schedule for the ExternalInterface compact schedule.
2001 : // It will be overwritten during run time stepping after the warm up period
2002 0 : if (NumNumbers < 1) {
2003 0 : ShowWarningError(state,
2004 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
2005 : "\", initial value is not numeric or is missing. Fix idf file.");
2006 0 : NumErrorFlag = true;
2007 : }
2008 0 : ExternalInterfaceSetSchedule(state, AddDaySch, Numbers(1));
2009 : }
2010 : // added for FMU Import
2011 771 : CurrentModuleObject = "ExternalInterface:FunctionalMockupUnitImport:To:Schedule";
2012 773 : for (LoopIndex = 1; LoopIndex <= NumExternalInterfaceFunctionalMockupUnitImportSchedules; ++LoopIndex) {
2013 :
2014 2 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2015 : CurrentModuleObject,
2016 : LoopIndex,
2017 : Alphas,
2018 : NumAlphas,
2019 : Numbers,
2020 : NumNumbers,
2021 : Status,
2022 : lNumericBlanks,
2023 : lAlphaBlanks,
2024 : cAlphaFields,
2025 : cNumericFields);
2026 :
2027 2 : if (NumExternalInterfaceSchedules >= 1) {
2028 0 : GlobalNames::VerifyUniqueInterObjectName(
2029 : state,
2030 0 : state.dataScheduleMgr->UniqueScheduleNames,
2031 0 : Alphas(1),
2032 : CurrentModuleObject,
2033 0 : cAlphaFields(1) + "(defined as an ExternalInterface:Schedule and ExternalInterface:FunctionalMockupUnitImport:To:Schedule. This "
2034 : "will cause the schedule to be overwritten by PtolemyServer and FunctionalMockUpUnitImport)",
2035 : ErrorsFound);
2036 : } else {
2037 4 : GlobalNames::VerifyUniqueInterObjectName(
2038 4 : state, state.dataScheduleMgr->UniqueScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
2039 : }
2040 2 : ++SchNum;
2041 2 : state.dataScheduleMgr->Schedule(SchNum).Name = Alphas(1);
2042 2 : state.dataScheduleMgr->Schedule(SchNum).SchType = SchedType::ScheduleInput_external;
2043 :
2044 : // Validate ScheduleType
2045 2 : CheckIndex =
2046 4 : UtilityRoutines::FindItemInList(Alphas(2), state.dataScheduleMgr->ScheduleType({1, state.dataScheduleMgr->NumScheduleTypes}));
2047 2 : if (CheckIndex == 0) {
2048 0 : if (!lAlphaBlanks(2)) {
2049 0 : ShowWarningError(state,
2050 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(2) + "=\"" +
2051 0 : Alphas(2) + "\" not found -- will not be validated");
2052 : } else {
2053 0 : ShowWarningError(state,
2054 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Blank " + cAlphaFields(2) +
2055 : " input -- will not be validated.");
2056 : }
2057 : } else {
2058 2 : state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr = CheckIndex;
2059 : }
2060 2 : ++AddWeekSch;
2061 2 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).Name = Alphas(1);
2062 2 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).Used = true;
2063 734 : for (Hr = 1; Hr <= 366; ++Hr) {
2064 732 : state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(Hr) = AddWeekSch;
2065 : }
2066 2 : ++AddDaySch;
2067 2 : state.dataScheduleMgr->DaySchedule(AddDaySch).Name = Alphas(1);
2068 2 : state.dataScheduleMgr->DaySchedule(AddDaySch).ScheduleTypePtr = state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr;
2069 2 : state.dataScheduleMgr->DaySchedule(AddDaySch).Used = true;
2070 26 : for (Hr = 1; Hr <= maxDayTypes; ++Hr) {
2071 24 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).DaySchedulePointer(Hr) = AddDaySch;
2072 : }
2073 : // Initialize the ExternalInterface day schedule for the ExternalInterface compact schedule.
2074 : // It will be overwritten during run time stepping after the warm up period
2075 2 : if (NumNumbers < 1) {
2076 0 : ShowWarningError(state,
2077 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
2078 : "\", initial value is not numeric or is missing. Fix idf file.");
2079 0 : NumErrorFlag = true;
2080 : }
2081 2 : ExternalInterfaceSetSchedule(state, AddDaySch, Numbers(1));
2082 : }
2083 :
2084 : // added for FMU Export
2085 771 : CurrentModuleObject = "ExternalInterface:FunctionalMockupUnitExport:To:Schedule";
2086 771 : for (LoopIndex = 1; LoopIndex <= NumExternalInterfaceFunctionalMockupUnitExportSchedules; ++LoopIndex) {
2087 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2088 : CurrentModuleObject,
2089 : LoopIndex,
2090 : Alphas,
2091 : NumAlphas,
2092 : Numbers,
2093 : NumNumbers,
2094 : Status,
2095 : lNumericBlanks,
2096 : lAlphaBlanks,
2097 : cAlphaFields,
2098 : cNumericFields);
2099 :
2100 0 : if (NumExternalInterfaceSchedules >= 1) {
2101 0 : GlobalNames::VerifyUniqueInterObjectName(
2102 : state,
2103 0 : state.dataScheduleMgr->UniqueScheduleNames,
2104 0 : Alphas(1),
2105 : CurrentModuleObject,
2106 0 : cAlphaFields(1) + "(defined as an ExternalInterface:Schedule and ExternalInterface:FunctionalMockupUnitExport:To:Schedule. This "
2107 : "will cause the schedule to be overwritten by PtolemyServer and FunctionalMockUpUnitExport)",
2108 : ErrorsFound);
2109 : } else {
2110 0 : GlobalNames::VerifyUniqueInterObjectName(
2111 0 : state, state.dataScheduleMgr->UniqueScheduleNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
2112 : }
2113 :
2114 0 : ++SchNum;
2115 0 : state.dataScheduleMgr->Schedule(SchNum).Name = Alphas(1);
2116 0 : state.dataScheduleMgr->Schedule(SchNum).SchType = SchedType::ScheduleInput_external;
2117 :
2118 : // Validate ScheduleType
2119 0 : CheckIndex =
2120 0 : UtilityRoutines::FindItemInList(Alphas(2), state.dataScheduleMgr->ScheduleType({1, state.dataScheduleMgr->NumScheduleTypes}));
2121 0 : if (CheckIndex == 0) {
2122 0 : if (!lAlphaBlanks(2)) {
2123 0 : ShowWarningError(state,
2124 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", " + cAlphaFields(2) + "=\"" +
2125 0 : Alphas(2) + "\" not found -- will not be validated");
2126 : } else {
2127 0 : ShowWarningError(state,
2128 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", Blank " + cAlphaFields(2) +
2129 : " input -- will not be validated.");
2130 : }
2131 : } else {
2132 0 : state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr = CheckIndex;
2133 : }
2134 0 : ++AddWeekSch;
2135 0 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).Name = Alphas(1);
2136 0 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).Used = true;
2137 0 : for (Hr = 1; Hr <= 366; ++Hr) {
2138 0 : state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(Hr) = AddWeekSch;
2139 : }
2140 0 : ++AddDaySch;
2141 0 : state.dataScheduleMgr->DaySchedule(AddDaySch).Name = Alphas(1);
2142 0 : state.dataScheduleMgr->DaySchedule(AddDaySch).ScheduleTypePtr = state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr;
2143 0 : state.dataScheduleMgr->DaySchedule(AddDaySch).Used = true;
2144 0 : for (Hr = 1; Hr <= maxDayTypes; ++Hr) {
2145 0 : state.dataScheduleMgr->WeekSchedule(AddWeekSch).DaySchedulePointer(Hr) = AddDaySch;
2146 : }
2147 : // Initialize the ExternalInterface day schedule for the ExternalInterface compact schedule.
2148 : // It will be overwritten during run time stepping after the warm up period
2149 0 : if (NumNumbers < 1) {
2150 0 : ShowWarningError(state,
2151 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) +
2152 : "\", initial value is not numeric or is missing. Fix idf file.");
2153 0 : NumErrorFlag = true;
2154 : }
2155 0 : ExternalInterfaceSetSchedule(state, AddDaySch, Numbers(1));
2156 : }
2157 :
2158 : // Validate by ScheduleLimitsType
2159 16769 : for (SchNum = 1; SchNum <= state.dataScheduleMgr->NumSchedules; ++SchNum) {
2160 15998 : NumPointer = state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr;
2161 15998 : if (!state.dataScheduleMgr->ScheduleType(NumPointer).Limited) continue;
2162 24870 : if (CheckScheduleValueMinMax(state,
2163 : SchNum,
2164 : ">=",
2165 12435 : state.dataScheduleMgr->ScheduleType(NumPointer).Minimum,
2166 : "<=",
2167 12435 : state.dataScheduleMgr->ScheduleType(NumPointer).Maximum))
2168 12435 : continue;
2169 0 : ShowSevereError(state,
2170 0 : format("{}Schedule=\"{}\" has values outside its Schedule Type ({}) range",
2171 : RoutineName,
2172 0 : state.dataScheduleMgr->Schedule(SchNum).Name,
2173 0 : state.dataScheduleMgr->ScheduleType(NumPointer).Name));
2174 0 : ShowContinueError(state,
2175 0 : format(" Minimum should be >={:.3R} and Maximum should be <={:.3R}",
2176 0 : state.dataScheduleMgr->ScheduleType(NumPointer).Minimum,
2177 0 : state.dataScheduleMgr->ScheduleType(NumPointer).Maximum));
2178 0 : ErrorsFound = true;
2179 : }
2180 :
2181 771 : if (ErrorsFound) {
2182 0 : ShowFatalError(state, format("{}Preceding Errors cause termination.", RoutineName));
2183 : }
2184 :
2185 2313 : if (state.dataScheduleMgr->NumScheduleTypes + state.dataScheduleMgr->NumDaySchedules + state.dataScheduleMgr->NumWeekSchedules +
2186 1542 : state.dataScheduleMgr->NumSchedules >
2187 : 0) { // Report to EIO file
2188 770 : CurrentModuleObject = "Output:Schedules";
2189 770 : NumFields = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
2190 :
2191 : // RptSchedule=.FALSE.
2192 770 : RptLevel = 1;
2193 793 : for (Count = 1; Count <= NumFields; ++Count) {
2194 23 : state.dataInputProcessing->inputProcessor->getObjectItem(
2195 : state, CurrentModuleObject, Count, Alphas, NumAlphas, Numbers, NumNumbers, Status);
2196 : // RptSchedule=.TRUE.
2197 :
2198 : // IDD only allows Hourly or Timestep as valid values on the required field, anything else should be an error in the input processor
2199 : OutputReportLevel reportLevel =
2200 23 : static_cast<OutputReportLevel>(getEnumerationValue(outputScheduleReportLevelNamesUC, Alphas(1))); // NOLINT(modernize-use-auto)
2201 23 : if (reportLevel == OutputReportLevel::Invalid) {
2202 0 : ShowWarningError(state, format("{}Report for Schedules should specify \"HOURLY\" or \"TIMESTEP\" (\"DETAILED\")", RoutineName));
2203 0 : ShowContinueError(state, "HOURLY report will be done");
2204 0 : reportLevel = OutputReportLevel::Hourly;
2205 : }
2206 23 : ReportScheduleDetails(state, reportLevel);
2207 : }
2208 : }
2209 :
2210 771 : Alphas.deallocate();
2211 771 : cAlphaFields.deallocate();
2212 771 : cNumericFields.deallocate();
2213 771 : Numbers.deallocate();
2214 771 : lAlphaBlanks.deallocate();
2215 771 : lNumericBlanks.deallocate();
2216 :
2217 771 : print(state.files.audit, "{}\n", " Processing Schedule Input -- Complete");
2218 : }
2219 :
2220 23 : void ReportScheduleDetails(EnergyPlusData &state,
2221 : OutputReportLevel const LevelOfDetail) // =1: hourly; =2: timestep; = 3: make IDF excerpt
2222 : {
2223 : // SUBROUTINE INFORMATION:
2224 : // AUTHOR Linda K. Lawrie
2225 : // DATE WRITTEN January 2003
2226 : // MODIFIED February 2008 - add IDF outputs (compact schedules)
2227 : // RE-ENGINEERED na
2228 :
2229 : // PURPOSE OF THIS SUBROUTINE:
2230 : // This subroutine puts the details of the Schedules on the .eio file (Inits file).
2231 :
2232 : // SUBROUTINE PARAMETER DEFINITIONS:
2233 23 : constexpr std::array<std::string_view, 12> Months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
2234 23 : constexpr std::array<std::string_view, 25> HrField = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12",
2235 : "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"};
2236 :
2237 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2238 : int NumF;
2239 : int PMon;
2240 : int PDay;
2241 46 : Array1D_string ShowMinute;
2242 46 : Array1D_string TimeHHMM;
2243 46 : std::string NoAverageLinear;
2244 46 : std::string YesNo2;
2245 46 : std::string Num1;
2246 46 : std::string Num2;
2247 46 : Array2D_string RoundTSValue;
2248 23 : std::string_view constexpr SchDFmtdata{",{}"};
2249 :
2250 23 : ShowMinute.allocate(state.dataGlobal->NumOfTimeStepInHour);
2251 23 : TimeHHMM.allocate(state.dataGlobal->NumOfTimeStepInHour * 24);
2252 23 : RoundTSValue.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
2253 23 : ShowMinute = std::string{};
2254 23 : TimeHHMM = std::string{};
2255 23 : RoundTSValue = std::string{};
2256 :
2257 23 : int CurMinute = state.dataGlobal->MinutesPerTimeStep;
2258 128 : for (int Count = 1; Count <= state.dataGlobal->NumOfTimeStepInHour - 1; ++Count) {
2259 105 : ShowMinute(Count) = format("{:02}", CurMinute);
2260 105 : CurMinute += state.dataGlobal->MinutesPerTimeStep;
2261 : }
2262 23 : ShowMinute(state.dataGlobal->NumOfTimeStepInHour) = "00";
2263 :
2264 23 : switch (LevelOfDetail) {
2265 23 : case OutputReportLevel::Hourly:
2266 : case OutputReportLevel::TimeStep:
2267 23 : NumF = 1;
2268 575 : for (int Hr = 1; Hr <= 24; ++Hr) {
2269 552 : if (LevelOfDetail == OutputReportLevel::TimeStep) {
2270 2784 : for (int TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour - 1; ++TS) {
2271 2304 : TimeHHMM(NumF) = format("{}:{}", HrField[Hr - 1], ShowMinute(TS));
2272 2304 : ++NumF;
2273 : }
2274 : }
2275 552 : TimeHHMM(NumF) = format("{}:{}", HrField[Hr], ShowMinute(state.dataGlobal->NumOfTimeStepInHour));
2276 552 : ++NumF;
2277 23 : }
2278 23 : --NumF;
2279 :
2280 : // SchTFmt Schedule Types Header
2281 : {
2282 23 : std::string_view constexpr SchTFmt0("! Schedule Details Report={} =====================\n");
2283 23 : std::string_view constexpr SchDFmt{",{}"};
2284 23 : print(state.files.eio, SchTFmt0, outputScheduleReportLevelNames[static_cast<int>(LevelOfDetail)]);
2285 :
2286 23 : std::string_view constexpr SchTFmt("! <ScheduleType>,Name,Limited? {Yes/No},Minimum,Maximum,Continuous? {Yes/No - Discrete}");
2287 23 : print(state.files.eio, "{}\n", SchTFmt);
2288 23 : std::string_view constexpr SchDFmt0("! <DaySchedule>,Name,ScheduleType,Interpolated {Yes/No},Time (HH:MM) =>");
2289 23 : print(state.files.eio, "{}", SchDFmt0);
2290 2879 : for (int Count = 1; Count <= NumF; ++Count) {
2291 2856 : print(state.files.eio, SchDFmt, TimeHHMM(Count));
2292 : }
2293 23 : print(state.files.eio, "\n");
2294 : // SchWFmt Header (WeekSchedule)
2295 46 : std::string SchWFmt("! <WeekSchedule>,Name");
2296 299 : for (int Count = 1; Count <= maxDayTypes; ++Count) {
2297 276 : SchWFmt += "," + static_cast<std::string>(dayTypeNames[Count]);
2298 : }
2299 23 : print(state.files.eio, "{}\n", SchWFmt);
2300 23 : std::string_view constexpr SchSFmt("! <Schedule>,Name,ScheduleType,{Until Date,WeekSchedule}** Repeated until Dec 31");
2301 46 : print(state.files.eio, "{}\n", SchSFmt);
2302 : }
2303 :
2304 164 : for (int Count = 1; Count <= state.dataScheduleMgr->NumScheduleTypes; ++Count) {
2305 141 : if (state.dataScheduleMgr->ScheduleType(Count).Limited) {
2306 103 : NoAverageLinear = "Average";
2307 103 : Num1 = format("{:.2R}", state.dataScheduleMgr->ScheduleType(Count).Minimum);
2308 103 : strip(Num1);
2309 103 : Num2 = format("{:.2R}", state.dataScheduleMgr->ScheduleType(Count).Maximum);
2310 103 : strip(Num2);
2311 103 : if (state.dataScheduleMgr->ScheduleType(Count).IsReal) {
2312 66 : YesNo2 = "Yes";
2313 : } else {
2314 37 : YesNo2 = "No";
2315 37 : Num1 = fmt::to_string(static_cast<int>(state.dataScheduleMgr->ScheduleType(Count).Minimum));
2316 37 : Num2 = fmt::to_string(static_cast<int>(state.dataScheduleMgr->ScheduleType(Count).Maximum));
2317 : }
2318 : } else {
2319 38 : NoAverageLinear = "No";
2320 38 : Num1 = "N/A";
2321 38 : Num2 = "N/A";
2322 38 : YesNo2 = "N/A";
2323 : }
2324 141 : std::string_view constexpr SchTFmtdata("ScheduleTypeLimits,{},{},{},{},{}\n");
2325 141 : print(state.files.eio, SchTFmtdata, state.dataScheduleMgr->ScheduleType(Count).Name, NoAverageLinear, Num1, Num2, YesNo2);
2326 23 : }
2327 :
2328 946 : for (int Count = 1; Count <= state.dataScheduleMgr->NumDaySchedules; ++Count) {
2329 923 : NoAverageLinear = interpolationTypes[static_cast<int>(state.dataScheduleMgr->DaySchedule(Count).IntervalInterpolated)];
2330 23075 : for (int Hr = 1; Hr <= 24; ++Hr) {
2331 153000 : for (int TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
2332 130848 : RoundTSValue(TS, Hr) = format("{:.2R}", state.dataScheduleMgr->DaySchedule(Count).TSValue(TS, Hr));
2333 : }
2334 : }
2335 923 : std::string_view constexpr SchDFmtdata0("DaySchedule,{},{},{},{}");
2336 1846 : print(state.files.eio,
2337 : SchDFmtdata0,
2338 923 : state.dataScheduleMgr->DaySchedule(Count).Name,
2339 923 : state.dataScheduleMgr->ScheduleType(state.dataScheduleMgr->DaySchedule(Count).ScheduleTypePtr).Name,
2340 : NoAverageLinear,
2341 : "Values:");
2342 923 : switch (LevelOfDetail) {
2343 24 : case OutputReportLevel::Hourly:
2344 600 : for (int Hr = 1; Hr <= 24; ++Hr) {
2345 576 : print(state.files.eio, SchDFmtdata, RoundTSValue(state.dataGlobal->NumOfTimeStepInHour, Hr));
2346 24 : }
2347 24 : break;
2348 899 : case OutputReportLevel::TimeStep:
2349 22475 : for (int Hr = 1; Hr <= 24; ++Hr) {
2350 150120 : for (int TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
2351 128544 : print(state.files.eio, SchDFmtdata, RoundTSValue(TS, Hr));
2352 : }
2353 899 : }
2354 899 : break;
2355 0 : default:
2356 0 : assert(false);
2357 : }
2358 923 : print(state.files.eio, "\n");
2359 23 : }
2360 :
2361 674 : for (int Count = 1; Count <= state.dataScheduleMgr->NumWeekSchedules; ++Count) {
2362 651 : std::string_view constexpr SchWFmtdata("Schedule:Week:Daily,{}");
2363 651 : print(state.files.eio, SchWFmtdata, state.dataScheduleMgr->WeekSchedule(Count).Name);
2364 8463 : for (NumF = 1; NumF <= maxDayTypes; ++NumF) {
2365 15624 : print(state.files.eio,
2366 : ",{}",
2367 15624 : state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(Count).DaySchedulePointer(NumF)).Name);
2368 : }
2369 651 : print(state.files.eio, "\n");
2370 23 : }
2371 :
2372 666 : for (int Count = 1; Count <= state.dataScheduleMgr->NumSchedules; ++Count) {
2373 643 : NumF = 1;
2374 1929 : print(state.files.eio,
2375 : "Schedule,{},{}",
2376 643 : state.dataScheduleMgr->Schedule(Count).Name,
2377 1286 : state.dataScheduleMgr->ScheduleType(state.dataScheduleMgr->Schedule(Count).ScheduleTypePtr).Name);
2378 1945 : while (NumF <= 366) {
2379 651 : int TS = state.dataScheduleMgr->Schedule(Count).WeekSchedulePointer(NumF);
2380 651 : std::string_view constexpr ThruFmt(",Through {} {:02},{}");
2381 470041 : while (state.dataScheduleMgr->Schedule(Count).WeekSchedulePointer(NumF) == TS && NumF <= 366) {
2382 235338 : if (NumF == 366) {
2383 643 : General::InvOrdinalDay(NumF, PMon, PDay, 1);
2384 643 : print(state.files.eio, ThruFmt, Months[PMon - 1], PDay, state.dataScheduleMgr->WeekSchedule(TS).Name);
2385 : }
2386 235338 : ++NumF;
2387 235338 : if (NumF > 366) break; // compound If might have a problem unless this included.
2388 : }
2389 651 : if (NumF <= 366) {
2390 8 : General::InvOrdinalDay(NumF - 1, PMon, PDay, 1);
2391 8 : print(state.files.eio, ThruFmt, Months[PMon - 1], PDay, state.dataScheduleMgr->WeekSchedule(TS).Name);
2392 : }
2393 : }
2394 643 : print(state.files.eio, "\n");
2395 23 : }
2396 23 : break;
2397 0 : default:
2398 0 : break;
2399 : }
2400 :
2401 : // So this section of the code was not accessible. The input processor would never have let anything but hourly or timestep on the object
2402 : // This code is obviously not covered by any of our integration or unit tests.
2403 : // for (Count = 1; Count <= state.dataScheduleMgr->NumSchedules; ++Count) {
2404 : // print(state.files.debug, "\n");
2405 : // print(state.files.debug, " Schedule:Compact,\n");
2406 : // print(state.files.debug, " {}, !- Name\n", state.dataScheduleMgr->Schedule(Count).Name);
2407 : // print(state.files.debug,
2408 : // " {}, !- ScheduleTypeLimits\n",
2409 : // state.dataScheduleMgr->ScheduleType(state.dataScheduleMgr->Schedule(Count).ScheduleTypePtr).Name);
2410 : // NumF = 1;
2411 : // while (NumF <= 366) {
2412 : // TS = state.dataScheduleMgr->Schedule(Count).WeekSchedulePointer(NumF);
2413 : // while (state.dataScheduleMgr->Schedule(Count).WeekSchedulePointer(NumF) == TS && NumF <= 366) {
2414 : // if (NumF == 366) {
2415 : // General::InvOrdinalDay(NumF, PMon, PDay, 1);
2416 : // print(state.files.debug, " Through: {}/{},\n", PMon, PDay);
2417 : // iDayP = 0;
2418 : // for (DT = 2; DT <= 6; ++DT) {
2419 : // print(state.files.debug, " For: {},\n", ValidDayTypes(DT));
2420 : // iWeek = state.dataScheduleMgr->Schedule(Count).WeekSchedulePointer(NumF - 1);
2421 : // iDay = state.dataScheduleMgr->WeekSchedule(iWeek).DaySchedulePointer(DT);
2422 : // if (iDay != iDayP) {
2423 : // for (Hr = 1; Hr <= 24; ++Hr) {
2424 : // print(state.files.debug,
2425 : // " Until: {}:{},{:.2R},\n",
2426 : // Hr,
2427 : // ShowMinute(state.dataGlobal->NumOfTimeStepInHour),
2428 : // state.dataScheduleMgr->DaySchedule(iDay).TSValue(state.dataGlobal->NumOfTimeStepInHour, Hr));
2429 : // }
2430 : // } else {
2431 : // print(state.files.debug, " Same as previous\n");
2432 : // }
2433 : // iDayP = iDay;
2434 : // }
2435 : // DT = 1;
2436 : // print(state.files.debug, " For: {},\n", ValidDayTypes(DT));
2437 : // iWeek = state.dataScheduleMgr->Schedule(Count).WeekSchedulePointer(NumF - 1);
2438 : // iDay = state.dataScheduleMgr->WeekSchedule(iWeek).DaySchedulePointer(DT);
2439 : // if (iDay != iDayP) {
2440 : // for (Hr = 1; Hr <= 24; ++Hr) {
2441 : // print(state.files.debug,
2442 : // " Until: {}:{},{:.2R},\n",
2443 : // Hr,
2444 : // ShowMinute(state.dataGlobal->NumOfTimeStepInHour),
2445 : // state.dataScheduleMgr->DaySchedule(iDay).TSValue(state.dataGlobal->NumOfTimeStepInHour, Hr));
2446 : // }
2447 : // } else {
2448 : // print(state.files.debug, " Same as previous\n");
2449 : // }
2450 : // iDayP = iDay;
2451 : // for (DT = 7; DT <= MaxDayTypes; ++DT) {
2452 : // print(state.files.debug, " For: {},\n", ValidDayTypes(DT));
2453 : // iWeek = state.dataScheduleMgr->Schedule(Count).WeekSchedulePointer(NumF - 1);
2454 : // iDay = state.dataScheduleMgr->WeekSchedule(iWeek).DaySchedulePointer(DT);
2455 : // if (iDay != iDayP) {
2456 : // for (Hr = 1; Hr <= 24; ++Hr) {
2457 : // print(state.files.debug,
2458 : // " Until: {}:{},{:.2R},\n",
2459 : // Hr,
2460 : // ShowMinute(state.dataGlobal->NumOfTimeStepInHour),
2461 : // state.dataScheduleMgr->DaySchedule(iDay).TSValue(state.dataGlobal->NumOfTimeStepInHour, Hr));
2462 : // }
2463 : // } else {
2464 : // print(state.files.debug, " Same as previous\n");
2465 : // }
2466 : // iDayP = iDay;
2467 : // }
2468 : // }
2469 : // ++NumF;
2470 : // if (NumF > 366) break; // compound If might have a problem unless this included.
2471 : // }
2472 : // if (NumF <= 366) {
2473 : // General::InvOrdinalDay(NumF - 1, PMon, PDay, 1);
2474 : // print(state.files.debug, " Through: {}/{},\n", PMon, PDay);
2475 : // iDayP = 0;
2476 : // for (DT = 2; DT <= 6; ++DT) {
2477 : // print(state.files.debug, " For: {},\n", ValidDayTypes(DT));
2478 : // iWeek = state.dataScheduleMgr->Schedule(Count).WeekSchedulePointer(NumF - 1);
2479 : // iDay = state.dataScheduleMgr->WeekSchedule(iWeek).DaySchedulePointer(DT);
2480 : // if (iDay != iDayP) {
2481 : // for (Hr = 1; Hr <= 24; ++Hr) {
2482 : // print(state.files.debug,
2483 : // " Until: {}:{},{:.2R},\n",
2484 : // Hr,
2485 : // ShowMinute(state.dataGlobal->NumOfTimeStepInHour),
2486 : // state.dataScheduleMgr->DaySchedule(iDay).TSValue(state.dataGlobal->NumOfTimeStepInHour, Hr));
2487 : // }
2488 : // } else {
2489 : // print(state.files.debug, " Same as previous\n");
2490 : // }
2491 : // iDayP = iDay;
2492 : // }
2493 : // DT = 1;
2494 : // print(state.files.debug, " For: {},\n", ValidDayTypes(DT));
2495 : // iWeek = state.dataScheduleMgr->Schedule(Count).WeekSchedulePointer(NumF - 1);
2496 : // iDay = state.dataScheduleMgr->WeekSchedule(iWeek).DaySchedulePointer(DT);
2497 : // if (iDay != iDayP) {
2498 : // for (Hr = 1; Hr <= 24; ++Hr) {
2499 : // print(state.files.debug,
2500 : // " Until: {}:{},{:.2R},\n",
2501 : // Hr,
2502 : // ShowMinute(state.dataGlobal->NumOfTimeStepInHour),
2503 : // state.dataScheduleMgr->DaySchedule(iDay).TSValue(state.dataGlobal->NumOfTimeStepInHour, Hr));
2504 : // }
2505 : // } else {
2506 : // print(state.files.debug, " Same as previous\n");
2507 : // }
2508 : // iDayP = iDay;
2509 : // for (DT = 7; DT <= MaxDayTypes; ++DT) {
2510 : // print(state.files.debug, " For: {},\n", ValidDayTypes(DT));
2511 : // iWeek = state.dataScheduleMgr->Schedule(Count).WeekSchedulePointer(NumF - 1);
2512 : // iDay = state.dataScheduleMgr->WeekSchedule(iWeek).DaySchedulePointer(DT);
2513 : // if (iDay != iDayP) {
2514 : // for (Hr = 1; Hr <= 24; ++Hr) {
2515 : // print(state.files.debug,
2516 : // " Until: {}:{},{:.2R},\n",
2517 : // Hr,
2518 : // ShowMinute(state.dataGlobal->NumOfTimeStepInHour),
2519 : // state.dataScheduleMgr->DaySchedule(iDay).TSValue(state.dataGlobal->NumOfTimeStepInHour, Hr));
2520 : // }
2521 : // } else {
2522 : // print(state.files.debug, " Same as previous\n");
2523 : // }
2524 : // iDayP = iDay;
2525 : // }
2526 : // }
2527 : // }
2528 : // }
2529 :
2530 23 : ShowMinute.deallocate();
2531 23 : TimeHHMM.deallocate();
2532 23 : RoundTSValue.deallocate();
2533 23 : }
2534 :
2535 1425810255 : Real64 GetCurrentScheduleValue(EnergyPlusData &state, int const ScheduleIndex)
2536 : {
2537 : // FUNCTION INFORMATION:
2538 : // AUTHOR Linda K. Lawrie
2539 : // DATE WRITTEN September 1997
2540 : // MODIFIED August 2011; adapt Autodesk changes (time reduction)
2541 : // RE-ENGINEERED na
2542 :
2543 : // PURPOSE OF THIS FUNCTION:
2544 : // This function returns the hourly schedule value for the current day.
2545 :
2546 : // METHODOLOGY EMPLOYED:
2547 : // Use internal Schedule data structure to return value. Note that missing values in
2548 : // input will equate to 0 indices in arrays -- which has been set up to return legally with
2549 : // 0.0 values.
2550 :
2551 : // REFERENCES:
2552 : // na
2553 :
2554 : // USE STATEMENTS:
2555 : // na
2556 :
2557 : // Return value
2558 :
2559 : // Locals
2560 : // FUNCTION ARGUMENT DEFINITIONS:
2561 :
2562 : // FUNCTION PARAMETER DEFINITIONS:
2563 : // na
2564 :
2565 : // INTERFACE BLOCK SPECIFICATIONS
2566 : // na
2567 :
2568 : // DERIVED TYPE DEFINITIONS
2569 : // na
2570 :
2571 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2572 : // na
2573 :
2574 : // Checking if valid index is passed is necessary
2575 1425810255 : if (ScheduleIndex == -1) {
2576 283141222 : return 1.0;
2577 1142669033 : } else if (ScheduleIndex == 0) {
2578 649965 : return 0.0;
2579 1142019068 : } else if (!state.dataScheduleMgr->Schedule(ScheduleIndex).EMSActuatedOn) {
2580 1141053564 : return state.dataScheduleMgr->Schedule(ScheduleIndex)
2581 1141053564 : .CurrentValue; // This block probably unecessary, UpdateScheduleValues already does it
2582 : } else {
2583 965504 : return state.dataScheduleMgr->Schedule(ScheduleIndex).EMSValue;
2584 : }
2585 : }
2586 :
2587 5229481 : void UpdateScheduleValues(EnergyPlusData &state)
2588 : {
2589 : // SUBROUTINE INFORMATION:
2590 : // AUTHOR Linda Lawrie
2591 : // DATE WRITTEN August 2011; adapted from Autodesk (time reduction)
2592 : // MODIFIED na
2593 : // RE-ENGINEERED na
2594 :
2595 : // PURPOSE OF THIS SUBROUTINE:
2596 : // This routine calculates all the scheduled values as a time reduction measure and
2597 : // stores them in the CurrentValue item of the schedule data structure.
2598 :
2599 : // METHODOLOGY EMPLOYED:
2600 : // Use internal Schedule data structure to calculate current value. Note that missing values in
2601 : // input will equate to 0 indices in arrays -- which has been set up to return legally with
2602 : // 0.0 values.
2603 :
2604 : // REFERENCES:
2605 : // na
2606 :
2607 : // Using/Aliasing
2608 :
2609 : // Locals
2610 : // SUBROUTINE ARGUMENT DEFINITIONS:
2611 : // na
2612 :
2613 : // SUBROUTINE PARAMETER DEFINITIONS:
2614 : // na
2615 :
2616 : // INTERFACE BLOCK SPECIFICATIONS:
2617 : // na
2618 :
2619 : // DERIVED TYPE DEFINITIONS:
2620 : // na
2621 :
2622 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2623 :
2624 5229481 : if (!state.dataScheduleMgr->ScheduleInputProcessed) {
2625 699 : ProcessScheduleInput(state);
2626 699 : state.dataScheduleMgr->ScheduleInputProcessed = true;
2627 : }
2628 :
2629 123448443 : for (int ScheduleIndex = 1; ScheduleIndex <= state.dataScheduleMgr->NumSchedules; ++ScheduleIndex) {
2630 118218962 : if (state.dataScheduleMgr->Schedule(ScheduleIndex).EMSActuatedOn) {
2631 148069 : state.dataScheduleMgr->Schedule(ScheduleIndex).CurrentValue = state.dataScheduleMgr->Schedule(ScheduleIndex).EMSValue;
2632 : } else {
2633 118070893 : state.dataScheduleMgr->Schedule(ScheduleIndex).CurrentValue =
2634 118070893 : LookUpScheduleValue(state, ScheduleIndex, state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep);
2635 : }
2636 : }
2637 5229481 : }
2638 :
2639 123079624 : Real64 LookUpScheduleValue(EnergyPlusData &state,
2640 : int const ScheduleIndex,
2641 : int const ThisHour,
2642 : int const ThisTimeStep // Negative => unspecified
2643 : )
2644 : {
2645 : // FUNCTION INFORMATION:
2646 : // AUTHOR Linda K. Lawrie
2647 : // DATE WRITTEN January 2003
2648 : // MODIFIED na
2649 : // RE-ENGINEERED na
2650 :
2651 : // PURPOSE OF THIS FUNCTION:
2652 : // This function provides a method to look up schedule values for any hour, timestep, day
2653 : // of the year (rather than just the "current time").
2654 :
2655 : // METHODOLOGY EMPLOYED:
2656 : // na
2657 :
2658 : // REFERENCES:
2659 : // na
2660 :
2661 : // Using/Aliasing
2662 :
2663 : // Return value
2664 123079624 : Real64 scheduleValue(0.0);
2665 :
2666 : // Locals
2667 : // FUNCTION ARGUMENT DEFINITIONS:
2668 :
2669 : // FUNCTION PARAMETER DEFINITIONS:
2670 : // na
2671 :
2672 : // INTERFACE BLOCK SPECIFICATIONS
2673 : // na
2674 :
2675 : // DERIVED TYPE DEFINITIONS
2676 : // na
2677 :
2678 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2679 :
2680 123079624 : if (ThisHour > 24) {
2681 0 : ShowFatalError(state, format("LookUpScheduleValue called with thisHour={}", ThisHour));
2682 : }
2683 :
2684 123079624 : if (ScheduleIndex == -1) {
2685 0 : return 1.0;
2686 123079624 : } else if (ScheduleIndex == 0) {
2687 1341647 : return 0.0;
2688 : }
2689 :
2690 121737977 : if (!state.dataScheduleMgr->ScheduleInputProcessed) {
2691 0 : ProcessScheduleInput(state);
2692 0 : state.dataScheduleMgr->ScheduleInputProcessed = true;
2693 : }
2694 :
2695 : // so, current date, but maybe TimeStep added
2696 :
2697 : // Hourly Value
2698 121737977 : int thisHour = ThisHour + state.dataEnvrn->DSTIndicator * state.dataScheduleMgr->Schedule(ScheduleIndex).UseDaylightSaving;
2699 :
2700 121737977 : int thisDayOfYear = state.dataEnvrn->DayOfYear_Schedule;
2701 121737977 : int thisDayOfWeek = state.dataEnvrn->DayOfWeek;
2702 121737977 : int thisHolidayIndex = state.dataEnvrn->HolidayIndex;
2703 121737977 : if (thisHour > 24) { // In case HourOfDay is 24 and DSTIndicator is 1, you're actually the next day
2704 42064 : thisDayOfYear += 1;
2705 42064 : thisHour -= 24;
2706 42064 : thisDayOfWeek = state.dataEnvrn->DayOfWeekTomorrow;
2707 42064 : thisHolidayIndex = state.dataEnvrn->HolidayIndexTomorrow;
2708 : }
2709 :
2710 : // In the case where DST is applied on 12/31 at 24:00, which is the case for a Southern Hemisphere location for eg
2711 : // (DayOfYear_Schedule is a bit weird, ScheduleManager always assumes LeapYear)
2712 121737977 : if (thisDayOfYear == 367) {
2713 0 : thisDayOfYear = 1;
2714 : }
2715 :
2716 121737977 : int WeekSchedulePointer = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(thisDayOfYear);
2717 : int DaySchedulePointer;
2718 :
2719 121737977 : if (thisHolidayIndex > 0) {
2720 115832368 : DaySchedulePointer = state.dataScheduleMgr->WeekSchedule(WeekSchedulePointer).DaySchedulePointer(thisHolidayIndex);
2721 : } else {
2722 5905609 : DaySchedulePointer = state.dataScheduleMgr->WeekSchedule(WeekSchedulePointer).DaySchedulePointer(thisDayOfWeek);
2723 : }
2724 :
2725 : // If Unspecified or equal to zero, use NumOfTimeStepInHour, otherwise use supplied
2726 121737977 : int thisTimeStep = ThisTimeStep > 0 ? ThisTimeStep : state.dataGlobal->NumOfTimeStepInHour;
2727 121737977 : scheduleValue = state.dataScheduleMgr->DaySchedule(DaySchedulePointer).TSValue(thisTimeStep, thisHour);
2728 :
2729 121737977 : return scheduleValue;
2730 : }
2731 :
2732 134134 : int GetScheduleIndex(EnergyPlusData &state, std::string const &ScheduleName)
2733 : {
2734 : // FUNCTION INFORMATION:
2735 : // AUTHOR Linda K. Lawrie
2736 : // DATE WRITTEN September 1997
2737 : // MODIFIED na
2738 : // RE-ENGINEERED na
2739 :
2740 : // PURPOSE OF THIS FUNCTION:
2741 : // This function returns the internal pointer to Schedule "ScheduleName".
2742 :
2743 : // Return value
2744 : int GetScheduleIndex;
2745 :
2746 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2747 : int DayCtr;
2748 : int WeekCtr;
2749 :
2750 134134 : if (!state.dataScheduleMgr->ScheduleInputProcessed) {
2751 70 : ProcessScheduleInput(state);
2752 70 : state.dataScheduleMgr->ScheduleInputProcessed = true;
2753 : }
2754 :
2755 134134 : if (state.dataScheduleMgr->NumSchedules > 0) {
2756 134114 : GetScheduleIndex =
2757 268228 : UtilityRoutines::FindItemInList(ScheduleName, state.dataScheduleMgr->Schedule({1, state.dataScheduleMgr->NumSchedules}));
2758 134114 : if (GetScheduleIndex > 0) {
2759 70014 : if (!state.dataScheduleMgr->Schedule(GetScheduleIndex).Used) {
2760 15287 : state.dataScheduleMgr->Schedule(GetScheduleIndex).Used = true;
2761 5610329 : for (WeekCtr = 1; WeekCtr <= 366; ++WeekCtr) {
2762 5595042 : if (state.dataScheduleMgr->Schedule(GetScheduleIndex).WeekSchedulePointer(WeekCtr) > 0) {
2763 5595042 : state.dataScheduleMgr->WeekSchedule(state.dataScheduleMgr->Schedule(GetScheduleIndex).WeekSchedulePointer(WeekCtr)).Used =
2764 : true;
2765 72735546 : for (DayCtr = 1; DayCtr <= maxDayTypes; ++DayCtr) {
2766 : state.dataScheduleMgr
2767 67140504 : ->DaySchedule(state.dataScheduleMgr
2768 67140504 : ->WeekSchedule(state.dataScheduleMgr->Schedule(GetScheduleIndex).WeekSchedulePointer(WeekCtr))
2769 134281008 : .DaySchedulePointer(DayCtr))
2770 67140504 : .Used = true;
2771 : }
2772 : }
2773 : }
2774 : }
2775 : }
2776 : } else {
2777 20 : GetScheduleIndex = 0;
2778 : }
2779 :
2780 134134 : return GetScheduleIndex;
2781 : }
2782 :
2783 19060 : std::string GetScheduleType(EnergyPlusData &state, int const ScheduleIndex)
2784 : {
2785 : // FUNCTION INFORMATION:
2786 : // AUTHOR Jason Glazer
2787 : // DATE WRITTEN July 2007
2788 : // MODIFIED na
2789 : // RE-ENGINEERED na
2790 :
2791 : // PURPOSE OF THIS FUNCTION:
2792 : // This function returns the internal pointer to Schedule "ScheduleName".
2793 :
2794 : // METHODOLOGY EMPLOYED:
2795 : // na
2796 :
2797 : // REFERENCES:
2798 : // na
2799 :
2800 : // USE STATEMENTS:
2801 :
2802 : // Return value
2803 19060 : std::string TypeOfSchedule;
2804 :
2805 : // Locals
2806 : // FUNCTION ARGUMENT DEFINITIONS:
2807 :
2808 : // FUNCTION PARAMETER DEFINITIONS:
2809 : // na
2810 :
2811 : // INTERFACE BLOCK SPECIFICATIONS
2812 : // na
2813 :
2814 : // DERIVED TYPE DEFINITIONS
2815 : // na
2816 :
2817 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2818 : int curSchType;
2819 :
2820 19060 : if (!state.dataScheduleMgr->ScheduleInputProcessed) {
2821 0 : ProcessScheduleInput(state);
2822 0 : state.dataScheduleMgr->ScheduleInputProcessed = true;
2823 : }
2824 :
2825 19060 : if ((ScheduleIndex > 0) && (ScheduleIndex <= state.dataScheduleMgr->NumSchedules)) {
2826 19060 : curSchType = state.dataScheduleMgr->Schedule(ScheduleIndex).ScheduleTypePtr;
2827 19060 : if ((curSchType > 0) && (curSchType <= state.dataScheduleMgr->NumScheduleTypes)) {
2828 18898 : TypeOfSchedule = state.dataScheduleMgr->ScheduleType(curSchType).Name;
2829 : } else {
2830 162 : TypeOfSchedule = "";
2831 : }
2832 : } else {
2833 0 : TypeOfSchedule = "";
2834 : }
2835 19060 : return TypeOfSchedule;
2836 : }
2837 :
2838 21 : int GetDayScheduleIndex(EnergyPlusData &state, std::string &ScheduleName)
2839 : {
2840 : // FUNCTION INFORMATION:
2841 : // AUTHOR Linda K. Lawrie
2842 : // DATE WRITTEN August 2003
2843 : // MODIFIED na
2844 : // RE-ENGINEERED na
2845 :
2846 : // PURPOSE OF THIS FUNCTION:
2847 : // This function returns the internal pointer to Day Schedule "ScheduleName".
2848 :
2849 : // Return value
2850 : int GetDayScheduleIndex;
2851 :
2852 21 : if (!state.dataScheduleMgr->ScheduleInputProcessed) {
2853 2 : ProcessScheduleInput(state);
2854 2 : state.dataScheduleMgr->ScheduleInputProcessed = true;
2855 : }
2856 :
2857 21 : if (state.dataScheduleMgr->NumDaySchedules > 0) {
2858 21 : GetDayScheduleIndex =
2859 42 : UtilityRoutines::FindItemInList(ScheduleName, state.dataScheduleMgr->DaySchedule({1, state.dataScheduleMgr->NumDaySchedules}));
2860 21 : if (GetDayScheduleIndex > 0) {
2861 21 : state.dataScheduleMgr->DaySchedule(GetDayScheduleIndex).Used = true;
2862 : }
2863 : } else {
2864 0 : GetDayScheduleIndex = 0;
2865 : }
2866 :
2867 21 : return GetDayScheduleIndex;
2868 : }
2869 :
2870 33298 : void GetScheduleValuesForDay(
2871 : EnergyPlusData &state, int const ScheduleIndex, Array2S<Real64> DayValues, Optional_int_const JDay, Optional_int_const CurDayofWeek)
2872 : {
2873 : // SUBROUTINE INFORMATION:
2874 : // AUTHOR Linda K. Lawrie
2875 : // DATE WRITTEN September 1997
2876 : // MODIFIED na
2877 : // RE-ENGINEERED na
2878 :
2879 : // PURPOSE OF THIS SUBROUTINE:
2880 : // This subroutine returns an entire day's worth of schedule values.
2881 :
2882 : // METHODOLOGY EMPLOYED:
2883 : // Use internal data to fill DayValues array.
2884 :
2885 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2886 : int WeekSchedulePointer;
2887 : int DaySchedulePointer;
2888 :
2889 33298 : if (!state.dataScheduleMgr->ScheduleInputProcessed) {
2890 0 : ProcessScheduleInput(state);
2891 0 : state.dataScheduleMgr->ScheduleInputProcessed = true;
2892 : }
2893 :
2894 33298 : if (ScheduleIndex == -1) {
2895 0 : DayValues({1, state.dataGlobal->NumOfTimeStepInHour}, {1, 24}) = 1.0;
2896 0 : return;
2897 33298 : } else if (ScheduleIndex == 0) {
2898 32 : DayValues({1, state.dataGlobal->NumOfTimeStepInHour}, {1, 24}) = 0.0;
2899 32 : return;
2900 : }
2901 :
2902 : // Determine which Week Schedule is used
2903 33266 : if (!present(JDay)) {
2904 28072 : WeekSchedulePointer = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(state.dataEnvrn->DayOfYear_Schedule);
2905 : } else {
2906 5194 : WeekSchedulePointer = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(JDay);
2907 : }
2908 :
2909 : // Now, which day?
2910 33266 : if (!present(CurDayofWeek)) {
2911 28224 : if (state.dataEnvrn->HolidayIndex > 0) {
2912 28224 : DaySchedulePointer = state.dataScheduleMgr->WeekSchedule(WeekSchedulePointer).DaySchedulePointer(state.dataEnvrn->HolidayIndex);
2913 : } else {
2914 0 : DaySchedulePointer = state.dataScheduleMgr->WeekSchedule(WeekSchedulePointer).DaySchedulePointer(state.dataEnvrn->DayOfWeek);
2915 : }
2916 5042 : } else if (CurDayofWeek <= 7 && state.dataEnvrn->HolidayIndex > 0) {
2917 5042 : DaySchedulePointer = state.dataScheduleMgr->WeekSchedule(WeekSchedulePointer).DaySchedulePointer(state.dataEnvrn->HolidayIndex);
2918 : } else {
2919 0 : DaySchedulePointer = state.dataScheduleMgr->WeekSchedule(WeekSchedulePointer).DaySchedulePointer(CurDayofWeek);
2920 : }
2921 :
2922 : // Return Values
2923 33266 : DayValues({1, state.dataGlobal->NumOfTimeStepInHour}, {1, 24}) = state.dataScheduleMgr->DaySchedule(DaySchedulePointer).TSValue;
2924 : }
2925 :
2926 20 : void GetSingleDayScheduleValues(EnergyPlusData &state,
2927 : int const DayScheduleIndex, // Index of the DaySchedule for values
2928 : Array2S<Real64> DayValues // Returned set of values
2929 : )
2930 : {
2931 : // SUBROUTINE INFORMATION:
2932 : // AUTHOR Linda K. Lawrie
2933 : // DATE WRITTEN August 2003
2934 : // MODIFIED na
2935 : // RE-ENGINEERED na
2936 :
2937 : // PURPOSE OF THIS SUBROUTINE:
2938 : // This subroutine returns an entire day's worth of schedule values for a specified Day Schedule Index item.
2939 :
2940 : // METHODOLOGY EMPLOYED:
2941 : // Use internal data to fill DayValues array.
2942 :
2943 : // REFERENCES:
2944 : // na
2945 :
2946 : // USE STATEMENTS:
2947 : // na
2948 :
2949 : // Argument array dimensioning
2950 :
2951 : // Locals
2952 : // SUBROUTINE ARGUMENT DEFINITIONS:
2953 :
2954 : // SUBROUTINE PARAMETER DEFINITIONS:
2955 : // na
2956 :
2957 : // INTERFACE BLOCK SPECIFICATIONS
2958 : // na
2959 :
2960 : // DERIVED TYPE DEFINITIONS
2961 : // na
2962 :
2963 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2964 : // na
2965 :
2966 20 : if (!state.dataScheduleMgr->ScheduleInputProcessed) {
2967 0 : ProcessScheduleInput(state);
2968 0 : state.dataScheduleMgr->ScheduleInputProcessed = true;
2969 : }
2970 :
2971 : // Return Values
2972 20 : DayValues({1, state.dataGlobal->NumOfTimeStepInHour}, {1, 24}) = state.dataScheduleMgr->DaySchedule(DayScheduleIndex).TSValue;
2973 20 : }
2974 :
2975 2 : void ExternalInterfaceSetSchedule(EnergyPlusData &state,
2976 : int &ScheduleIndex,
2977 : Real64 &Value // The new value for the schedule
2978 : )
2979 : {
2980 : // FUNCTION INFORMATION:
2981 : // AUTHOR Michael Wetter
2982 : // DATE WRITTEN February 2010
2983 : // MODIFIED na
2984 : // RE-ENGINEERED na
2985 :
2986 : // PURPOSE OF THIS SUBROUTINE:
2987 : // This subroutine sets all values of the schedule referenced by 'ScheduleIndex'
2988 : // to the value specified by 'Value'. The subroutine is used by the ExternalInterface to
2989 : // write real-time data into a schedule so that EnergyPlus modules can use
2990 : // real-time data by referencing a schedule. This allows overwriting setpoint
2991 : // for supervisory controls or internal gains obtained from real-time occupancy
2992 : // measurements.
2993 :
2994 : // METHODOLOGY EMPLOYED:
2995 : // na
2996 :
2997 : // REFERENCES:
2998 : // na
2999 :
3000 : // Using/Aliasing
3001 : // Locals
3002 : // FUNCTION ARGUMENT DEFINITIONS:
3003 :
3004 : // FUNCTION PARAMETER DEFINITIONS:
3005 : // na
3006 :
3007 : // INTERFACE BLOCK SPECIFICATIONS
3008 : // na
3009 :
3010 : // DERIVED TYPE DEFINITIONS
3011 : // na
3012 :
3013 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3014 : int TS; // Counter for Num Of Time Steps in Hour
3015 : int Hr; // Hour Counter
3016 :
3017 : // Assign the value of the variable
3018 50 : for (Hr = 1; Hr <= 24; ++Hr) {
3019 240 : for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
3020 192 : state.dataScheduleMgr->DaySchedule(ScheduleIndex).TSValue(TS, Hr) = Value;
3021 : }
3022 : }
3023 2 : }
3024 :
3025 32533 : void ProcessIntervalFields(EnergyPlusData &state,
3026 : Array1S_string const Untils,
3027 : Array1S<Real64> const Numbers,
3028 : int const NumUntils,
3029 : int const NumNumbers,
3030 : Array2A<Real64> MinuteValue,
3031 : Array2A_bool SetMinuteValue,
3032 : bool &ErrorsFound,
3033 : std::string const &DayScheduleName, // Name (used for errors)
3034 : std::string const &ErrContext, // Context (used for errors)
3035 : ScheduleInterpolation interpolationKind // enumeration on how to interpolate values in schedule
3036 : )
3037 : {
3038 : // SUBROUTINE INFORMATION:
3039 : // AUTHOR <author>
3040 : // DATE WRITTEN <date_written>
3041 : // MODIFIED na
3042 : // RE-ENGINEERED na
3043 :
3044 : // PURPOSE OF THIS SUBROUTINE:
3045 : // This subroutine processes the "interval" fields with/without optional "until" in front of
3046 : // time (hh:mm).
3047 :
3048 : // METHODOLOGY EMPLOYED:
3049 : // na.
3050 :
3051 : // REFERENCES:
3052 : // na
3053 :
3054 : // USE STATEMENTS:
3055 : // na
3056 :
3057 : // Argument array dimensioning
3058 32533 : MinuteValue.dim(60, 24);
3059 32533 : SetMinuteValue.dim(60, 24);
3060 :
3061 : // Locals
3062 : // SUBROUTINE ARGUMENT DEFINITIONS:
3063 :
3064 : // SUBROUTINE PARAMETER DEFINITIONS:
3065 : // na
3066 :
3067 : // INTERFACE BLOCK SPECIFICATIONS
3068 : // na
3069 :
3070 : // DERIVED TYPE DEFINITIONS
3071 : // na
3072 :
3073 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3074 : int Count;
3075 : std::string::size_type Pos;
3076 : int HHField;
3077 : int MMField;
3078 : int Hr;
3079 : int Min;
3080 : int SHr; // starting hour
3081 : int SMin; // starting minute
3082 : int EHr; // ending hour
3083 : int EMin; // ending minute
3084 : std::string::size_type sFld;
3085 : int totalMinutes;
3086 : Real64 incrementPerMinute;
3087 : Real64 curValue;
3088 :
3089 32533 : MinuteValue = 0.0;
3090 32533 : SetMinuteValue = false;
3091 32533 : SHr = 1;
3092 32533 : SMin = 1;
3093 32533 : EHr = 0;
3094 32533 : EMin = 0;
3095 32533 : sFld = 0;
3096 :
3097 32533 : Real64 StartValue = 0;
3098 32533 : Real64 EndValue = 0;
3099 :
3100 32533 : if (NumUntils != NumNumbers) {
3101 0 : ShowSevereError(state,
3102 0 : "ProcessScheduleInput: ProcessIntervalFields, number of Time fields does not match number of value fields, " +
3103 0 : ErrContext + '=' + DayScheduleName);
3104 0 : ErrorsFound = true;
3105 0 : return;
3106 : }
3107 :
3108 110988 : for (Count = 1; Count <= NumUntils; ++Count) {
3109 78455 : Pos = index(Untils(Count), "UNTIL");
3110 78455 : if (Pos == 0) {
3111 76317 : if (Untils(Count)[5] == ':') {
3112 76301 : sFld = 6;
3113 : } else {
3114 16 : sFld = 5;
3115 : }
3116 76317 : DecodeHHMMField(state, Untils(Count).substr(sFld), HHField, MMField, ErrorsFound, DayScheduleName, Untils(Count), interpolationKind);
3117 2138 : } else if (Pos == std::string::npos) {
3118 2138 : DecodeHHMMField(state, Untils(Count), HHField, MMField, ErrorsFound, DayScheduleName, Untils(Count), interpolationKind);
3119 : } else { // Until found but wasn't first field
3120 0 : ShowSevereError(state, "ProcessScheduleInput: ProcessIntervalFields, Invalid \"Until\" field encountered=" + Untils(Count));
3121 0 : ShowContinueError(state, "Occurred in Day Schedule=" + DayScheduleName);
3122 0 : ErrorsFound = true;
3123 0 : continue;
3124 : }
3125 : // Field decoded
3126 78455 : if (HHField < 0 || HHField > 24 || MMField < 0 || MMField > 60) {
3127 0 : ShowSevereError(state, "ProcessScheduleInput: ProcessIntervalFields, Invalid \"Until\" field encountered=" + Untils(Count));
3128 0 : ShowContinueError(state, "Occurred in Day Schedule=" + DayScheduleName);
3129 0 : ErrorsFound = true;
3130 0 : continue;
3131 : }
3132 78455 : if (HHField == 24 && MMField > 0 && MMField < 60) {
3133 0 : ShowWarningError(state, "ProcessScheduleInput: ProcessIntervalFields, Invalid \"Until\" field encountered=" + Untils(Count));
3134 0 : ShowContinueError(state, "Occurred in Day Schedule=" + DayScheduleName);
3135 0 : ShowContinueError(state, "Terminating the field at 24:00");
3136 0 : MMField = 0;
3137 : }
3138 :
3139 : // Fill in values
3140 78455 : if (MMField == 0) {
3141 77617 : EHr = HHField + 1;
3142 77617 : EMin = 60;
3143 : }
3144 78455 : if (MMField < 60) {
3145 78455 : EHr = HHField + 1;
3146 78455 : EMin = MMField;
3147 : }
3148 :
3149 78455 : if (interpolationKind == ScheduleInterpolation::Linear) {
3150 0 : totalMinutes = (EHr - SHr) * 60 + (EMin - SMin) + 1;
3151 0 : if (totalMinutes == 0) totalMinutes = 1; // protect future division
3152 0 : if (Count == 1) {
3153 0 : StartValue = Numbers(Count); // assume first period is flat
3154 0 : EndValue = Numbers(Count);
3155 : } else {
3156 0 : StartValue = EndValue;
3157 0 : EndValue = Numbers(Count);
3158 : }
3159 0 : incrementPerMinute = (EndValue - StartValue) / totalMinutes;
3160 0 : curValue = StartValue + incrementPerMinute;
3161 : }
3162 :
3163 78455 : if (SHr == EHr) {
3164 15784 : for (Min = SMin; Min <= EMin; ++Min) {
3165 15088 : if (SetMinuteValue(Min, SHr)) {
3166 0 : ShowSevereError(state,
3167 0 : "ProcessScheduleInput: ProcessIntervalFields, Processing time fields, overlapping times detected, " +
3168 0 : ErrContext + '=' + DayScheduleName);
3169 0 : ErrorsFound = true;
3170 0 : goto UntilLoop_exit;
3171 : }
3172 15088 : if (interpolationKind == ScheduleInterpolation::Linear) {
3173 0 : MinuteValue(Min, EHr) = curValue;
3174 0 : curValue += incrementPerMinute;
3175 0 : SetMinuteValue(Min, SHr) = true;
3176 : } else {
3177 15088 : MinuteValue(Min, SHr) = Numbers(Count);
3178 15088 : SetMinuteValue(Min, SHr) = true;
3179 : }
3180 : }
3181 696 : SMin = EMin + 1;
3182 696 : if (SMin > 60) {
3183 0 : ++SHr;
3184 0 : SMin = 1;
3185 : }
3186 77759 : } else if (EHr < SHr) {
3187 0 : ShowSevereError(state,
3188 0 : "ProcessScheduleInput: ProcessIntervalFields, Processing time fields, overlapping times detected, " + ErrContext +
3189 0 : '=' + DayScheduleName);
3190 0 : ErrorsFound = true;
3191 : } else {
3192 77759 : if (interpolationKind == ScheduleInterpolation::Linear) {
3193 0 : for (Min = SMin; Min <= 60; ++Min) { // for portion of starting hour
3194 0 : MinuteValue(Min, SHr) = curValue;
3195 0 : curValue += incrementPerMinute;
3196 0 : SetMinuteValue(Min, SHr) = true;
3197 : }
3198 0 : for (Hr = SHr + 1; Hr <= EHr - 1; ++Hr) { // for intermediate hours
3199 0 : for (Min = 1; Min <= 60; ++Min) {
3200 0 : MinuteValue(Min, Hr) = curValue;
3201 0 : curValue += incrementPerMinute;
3202 0 : SetMinuteValue(Min, Hr) = true;
3203 : }
3204 : }
3205 0 : for (Min = 1; Min <= EMin; ++Min) { // for ending hour
3206 0 : MinuteValue(Min, EHr) = curValue;
3207 0 : curValue += incrementPerMinute;
3208 0 : SetMinuteValue(Min, EHr) = true;
3209 : }
3210 : } else { // either no interpolation or "average" interpolation (average just is when the interval does not match the timestep)
3211 4724037 : for (Min = SMin; Min <= 60; ++Min) { // for portion of starting hour
3212 4646278 : MinuteValue(Min, SHr) = Numbers(Count);
3213 4646278 : SetMinuteValue(Min, SHr) = true;
3214 : }
3215 780792 : for (Hr = SHr + 1; Hr <= EHr - 1; ++Hr) { // for intermediate hours
3216 703033 : MinuteValue(_, Hr) = Numbers(Count);
3217 703033 : SetMinuteValue(_, Hr) = true;
3218 : }
3219 81933 : for (Min = 1; Min <= EMin; ++Min) { // for ending hour
3220 4174 : MinuteValue(Min, EHr) = Numbers(Count);
3221 4174 : SetMinuteValue(Min, EHr) = true;
3222 : }
3223 : }
3224 77759 : SHr = EHr;
3225 77759 : SMin = EMin + 1;
3226 77759 : if (SMin > 60) {
3227 0 : ++SHr;
3228 0 : SMin = 1;
3229 : }
3230 : }
3231 : }
3232 32533 : UntilLoop_exit:;
3233 :
3234 32533 : if (!all(SetMinuteValue)) {
3235 0 : ShowSevereError(state,
3236 0 : "ProcessScheduleInput: ProcessIntervalFields, Processing time fields, incomplete day detected, " + ErrContext + '=' +
3237 : DayScheduleName);
3238 0 : ErrorsFound = true;
3239 : }
3240 : }
3241 :
3242 78455 : void DecodeHHMMField(EnergyPlusData &state,
3243 : std::string const &FieldValue, // Input field value
3244 : int &RetHH, // Returned "hour"
3245 : int &RetMM, // Returned "minute"
3246 : bool &ErrorsFound, // True if errors found in this field
3247 : std::string const &DayScheduleName, // originating day schedule name
3248 : std::string const &FullFieldValue, // Full Input field value
3249 : ScheduleInterpolation interpolationKind // enumeration on how to interpolate values in schedule
3250 : )
3251 : {
3252 : // SUBROUTINE INFORMATION:
3253 : // AUTHOR Linda K Lawrie
3254 : // DATE WRITTEN January 2003
3255 : // MODIFIED na
3256 : // RE-ENGINEERED na
3257 :
3258 : // PURPOSE OF THIS SUBROUTINE:
3259 : // This subroutine decodes a hhmm date field input as part of the "until" time in a schedule
3260 : // representation.
3261 :
3262 : // METHODOLOGY EMPLOYED:
3263 : // na
3264 :
3265 : // REFERENCES:
3266 : // na
3267 :
3268 : // USE STATEMENTS:
3269 : // na
3270 :
3271 : // Locals
3272 : // SUBROUTINE ARGUMENT DEFINITIONS:
3273 :
3274 : // SUBROUTINE PARAMETER DEFINITIONS:
3275 :
3276 : // INTERFACE BLOCK SPECIFICATIONS
3277 : // na
3278 :
3279 : // DERIVED TYPE DEFINITIONS
3280 : // na
3281 :
3282 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3283 : Real64 rRetHH; // real Returned "hour"
3284 : Real64 rRetMM; // real Returned "minute"
3285 : bool nonIntegral;
3286 156910 : std::string hHour;
3287 156910 : std::string mMinute;
3288 :
3289 156910 : std::string String = stripped(FieldValue);
3290 78455 : std::string::size_type const Pos = index(String, ':');
3291 78455 : nonIntegral = false;
3292 78455 : if (Pos == std::string::npos) {
3293 0 : ShowSevereError(state,
3294 0 : "ProcessScheduleInput: DecodeHHMMField, Invalid \"until\" field submitted (no : separator in hh:mm)=" +
3295 0 : stripped(FullFieldValue));
3296 0 : ShowContinueError(state, "Occurred in Day Schedule=" + DayScheduleName);
3297 0 : ErrorsFound = true;
3298 0 : return;
3299 78455 : } else if (Pos == 0) {
3300 0 : RetHH = 0;
3301 : } else {
3302 78455 : bool error = false;
3303 78455 : rRetHH = UtilityRoutines::ProcessNumber(String.substr(0, Pos), error);
3304 78455 : RetHH = int(rRetHH);
3305 78455 : if (double(RetHH) != rRetHH || error || rRetHH < 0.0) {
3306 0 : if (double(RetHH) != rRetHH && rRetHH >= 0.0) {
3307 0 : ShowWarningError(state,
3308 0 : "ProcessScheduleInput: DecodeHHMMField, Invalid \"until\" field submitted (non-integer numeric in HH)=" +
3309 0 : stripped(FullFieldValue));
3310 0 : ShowContinueError(state, "Other errors may result. Occurred in Day Schedule=" + DayScheduleName);
3311 0 : nonIntegral = true;
3312 : } else {
3313 0 : ShowSevereError(state,
3314 0 : "ProcessScheduleInput: DecodeHHMMField, Invalid \"until\" field submitted (invalid numeric in HH)=" +
3315 0 : stripped(FullFieldValue));
3316 0 : ShowContinueError(state, "Field values must be integer and represent hours:minutes. Occurred in Day Schedule=" + DayScheduleName);
3317 0 : ErrorsFound = true;
3318 0 : return;
3319 : }
3320 : }
3321 : }
3322 :
3323 78455 : String.erase(0, Pos + 1);
3324 78455 : bool error = false;
3325 78455 : rRetMM = UtilityRoutines::ProcessNumber(String, error);
3326 78455 : RetMM = int(rRetMM);
3327 78455 : if (double(RetMM) != rRetMM || error || rRetMM < 0.0) {
3328 0 : if (double(RetMM) != rRetMM && rRetMM >= 0.0) {
3329 0 : ShowWarningError(state,
3330 0 : "ProcessScheduleInput: DecodeHHMMField, Invalid \"until\" field submitted (non-integer numeric in MM)=" +
3331 0 : stripped(FullFieldValue));
3332 0 : ShowContinueError(state, "Other errors may result. Occurred in Day Schedule=" + DayScheduleName);
3333 0 : nonIntegral = true;
3334 : } else {
3335 0 : ShowSevereError(state,
3336 0 : "ProcessScheduleInput: DecodeHHMMField, Invalid \"until\" field submitted (invalid numeric in MM)=" +
3337 0 : stripped(FullFieldValue));
3338 0 : ShowContinueError(state, "Field values must be integer and represent hours:minutes. Occurred in Day Schedule=" + DayScheduleName);
3339 0 : ErrorsFound = true;
3340 0 : return;
3341 : }
3342 : }
3343 :
3344 78455 : if (nonIntegral) {
3345 0 : ShowContinueError(state, format("Until value to be used will be: {:2.2F}:{:2.2F}", hHour, mMinute));
3346 : }
3347 78455 : if (interpolationKind == ScheduleInterpolation::No) {
3348 77143 : if (!isMinuteMultipleOfTimestep(RetMM, state.dataGlobal->MinutesPerTimeStep)) {
3349 123 : ShowWarningError(
3350 : state,
3351 82 : "ProcessScheduleInput: DecodeHHMMField, Invalid \"until\" field value is not a multiple of the minutes for each timestep: " +
3352 82 : stripped(FullFieldValue));
3353 41 : ShowContinueError(state, "Other errors may result. Occurred in Day Schedule=" + DayScheduleName);
3354 : }
3355 : }
3356 : }
3357 :
3358 77143 : bool isMinuteMultipleOfTimestep(int minute, int numMinutesPerTimestep)
3359 : {
3360 77143 : if (minute != 0) {
3361 250 : return (minute % numMinutesPerTimestep == 0);
3362 : } else {
3363 76893 : return true;
3364 : }
3365 : }
3366 :
3367 32416 : void ProcessForDayTypes(EnergyPlusData &state,
3368 : std::string const &ForDayField, // Field containing the "FOR:..."
3369 : Array1D_bool &TheseDays, // Array to contain returned "true" days
3370 : Array1D_bool &AlReady, // Array of days already done
3371 : bool &ErrorsFound // Will be true if error found.
3372 : )
3373 : {
3374 : // SUBROUTINE INFORMATION:
3375 : // AUTHOR Linda K. Lawrie
3376 : // DATE WRITTEN February 2003
3377 : // MODIFIED na
3378 : // RE-ENGINEERED na
3379 :
3380 : // PURPOSE OF THIS SUBROUTINE:
3381 : // This subroutine processes a field "For: day types" and returns
3382 : // those day types (can be multiple) from field.
3383 :
3384 : // METHODOLOGY EMPLOYED:
3385 : // na
3386 :
3387 : // REFERENCES:
3388 : // na
3389 :
3390 : // USE STATEMENTS:
3391 : // na
3392 :
3393 : // Argument array dimensioning
3394 32416 : EP_SIZE_CHECK(TheseDays, maxDayTypes);
3395 32416 : EP_SIZE_CHECK(AlReady, maxDayTypes);
3396 :
3397 : // Locals
3398 : // SUBROUTINE ARGUMENT DEFINITIONS:
3399 :
3400 : // SUBROUTINE PARAMETER DEFINITIONS:
3401 : // na
3402 :
3403 : // INTERFACE BLOCK SPECIFICATIONS
3404 : // na
3405 :
3406 : // DERIVED TYPE DEFINITIONS
3407 : // na
3408 :
3409 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3410 : int DayT;
3411 : bool OneValid;
3412 : bool DupAssignment;
3413 :
3414 32416 : OneValid = false;
3415 32416 : DupAssignment = false;
3416 : // Just test for specific days
3417 32416 : if (has(ForDayField, "WEEKDAY")) {
3418 4725 : TheseDays({2, 6}) = true;
3419 4725 : if (any(AlReady({2, 6}))) {
3420 0 : DupAssignment = true;
3421 : } else {
3422 4725 : AlReady({2, 6}) = true;
3423 : }
3424 4725 : OneValid = true;
3425 : }
3426 32416 : if (has(ForDayField, "MONDAY")) {
3427 106 : TheseDays(2) = true;
3428 106 : if (AlReady(2)) {
3429 0 : DupAssignment = true;
3430 : } else {
3431 106 : AlReady(2) = true;
3432 : }
3433 106 : OneValid = true;
3434 : }
3435 32416 : if (has(ForDayField, "TUESDAY")) {
3436 143 : TheseDays(3) = true;
3437 143 : if (AlReady(3)) {
3438 0 : DupAssignment = true;
3439 : } else {
3440 143 : AlReady(3) = true;
3441 : }
3442 143 : OneValid = true;
3443 : }
3444 32416 : if (has(ForDayField, "WEDNESDAY")) {
3445 88 : TheseDays(4) = true;
3446 88 : if (AlReady(4)) {
3447 0 : DupAssignment = true;
3448 : } else {
3449 88 : AlReady(4) = true;
3450 : }
3451 88 : OneValid = true;
3452 : }
3453 32416 : if (has(ForDayField, "THURSDAY")) {
3454 88 : TheseDays(5) = true;
3455 88 : if (AlReady(5)) {
3456 0 : DupAssignment = true;
3457 : } else {
3458 88 : AlReady(5) = true;
3459 : }
3460 88 : OneValid = true;
3461 : }
3462 32416 : if (has(ForDayField, "FRIDAY")) {
3463 125 : TheseDays(6) = true;
3464 125 : if (AlReady(6)) {
3465 0 : DupAssignment = true;
3466 : } else {
3467 125 : AlReady(6) = true;
3468 : }
3469 125 : OneValid = true;
3470 : }
3471 32416 : if (has(ForDayField, "WEEKEND")) {
3472 1983 : TheseDays(1) = true;
3473 1983 : TheseDays(7) = true;
3474 1983 : if (AlReady(1)) {
3475 0 : DupAssignment = true;
3476 : } else {
3477 1983 : AlReady(1) = true;
3478 : }
3479 1983 : if (AlReady(7)) {
3480 0 : DupAssignment = true;
3481 : } else {
3482 1983 : AlReady(7) = true;
3483 : }
3484 1983 : OneValid = true;
3485 : }
3486 32416 : if (has(ForDayField, "SATURDAY")) {
3487 1661 : TheseDays(7) = true;
3488 1661 : if (AlReady(7)) {
3489 0 : DupAssignment = true;
3490 : } else {
3491 1661 : AlReady(7) = true;
3492 : }
3493 1661 : OneValid = true;
3494 : }
3495 32416 : if (has(ForDayField, "SUNDAY")) {
3496 1188 : TheseDays(1) = true;
3497 1188 : if (AlReady(1)) {
3498 0 : DupAssignment = true;
3499 : } else {
3500 1188 : AlReady(1) = true;
3501 : }
3502 1188 : OneValid = true;
3503 : }
3504 32416 : if (has(ForDayField, "CUSTOMDAY1")) {
3505 1703 : TheseDays(11) = true;
3506 1703 : if (AlReady(11)) {
3507 0 : DupAssignment = true;
3508 : } else {
3509 1703 : AlReady(11) = true;
3510 : }
3511 1703 : OneValid = true;
3512 : }
3513 32416 : if (has(ForDayField, "CUSTOMDAY2")) {
3514 1691 : TheseDays(12) = true;
3515 1691 : if (AlReady(12)) {
3516 0 : DupAssignment = true;
3517 : } else {
3518 1691 : AlReady(12) = true;
3519 : }
3520 1691 : OneValid = true;
3521 : }
3522 32416 : if (has(ForDayField, "ALLDAY")) {
3523 15849 : TheseDays({1, maxDayTypes}) = true;
3524 15849 : if (any(AlReady)) {
3525 0 : DupAssignment = true;
3526 : } else {
3527 15849 : AlReady = true;
3528 : }
3529 15849 : OneValid = true;
3530 : }
3531 32416 : if (has(ForDayField, "HOLIDAY")) {
3532 3140 : TheseDays(8) = true;
3533 3140 : if (AlReady(8)) {
3534 0 : DupAssignment = true;
3535 : } else {
3536 3140 : AlReady(8) = true;
3537 : }
3538 3140 : OneValid = true;
3539 : }
3540 32416 : if (has(ForDayField, "SUMMER")) {
3541 4663 : TheseDays(9) = true;
3542 4663 : if (AlReady(9)) {
3543 0 : DupAssignment = true;
3544 : } else {
3545 4663 : AlReady(9) = true;
3546 : }
3547 4663 : OneValid = true;
3548 : }
3549 32416 : if (has(ForDayField, "WINTER")) {
3550 4375 : TheseDays(10) = true;
3551 4375 : if (AlReady(10)) {
3552 0 : DupAssignment = true;
3553 : } else {
3554 4375 : AlReady(10) = true;
3555 : }
3556 4375 : OneValid = true;
3557 : }
3558 32416 : if (has(ForDayField, "ALLOTHERDAY")) {
3559 47736 : for (DayT = 1; DayT <= maxDayTypes; ++DayT) {
3560 44064 : if (AlReady(DayT)) continue;
3561 17014 : TheseDays(DayT) = true;
3562 17014 : AlReady(DayT) = true;
3563 : }
3564 3672 : OneValid = true;
3565 : }
3566 :
3567 32416 : if (DupAssignment) {
3568 0 : ShowSevereError(state, "ProcessScheduleInput: ProcessForDayTypes, Duplicate assignment attempted in \"for\" days field=" + ForDayField);
3569 0 : ErrorsFound = true;
3570 : }
3571 32416 : if (!OneValid) {
3572 0 : ShowSevereError(state, "ProcessScheduleInput: ProcessForDayTypes, No valid day assignments found in \"for\" days field=" + ForDayField);
3573 0 : ErrorsFound = true;
3574 : }
3575 32416 : }
3576 :
3577 17 : bool CheckScheduleValueMinMax(EnergyPlusData &state,
3578 : int const ScheduleIndex, // Which Schedule being tested
3579 : std::string const &MinString, // Minimum indicator ('>', '>=')
3580 : Real64 const Minimum // Minimum desired value
3581 : )
3582 : {
3583 : // FUNCTION INFORMATION:
3584 : // AUTHOR Linda K. Lawrie
3585 : // DATE WRITTEN February 2003
3586 : // MODIFIED na
3587 : // RE-ENGINEERED na
3588 :
3589 : // PURPOSE OF THIS FUNCTION:
3590 : // This function checks the indicated schedule values for validity. Uses the ScheduleIndex
3591 : // from (GetScheduleIndex), a minimum and a maximum -- one or other optional to check "internals".
3592 :
3593 : // METHODOLOGY EMPLOYED:
3594 : // Schedule data structure stores this on first validity check. If there, then is returned else
3595 : // looks up minimum and maximum values for the schedule and then sets result of function based on
3596 : // requested minimum/maximum checks.
3597 :
3598 : // REFERENCES:
3599 : // na
3600 :
3601 : // USE STATEMENTS:
3602 : // na
3603 :
3604 : // Return value
3605 : bool CheckScheduleValueMinMax;
3606 :
3607 : // Locals
3608 : // FUNCTION ARGUMENT DEFINITIONS:
3609 :
3610 : // FUNCTION PARAMETER DEFINITIONS:
3611 : // na
3612 :
3613 : // INTERFACE BLOCK SPECIFICATIONS
3614 : // na
3615 :
3616 : // DERIVED TYPE DEFINITIONS
3617 : // na
3618 :
3619 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3620 : int Loop; // Loop Control variable
3621 : int DayT; // Day Type Loop control
3622 : int WkSch; // Pointer for WeekSchedule value
3623 17 : Real64 MinValue(0.0); // For total minimum
3624 17 : Real64 MaxValue(0.0); // For total maximum
3625 17 : bool MinValueOk(true);
3626 17 : bool MaxValueOk(true);
3627 :
3628 17 : if (ScheduleIndex == -1) {
3629 0 : MinValue = 1.0;
3630 0 : MaxValue = 1.0;
3631 17 : } else if (ScheduleIndex == 0) {
3632 0 : MinValue = 0.0;
3633 0 : MaxValue = 0.0;
3634 17 : } else if (ScheduleIndex < 1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
3635 0 : ShowFatalError(state, "CheckScheduleValueMinMax called with ScheduleIndex out of range");
3636 : }
3637 :
3638 17 : if (ScheduleIndex > 0) {
3639 17 : if (!state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet) { // Set Minimum/Maximums for this schedule
3640 12 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(1);
3641 12 : MinValue = minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValue);
3642 12 : MaxValue = maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValue);
3643 144 : for (DayT = 2; DayT <= maxDayTypes; ++DayT) {
3644 132 : MinValue =
3645 132 : min(MinValue,
3646 132 : minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3647 132 : MaxValue =
3648 132 : max(MaxValue,
3649 132 : maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3650 : }
3651 4392 : for (Loop = 2; Loop <= 366; ++Loop) {
3652 4380 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(Loop);
3653 56940 : for (DayT = 1; DayT <= maxDayTypes; ++DayT) {
3654 52560 : MinValue = min(
3655 : MinValue,
3656 52560 : minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3657 52560 : MaxValue = max(
3658 : MaxValue,
3659 52560 : maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3660 : }
3661 : }
3662 12 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet = true;
3663 12 : state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue = MinValue;
3664 12 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue = MaxValue;
3665 : }
3666 : }
3667 :
3668 : // Min/max for schedule has been set. Test.
3669 17 : MinValueOk = (FLT_EPSILON >= Minimum - state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue);
3670 17 : if (MinString == ">") {
3671 7 : MinValueOk = (state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue > Minimum);
3672 : } else {
3673 10 : MinValueOk = (FLT_EPSILON >= Minimum - state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue);
3674 : }
3675 :
3676 17 : CheckScheduleValueMinMax = (MinValueOk && MaxValueOk);
3677 :
3678 17 : return CheckScheduleValueMinMax;
3679 : }
3680 :
3681 19273 : bool CheckScheduleValueMinMax(EnergyPlusData &state,
3682 : int const ScheduleIndex, // Which Schedule being tested
3683 : std::string const &MinString, // Minimum indicator ('>', '>=')
3684 : Real64 const Minimum, // Minimum desired value
3685 : std::string const &MaxString, // Maximum indicator ('<', ',=')
3686 : Real64 const Maximum // Maximum desired value
3687 : )
3688 : {
3689 : // FUNCTION INFORMATION:
3690 : // AUTHOR Linda K. Lawrie
3691 : // DATE WRITTEN February 2003
3692 : // MODIFIED na
3693 : // RE-ENGINEERED na
3694 :
3695 : // PURPOSE OF THIS FUNCTION:
3696 : // This function checks the indicated schedule values for validity. Uses the ScheduleIndex
3697 : // from (GetScheduleIndex), a minimum and a maximum -- one or other optional to check "internals".
3698 :
3699 : // METHODOLOGY EMPLOYED:
3700 : // Schedule data structure stores this on first validity check. If there, then is returned else
3701 : // looks up minimum and maximum values for the schedule and then sets result of function based on
3702 : // requested minimum/maximum checks.
3703 :
3704 : // REFERENCES:
3705 : // na
3706 :
3707 : // USE STATEMENTS:
3708 : // na
3709 :
3710 : // Return value
3711 : bool CheckScheduleValueMinMax;
3712 :
3713 : // Locals
3714 : // FUNCTION ARGUMENT DEFINITIONS:
3715 :
3716 : // FUNCTION PARAMETER DEFINITIONS:
3717 : // na
3718 :
3719 : // INTERFACE BLOCK SPECIFICATIONS
3720 : // na
3721 :
3722 : // DERIVED TYPE DEFINITIONS
3723 : // na
3724 :
3725 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3726 : int Loop; // Loop Control variable
3727 : int DayT; // Day Type Loop control
3728 : int WkSch; // Pointer for WeekSchedule value
3729 19273 : Real64 MinValue(0.0); // For total minimum
3730 19273 : Real64 MaxValue(0.0); // For total maximum
3731 19273 : bool MinValueOk(true);
3732 19273 : bool MaxValueOk(true);
3733 : /////////// hoisted into namespace CheckScheduleValueMinMaxRunOnceOnly////////////
3734 : // static bool RunOnceOnly( true );
3735 : /////////////////////////////////////////////////
3736 : // precompute the dayschedule max and min so that it is not in nested loop
3737 19273 : if (state.dataScheduleMgr->CheckScheduleValueMinMaxRunOnceOnly) {
3738 124400 : for (Loop = 0; Loop <= state.dataScheduleMgr->NumDaySchedules; ++Loop) {
3739 123643 : state.dataScheduleMgr->DaySchedule(Loop).TSValMin = minval(state.dataScheduleMgr->DaySchedule(Loop).TSValue);
3740 123643 : state.dataScheduleMgr->DaySchedule(Loop).TSValMax = maxval(state.dataScheduleMgr->DaySchedule(Loop).TSValue);
3741 : }
3742 757 : state.dataScheduleMgr->CheckScheduleValueMinMaxRunOnceOnly = false;
3743 : }
3744 :
3745 19273 : if (ScheduleIndex == -1) {
3746 0 : MinValue = 1.0;
3747 0 : MaxValue = 1.0;
3748 19273 : } else if (ScheduleIndex == 0) {
3749 0 : MinValue = 0.0;
3750 0 : MaxValue = 0.0;
3751 19273 : } else if (ScheduleIndex < 1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
3752 0 : ShowFatalError(state, "CheckScheduleValueMinMax called with ScheduleIndex out of range");
3753 : }
3754 :
3755 19273 : if (ScheduleIndex > 0) {
3756 19273 : if (!state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet) { // Set Minimum/Maximums for this schedule
3757 12770 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(1);
3758 12770 : MinValue = state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValMin;
3759 12770 : MaxValue = state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValMax;
3760 153240 : for (DayT = 2; DayT <= maxDayTypes; ++DayT) {
3761 140470 : MinValue = min(MinValue,
3762 140470 : state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValMin);
3763 140470 : MaxValue = max(MaxValue,
3764 140470 : state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValMax);
3765 : }
3766 4673820 : for (Loop = 2; Loop <= 366; ++Loop) {
3767 4661050 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(Loop);
3768 60593650 : for (DayT = 1; DayT <= maxDayTypes; ++DayT) {
3769 55932600 : MinValue =
3770 55932600 : min(MinValue,
3771 55932600 : state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValMin);
3772 55932600 : MaxValue =
3773 55932600 : max(MaxValue,
3774 55932600 : state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValMax);
3775 : }
3776 : }
3777 12770 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet = true;
3778 12770 : state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue = MinValue;
3779 12770 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue = MaxValue;
3780 : }
3781 : }
3782 :
3783 : // Min/max for schedule has been set. Test.
3784 19273 : if (MinString == ">") {
3785 15 : MinValueOk = (state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue > Minimum);
3786 : } else {
3787 19258 : MinValueOk = (FLT_EPSILON >= Minimum - state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue);
3788 : }
3789 :
3790 19273 : MaxValueOk = (state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue - Maximum <= FLT_EPSILON);
3791 19273 : if (MaxString == "<") {
3792 0 : MaxValueOk = (state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue < Maximum);
3793 : } else {
3794 19273 : MaxValueOk = (state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue - Maximum <= FLT_EPSILON);
3795 : }
3796 :
3797 19273 : CheckScheduleValueMinMax = (MinValueOk && MaxValueOk);
3798 :
3799 19273 : return CheckScheduleValueMinMax;
3800 : }
3801 :
3802 0 : bool CheckScheduleValueMinMax(EnergyPlusData &state,
3803 : int const ScheduleIndex, // Which Schedule being tested
3804 : std::string const &MinString, // Minimum indicator ('>', '>=')
3805 : Real32 const Minimum // Minimum desired value
3806 : )
3807 : {
3808 : // FUNCTION INFORMATION:
3809 : // AUTHOR Linda K. Lawrie
3810 : // DATE WRITTEN February 2003
3811 : // MODIFIED na
3812 : // RE-ENGINEERED na
3813 :
3814 : // PURPOSE OF THIS FUNCTION:
3815 : // This function checks the indicated schedule values for validity. Uses the ScheduleIndex
3816 : // from (GetScheduleIndex), a minimum and a maximum -- one or other optional to check "internals".
3817 :
3818 : // METHODOLOGY EMPLOYED:
3819 : // Schedule data structure stores this on first validity check. If there, then is returned else
3820 : // looks up minimum and maximum values for the schedule and then sets result of function based on
3821 : // requested minimum/maximum checks.
3822 :
3823 : // REFERENCES:
3824 : // na
3825 :
3826 : // USE STATEMENTS:
3827 : // na
3828 :
3829 : // Return value
3830 : bool CheckScheduleValueMinMax;
3831 :
3832 : // Locals
3833 : // FUNCTION ARGUMENT DEFINITIONS:
3834 :
3835 : // FUNCTION PARAMETER DEFINITIONS:
3836 : // na
3837 :
3838 : // INTERFACE BLOCK SPECIFICATIONS
3839 : // na
3840 :
3841 : // DERIVED TYPE DEFINITIONS
3842 : // na
3843 :
3844 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3845 : int Loop; // Loop Control variable
3846 : int DayT; // Day Type Loop control
3847 : int WkSch; // Pointer for WeekSchedule value
3848 0 : Real64 MinValue(0.0); // For total minimum
3849 0 : Real64 MaxValue(0.0); // For total maximum
3850 0 : bool MinValueOk(true);
3851 0 : bool MaxValueOk(true);
3852 :
3853 0 : if (ScheduleIndex == -1) {
3854 0 : MinValue = 1.0;
3855 0 : MaxValue = 1.0;
3856 0 : } else if (ScheduleIndex == 0) {
3857 0 : MinValue = 0.0;
3858 0 : MaxValue = 0.0;
3859 0 : } else if (ScheduleIndex < 1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
3860 0 : ShowFatalError(state, "CheckScheduleValueMinMax called with ScheduleIndex out of range");
3861 : }
3862 :
3863 0 : if (ScheduleIndex > 0) {
3864 0 : if (!state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet) { // Set Minimum/Maximums for this schedule
3865 0 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(1);
3866 0 : MinValue = minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValue);
3867 0 : MaxValue = maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValue);
3868 0 : for (DayT = 2; DayT <= maxDayTypes; ++DayT) {
3869 0 : MinValue =
3870 0 : min(MinValue,
3871 0 : minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3872 0 : MaxValue =
3873 0 : max(MaxValue,
3874 0 : maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3875 : }
3876 0 : for (Loop = 2; Loop <= 366; ++Loop) {
3877 0 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(Loop);
3878 0 : for (DayT = 1; DayT <= maxDayTypes; ++DayT) {
3879 0 : MinValue = min(
3880 : MinValue,
3881 0 : minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3882 0 : MaxValue = max(
3883 : MaxValue,
3884 0 : maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3885 : }
3886 : }
3887 0 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet = true;
3888 0 : state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue = MinValue;
3889 0 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue = MaxValue;
3890 : }
3891 : }
3892 :
3893 : // Min/max for schedule has been set. Test.
3894 0 : MinValueOk = (FLT_EPSILON >= Minimum - state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue);
3895 0 : if (MinString == ">") {
3896 0 : MinValueOk = (state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue > Minimum);
3897 : } else {
3898 0 : MinValueOk = (FLT_EPSILON >= Minimum - state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue);
3899 : }
3900 :
3901 0 : CheckScheduleValueMinMax = (MinValueOk && MaxValueOk);
3902 :
3903 0 : return CheckScheduleValueMinMax;
3904 : }
3905 :
3906 0 : bool CheckScheduleValueMinMax(EnergyPlusData &state,
3907 : int const ScheduleIndex, // Which Schedule being tested
3908 : std::string const &MinString, // Minimum indicator ('>', '>=')
3909 : Real32 const Minimum, // Minimum desired value
3910 : std::string const &MaxString, // Maximum indicator ('<', ',=')
3911 : Real32 const Maximum // Maximum desired value
3912 : )
3913 : {
3914 : // FUNCTION INFORMATION:
3915 : // AUTHOR Linda K. Lawrie
3916 : // DATE WRITTEN February 2003
3917 : // MODIFIED na
3918 : // RE-ENGINEERED na
3919 :
3920 : // PURPOSE OF THIS FUNCTION:
3921 : // This function checks the indicated schedule values for validity. Uses the ScheduleIndex
3922 : // from (GetScheduleIndex), a minimum and a maximum -- one or other optional to check "internals".
3923 :
3924 : // METHODOLOGY EMPLOYED:
3925 : // Schedule data structure stores this on first validity check. If there, then is returned else
3926 : // looks up minimum and maximum values for the schedule and then sets result of function based on
3927 : // requested minimum/maximum checks.
3928 :
3929 : // REFERENCES:
3930 : // na
3931 :
3932 : // USE STATEMENTS:
3933 : // na
3934 :
3935 : // Return value
3936 : bool CheckScheduleValueMinMax;
3937 :
3938 : // Locals
3939 : // FUNCTION ARGUMENT DEFINITIONS:
3940 :
3941 : // FUNCTION PARAMETER DEFINITIONS:
3942 : // na
3943 :
3944 : // INTERFACE BLOCK SPECIFICATIONS
3945 : // na
3946 :
3947 : // DERIVED TYPE DEFINITIONS
3948 : // na
3949 :
3950 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3951 : int Loop; // Loop Control variable
3952 : int DayT; // Day Type Loop control
3953 : int WkSch; // Pointer for WeekSchedule value
3954 0 : Real64 MinValue(0.0); // For total minimum
3955 0 : Real64 MaxValue(0.0); // For total maximum
3956 : bool MinValueOk;
3957 : bool MaxValueOk;
3958 :
3959 0 : if (ScheduleIndex == -1) {
3960 0 : MinValue = 1.0;
3961 0 : MaxValue = 1.0;
3962 0 : } else if (ScheduleIndex == 0) {
3963 0 : MinValue = 0.0;
3964 0 : MaxValue = 0.0;
3965 0 : } else if (ScheduleIndex < 1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
3966 0 : ShowFatalError(state, "CheckScheduleValueMinMax called with ScheduleIndex out of range");
3967 : }
3968 :
3969 0 : if (ScheduleIndex > 0) {
3970 0 : if (!state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet) { // Set Minimum/Maximums for this schedule
3971 0 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(1);
3972 0 : MinValue = minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValue);
3973 0 : MaxValue = maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValue);
3974 0 : for (DayT = 2; DayT <= maxDayTypes; ++DayT) {
3975 0 : MinValue =
3976 0 : min(MinValue,
3977 0 : minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3978 0 : MaxValue =
3979 0 : max(MaxValue,
3980 0 : maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3981 : }
3982 0 : for (Loop = 2; Loop <= 366; ++Loop) {
3983 0 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(Loop);
3984 0 : for (DayT = 1; DayT <= maxDayTypes; ++DayT) {
3985 0 : MinValue = min(
3986 : MinValue,
3987 0 : minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3988 0 : MaxValue = max(
3989 : MaxValue,
3990 0 : maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
3991 : }
3992 : }
3993 0 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet = true;
3994 0 : state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue = MinValue;
3995 0 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue = MaxValue;
3996 : }
3997 : }
3998 :
3999 : // Min/max for schedule has been set. Test.
4000 0 : MinValueOk = true;
4001 0 : MaxValueOk = true;
4002 0 : if (MinString == ">") {
4003 0 : MinValueOk = (state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue > Minimum);
4004 : } else {
4005 0 : MinValueOk = (FLT_EPSILON >= Minimum - state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue);
4006 : }
4007 :
4008 0 : MaxValueOk = (state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue - Maximum <= FLT_EPSILON);
4009 0 : if (MaxString == "<") {
4010 0 : MaxValueOk = (state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue < Maximum);
4011 : } else {
4012 0 : MaxValueOk = (state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue - Maximum <= FLT_EPSILON);
4013 : }
4014 :
4015 0 : CheckScheduleValueMinMax = (MinValueOk && MaxValueOk);
4016 :
4017 0 : return CheckScheduleValueMinMax;
4018 : }
4019 :
4020 580 : bool CheckScheduleValue(EnergyPlusData &state,
4021 : int const ScheduleIndex, // Which Schedule being tested
4022 : Real64 const Value // Actual desired value
4023 : )
4024 : {
4025 : // FUNCTION INFORMATION:
4026 : // AUTHOR Linda K. Lawrie
4027 : // DATE WRITTEN November 2004
4028 : // MODIFIED na
4029 : // RE-ENGINEERED na
4030 :
4031 : // PURPOSE OF THIS FUNCTION:
4032 : // This function checks the indicated schedule value for validity. Uses the ScheduleIndex
4033 : // from (GetScheduleIndex).
4034 :
4035 : // METHODOLOGY EMPLOYED:
4036 : // This routine is best used with "discrete" schedules. The routine must traverse all values
4037 : // in the schedule and compares by equality.
4038 :
4039 : // REFERENCES:
4040 : // na
4041 :
4042 : // USE STATEMENTS:
4043 : // na
4044 :
4045 : // Return value
4046 : bool CheckScheduleValue;
4047 :
4048 : // Locals
4049 : // FUNCTION ARGUMENT DEFINITIONS:
4050 :
4051 : // FUNCTION PARAMETER DEFINITIONS:
4052 : // na
4053 :
4054 : // INTERFACE BLOCK SPECIFICATIONS
4055 : // na
4056 :
4057 : // DERIVED TYPE DEFINITIONS
4058 : // na
4059 :
4060 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4061 : int Loop; // Loop Control variable
4062 : int DayT; // Day Type Loop control
4063 : int WkSch; // Pointer for WeekSchedule value
4064 :
4065 580 : CheckScheduleValue = false;
4066 :
4067 580 : if (ScheduleIndex == -1) {
4068 0 : CheckScheduleValue = (Value == 1.0);
4069 580 : } else if (ScheduleIndex == 0) {
4070 0 : CheckScheduleValue = (Value == 0.0);
4071 580 : } else if (ScheduleIndex < 1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
4072 0 : ShowFatalError(state, "CheckScheduleValue called with ScheduleIndex out of range");
4073 : }
4074 :
4075 580 : if (ScheduleIndex > 0) {
4076 580 : CheckScheduleValue = false;
4077 73414 : for (Loop = 1; Loop <= 366; ++Loop) {
4078 73215 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(Loop);
4079 947225 : for (DayT = 1; DayT <= maxDayTypes; ++DayT) {
4080 874391 : if (any_eq(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue,
4081 : Value)) {
4082 381 : CheckScheduleValue = true;
4083 381 : goto DayLoop_exit;
4084 : }
4085 : }
4086 : }
4087 199 : DayLoop_exit:;
4088 : }
4089 :
4090 580 : return CheckScheduleValue;
4091 : }
4092 :
4093 675 : bool CheckScheduleValue(EnergyPlusData &state,
4094 : int const ScheduleIndex, // Which Schedule being tested
4095 : int const Value // Actual desired value
4096 : )
4097 : {
4098 : // FUNCTION INFORMATION:
4099 : // AUTHOR Linda K. Lawrie
4100 : // DATE WRITTEN November 2004
4101 : // MODIFIED na
4102 : // RE-ENGINEERED na
4103 :
4104 : // PURPOSE OF THIS FUNCTION:
4105 : // This function checks the indicated schedule value for validity. Uses the ScheduleIndex
4106 : // from (GetScheduleIndex).
4107 :
4108 : // METHODOLOGY EMPLOYED:
4109 : // This routine is best used with "discrete" schedules. The routine must traverse all values
4110 : // in the schedule and compares by equality.
4111 :
4112 : // REFERENCES:
4113 : // na
4114 :
4115 : // USE STATEMENTS:
4116 : // na
4117 :
4118 : // Return value
4119 : bool CheckScheduleValue;
4120 :
4121 : // Locals
4122 : // FUNCTION ARGUMENT DEFINITIONS:
4123 :
4124 : // FUNCTION PARAMETER DEFINITIONS:
4125 : // na
4126 :
4127 : // INTERFACE BLOCK SPECIFICATIONS
4128 : // na
4129 :
4130 : // DERIVED TYPE DEFINITIONS
4131 : // na
4132 :
4133 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4134 : int Loop; // Loop Control variable
4135 : int DayT; // Day Type Loop control
4136 : int WkSch; // Pointer for WeekSchedule value
4137 :
4138 675 : CheckScheduleValue = false;
4139 675 : if (ScheduleIndex == -1) {
4140 0 : CheckScheduleValue = (Value == 1);
4141 675 : } else if (ScheduleIndex == 0) {
4142 0 : CheckScheduleValue = (Value == 0);
4143 675 : } else if (ScheduleIndex < 1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
4144 0 : ShowFatalError(state, "CheckScheduleValue called with ScheduleIndex out of range");
4145 : }
4146 :
4147 675 : if (ScheduleIndex > 0) {
4148 246627 : for (Loop = 1; Loop <= 366; ++Loop) {
4149 245955 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(Loop);
4150 3197379 : for (DayT = 1; DayT <= maxDayTypes; ++DayT) {
4151 5902854 : if (any_eq(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue,
4152 5902854 : double(Value))) {
4153 3 : CheckScheduleValue = true;
4154 3 : goto DayLoop_exit;
4155 : }
4156 : }
4157 : }
4158 672 : DayLoop_exit:;
4159 : }
4160 :
4161 675 : return CheckScheduleValue;
4162 : }
4163 :
4164 8 : bool CheckDayScheduleValueMinMax(EnergyPlusData &state,
4165 : int const ScheduleIndex, // Which Day Schedule being tested
4166 : Real64 const Minimum, // Minimum desired value
4167 : bool const exclusiveMin, // Minimum indicator ('>', '>=')
4168 : Real64 const Maximum, // Maximum desired value
4169 : bool const exclusiveMax // Maximum indicator ('<', ',=')
4170 : )
4171 : {
4172 : // FUNCTION INFORMATION:
4173 : // AUTHOR Linda K. Lawrie
4174 : // DATE WRITTEN February 2003
4175 : // MODIFIED na
4176 : // RE-ENGINEERED na
4177 :
4178 : // PURPOSE OF THIS FUNCTION:
4179 : // This function checks the indicated schedule values for validity. Uses the ScheduleIndex
4180 : // from (GetScheduleIndex), a minimum and a maximum -- one or other optional to check "internals".
4181 :
4182 : // METHODOLOGY EMPLOYED:
4183 : // Schedule data structure stores this on first validity check. If there, then is returned else
4184 : // looks up minimum and maximum values for the schedule and then sets result of function based on
4185 : // requested minimum/maximum checks.
4186 :
4187 : // REFERENCES:
4188 : // na
4189 :
4190 : // USE STATEMENTS:
4191 : // na
4192 :
4193 : // Return value
4194 : bool CheckDayScheduleValueMinMax;
4195 :
4196 : // Locals
4197 : // FUNCTION ARGUMENT DEFINITIONS:
4198 :
4199 : // FUNCTION PARAMETER DEFINITIONS:
4200 : // na
4201 :
4202 : // INTERFACE BLOCK SPECIFICATIONS
4203 : // na
4204 :
4205 : // DERIVED TYPE DEFINITIONS
4206 : // na
4207 :
4208 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4209 8 : Real64 MinValue(0.0); // For total minimum
4210 8 : Real64 MaxValue(0.0); // For total maximum
4211 : bool MinValueOk;
4212 : bool MaxValueOk;
4213 :
4214 8 : if (ScheduleIndex == -1) {
4215 0 : MinValue = 1.0;
4216 0 : MaxValue = 1.0;
4217 8 : } else if (ScheduleIndex == 0) {
4218 0 : MinValue = 0.0;
4219 0 : MaxValue = 0.0;
4220 8 : } else if (ScheduleIndex < 1 || ScheduleIndex > state.dataScheduleMgr->NumDaySchedules) {
4221 0 : ShowFatalError(state, "CheckDayScheduleValueMinMax called with ScheduleIndex out of range");
4222 : }
4223 :
4224 8 : if (ScheduleIndex > 0) {
4225 8 : MinValue = minval(state.dataScheduleMgr->DaySchedule(ScheduleIndex).TSValue);
4226 8 : MaxValue = maxval(state.dataScheduleMgr->DaySchedule(ScheduleIndex).TSValue);
4227 : }
4228 :
4229 : // Min/max for schedule has been set. Test.
4230 8 : MinValueOk = true;
4231 8 : MaxValueOk = true;
4232 :
4233 8 : if (exclusiveMin) {
4234 0 : MinValueOk = (MinValue > Minimum);
4235 : } else {
4236 8 : MinValueOk = (FLT_EPSILON >= Minimum - MinValue);
4237 : }
4238 :
4239 8 : if (exclusiveMax) {
4240 0 : MaxValueOk = (MaxValue < Maximum);
4241 : } else {
4242 8 : MaxValueOk = (MaxValue - Maximum <= FLT_EPSILON);
4243 : }
4244 :
4245 8 : CheckDayScheduleValueMinMax = (MinValueOk && MaxValueOk);
4246 :
4247 8 : return CheckDayScheduleValueMinMax;
4248 : }
4249 :
4250 9 : bool CheckDayScheduleValueMinMax(EnergyPlusData &state,
4251 : int const ScheduleIndex, // Which Day Schedule being tested
4252 : Real64 const Minimum, // Minimum desired value
4253 : bool const exclusiveMin // Minimum indicator ('>', '>=')
4254 : )
4255 : {
4256 : // FUNCTION INFORMATION:
4257 : // AUTHOR Linda K. Lawrie
4258 : // DATE WRITTEN February 2003
4259 : // MODIFIED na
4260 : // RE-ENGINEERED na
4261 :
4262 : // PURPOSE OF THIS FUNCTION:
4263 : // This function checks the indicated schedule values for validity. Uses the ScheduleIndex
4264 : // from (GetScheduleIndex), a minimum and a maximum -- one or other optional to check "internals".
4265 :
4266 : // METHODOLOGY EMPLOYED:
4267 : // Schedule data structure stores this on first validity check. If there, then is returned else
4268 : // looks up minimum and maximum values for the schedule and then sets result of function based on
4269 : // requested minimum/maximum checks.
4270 :
4271 : // REFERENCES:
4272 : // na
4273 :
4274 : // USE STATEMENTS:
4275 : // na
4276 :
4277 : // Return value
4278 : bool CheckDayScheduleValueMinMax;
4279 :
4280 : // Locals
4281 : // FUNCTION ARGUMENT DEFINITIONS:
4282 :
4283 : // FUNCTION PARAMETER DEFINITIONS:
4284 : // na
4285 :
4286 : // INTERFACE BLOCK SPECIFICATIONS
4287 : // na
4288 :
4289 : // DERIVED TYPE DEFINITIONS
4290 : // na
4291 :
4292 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4293 9 : Real64 MinValue(0.0); // For total minimum
4294 : bool MinValueOk;
4295 :
4296 9 : if (ScheduleIndex == -1) {
4297 0 : MinValue = 1.0;
4298 9 : } else if (ScheduleIndex == 0) {
4299 0 : MinValue = 0.0;
4300 9 : } else if (ScheduleIndex < 1 || ScheduleIndex > state.dataScheduleMgr->NumDaySchedules) {
4301 0 : ShowFatalError(state, "CheckDayScheduleValueMinMax called with ScheduleIndex out of range");
4302 : }
4303 :
4304 9 : if (ScheduleIndex > 0) {
4305 9 : MinValue = minval(state.dataScheduleMgr->DaySchedule(ScheduleIndex).TSValue);
4306 : }
4307 :
4308 : // Min/max for schedule has been set. Test.
4309 9 : MinValueOk = true;
4310 :
4311 9 : if (exclusiveMin) {
4312 0 : MinValueOk = (MinValue > Minimum);
4313 : } else {
4314 9 : MinValueOk = (FLT_EPSILON >= Minimum - MinValue);
4315 : }
4316 :
4317 9 : CheckDayScheduleValueMinMax = MinValueOk;
4318 :
4319 9 : return CheckDayScheduleValueMinMax;
4320 : }
4321 :
4322 141 : bool HasFractionalScheduleValue(EnergyPlusData &state, int const ScheduleIndex) // Which Schedule being tested
4323 : {
4324 : // FUNCTION INFORMATION:
4325 : // AUTHOR Linda K. Lawrie
4326 : // DATE WRITTEN March 2008
4327 : // MODIFIED na
4328 : // RE-ENGINEERED na
4329 :
4330 : // PURPOSE OF THIS FUNCTION:
4331 : // This function returns true if the schedule contains fractional
4332 : // values [>0, <1].
4333 :
4334 : // METHODOLOGY EMPLOYED:
4335 : // na
4336 :
4337 : // REFERENCES:
4338 : // na
4339 :
4340 : // USE STATEMENTS:
4341 : // na
4342 :
4343 : // Return value
4344 : bool HasFractions; // True if the schedule has fractional values
4345 :
4346 : // Locals
4347 : // FUNCTION ARGUMENT DEFINITIONS:
4348 :
4349 : // FUNCTION PARAMETER DEFINITIONS:
4350 : // na
4351 :
4352 : // INTERFACE BLOCK SPECIFICATIONS
4353 : // na
4354 :
4355 : // DERIVED TYPE DEFINITIONS
4356 : // na
4357 :
4358 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4359 : int WkSch;
4360 : int DayT;
4361 : int Loop;
4362 : int Hour;
4363 : int TStep;
4364 :
4365 141 : if (ScheduleIndex == -1 || ScheduleIndex == 0) {
4366 :
4367 141 : } else if (ScheduleIndex < 1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
4368 0 : ShowFatalError(state, "HasFractionalScheduleValue called with ScheduleIndex out of range");
4369 : }
4370 :
4371 141 : HasFractions = false;
4372 :
4373 141 : if (ScheduleIndex > 0) {
4374 141 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(1);
4375 1833 : for (DayT = 1; DayT <= maxDayTypes; ++DayT) {
4376 42300 : for (Hour = 1; Hour <= 24; ++Hour) {
4377 237600 : for (TStep = 1; TStep <= state.dataGlobal->NumOfTimeStepInHour; ++TStep) {
4378 393984 : if (state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT))
4379 351326 : .TSValue(TStep, Hour) > 0.0 &&
4380 154334 : state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT))
4381 154334 : .TSValue(TStep, Hour) < 1.0) {
4382 0 : HasFractions = true;
4383 0 : goto DayTLoop_exit;
4384 : }
4385 : }
4386 : }
4387 : }
4388 141 : DayTLoop_exit:;
4389 141 : if (!HasFractions) {
4390 51606 : for (Loop = 2; Loop <= 366; ++Loop) {
4391 51465 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(Loop);
4392 669045 : for (DayT = 1; DayT <= maxDayTypes; ++DayT) {
4393 15439500 : for (Hour = 1; Hour <= 24; ++Hour) {
4394 86724000 : for (TStep = 1; TStep <= state.dataGlobal->NumOfTimeStepInHour; ++TStep) {
4395 143804160 : if (state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT))
4396 124851248 : .TSValue(TStep, Hour) > 0.0 &&
4397 52949168 : state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT))
4398 52949168 : .TSValue(TStep, Hour) < 1.0) {
4399 0 : HasFractions = true;
4400 0 : goto DayTLoop2_exit;
4401 : }
4402 : }
4403 : }
4404 : }
4405 51465 : DayTLoop2_exit:;
4406 : }
4407 : }
4408 : }
4409 :
4410 141 : return HasFractions;
4411 : }
4412 :
4413 35290 : Real64 GetScheduleMinValue(EnergyPlusData &state, int const ScheduleIndex) // Which Schedule being tested
4414 : {
4415 : // FUNCTION INFORMATION:
4416 : // AUTHOR Linda K. Lawrie
4417 : // DATE WRITTEN February 2004
4418 : // MODIFIED na
4419 : // RE-ENGINEERED na
4420 :
4421 : // PURPOSE OF THIS FUNCTION:
4422 : // This function returns the minimum value used by a schedule over
4423 : // the entire year.
4424 :
4425 : // METHODOLOGY EMPLOYED:
4426 : // na
4427 :
4428 : // REFERENCES:
4429 : // na
4430 :
4431 : // USE STATEMENTS:
4432 : // na
4433 :
4434 : // Return value
4435 : Real64 MinimumValue; // Minimum value for schedule
4436 :
4437 : // Locals
4438 : // FUNCTION ARGUMENT DEFINITIONS:
4439 :
4440 : // FUNCTION PARAMETER DEFINITIONS:
4441 : // na
4442 :
4443 : // INTERFACE BLOCK SPECIFICATIONS
4444 : // na
4445 :
4446 : // DERIVED TYPE DEFINITIONS
4447 : // na
4448 :
4449 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4450 35290 : Real64 MinValue(0.0);
4451 35290 : Real64 MaxValue(0.0);
4452 : int WkSch;
4453 : int DayT;
4454 : int Loop;
4455 :
4456 35290 : if (ScheduleIndex == -1) {
4457 0 : MinValue = 1.0;
4458 0 : MaxValue = 1.0;
4459 35290 : } else if (ScheduleIndex == 0) {
4460 0 : MinValue = 0.0;
4461 0 : MaxValue = 0.0;
4462 35290 : } else if (ScheduleIndex < 1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
4463 0 : ShowFatalError(state, "GetScheduleMinValue called with ScheduleIndex out of range");
4464 : }
4465 :
4466 35290 : if (ScheduleIndex > 0) {
4467 35290 : if (!state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet) { // Set Minimum/Maximums for this schedule
4468 2114 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(1);
4469 2114 : MinValue = minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValue);
4470 2114 : MaxValue = maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValue);
4471 25368 : for (DayT = 2; DayT <= maxDayTypes; ++DayT) {
4472 23254 : MinValue =
4473 23254 : min(MinValue,
4474 23254 : minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
4475 23254 : MaxValue =
4476 23254 : max(MaxValue,
4477 23254 : maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
4478 : }
4479 773724 : for (Loop = 2; Loop <= 366; ++Loop) {
4480 771610 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(Loop);
4481 10030930 : for (DayT = 1; DayT <= maxDayTypes; ++DayT) {
4482 9259320 : MinValue = min(
4483 : MinValue,
4484 9259320 : minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
4485 9259320 : MaxValue = max(
4486 : MaxValue,
4487 9259320 : maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
4488 : }
4489 : }
4490 2114 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet = true;
4491 2114 : state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue = MinValue;
4492 2114 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue = MaxValue;
4493 : }
4494 :
4495 : // Min/max for schedule has been set.
4496 35290 : MinimumValue = state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue;
4497 : } else {
4498 0 : MinimumValue = MinValue;
4499 : }
4500 :
4501 35290 : return MinimumValue;
4502 : }
4503 :
4504 43258 : Real64 GetScheduleMaxValue(EnergyPlusData &state, int const ScheduleIndex) // Which Schedule being tested
4505 : {
4506 : // FUNCTION INFORMATION:
4507 : // AUTHOR Linda K. Lawrie
4508 : // DATE WRITTEN February 2004
4509 : // MODIFIED na
4510 : // RE-ENGINEERED na
4511 :
4512 : // PURPOSE OF THIS FUNCTION:
4513 : // This function returns the maximum value used by a schedule over
4514 : // the entire year.
4515 :
4516 : // METHODOLOGY EMPLOYED:
4517 : // na
4518 :
4519 : // REFERENCES:
4520 : // na
4521 :
4522 : // USE STATEMENTS:
4523 : // na
4524 :
4525 : // Return value
4526 : Real64 MaximumValue; // Maximum value for schedule
4527 :
4528 : // Locals
4529 : // FUNCTION ARGUMENT DEFINITIONS:
4530 :
4531 : // FUNCTION PARAMETER DEFINITIONS:
4532 : // na
4533 :
4534 : // INTERFACE BLOCK SPECIFICATIONS
4535 : // na
4536 :
4537 : // DERIVED TYPE DEFINITIONS
4538 : // na
4539 :
4540 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4541 43258 : Real64 MinValue(0.0);
4542 43258 : Real64 MaxValue(0.0);
4543 : int WkSch;
4544 : int DayT;
4545 : int Loop;
4546 :
4547 43258 : if (ScheduleIndex == -1) {
4548 0 : MinValue = 1.0;
4549 0 : MaxValue = 1.0;
4550 43258 : } else if (ScheduleIndex == 0) {
4551 0 : MinValue = 0.0;
4552 0 : MaxValue = 0.0;
4553 43258 : } else if (ScheduleIndex < 1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
4554 0 : ShowFatalError(state, "CheckScheduleMaxValue called with ScheduleIndex out of range");
4555 : }
4556 :
4557 43258 : if (ScheduleIndex > 0) {
4558 43258 : if (!state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet) { // Set Minimum/Maximums for this schedule
4559 190 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(1);
4560 190 : MinValue = minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValue);
4561 190 : MaxValue = maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(1)).TSValue);
4562 2280 : for (DayT = 2; DayT <= maxDayTypes; ++DayT) {
4563 2090 : MinValue =
4564 2090 : min(MinValue,
4565 2090 : minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
4566 2090 : MaxValue =
4567 2090 : max(MaxValue,
4568 2090 : maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
4569 : }
4570 69540 : for (Loop = 2; Loop <= 366; ++Loop) {
4571 69350 : WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(Loop);
4572 901550 : for (DayT = 1; DayT <= maxDayTypes; ++DayT) {
4573 832200 : MinValue = min(
4574 : MinValue,
4575 832200 : minval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
4576 832200 : MaxValue = max(
4577 : MaxValue,
4578 832200 : maxval(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue));
4579 : }
4580 : }
4581 190 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxMinSet = true;
4582 190 : state.dataScheduleMgr->Schedule(ScheduleIndex).MinValue = MinValue;
4583 190 : state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue = MaxValue;
4584 : }
4585 :
4586 : // Min/max for schedule has been set.
4587 :
4588 43258 : MaximumValue = state.dataScheduleMgr->Schedule(ScheduleIndex).MaxValue;
4589 : } else {
4590 0 : MaximumValue = MaxValue;
4591 : }
4592 :
4593 43258 : return MaximumValue;
4594 : }
4595 :
4596 34590 : std::string GetScheduleName(EnergyPlusData &state, int const ScheduleIndex)
4597 : {
4598 : // FUNCTION INFORMATION:
4599 : // AUTHOR Linda K. Lawrie
4600 : // DATE WRITTEN February 2008
4601 : // MODIFIED na
4602 : // RE-ENGINEERED na
4603 :
4604 : // PURPOSE OF THIS FUNCTION:
4605 : // This function returns the schedule name from the Schedule Index.
4606 :
4607 : // METHODOLOGY EMPLOYED:
4608 : // na
4609 :
4610 : // REFERENCES:
4611 : // na
4612 :
4613 : // USE STATEMENTS:
4614 : // na
4615 :
4616 : // Return value
4617 34590 : std::string ScheduleName;
4618 :
4619 : // Locals
4620 : // FUNCTION ARGUMENT DEFINITIONS:
4621 :
4622 : // FUNCTION PARAMETER DEFINITIONS:
4623 : // na
4624 :
4625 : // INTERFACE BLOCK SPECIFICATIONS
4626 : // na
4627 :
4628 : // DERIVED TYPE DEFINITIONS
4629 : // na
4630 :
4631 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4632 : // na
4633 :
4634 34590 : if (!state.dataScheduleMgr->ScheduleInputProcessed) {
4635 0 : ProcessScheduleInput(state);
4636 0 : state.dataScheduleMgr->ScheduleInputProcessed = true;
4637 : }
4638 :
4639 34590 : if (ScheduleIndex > 0) {
4640 34449 : ScheduleName = state.dataScheduleMgr->Schedule(ScheduleIndex).Name;
4641 141 : } else if (ScheduleIndex == -1) {
4642 8 : ScheduleName = "Constant-1.0";
4643 133 : } else if (ScheduleIndex == 0) {
4644 133 : ScheduleName = "Constant-0.0";
4645 : } else {
4646 0 : ScheduleName = "N/A-Invalid";
4647 : }
4648 :
4649 34590 : return ScheduleName;
4650 : }
4651 :
4652 2568312 : void ReportScheduleValues(EnergyPlusData &state)
4653 : {
4654 : // SUBROUTINE INFORMATION:
4655 : // AUTHOR Linda Lawrie
4656 : // DATE WRITTEN February 2004
4657 : // MODIFIED na
4658 : // RE-ENGINEERED na
4659 :
4660 : // PURPOSE OF THIS SUBROUTINE:
4661 : // This subroutine puts the proper current schedule values into the "reporting"
4662 : // slot for later reporting.
4663 :
4664 2568312 : if (!state.dataScheduleMgr->ScheduleInputProcessed) {
4665 0 : ProcessScheduleInput(state);
4666 0 : state.dataScheduleMgr->ScheduleInputProcessed = true;
4667 : }
4668 :
4669 2568312 : if (state.dataScheduleMgr->DoScheduleReportingSetup) { // CurrentModuleObject='Any Schedule'
4670 16730 : for (int ScheduleIndex = 1; ScheduleIndex <= state.dataScheduleMgr->NumSchedules; ++ScheduleIndex) {
4671 : // Set Up Reporting
4672 63840 : SetupOutputVariable(state,
4673 : "Schedule Value",
4674 : OutputProcessor::Unit::None,
4675 15960 : state.dataScheduleMgr->Schedule(ScheduleIndex).CurrentValue,
4676 : OutputProcessor::SOVTimeStepType::Zone,
4677 : OutputProcessor::SOVStoreType::Average,
4678 31920 : state.dataScheduleMgr->Schedule(ScheduleIndex).Name);
4679 : }
4680 770 : state.dataScheduleMgr->DoScheduleReportingSetup = false;
4681 : }
4682 :
4683 : // TODO: Is this needed?
4684 : // Why is it doing exactly the same as UpdateScheduleValues?
4685 2568312 : UpdateScheduleValues(state);
4686 2568312 : }
4687 :
4688 769 : void ReportOrphanSchedules(EnergyPlusData &state)
4689 : {
4690 : // SUBROUTINE INFORMATION:
4691 : // AUTHOR Linda Lawrie
4692 : // DATE WRITTEN April 2008
4693 : // MODIFIED na
4694 : // RE-ENGINEERED na
4695 :
4696 : // PURPOSE OF THIS SUBROUTINE:
4697 : // In response to CR7498, report orphan (unused) schedule items.
4698 :
4699 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4700 : bool NeedOrphanMessage;
4701 : bool NeedUseMessage;
4702 : int Item;
4703 : int NumCount;
4704 :
4705 769 : NeedOrphanMessage = true;
4706 769 : NeedUseMessage = false;
4707 769 : NumCount = 0;
4708 :
4709 16691 : for (Item = 1; Item <= state.dataScheduleMgr->NumSchedules; ++Item) {
4710 15922 : if (state.dataScheduleMgr->Schedule(Item).Used) continue;
4711 677 : if (NeedOrphanMessage && state.dataGlobal->DisplayUnusedSchedules) {
4712 1 : ShowWarningError(state, "The following schedule names are \"Unused Schedules\". These schedules are in the idf");
4713 1 : ShowContinueError(state, " file but are never obtained by the simulation and therefore are NOT used.");
4714 1 : NeedOrphanMessage = false;
4715 : }
4716 677 : if (state.dataGlobal->DisplayUnusedSchedules) {
4717 3 : ShowMessage(state,
4718 2 : "Schedule:Year or Schedule:Compact or Schedule:File or Schedule:Constant=" + state.dataScheduleMgr->Schedule(Item).Name);
4719 : } else {
4720 676 : ++NumCount;
4721 : }
4722 : }
4723 :
4724 769 : if (NumCount > 0) {
4725 196 : ShowMessage(state, fmt::format("There are {} unused schedules in input.", NumCount));
4726 98 : NeedUseMessage = true;
4727 : }
4728 :
4729 769 : NeedOrphanMessage = true;
4730 769 : NumCount = 0;
4731 :
4732 113005 : for (Item = 1; Item <= state.dataScheduleMgr->NumWeekSchedules; ++Item) {
4733 112236 : if (state.dataScheduleMgr->WeekSchedule(Item).Used) continue;
4734 1025 : if (state.dataScheduleMgr->WeekSchedule(Item).Name == BlankString) continue;
4735 49 : if (NeedOrphanMessage && state.dataGlobal->DisplayUnusedSchedules) {
4736 0 : ShowWarningError(state, "The following week schedule names are \"Unused Schedules\". These schedules are in the idf");
4737 0 : ShowContinueError(state, " file but are never obtained by the simulation and therefore are NOT used.");
4738 0 : NeedOrphanMessage = false;
4739 : }
4740 49 : if (state.dataGlobal->DisplayUnusedSchedules) {
4741 0 : ShowMessage(state, "Schedule:Week:Daily or Schedule:Week:Compact=" + state.dataScheduleMgr->WeekSchedule(Item).Name);
4742 : } else {
4743 49 : ++NumCount;
4744 : }
4745 : }
4746 :
4747 769 : if (NumCount > 0) {
4748 16 : ShowMessage(state, fmt::format("There are {} unused week schedules in input.", NumCount));
4749 8 : NeedUseMessage = true;
4750 : }
4751 :
4752 769 : NeedOrphanMessage = true;
4753 769 : NumCount = 0;
4754 :
4755 123543 : for (Item = 1; Item <= state.dataScheduleMgr->NumDaySchedules; ++Item) {
4756 122774 : if (state.dataScheduleMgr->DaySchedule(Item).Used) continue;
4757 321 : if (state.dataScheduleMgr->DaySchedule(Item).Name == BlankString) continue;
4758 75 : if (NeedOrphanMessage && state.dataGlobal->DisplayUnusedSchedules) {
4759 0 : ShowWarningError(state, "The following day schedule names are \"Unused Schedules\". These schedules are in the idf");
4760 0 : ShowContinueError(state, " file but are never obtained by the simulation and therefore are NOT used.");
4761 0 : NeedOrphanMessage = false;
4762 : }
4763 75 : if (state.dataGlobal->DisplayUnusedSchedules) {
4764 0 : ShowMessage(state,
4765 0 : "Schedule:Day:Hourly or Schedule:Day:Interval or Schedule:Day:List=" + state.dataScheduleMgr->DaySchedule(Item).Name);
4766 : } else {
4767 75 : ++NumCount;
4768 : }
4769 : }
4770 :
4771 769 : if (NumCount > 0) {
4772 18 : ShowMessage(state, fmt::format("There are {} unused day schedules in input.", NumCount));
4773 9 : NeedUseMessage = true;
4774 : }
4775 :
4776 769 : if (NeedUseMessage) ShowMessage(state, "Use Output:Diagnostics,DisplayUnusedSchedules; to see them.");
4777 769 : }
4778 :
4779 : // returns the annual full load hours for a schedule - essentially the sum of the hourly values
4780 10462 : Real64 ScheduleAnnualFullLoadHours(EnergyPlusData &state,
4781 : int const ScheduleIndex, // Which Schedule being tested
4782 : int const StartDayOfWeek, // Day of week for start of year
4783 : bool const isItLeapYear // true if it is a leap year containing February 29
4784 : )
4785 : {
4786 : // J. Glazer - July 2017
4787 : // adapted from Linda K. Lawrie original code for ScheduleAverageHoursPerWeek()
4788 :
4789 : int DaysInYear;
4790 :
4791 10462 : if (isItLeapYear) {
4792 16 : DaysInYear = 366;
4793 : } else {
4794 10446 : DaysInYear = 365;
4795 : }
4796 :
4797 10462 : if (ScheduleIndex < -1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
4798 0 : ShowFatalError(state, "ScheduleAnnualFullLoadHours called with ScheduleIndex out of range");
4799 : }
4800 :
4801 10462 : int DayT = StartDayOfWeek;
4802 10462 : Real64 TotalHours = 0.0;
4803 :
4804 10462 : if (DayT == 0) return TotalHours;
4805 :
4806 3829108 : for (int Loop = 1; Loop <= DaysInYear; ++Loop) {
4807 3818646 : int WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(Loop);
4808 7637292 : TotalHours += sum(state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT)).TSValue) /
4809 3818646 : double(state.dataGlobal->NumOfTimeStepInHour);
4810 3818646 : ++DayT;
4811 3818646 : if (DayT > 7) DayT = 1;
4812 : }
4813 :
4814 10462 : return TotalHours;
4815 : }
4816 :
4817 : // returns the average number of hours per week based on the schedule index provided
4818 4058 : Real64 ScheduleAverageHoursPerWeek(EnergyPlusData &state,
4819 : int const ScheduleIndex, // Which Schedule being tested
4820 : int const StartDayOfWeek, // Day of week for start of year
4821 : bool const isItLeapYear // true if it is a leap year containing February 29
4822 : )
4823 : {
4824 : // FUNCTION INFORMATION:
4825 : // AUTHOR Linda K. Lawrie
4826 : // DATE WRITTEN August 2006
4827 : // MODIFIED September 2012; Glazer - CR8849
4828 : // RE-ENGINEERED na
4829 :
4830 : // PURPOSE OF THIS FUNCTION:
4831 : // This function returns the "average" hours per week for a schedule over
4832 : // the entire year.
4833 :
4834 : // Return value
4835 :
4836 : Real64 WeeksInYear;
4837 :
4838 4058 : if (isItLeapYear) {
4839 5 : WeeksInYear = 366.0 / 7.0;
4840 : } else {
4841 4053 : WeeksInYear = 365.0 / 7.0;
4842 : }
4843 :
4844 4058 : if (ScheduleIndex < -1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
4845 0 : ShowFatalError(state, "ScheduleAverageHoursPerWeek called with ScheduleIndex out of range");
4846 : }
4847 :
4848 4058 : Real64 TotalHours = ScheduleAnnualFullLoadHours(state, ScheduleIndex, StartDayOfWeek, isItLeapYear);
4849 :
4850 4058 : return TotalHours / WeeksInYear; // Ok to return a fraction since WeeksInYear we know is always non-zero
4851 : }
4852 :
4853 : // returns the annual hours greater than 1% for a schedule - essentially the number of hours with any operation
4854 6404 : Real64 ScheduleHoursGT1perc(EnergyPlusData &state,
4855 : int const ScheduleIndex, // Which Schedule being tested
4856 : int const StartDayOfWeek, // Day of week for start of year
4857 : bool const isItLeapYear // true if it is a leap year containing February 29
4858 : )
4859 : {
4860 : // J. Glazer - July 2017
4861 : // adapted from Linda K. Lawrie original code for ScheduleAverageHoursPerWeek()
4862 :
4863 : int DaysInYear;
4864 :
4865 6404 : if (isItLeapYear) {
4866 11 : DaysInYear = 366;
4867 : } else {
4868 6393 : DaysInYear = 365;
4869 : }
4870 :
4871 6404 : if (ScheduleIndex < -1 || ScheduleIndex > state.dataScheduleMgr->NumSchedules) {
4872 0 : ShowFatalError(state, "ScheduleHoursGT1perc called with ScheduleIndex out of range");
4873 : }
4874 :
4875 6404 : int DayT = StartDayOfWeek;
4876 6404 : Real64 TotalHours = 0.0;
4877 :
4878 6404 : if (DayT == 0) return TotalHours;
4879 :
4880 2343875 : for (int Loop = 1; Loop <= DaysInYear; ++Loop) {
4881 2337471 : int WkSch = state.dataScheduleMgr->Schedule(ScheduleIndex).WeekSchedulePointer(Loop);
4882 58436775 : for (int hrOfDay = 1; hrOfDay <= 24; ++hrOfDay) {
4883 342482280 : for (int TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
4884 572765952 : if (state.dataScheduleMgr->DaySchedule(state.dataScheduleMgr->WeekSchedule(WkSch).DaySchedulePointer(DayT))
4885 286382976 : .TSValue(TS, hrOfDay)) {
4886 208311327 : TotalHours += state.dataGlobal->TimeStepZone;
4887 : }
4888 : }
4889 : }
4890 :
4891 2337471 : ++DayT;
4892 2337471 : if (DayT > 7) DayT = 1;
4893 : }
4894 :
4895 6404 : return TotalHours;
4896 : }
4897 :
4898 116 : int GetNumberOfSchedules(EnergyPlusData &state)
4899 : {
4900 : // FUNCTION INFORMATION:
4901 : // AUTHOR Greg Stark
4902 : // DATE WRITTEN September 2008
4903 : // MODIFIED na
4904 : // RE-ENGINEERED na
4905 :
4906 : // PURPOSE OF THIS FUNCTION:
4907 : // This function returns the number of schedules.
4908 :
4909 : // METHODOLOGY EMPLOYED:
4910 : // na
4911 :
4912 : // REFERENCES:
4913 : // na
4914 :
4915 : // USE STATEMENTS:
4916 : // na
4917 :
4918 : // Return value
4919 : int NumberOfSchedules;
4920 :
4921 : // Locals
4922 : // FUNCTION ARGUMENT DEFINITIONS:
4923 :
4924 : // FUNCTION PARAMETER DEFINITIONS:
4925 : // na
4926 :
4927 : // INTERFACE BLOCK SPECIFICATIONS
4928 : // na
4929 :
4930 : // DERIVED TYPE DEFINITIONS
4931 : // na
4932 :
4933 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4934 : // na
4935 :
4936 116 : NumberOfSchedules = state.dataScheduleMgr->NumSchedules;
4937 :
4938 116 : return NumberOfSchedules;
4939 : }
4940 :
4941 : } // namespace ScheduleManager
4942 :
4943 2313 : } // namespace EnergyPlus
|