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 <cassert>
50 : #include <cmath>
51 :
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Array.functions.hh>
54 : #include <ObjexxFCL/Array2D.hh>
55 : #include <ObjexxFCL/ArrayS.functions.hh>
56 : #include <ObjexxFCL/Fmath.hh>
57 : #include <ObjexxFCL/char.functions.hh>
58 : #include <ObjexxFCL/random.hh>
59 : #include <ObjexxFCL/string.functions.hh>
60 : #include <ObjexxFCL/time.hh>
61 :
62 : // EnergyPlus Headers
63 : #include <EnergyPlus/Construction.hh>
64 : #include <EnergyPlus/CurveManager.hh>
65 : #include <EnergyPlus/Data/EnergyPlusData.hh>
66 : #include <EnergyPlus/DataEnvironment.hh>
67 : #include <EnergyPlus/DataHVACGlobals.hh>
68 : #include <EnergyPlus/DataIPShortCuts.hh>
69 : #include <EnergyPlus/DataSystemVariables.hh>
70 : #include <EnergyPlus/EMSManager.hh>
71 : #include <EnergyPlus/General.hh>
72 : #include <EnergyPlus/GlobalNames.hh>
73 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
74 : #include <EnergyPlus/OutputProcessor.hh>
75 : #include <EnergyPlus/Psychrometrics.hh>
76 : #include <EnergyPlus/RuntimeLanguageProcessor.hh>
77 : #include <EnergyPlus/UtilityRoutines.hh>
78 : #include <EnergyPlus/WeatherManager.hh>
79 :
80 : namespace EnergyPlus::RuntimeLanguageProcessor {
81 :
82 : // MODULE INFORMATION:
83 : // AUTHOR Peter Graham Ellis
84 : // DATE WRITTEN June 2006
85 : // MODIFIED Brent Griffith, May - August 2009
86 : // RE-ENGINEERED na
87 :
88 : // Using/Aliasing
89 : using namespace DataRuntimeLanguage;
90 :
91 4116712 : void InitializeRuntimeLanguage(EnergyPlusData &state)
92 : {
93 :
94 : // SUBROUTINE INFORMATION:
95 : // AUTHOR Peter Graham Ellis
96 : // DATE WRITTEN June 2006
97 : // MODIFIED Rui Zhang February 2010
98 : // RE-ENGINEERED na
99 :
100 : // METHODOLOGY EMPLOYED:
101 : // One time run. Must be run BEFORE anything gets parsed.
102 :
103 : // Using/Aliasing
104 4116712 : auto &SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
105 4116712 : auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
106 :
107 4116712 : Real64 tmpCurrentTime(0.0);
108 4116712 : Real64 tmpMinutes(0.0);
109 4116712 : Real64 tmpHours(0.0);
110 4116712 : Real64 tmpCurEnvirNum(0.0);
111 8233424 : Array1D_int datevalues(8);
112 : // value(1) Current year
113 : // value(2) Current month
114 : // value(3) Current day
115 : // value(4) Time difference with respect to UTC in minutes (0-59)
116 : // value(5) Hour of the day (0-23)
117 : // value(6) Minutes (0-59)
118 : // value(7) Seconds (0-59)
119 : // value(8) Milliseconds (0-999)
120 :
121 8233424 : std::string datestring; // supposedly returns blank when no date available.
122 :
123 4116712 : if (state.dataRuntimeLangProcessor->InitializeOnce) {
124 :
125 71 : state.dataRuntimeLang->False = SetErlValueNumber(0.0);
126 71 : state.dataRuntimeLang->True = SetErlValueNumber(1.0);
127 :
128 : // Create constant built-in variables
129 71 : state.dataRuntimeLangProcessor->NullVariableNum = NewEMSVariable(state, "NULL", 0, SetErlValueNumber(0.0));
130 71 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->NullVariableNum).Value.Type = Value::Null;
131 71 : state.dataRuntimeLangProcessor->FalseVariableNum = NewEMSVariable(state, "FALSE", 0, state.dataRuntimeLang->False);
132 71 : state.dataRuntimeLangProcessor->TrueVariableNum = NewEMSVariable(state, "TRUE", 0, state.dataRuntimeLang->True);
133 71 : state.dataRuntimeLangProcessor->OffVariableNum = NewEMSVariable(state, "OFF", 0, state.dataRuntimeLang->False);
134 71 : state.dataRuntimeLangProcessor->OnVariableNum = NewEMSVariable(state, "ON", 0, state.dataRuntimeLang->True);
135 71 : state.dataRuntimeLangProcessor->PiVariableNum = NewEMSVariable(state, "PI", 0, SetErlValueNumber(DataGlobalConstants::Pi));
136 71 : state.dataRuntimeLangProcessor->TimeStepsPerHourVariableNum =
137 142 : NewEMSVariable(state, "TIMESTEPSPERHOUR", 0, SetErlValueNumber(double(state.dataGlobal->NumOfTimeStepInHour)));
138 :
139 : // Create dynamic built-in variables
140 71 : state.dataRuntimeLangProcessor->YearVariableNum = NewEMSVariable(state, "YEAR", 0);
141 71 : state.dataRuntimeLangProcessor->MonthVariableNum = NewEMSVariable(state, "MONTH", 0);
142 71 : state.dataRuntimeLangProcessor->DayOfMonthVariableNum = NewEMSVariable(state, "DAYOFMONTH", 0); // 'DAYOFMONTH'?
143 71 : state.dataRuntimeLangProcessor->DayOfWeekVariableNum = NewEMSVariable(state, "DAYOFWEEK", 0);
144 71 : state.dataRuntimeLangProcessor->DayOfYearVariableNum = NewEMSVariable(state, "DAYOFYEAR", 0);
145 71 : state.dataRuntimeLangProcessor->HourVariableNum = NewEMSVariable(state, "HOUR", 0);
146 71 : state.dataRuntimeLangProcessor->TimeStepNumVariableNum = NewEMSVariable(state, "TIMESTEPNUM", 0);
147 71 : state.dataRuntimeLangProcessor->MinuteVariableNum = NewEMSVariable(state, "MINUTE", 0);
148 71 : state.dataRuntimeLangProcessor->HolidayVariableNum = NewEMSVariable(state, "HOLIDAY", 0);
149 71 : state.dataRuntimeLangProcessor->DSTVariableNum = NewEMSVariable(state, "DAYLIGHTSAVINGS", 0);
150 71 : state.dataRuntimeLangProcessor->CurrentTimeVariableNum = NewEMSVariable(state, "CURRENTTIME", 0);
151 71 : state.dataRuntimeLangProcessor->SunIsUpVariableNum = NewEMSVariable(state, "SUNISUP", 0);
152 71 : state.dataRuntimeLangProcessor->IsRainingVariableNum = NewEMSVariable(state, "ISRAINING", 0);
153 71 : state.dataRuntimeLangProcessor->SystemTimeStepVariableNum = NewEMSVariable(state, "SYSTEMTIMESTEP", 0);
154 71 : state.dataRuntimeLangProcessor->ZoneTimeStepVariableNum = NewEMSVariable(state, "ZONETIMESTEP", 0);
155 142 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->ZoneTimeStepVariableNum).Value =
156 213 : SetErlValueNumber(state.dataGlobal->TimeStepZone);
157 71 : state.dataRuntimeLangProcessor->CurrentEnvironmentPeriodNum = NewEMSVariable(state, "CURRENTENVIRONMENT", 0);
158 71 : state.dataRuntimeLangProcessor->ActualDateAndTimeNum = NewEMSVariable(state, "ACTUALDATEANDTIME", 0);
159 71 : state.dataRuntimeLangProcessor->ActualTimeNum = NewEMSVariable(state, "ACTUALTIME", 0);
160 71 : state.dataRuntimeLangProcessor->WarmUpFlagNum = NewEMSVariable(state, "WARMUPFLAG", 0);
161 :
162 71 : GetRuntimeLanguageUserInput(state); // Load and parse all runtime language objects
163 :
164 71 : date_and_time(datestring, _, _, datevalues);
165 71 : if (datestring != "") {
166 142 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->ActualDateAndTimeNum).Value =
167 213 : SetErlValueNumber(double(sum(datevalues)));
168 : // datevalues(1)+datevalues(2)+datevalues(3)+ &
169 : // datevalues(5)+datevalues(6)+datevalues(7)+datevalues(8)
170 142 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->ActualTimeNum).Value =
171 213 : SetErlValueNumber(double(sum(datevalues({5, 8}))));
172 : // datevalues(5)+datevalues(6)+datevalues(7)+datevalues(8)
173 : // ELSE
174 : // ErlVariable(ActualDateAndTimeNum)%Value = SetErlValueNumber(REAL(RANDOM_NUMBER(X=509),r64))
175 : // ErlVariable(ActualTimeNum)%Value = SetErlValueNumber(REAL(RANDOM_NUMBER(X=400),r64))
176 : }
177 :
178 71 : state.dataRuntimeLangProcessor->InitializeOnce = false;
179 : }
180 :
181 : // Update built-in variables
182 4116712 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->YearVariableNum).Value = SetErlValueNumber(double(state.dataEnvrn->Year));
183 4116712 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->MonthVariableNum).Value = SetErlValueNumber(double(state.dataEnvrn->Month));
184 8233424 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->DayOfMonthVariableNum).Value =
185 12350136 : SetErlValueNumber(double(state.dataEnvrn->DayOfMonth));
186 8233424 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->DayOfWeekVariableNum).Value =
187 12350136 : SetErlValueNumber(double(state.dataEnvrn->DayOfWeek));
188 8233424 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->DayOfYearVariableNum).Value =
189 12350136 : SetErlValueNumber(double(state.dataEnvrn->DayOfYear));
190 8233424 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->TimeStepNumVariableNum).Value =
191 12350136 : SetErlValueNumber(double(state.dataGlobal->TimeStep));
192 :
193 8233424 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->DSTVariableNum).Value =
194 12350136 : SetErlValueNumber(double(state.dataEnvrn->DSTIndicator));
195 : // DSTadjust = REAL(DSTIndicator, r64)
196 4116712 : tmpHours = double(state.dataGlobal->HourOfDay - 1); // no, just stay on 0..23+ DSTadjust ! offset by 1 and daylight savings time
197 4116712 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->HourVariableNum).Value = SetErlValueNumber(tmpHours);
198 :
199 4116712 : if (TimeStepSys < state.dataGlobal->TimeStepZone) {
200 : // CurrentTime is for end of zone timestep, need to account for system timestep
201 1165961 : tmpCurrentTime = state.dataGlobal->CurrentTime - state.dataGlobal->TimeStepZone + SysTimeElapsed + TimeStepSys;
202 : } else {
203 2950751 : tmpCurrentTime = state.dataGlobal->CurrentTime;
204 : }
205 4116712 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->CurrentTimeVariableNum).Value = SetErlValueNumber(tmpCurrentTime);
206 4116712 : tmpMinutes = ((tmpCurrentTime - double(state.dataGlobal->HourOfDay - 1)) * 60.0); // -1.0 // off by 1
207 4116712 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->MinuteVariableNum).Value = SetErlValueNumber(tmpMinutes);
208 : // Subtract 7 from HolidayIndex to maintain compatability for EMS where 1=Holiday,2=SummerDesignDay, 3=WinterDesignDay, 4=CustomDay1,
209 : // 5=CustomDay2, but not <0
210 4116712 : if (state.dataEnvrn->HolidayIndex == 0) {
211 5359 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->HolidayVariableNum).Value = SetErlValueNumber(0.0);
212 : } else {
213 8222706 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->HolidayVariableNum).Value =
214 12334059 : SetErlValueNumber(double(state.dataEnvrn->HolidayIndex - 7));
215 : }
216 4116712 : if (state.dataEnvrn->SunIsUp) {
217 1995253 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->SunIsUpVariableNum).Value = SetErlValueNumber(1.0);
218 : } else {
219 2121459 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->SunIsUpVariableNum).Value = SetErlValueNumber(0.0);
220 : }
221 4116712 : if (state.dataEnvrn->IsRain) {
222 48 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->IsRainingVariableNum).Value = SetErlValueNumber(1.0);
223 : } else {
224 4116664 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->IsRainingVariableNum).Value = SetErlValueNumber(0.0);
225 : }
226 4116712 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->SystemTimeStepVariableNum).Value = SetErlValueNumber(TimeStepSys);
227 :
228 4116712 : tmpCurEnvirNum = double(state.dataEnvrn->CurEnvirNum);
229 4116712 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->CurrentEnvironmentPeriodNum).Value = SetErlValueNumber(tmpCurEnvirNum);
230 4116712 : if (state.dataGlobal->WarmupFlag) {
231 3588197 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->WarmUpFlagNum).Value = SetErlValueNumber(1.0);
232 : } else {
233 528515 : state.dataRuntimeLang->ErlVariable(state.dataRuntimeLangProcessor->WarmUpFlagNum).Value = SetErlValueNumber(0.0);
234 : }
235 4116712 : }
236 :
237 208 : void BeginEnvrnInitializeRuntimeLanguage(EnergyPlusData &state)
238 : {
239 :
240 : // SUBROUTINE INFORMATION:
241 : // AUTHOR B. Griffith
242 : // DATE WRITTEN March 2010
243 : // MODIFIED B. Griffith, added Sensor initialation
244 : // RE-ENGINEERED na
245 :
246 : // PURPOSE OF THIS SUBROUTINE:
247 : // re initialize Erl for new simulation environment period
248 :
249 : // METHODOLOGY EMPLOYED:
250 : // na
251 :
252 : // REFERENCES:
253 : // na
254 :
255 : // Using/Aliasing
256 : using OutputProcessor::SetInternalVariableValue;
257 :
258 : // Locals
259 : // SUBROUTINE ARGUMENT DEFINITIONS:
260 : // na
261 :
262 : // SUBROUTINE PARAMETER DEFINITIONS:
263 : // na
264 :
265 : // INTERFACE BLOCK SPECIFICATIONS:
266 : // na
267 :
268 : // DERIVED TYPE DEFINITIONS:
269 : // na
270 :
271 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
272 : int ActuatorUsedLoop;
273 : int EMSActuatorVariableNum;
274 : int ErlVariableNum;
275 : int TrendVarNum;
276 : int SensorNum;
277 : int TrendDepth;
278 : int loop;
279 : bool CycleThisVariable;
280 :
281 : // reinitialize state of Erl variable values to zero, this gets sensors and internal variables used
282 22735 : for (ErlVariableNum = 1; ErlVariableNum <= state.dataRuntimeLang->NumErlVariables; ++ErlVariableNum) {
283 : // but skip constant built-in variables so don't overwrite them
284 22527 : if (ErlVariableNum == state.dataRuntimeLangProcessor->NullVariableNum) continue;
285 22319 : if (ErlVariableNum == state.dataRuntimeLangProcessor->FalseVariableNum) continue;
286 22111 : if (ErlVariableNum == state.dataRuntimeLangProcessor->TrueVariableNum) continue;
287 21903 : if (ErlVariableNum == state.dataRuntimeLangProcessor->OffVariableNum) continue;
288 21695 : if (ErlVariableNum == state.dataRuntimeLangProcessor->OnVariableNum) continue;
289 21487 : if (ErlVariableNum == state.dataRuntimeLangProcessor->PiVariableNum) continue;
290 21279 : if (ErlVariableNum == state.dataRuntimeLangProcessor->ZoneTimeStepVariableNum) continue;
291 21071 : if (ErlVariableNum == state.dataRuntimeLangProcessor->ActualDateAndTimeNum) continue;
292 20863 : if (ErlVariableNum == state.dataRuntimeLangProcessor->ActualTimeNum) continue;
293 :
294 : // need to preserve curve index variables
295 20655 : CycleThisVariable = false;
296 25500 : for (loop = 1; loop <= state.dataRuntimeLang->NumEMSCurveIndices; ++loop) {
297 4845 : if (ErlVariableNum == state.dataRuntimeLangProcessor->CurveIndexVariableNums(loop)) CycleThisVariable = true;
298 : }
299 20655 : if (CycleThisVariable) continue;
300 20625 : CycleThisVariable = false;
301 22791 : for (loop = 1; loop <= state.dataRuntimeLang->NumEMSConstructionIndices; ++loop) {
302 2166 : if (ErlVariableNum == state.dataRuntimeLangProcessor->ConstructionIndexVariableNums(loop)) CycleThisVariable = true;
303 : }
304 20625 : if (CycleThisVariable) continue;
305 :
306 20568 : if (state.dataRuntimeLang->ErlVariable(ErlVariableNum).Value.initialized) {
307 35312 : state.dataRuntimeLang->ErlVariable(ErlVariableNum).Value =
308 52968 : SetErlValueNumber(0.0, state.dataRuntimeLang->ErlVariable(ErlVariableNum).Value);
309 : }
310 : }
311 : // reinitialize state of actuators
312 2296 : for (ActuatorUsedLoop = 1; ActuatorUsedLoop <= state.dataRuntimeLang->numActuatorsUsed + state.dataRuntimeLang->NumExternalInterfaceActuatorsUsed;
313 : ++ActuatorUsedLoop) {
314 2088 : EMSActuatorVariableNum = state.dataRuntimeLang->EMSActuatorUsed(ActuatorUsedLoop).ActuatorVariableNum;
315 2088 : ErlVariableNum = state.dataRuntimeLang->EMSActuatorUsed(ActuatorUsedLoop).ErlVariableNum;
316 2088 : state.dataRuntimeLang->ErlVariable(ErlVariableNum).Value.Type = Value::Null;
317 2088 : *state.dataRuntimeLang->EMSActuatorAvailable(EMSActuatorVariableNum).Actuated = false;
318 2088 : switch (state.dataRuntimeLang->EMSActuatorAvailable(EMSActuatorVariableNum).PntrVarTypeUsed) {
319 2052 : case PtrDataType::Real:
320 2052 : *state.dataRuntimeLang->EMSActuatorAvailable(EMSActuatorVariableNum).RealValue = 0.0;
321 2052 : break;
322 36 : case PtrDataType::Integer:
323 36 : *state.dataRuntimeLang->EMSActuatorAvailable(EMSActuatorVariableNum).IntValue = 0;
324 36 : break;
325 0 : case PtrDataType::Logical:
326 0 : *state.dataRuntimeLang->EMSActuatorAvailable(EMSActuatorVariableNum).LogValue = false;
327 0 : break;
328 0 : default:
329 0 : break; // nothing to do for those
330 : }
331 : }
332 :
333 : // reinitialize trend variables so old data are purged
334 217 : for (TrendVarNum = 1; TrendVarNum <= state.dataRuntimeLang->NumErlTrendVariables; ++TrendVarNum) {
335 9 : TrendDepth = state.dataRuntimeLang->TrendVariable(TrendVarNum).LogDepth;
336 9 : state.dataRuntimeLang->TrendVariable(TrendVarNum).TrendValARR({1, TrendDepth}) = 0.0;
337 : }
338 :
339 : // reinitilize sensors
340 6277 : for (SensorNum = 1; SensorNum <= state.dataRuntimeLang->NumSensors; ++SensorNum) {
341 12138 : SetInternalVariableValue(
342 12138 : state, state.dataRuntimeLang->Sensor(SensorNum).VariableType, state.dataRuntimeLang->Sensor(SensorNum).Index, 0.0, 0);
343 : }
344 208 : }
345 :
346 629 : void ParseStack(EnergyPlusData &state, int const StackNum)
347 : {
348 :
349 : // SUBROUTINE INFORMATION:
350 : // AUTHOR Peter Graham Ellis
351 : // DATE WRITTEN June 2006
352 : // MODIFIED Brent Griffith June 2009
353 : // Brent Griffith March 2012, add WHILE loops
354 : // RE-ENGINEERED na
355 :
356 : // PURPOSE OF THIS SUBROUTINE:
357 : // Parsing a block of text creates a program stack in DataRuntimeLanguage.
358 : // This routine only executes once for each Erl program.
359 :
360 : // METHODOLOGY EMPLOYED:
361 : // Loop over each line of Erl code and parse based on statement keyword
362 :
363 : // Using/Aliasing
364 :
365 : // Locals
366 : // SUBROUTINE ARGUMENT DEFINITIONS:
367 :
368 : // SUBROUTINE PARAMETER DEFINITIONS:
369 629 : int constexpr IfDepthAllowed(5); // depth of IF block nesting
370 629 : int constexpr ELSEIFLengthAllowed(200); // number of ELSEIFs allowed
371 629 : int constexpr WhileDepthAllowed(1); // depth of While block nesting
372 :
373 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
374 : int LineNum;
375 : int StackNum2;
376 : std::string::size_type Pos;
377 : int ExpressionNum;
378 : int VariableNum;
379 1258 : std::string Line; // local copy of a single line of Erl program code
380 1258 : std::string Keyword; // local copy of statement keyword parsed from line (Run, Set, If, etc)
381 1258 : std::string Remainder; // local copy of what is left for text in the line after keyword
382 1258 : std::string Expression;
383 1258 : std::string Variable;
384 : int NestedIfDepth; // indicates depth into If statement,
385 : int NestedWhileDepth; // indicates depth into While statement
386 : int InstructionNum;
387 : int InstructionNum2;
388 : int GotoNum;
389 1258 : Array1D_int SavedIfInstructionNum(IfDepthAllowed); // index is depth of If statements
390 1258 : Array2D_int SavedGotoInstructionNum(ELSEIFLengthAllowed, IfDepthAllowed);
391 1258 : Array1D_int NumGotos(IfDepthAllowed); // index is depth of If statements,
392 : int SavedWhileInstructionNum;
393 : int SavedWhileExpressionNum;
394 : int NumWhileGotos;
395 1258 : Array1D_bool ReadyForElse(IfDepthAllowed);
396 1258 : Array1D_bool ReadyForEndif(IfDepthAllowed);
397 :
398 629 : LineNum = 1;
399 629 : NestedIfDepth = 0;
400 629 : ReadyForElse = false;
401 629 : ReadyForEndif = false;
402 629 : SavedIfInstructionNum = 0;
403 629 : SavedGotoInstructionNum = 0;
404 629 : NumGotos = 0;
405 629 : NestedWhileDepth = 0;
406 629 : SavedWhileInstructionNum = 0;
407 629 : SavedWhileExpressionNum = 0;
408 629 : NumWhileGotos = 0;
409 :
410 17727 : while (LineNum <= state.dataRuntimeLang->ErlStack(StackNum).NumLines) {
411 :
412 8549 : Line = stripped(state.dataRuntimeLang->ErlStack(StackNum).Line(LineNum));
413 8549 : if (len(Line) == 0) {
414 0 : ++LineNum;
415 0 : continue; // Blank lines can be skipped
416 : }
417 :
418 8549 : Pos = scan(Line, ' ');
419 8549 : if (Pos == std::string::npos) {
420 1425 : Pos = len(Line);
421 1425 : Remainder.clear();
422 : } else {
423 7124 : Remainder = stripped(Line.substr(Pos + 1));
424 : }
425 : // Keyword = UtilityRoutines::MakeUPPERCase(Line(1:Pos-1))
426 8549 : Keyword = Line.substr(0, Pos);
427 :
428 : // the functionality in each block of this parser structure is so different that a regular IF block seems reasonable
429 8549 : if (Keyword == "RETURN") {
430 33 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "RETURN \"{}\"\n", Line);
431 33 : if (Remainder.empty()) {
432 33 : InstructionNum = AddInstruction(state, StackNum, LineNum, RuntimeLanguageProcessor::ErlKeywordParam::Return);
433 : } else {
434 0 : ParseExpression(state, Remainder, StackNum, ExpressionNum, Line);
435 0 : InstructionNum = AddInstruction(state, StackNum, LineNum, DataRuntimeLanguage::ErlKeywordParam::Return, ExpressionNum);
436 : }
437 :
438 8516 : } else if (Keyword == "SET") {
439 5600 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "SET \"{}\"\n", Line);
440 5600 : Pos = scan(Remainder, '=');
441 5600 : if (Pos == std::string::npos) {
442 0 : AddError(state, StackNum, LineNum, "Equal sign missing for the SET instruction.");
443 5600 : } else if (Pos == 0) {
444 0 : AddError(state, StackNum, LineNum, "Variable name missing for the SET instruction.");
445 : } else {
446 5600 : Variable = stripped(Remainder.substr(0, Pos)); // VariableName would be more expressive
447 5600 : VariableNum = NewEMSVariable(state, Variable, StackNum);
448 : // Check for invalid variable name
449 :
450 5600 : if (Pos + 1 < Remainder.length()) {
451 5600 : Expression = stripped(Remainder.substr(Pos + 1));
452 : } else {
453 0 : Expression.clear();
454 : }
455 5600 : if (Expression.empty()) {
456 0 : AddError(state, StackNum, LineNum, "Expression missing for the SET instruction.");
457 : } else {
458 5600 : ParseExpression(state, Expression, StackNum, ExpressionNum, Line);
459 5600 : InstructionNum = AddInstruction(state, StackNum, LineNum, DataRuntimeLanguage::ErlKeywordParam::Set, VariableNum, ExpressionNum);
460 : }
461 : }
462 :
463 2916 : } else if (Keyword == "RUN") {
464 34 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "RUN \"{}\"\n", Line);
465 34 : if (Remainder.empty()) {
466 0 : AddError(state, StackNum, LineNum, "Program or Subroutine name missing for the RUN instruction.");
467 : } else {
468 34 : Pos = scan(Remainder, ' ');
469 34 : if (Pos == std::string::npos) Pos = Remainder.length();
470 34 : Variable =
471 68 : UtilityRoutines::MakeUPPERCase(stripped(Remainder.substr(0, Pos))); // really the subroutine, or reference to instruction set
472 34 : StackNum2 = UtilityRoutines::FindItemInList(Variable, state.dataRuntimeLang->ErlStack);
473 34 : if (StackNum2 == 0) {
474 0 : AddError(state, StackNum, LineNum, "Program or Subroutine name [" + Variable + "] not found for the RUN instruction.");
475 : } else {
476 34 : InstructionNum = AddInstruction(state, StackNum, LineNum, DataRuntimeLanguage::ErlKeywordParam::Run, StackNum2);
477 : }
478 : }
479 :
480 2882 : } else if (Keyword == "IF") {
481 818 : if (state.dataSysVars->DeveloperFlag) {
482 0 : print(state.files.debug, "IF \"{}\"\n", Line);
483 0 : print(state.files.debug, "NestedIf={}\n", NestedIfDepth);
484 : }
485 818 : if (Remainder.empty()) {
486 0 : AddError(state, StackNum, LineNum, "Expression missing for the IF instruction.");
487 0 : ExpressionNum = 0;
488 : } else {
489 818 : Expression = stripped(Remainder);
490 818 : ParseExpression(state, Expression, StackNum, ExpressionNum, Line);
491 : }
492 :
493 818 : ++NestedIfDepth;
494 818 : ReadyForElse(NestedIfDepth) = true;
495 818 : ReadyForEndif(NestedIfDepth) = true;
496 818 : if (NestedIfDepth > IfDepthAllowed) {
497 0 : AddError(state, StackNum, LineNum, "Detected IF nested deeper than is allowed; need to terminate an earlier IF instruction.");
498 0 : break;
499 : } else {
500 818 : InstructionNum = AddInstruction(state,
501 : StackNum,
502 : LineNum,
503 : DataRuntimeLanguage::ErlKeywordParam::If,
504 : ExpressionNum); // Arg2 added at next ELSEIF, ELSE, ENDIF
505 818 : SavedIfInstructionNum(NestedIfDepth) = InstructionNum;
506 : }
507 :
508 2064 : } else if (Keyword == "ELSEIF") {
509 670 : if (state.dataSysVars->DeveloperFlag) {
510 0 : print(state.files.debug, "ELSEIF \"{}\"\n", Line);
511 0 : print(state.files.debug, "NestedIf={}\n", NestedIfDepth);
512 : }
513 670 : if (NestedIfDepth == 0) {
514 0 : AddError(state, StackNum, LineNum, "Starting IF instruction missing for the ELSEIF instruction.");
515 0 : break; // Getting strange error on DEALLOCATE for the next instruction that I try to add, so doing EXIT here
516 : }
517 :
518 : // Complete the preceding block with a GOTO instruction
519 670 : InstructionNum = AddInstruction(state, StackNum, 0, DataRuntimeLanguage::ErlKeywordParam::Goto); // Arg2 is added at the ENDIF
520 670 : ++NumGotos(NestedIfDepth);
521 670 : if (NumGotos(NestedIfDepth) > ELSEIFLengthAllowed) {
522 0 : AddError(state, StackNum, LineNum, "Detected ELSEIF series that is longer than allowed; terminate earlier IF instruction.");
523 0 : break;
524 : } else {
525 670 : SavedGotoInstructionNum(NumGotos(NestedIfDepth), NestedIfDepth) = InstructionNum;
526 : }
527 :
528 670 : if (Remainder.empty()) {
529 0 : AddError(state, StackNum, LineNum, "Expression missing for the ELSEIF instruction.");
530 0 : ExpressionNum = 0;
531 : } else {
532 670 : Expression = stripped(Remainder);
533 670 : ParseExpression(state, Expression, StackNum, ExpressionNum, Line);
534 : }
535 :
536 670 : InstructionNum = AddInstruction(state,
537 : StackNum,
538 : LineNum,
539 : DataRuntimeLanguage::ErlKeywordParam::If,
540 : ExpressionNum); // Arg2 added at next ELSEIF, ELSE, ENDIF
541 670 : state.dataRuntimeLang->ErlStack(StackNum).Instruction(SavedIfInstructionNum(NestedIfDepth)).Argument2 = InstructionNum;
542 670 : SavedIfInstructionNum(NestedIfDepth) = InstructionNum;
543 :
544 1394 : } else if (Keyword == "ELSE") {
545 572 : if (state.dataSysVars->DeveloperFlag) {
546 0 : print(state.files.debug, "ELSE \"{}\"\n", Line);
547 0 : print(state.files.debug, "NestedIf={}\n", NestedIfDepth);
548 : }
549 572 : if (NestedIfDepth == 0) {
550 0 : AddError(state, StackNum, LineNum, "Starting IF instruction missing for the ELSE instruction.");
551 0 : break; // Getting strange error on DEALLOCATE for the next instruction that I try to add, so doing EXIT here
552 : }
553 572 : if (!ReadyForElse(NestedIfDepth)) {
554 0 : AddError(state, StackNum, LineNum, "ELSE statement without corresponding IF statement.");
555 : }
556 572 : ReadyForElse(NestedIfDepth) = false;
557 :
558 : // Complete the preceding block with a GOTO instruction
559 572 : InstructionNum = AddInstruction(state, StackNum, 0, DataRuntimeLanguage::ErlKeywordParam::Goto); // Arg2 is added at the ENDIF
560 572 : ++NumGotos(NestedIfDepth);
561 572 : if (NumGotos(NestedIfDepth) > ELSEIFLengthAllowed) {
562 0 : AddError(state, StackNum, LineNum, "Detected ELSEIF-ELSE series that is longer than allowed.");
563 0 : break;
564 : } else {
565 572 : SavedGotoInstructionNum(NumGotos(NestedIfDepth), NestedIfDepth) = InstructionNum;
566 : }
567 :
568 572 : if (!Remainder.empty()) {
569 0 : AddError(state, StackNum, LineNum, "Nothing is allowed to follow the ELSE instruction.");
570 : }
571 :
572 572 : InstructionNum = AddInstruction(state, StackNum, LineNum, DataRuntimeLanguage::ErlKeywordParam::Else); // can make this into a KeywordIf?
573 572 : state.dataRuntimeLang->ErlStack(StackNum).Instruction(SavedIfInstructionNum(NestedIfDepth)).Argument2 = InstructionNum;
574 572 : SavedIfInstructionNum(NestedIfDepth) = InstructionNum;
575 :
576 822 : } else if (Keyword == "ENDIF") {
577 818 : if (state.dataSysVars->DeveloperFlag) {
578 0 : print(state.files.debug, "ENDIF \"{}\"\n", Line);
579 0 : print(state.files.debug, "NestedIf={}\n", NestedIfDepth);
580 : }
581 818 : if (NestedIfDepth == 0) {
582 0 : AddError(state, StackNum, LineNum, "Starting IF instruction missing for the ENDIF instruction.");
583 0 : break; // PE Getting strange error on DEALLOCATE for the next instruction that I try to add, so doing EXIT here
584 : }
585 :
586 818 : if (!ReadyForEndif(NestedIfDepth)) {
587 0 : AddError(state, StackNum, LineNum, "ENDIF statement without corresponding IF stetement.");
588 : }
589 818 : ReadyForEndif(NestedIfDepth) = false;
590 818 : ReadyForElse(NestedIfDepth) = false;
591 :
592 818 : if (!Remainder.empty()) {
593 0 : AddError(state, StackNum, LineNum, "Nothing is allowed to follow the ENDIF instruction.");
594 : }
595 :
596 818 : InstructionNum = AddInstruction(state, StackNum, LineNum, DataRuntimeLanguage::ErlKeywordParam::EndIf);
597 818 : state.dataRuntimeLang->ErlStack(StackNum).Instruction(SavedIfInstructionNum(NestedIfDepth)).Argument2 = InstructionNum;
598 :
599 : // Go back and complete all of the GOTOs that terminate each IF and ELSEIF block
600 2060 : for (GotoNum = 1; GotoNum <= NumGotos(NestedIfDepth); ++GotoNum) {
601 1242 : InstructionNum2 = SavedGotoInstructionNum(GotoNum, NestedIfDepth);
602 1242 : state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum2).Argument1 = InstructionNum;
603 1242 : SavedGotoInstructionNum(GotoNum, NestedIfDepth) = 0;
604 : }
605 :
606 818 : NumGotos(NestedIfDepth) = 0;
607 818 : SavedIfInstructionNum(NestedIfDepth) = 0;
608 818 : --NestedIfDepth;
609 :
610 4 : } else if (Keyword == "WHILE") {
611 2 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "WHILE \"{}\"\n", Line);
612 2 : if (Remainder.empty()) {
613 0 : AddError(state, StackNum, LineNum, "Expression missing for the WHILE instruction.");
614 0 : ExpressionNum = 0;
615 : } else {
616 2 : Expression = stripped(Remainder);
617 2 : ParseExpression(state, Expression, StackNum, ExpressionNum, Line);
618 : }
619 :
620 2 : ++NestedWhileDepth;
621 2 : if (NestedWhileDepth > WhileDepthAllowed) {
622 0 : AddError(state, StackNum, LineNum, "Detected WHILE nested deeper than is allowed; need to terminate an earlier WHILE instruction.");
623 0 : break;
624 : } else {
625 2 : InstructionNum = AddInstruction(state, StackNum, LineNum, DataRuntimeLanguage::ErlKeywordParam::While, ExpressionNum);
626 2 : SavedWhileInstructionNum = InstructionNum;
627 2 : SavedWhileExpressionNum = ExpressionNum;
628 : }
629 :
630 2 : } else if (Keyword == "ENDWHILE") {
631 2 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "ENDWHILE \"{}\"\n", Line);
632 2 : if (NestedWhileDepth == 0) {
633 0 : AddError(state, StackNum, LineNum, "Starting WHILE instruction missing for the ENDWHILE instruction.");
634 0 : break;
635 : }
636 2 : if (!Remainder.empty()) {
637 0 : AddError(state, StackNum, LineNum, "Nothing is allowed to follow the ENDWHILE instruction.");
638 : }
639 :
640 2 : InstructionNum = AddInstruction(state, StackNum, LineNum, DataRuntimeLanguage::ErlKeywordParam::EndWhile);
641 2 : state.dataRuntimeLang->ErlStack(StackNum).Instruction(SavedWhileInstructionNum).Argument2 = InstructionNum;
642 2 : state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument1 = SavedWhileExpressionNum;
643 2 : state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument2 = SavedWhileInstructionNum;
644 :
645 2 : NestedWhileDepth = 0;
646 2 : SavedWhileInstructionNum = 0;
647 2 : SavedWhileExpressionNum = 0;
648 :
649 : } else {
650 0 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "ERROR \"{}\"\n", Line);
651 0 : AddError(state, StackNum, LineNum, "Unknown keyword [" + Keyword + "].");
652 : }
653 :
654 8549 : ++LineNum;
655 : } // LineNum
656 :
657 629 : if (NestedIfDepth == 1) {
658 0 : AddError(state, StackNum, 0, "Missing an ENDIF instruction needed to terminate an earlier IF instruction.");
659 629 : } else if (NestedIfDepth > 1) {
660 0 : AddError(state, StackNum, 0, format("Missing {} ENDIF instructions needed to terminate earlier IF instructions.", NestedIfDepth));
661 : }
662 :
663 : // ALLOCATE(DummyError(ErlStack(StackNum)%NumErrors))
664 : // DummyError = ErlStack(StackNum)%Error
665 629 : }
666 :
667 9791 : int AddInstruction(EnergyPlusData &state,
668 : int const StackNum,
669 : int const LineNum,
670 : DataRuntimeLanguage::ErlKeywordParam Keyword,
671 : Optional_int_const Argument1, // Erl variable index
672 : Optional_int_const Argument2)
673 : {
674 :
675 : // SUBROUTINE INFORMATION:
676 : // AUTHOR Peter Graham Ellis
677 : // DATE WRITTEN June 2006
678 : // MODIFIED na
679 : // RE-ENGINEERED na
680 :
681 : // PURPOSE OF THIS SUBROUTINE:
682 : // Adds an instruction to a stack.
683 :
684 : // METHODOLOGY EMPLOYED:
685 :
686 : // Return value
687 : int InstructionNum;
688 :
689 : // Locals
690 : // SUBROUTINE ARGUMENT DEFINITIONS:
691 :
692 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
693 :
694 : // Object Data
695 19582 : ErlStackType TempStack;
696 :
697 9791 : if (state.dataRuntimeLang->ErlStack(StackNum).NumInstructions == 0) {
698 629 : state.dataRuntimeLang->ErlStack(StackNum).Instruction.allocate(1);
699 629 : state.dataRuntimeLang->ErlStack(StackNum).NumInstructions = 1;
700 : } else {
701 9162 : TempStack = state.dataRuntimeLang->ErlStack(StackNum);
702 9162 : state.dataRuntimeLang->ErlStack(StackNum).Instruction.deallocate();
703 9162 : state.dataRuntimeLang->ErlStack(StackNum).Instruction.allocate(state.dataRuntimeLang->ErlStack(StackNum).NumInstructions + 1);
704 9162 : state.dataRuntimeLang->ErlStack(StackNum).Instruction({1, state.dataRuntimeLang->ErlStack(StackNum).NumInstructions}) =
705 18324 : TempStack.Instruction({1, state.dataRuntimeLang->ErlStack(StackNum).NumInstructions});
706 9162 : ++state.dataRuntimeLang->ErlStack(StackNum).NumInstructions;
707 : }
708 :
709 9791 : InstructionNum = state.dataRuntimeLang->ErlStack(StackNum).NumInstructions;
710 9791 : state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).LineNum = LineNum;
711 9791 : state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Keyword = Keyword;
712 :
713 9791 : if (present(Argument1)) state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument1 = Argument1;
714 9791 : if (present(Argument2)) state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument2 = Argument2;
715 :
716 19582 : return InstructionNum;
717 : }
718 :
719 0 : void AddError(EnergyPlusData &state,
720 : int const StackNum, // index pointer to location in ErlStack structure
721 : int const LineNum, // Erl program line number
722 : std::string const &Error // error message to be added to ErlStack
723 : )
724 : {
725 :
726 : // SUBROUTINE INFORMATION:
727 : // AUTHOR Peter Graham Ellis
728 : // DATE WRITTEN June 2006
729 : // MODIFIED na
730 : // RE-ENGINEERED na
731 :
732 : // PURPOSE OF THIS SUBROUTINE:
733 : // Adds an error message to a stack.
734 :
735 : // METHODOLOGY EMPLOYED:
736 :
737 : // Locals
738 : // SUBROUTINE ARGUMENT DEFINITIONS:
739 :
740 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
741 : int ErrorNum; // local count of errors for this ErlStack
742 :
743 : // Object Data
744 0 : ErlStackType TempStack; // temporary copy of single ErlStack
745 :
746 0 : if (state.dataRuntimeLang->ErlStack(StackNum).NumErrors == 0) {
747 0 : state.dataRuntimeLang->ErlStack(StackNum).Error.allocate(1);
748 0 : state.dataRuntimeLang->ErlStack(StackNum).NumErrors = 1;
749 : } else {
750 0 : TempStack = state.dataRuntimeLang->ErlStack(StackNum);
751 0 : state.dataRuntimeLang->ErlStack(StackNum).Error.deallocate();
752 0 : state.dataRuntimeLang->ErlStack(StackNum).Error.allocate(state.dataRuntimeLang->ErlStack(StackNum).NumErrors + 1);
753 0 : state.dataRuntimeLang->ErlStack(StackNum).Error({1, state.dataRuntimeLang->ErlStack(StackNum).NumErrors}) =
754 0 : TempStack.Error({1, state.dataRuntimeLang->ErlStack(StackNum).NumErrors});
755 0 : ++state.dataRuntimeLang->ErlStack(StackNum).NumErrors;
756 : }
757 :
758 0 : ErrorNum = state.dataRuntimeLang->ErlStack(StackNum).NumErrors;
759 0 : if (LineNum > 0) {
760 0 : state.dataRuntimeLang->ErlStack(StackNum).Error(ErrorNum) =
761 0 : format("Line {}: {} \"{}\"", LineNum, Error, state.dataRuntimeLang->ErlStack(StackNum).Line(LineNum));
762 : } else {
763 0 : state.dataRuntimeLang->ErlStack(StackNum).Error(ErrorNum) = Error;
764 : }
765 0 : }
766 :
767 3035803 : ErlValueType EvaluateStack(EnergyPlusData &state, int const StackNum)
768 : {
769 :
770 : // SUBROUTINE INFORMATION:
771 : // AUTHOR Peter Graham Ellis
772 : // DATE WRITTEN June 2006
773 : // MODIFIED Brent Griffith, May 2009
774 : // Brent Griffith, March 2012, add While loop support
775 : // RE-ENGINEERED na
776 :
777 : // PURPOSE OF THIS SUBROUTINE:
778 : // Runs a stack with the interpreter.
779 :
780 : // Return value
781 3035803 : ErlValueType ReturnValue;
782 :
783 : // Locals
784 : // SUBROUTINE ARGUMENT DEFINITIONS:
785 :
786 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
787 : int InstructionNum;
788 : int InstructionNum2;
789 : int ExpressionNum;
790 : int ESVariableNum;
791 : int WhileLoopExitCounter; // to avoid infinite loop in While loop
792 3035803 : bool seriousErrorFound(false); // once it gets set true (inside EvaluateExpresssion) it will trigger a fatal (in WriteTrace)
793 :
794 3035803 : WhileLoopExitCounter = 0;
795 3035803 : ReturnValue.Type = Value::Number;
796 3035803 : ReturnValue.Number = 0.0;
797 :
798 3035803 : InstructionNum = 1;
799 59437981 : while (InstructionNum <= state.dataRuntimeLang->ErlStack(StackNum).NumInstructions) {
800 :
801 : {
802 28280495 : auto const SELECT_CASE_var(state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Keyword);
803 :
804 28280495 : if (SELECT_CASE_var == DataRuntimeLanguage::ErlKeywordParam::None) {
805 : // There probably shouldn't be any of these
806 :
807 28280495 : } else if (SELECT_CASE_var == DataRuntimeLanguage::ErlKeywordParam::Return) {
808 79404 : if (state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument1 > 0)
809 0 : ReturnValue =
810 0 : EvaluateExpression(state, state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument1, seriousErrorFound);
811 79404 : WriteTrace(state, StackNum, InstructionNum, ReturnValue, seriousErrorFound);
812 79404 : break; // RETURN always terminates an instruction stack
813 :
814 28201091 : } else if (SELECT_CASE_var == DataRuntimeLanguage::ErlKeywordParam::Set) {
815 :
816 16329448 : ReturnValue =
817 32658897 : EvaluateExpression(state, state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument2, seriousErrorFound);
818 16329448 : ESVariableNum = state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument1;
819 32658896 : if ((!state.dataRuntimeLang->ErlVariable(ESVariableNum).ReadOnly) &&
820 16329448 : (!state.dataRuntimeLang->ErlVariable(ESVariableNum).Value.TrendVariable)) {
821 16308546 : state.dataRuntimeLang->ErlVariable(ESVariableNum).Value = ReturnValue;
822 20902 : } else if (state.dataRuntimeLang->ErlVariable(ESVariableNum).Value.TrendVariable) {
823 20902 : state.dataRuntimeLang->ErlVariable(ESVariableNum).Value.Number = ReturnValue.Number;
824 20902 : state.dataRuntimeLang->ErlVariable(ESVariableNum).Value.Error = ReturnValue.Error;
825 : }
826 :
827 16329448 : WriteTrace(state, StackNum, InstructionNum, ReturnValue, seriousErrorFound);
828 :
829 11871642 : } else if (SELECT_CASE_var == DataRuntimeLanguage::ErlKeywordParam::Run) {
830 135326 : ReturnValue.Type = Value::String;
831 135326 : ReturnValue.String = "";
832 135326 : WriteTrace(state, StackNum, InstructionNum, ReturnValue, seriousErrorFound);
833 135326 : ReturnValue = EvaluateStack(state, state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument1);
834 11736316 : } else if ((SELECT_CASE_var == DataRuntimeLanguage::ErlKeywordParam::If) ||
835 : (SELECT_CASE_var == DataRuntimeLanguage::ErlKeywordParam::Else)) { // same???
836 6687612 : ExpressionNum = state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument1;
837 6687612 : InstructionNum2 = state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument2;
838 9636876 : if (ExpressionNum > 0) { // could be 0 if this was an ELSE
839 5540835 : ReturnValue = EvaluateExpression(state, ExpressionNum, seriousErrorFound);
840 5540835 : WriteTrace(state, StackNum, InstructionNum, ReturnValue, seriousErrorFound);
841 9279183 : if (ReturnValue.Number == 0.0) { // This is the FALSE case
842 : // Eventually should handle strings and arrays too
843 3738348 : InstructionNum = InstructionNum2;
844 3738348 : continue;
845 : }
846 : } else {
847 : // KeywordELSE -- kind of a kludge
848 1146777 : ReturnValue.Type = Value::Number;
849 1146777 : ReturnValue.Number = 1.0;
850 1146777 : WriteTrace(state, StackNum, InstructionNum, ReturnValue, seriousErrorFound);
851 : }
852 6460751 : } else if (SELECT_CASE_var == DataRuntimeLanguage::ErlKeywordParam::Goto) {
853 1412047 : InstructionNum = state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument1;
854 :
855 : // For debug purposes only...
856 1412047 : ReturnValue.Type = Value::String;
857 1412047 : ReturnValue.String = ""; // IntegerToString(InstructionNum)
858 :
859 1412047 : continue;
860 : // PE if this ever went out of bounds, would the DO loop save it? or need check here?
861 :
862 3636657 : } else if (SELECT_CASE_var == DataRuntimeLanguage::ErlKeywordParam::EndIf) {
863 3552773 : ReturnValue.Type = Value::String;
864 3552773 : ReturnValue.String = "";
865 3552773 : WriteTrace(state, StackNum, InstructionNum, ReturnValue, seriousErrorFound);
866 :
867 83884 : } else if (SELECT_CASE_var == DataRuntimeLanguage::ErlKeywordParam::While) {
868 : // evaluate expression at while, skip to past endwhile if not true
869 41942 : ExpressionNum = state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument1;
870 41942 : InstructionNum2 = state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument2;
871 41942 : ReturnValue = EvaluateExpression(state, ExpressionNum, seriousErrorFound);
872 41942 : WriteTrace(state, StackNum, InstructionNum, ReturnValue, seriousErrorFound);
873 41942 : if (ReturnValue.Number == 0.0) { // This is the FALSE case
874 : // Eventually should handle strings and arrays too
875 0 : InstructionNum = InstructionNum2;
876 : // CYCLE
877 : }
878 41942 : } else if (SELECT_CASE_var == DataRuntimeLanguage::ErlKeywordParam::EndWhile) {
879 :
880 : // reevaluate expression at While and goto there if true, otherwise continue
881 41942 : ExpressionNum = state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument1;
882 41942 : InstructionNum2 = state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).Argument2;
883 41942 : ReturnValue = EvaluateExpression(state, ExpressionNum, seriousErrorFound);
884 73709 : if ((ReturnValue.Number != 0.0) && (WhileLoopExitCounter <= MaxWhileLoopIterations)) { // This is the True case
885 : // Eventually should handle strings and arrays too
886 31767 : WriteTrace(state, StackNum, InstructionNum, ReturnValue, seriousErrorFound); // duplicative?
887 31767 : InstructionNum = InstructionNum2;
888 31767 : ++WhileLoopExitCounter;
889 :
890 31767 : continue;
891 : } else { // false, leave while block
892 10175 : if (WhileLoopExitCounter > MaxWhileLoopIterations) {
893 0 : WhileLoopExitCounter = 0;
894 0 : ReturnValue.Type = Value::Error;
895 0 : ReturnValue.Error = "Maximum WHILE loop iteration limit reached";
896 0 : WriteTrace(state, StackNum, InstructionNum, ReturnValue, seriousErrorFound);
897 : } else {
898 10175 : ReturnValue.Type = Value::Number;
899 10175 : ReturnValue.Number = 0.0;
900 10175 : WriteTrace(state, StackNum, InstructionNum, ReturnValue, seriousErrorFound);
901 10175 : WhileLoopExitCounter = 0;
902 : }
903 : }
904 : } else {
905 0 : ShowFatalError(state, "Fatal error in RunStack: Unknown keyword.");
906 : }
907 : }
908 :
909 23018927 : ++InstructionNum;
910 : } // InstructionNum
911 :
912 3035801 : return ReturnValue;
913 : }
914 :
915 26868447 : void WriteTrace(EnergyPlusData &state, int const StackNum, int const InstructionNum, ErlValueType const &ReturnValue, bool const seriousErrorFound)
916 : {
917 :
918 : // SUBROUTINE INFORMATION:
919 : // AUTHOR Peter Graham Ellis
920 : // DATE WRITTEN June 2006
921 : // MODIFIED Brent Griffith, May 2009
922 : // Brent Griffith, May 2016, added bool and fatal error messages for runtime problems with math and unitialized vars
923 : // RE-ENGINEERED na
924 :
925 : // PURPOSE OF THIS SUBROUTINE:
926 :
927 : // METHODOLOGY EMPLOYED:
928 :
929 : // Using/Aliasing
930 : using General::CreateSysTimeIntervalString;
931 :
932 : // Locals
933 : // SUBROUTINE ARGUMENT DEFINITIONS:
934 :
935 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
936 : int LineNum;
937 28781250 : std::string NameString;
938 28781250 : std::string LineNumString;
939 28781250 : std::string LineString;
940 28781250 : std::string cValueString;
941 28781250 : std::string TimeString;
942 28781250 : std::string DuringWarmup;
943 :
944 26868447 : if ((!state.dataRuntimeLang->OutputFullEMSTrace) && (!state.dataRuntimeLang->OutputEMSErrors) && (!seriousErrorFound)) return;
945 :
946 17550416 : if ((state.dataRuntimeLang->OutputEMSErrors) && (!state.dataRuntimeLang->OutputFullEMSTrace) && (!seriousErrorFound)) {
947 : // see if error needs to be reported.
948 15637902 : if (ReturnValue.Type != Value::Error) return;
949 : }
950 :
951 1912803 : if (!state.dataRuntimeLangProcessor->WriteTraceMyOneTimeFlag) {
952 25 : print(state.files.edd, "**** Begin EMS Language Processor Error and Trace Output *** \n");
953 25 : print(state.files.edd, "<Erl program name, line #, line text, result, occurrence timing information ... >\n");
954 25 : state.dataRuntimeLangProcessor->WriteTraceMyOneTimeFlag = true;
955 : }
956 : // if have not return'd yet then write out full trace
957 :
958 1912803 : NameString = state.dataRuntimeLang->ErlStack(StackNum).Name;
959 1912803 : LineNum = state.dataRuntimeLang->ErlStack(StackNum).Instruction(InstructionNum).LineNum;
960 1912803 : LineNumString = fmt::to_string(LineNum);
961 1912803 : LineString = state.dataRuntimeLang->ErlStack(StackNum).Line(LineNum);
962 1912803 : cValueString = ValueToString(ReturnValue);
963 :
964 : // put together timestamp info
965 1912803 : if (state.dataGlobal->WarmupFlag) {
966 1686745 : if (!state.dataGlobal->DoingSizing) {
967 1623067 : DuringWarmup = " During Warmup, Occurrence info=";
968 : } else {
969 63678 : DuringWarmup = " During Warmup & Sizing, Occurrence info=";
970 : }
971 : } else {
972 226058 : if (!state.dataGlobal->DoingSizing) {
973 215538 : DuringWarmup = " Occurrence info=";
974 : } else {
975 10520 : DuringWarmup = " During Sizing, Occurrence info=";
976 : }
977 : }
978 1912803 : TimeString = DuringWarmup + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' + CreateSysTimeIntervalString(state);
979 :
980 1912803 : if (state.dataRuntimeLang->OutputFullEMSTrace || (state.dataRuntimeLang->OutputEMSErrors && (ReturnValue.Type == Value::Error))) {
981 1912803 : print(state.files.edd, "{},Line {},{},{},{}\n", NameString, LineNumString, LineString, cValueString, TimeString);
982 : }
983 :
984 1912803 : if (seriousErrorFound) { // throw EnergyPlus severe then fatal
985 0 : ShowSevereError(state, "Problem found in EMS EnergyPlus Runtime Language.");
986 0 : ShowContinueError(state, "Erl program name: " + NameString);
987 0 : ShowContinueError(state, "Erl program line number: " + LineNumString);
988 0 : ShowContinueError(state, "Erl program line text: " + LineString);
989 0 : ShowContinueError(state, "Error message: " + cValueString);
990 0 : ShowContinueErrorTimeStamp(state, "");
991 0 : ShowFatalError(state, "Previous EMS error caused program termination.");
992 : }
993 : }
994 :
995 : //******************************************************************************************
996 :
997 : // Expression Processor
998 :
999 : //******************************************************************************************
1000 :
1001 7090 : void ParseExpression(EnergyPlusData &state,
1002 : std::string const &InString, // String of expression text written in the Runtime Language
1003 : int const StackNum, // Parent StackNum??
1004 : int &ExpressionNum, // index of expression in structure
1005 : std::string const &Line // Actual line from string
1006 : )
1007 : {
1008 :
1009 : // SUBROUTINE INFORMATION:
1010 : // AUTHOR Peter Graham Ellis
1011 : // DATE WRITTEN June 2006
1012 : // MODIFIED Brent Griffith, May 2009
1013 : // RE-ENGINEERED na
1014 :
1015 : // PURPOSE OF THIS SUBROUTINE:
1016 : // Parsing string into a series of tokens
1017 :
1018 : // METHODOLOGY EMPLOYED:
1019 :
1020 : // Using/Aliasing
1021 :
1022 : // Locals
1023 : // SUBROUTINE PARAMETER DEFINITIONS:
1024 7090 : int constexpr MaxDoLoopCounts(500);
1025 :
1026 : // SUBROUTINE ARGUMENT DEFINITIONS:
1027 :
1028 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1029 : // CHARACTER(len=120), DIMENSION(MaxErrors) :: Error ! Errors should be stored with the stack
1030 : int NumErrors;
1031 : std::string::size_type Pos;
1032 14180 : std::string StringToken;
1033 : char NextChar;
1034 : bool PeriodFound;
1035 : bool MinusFound;
1036 : bool PlusFound;
1037 : bool MultFound;
1038 : bool DivFound;
1039 : bool ErrorFlag;
1040 : bool OperatorProcessing;
1041 : int CountDoLooping;
1042 : bool LastED; // last character in a numeric was an E or D
1043 :
1044 7090 : CountDoLooping = 0;
1045 7090 : NumErrors = 0;
1046 : // Error = 'No errors.'
1047 :
1048 : // Break the string into tokens
1049 7090 : int NumTokens(0);
1050 14180 : std::string String(InString);
1051 :
1052 : // Following is a workaround to parse unitary operators as first value in the expression.
1053 : // i.e. Set X = -1
1054 : // this creates Set X = 0-1
1055 : // and seems to work.
1056 :
1057 7090 : assert(!String.empty());
1058 7090 : if (String[0] == '-') {
1059 18 : String = "0" + String;
1060 7072 : } else if (String[0] == '+') {
1061 0 : String = "0" + String;
1062 : }
1063 7090 : std::string::size_type LastPos(String.length());
1064 7090 : Pos = 0;
1065 7090 : OperatorProcessing = false; // true when an operator is found until terminated by non-operator
1066 7090 : MinusFound = false;
1067 7090 : MultFound = false;
1068 7090 : DivFound = false;
1069 96724 : while (Pos < LastPos) {
1070 44817 : ++CountDoLooping;
1071 44817 : if (CountDoLooping > MaxDoLoopCounts) {
1072 0 : ShowSevereError(state, "EMS ParseExpression: Entity=" + state.dataRuntimeLang->ErlStack(StackNum).Name);
1073 0 : ShowContinueError(state, "...Line=" + Line);
1074 0 : ShowContinueError(state, "...Failed to process String=\"" + String + "\".");
1075 0 : ShowFatalError(state, "...program terminates due to preceding condition.");
1076 : }
1077 44817 : NextChar = String[Pos];
1078 59320 : if (NextChar == ' ') {
1079 14503 : ++Pos;
1080 14503 : continue;
1081 : }
1082 :
1083 : // Extend the token array
1084 30314 : state.dataRuntimeLangProcessor->PEToken.redimension(++NumTokens);
1085 :
1086 : // Get the next token
1087 30314 : StringToken = "";
1088 30314 : PeriodFound = false;
1089 30314 : PlusFound = false;
1090 30314 : ErrorFlag = false;
1091 30314 : LastED = false;
1092 30314 : if (is_any_of(NextChar, "0123456789.")) {
1093 : // Parse a number literal token
1094 5904 : ++Pos;
1095 5904 : StringToken += NextChar;
1096 5904 : OperatorProcessing = false;
1097 5904 : MultFound = false;
1098 5904 : DivFound = false;
1099 :
1100 5904 : if (NextChar == '.') PeriodFound = true;
1101 :
1102 26512 : while (Pos < LastPos) {
1103 13555 : NextChar = String[Pos];
1104 13555 : if (is_any_of(NextChar, "0123456789.eEdD")) {
1105 10302 : ++Pos;
1106 10302 : if (NextChar == '.') {
1107 2501 : if (PeriodFound) {
1108 : // ERROR: two periods appearing in a number literal!
1109 0 : ShowSevereError(state, "EMS Parse Expression, for \"" + state.dataRuntimeLang->ErlStack(StackNum).Name + "\".");
1110 0 : ShowContinueError(state, "...Line=\"" + Line + "\".");
1111 0 : ShowContinueError(state, "...Bad String=\"" + String + "\".");
1112 0 : ShowContinueError(state, "...Two decimal points detected in String.");
1113 0 : ++NumErrors;
1114 0 : ErrorFlag = true;
1115 0 : break;
1116 : } else {
1117 2501 : PeriodFound = true;
1118 : }
1119 : }
1120 10302 : if (is_any_of(NextChar, "eEdD")) {
1121 29 : StringToken += NextChar;
1122 29 : if (LastED) {
1123 0 : ShowSevereError(state, "EMS Parse Expression, for \"" + state.dataRuntimeLang->ErlStack(StackNum).Name + "\".");
1124 0 : ShowContinueError(state, "...Line=\"" + Line + "\".");
1125 0 : ShowContinueError(state, "...Bad String=\"" + String + "\".");
1126 0 : ShowContinueError(state, "...Two D/E in numeric String.");
1127 0 : ++NumErrors;
1128 0 : ErrorFlag = true;
1129 : // error
1130 0 : break;
1131 : } else {
1132 29 : LastED = true;
1133 : }
1134 : } else {
1135 10273 : StringToken += NextChar;
1136 : }
1137 3253 : } else if (is_any_of(NextChar, "+-")) { // +/- following an ED is okay.
1138 215 : if (LastED) {
1139 2 : StringToken += NextChar;
1140 2 : ++Pos;
1141 2 : LastED = false;
1142 : } else {
1143 : // +/- will be processed on next pass, nothing needs to be done after a numeral
1144 213 : break;
1145 : }
1146 3038 : } else if (is_any_of(NextChar, " +-*/^=<>)")) { // Any binary operator is okay
1147 3038 : break; // End of token
1148 : } else {
1149 : // Error: strange sequence of characters: return TokenString//NextChar e.g., 234.44a or 234.44%
1150 0 : StringToken += NextChar;
1151 0 : break;
1152 : }
1153 : }
1154 :
1155 : // Save the number token
1156 5904 : if (!ErrorFlag) {
1157 5904 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Type = Token::Number;
1158 5904 : state.dataRuntimeLangProcessor->PEToken(NumTokens).String = StringToken;
1159 5904 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "Number=\"{}\"\n", StringToken);
1160 5904 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Number = UtilityRoutines::ProcessNumber(StringToken, ErrorFlag);
1161 5904 : if (state.dataSysVars->DeveloperFlag && ErrorFlag) print(state.files.debug, "{}\n", "Numeric error flagged");
1162 5904 : if (MinusFound) {
1163 0 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Number = -state.dataRuntimeLangProcessor->PEToken(NumTokens).Number;
1164 0 : MinusFound = false;
1165 : }
1166 5904 : if (ErrorFlag) {
1167 : // Error: something wrong with this number!
1168 0 : ShowSevereError(state, "EMS Parse Expression, for \"" + state.dataRuntimeLang->ErlStack(StackNum).Name + "\".");
1169 0 : ShowContinueError(state, "...Line=\"" + Line + "\".");
1170 0 : ShowContinueError(state, "...Bad String=\"" + String + "\".");
1171 0 : ShowContinueError(state, "Invalid numeric=\"" + StringToken + "\".");
1172 0 : ++NumErrors;
1173 : }
1174 : }
1175 :
1176 24410 : } else if (is_any_of(NextChar, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")) {
1177 : // Parse an undetermined string token (could be a variable, subroutine, or named operator)
1178 10134 : ++Pos;
1179 10134 : StringToken += NextChar;
1180 10134 : OperatorProcessing = false;
1181 10134 : MultFound = false;
1182 10134 : DivFound = false;
1183 :
1184 301100 : while (Pos < LastPos) {
1185 152810 : NextChar = String[Pos];
1186 152810 : if (is_any_of(NextChar, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789")) {
1187 145483 : ++Pos;
1188 145483 : StringToken += NextChar;
1189 7327 : } else if (is_any_of(NextChar, " +-*/^=<>()")) {
1190 7327 : break; // End of token
1191 : } else {
1192 : // Error: bad syntax: return TokenString//NextChar e.g., var1$ or b%
1193 0 : break;
1194 : }
1195 : }
1196 :
1197 : // Save the variable token
1198 10134 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Type = Token::Variable;
1199 10134 : state.dataRuntimeLangProcessor->PEToken(NumTokens).String = StringToken;
1200 10134 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "Variable=\"{}\"\n", StringToken);
1201 10134 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Variable = NewEMSVariable(state, StringToken, StackNum);
1202 :
1203 14276 : } else if (is_any_of(NextChar, "+-*/^=<>@|&")) {
1204 : // Parse an operator token
1205 8950 : if (NextChar == '-') {
1206 776 : StringToken = "-";
1207 776 : if (MultFound) {
1208 0 : ShowSevereError(state, "EMS Parse Expression, for \"" + state.dataRuntimeLang->ErlStack(StackNum).Name + "\".");
1209 0 : ShowContinueError(state, "...Line = \"" + Line + "\".");
1210 0 : ShowContinueError(state, "...Minus sign used on the right side of multiplication sign.");
1211 0 : ShowContinueError(state, "...Use parenthesis to wrap appropriate variables. For example, X * ( -Y ).");
1212 0 : ++NumErrors;
1213 0 : MultFound = false;
1214 776 : } else if (DivFound) {
1215 0 : ShowSevereError(state, "EMS Parse Expression, for \"" + state.dataRuntimeLang->ErlStack(StackNum).Name + "\".");
1216 0 : ShowContinueError(state, "...Line = \"" + Line + "\".");
1217 0 : ShowContinueError(state, "...Minus sign used on the right side of division sign.");
1218 0 : ShowContinueError(state, "...Use parenthesis to wrap appropriate variables. For example, X / ( -Y ).");
1219 0 : ++NumErrors;
1220 0 : DivFound = false;
1221 776 : } else if (OperatorProcessing && (NextChar == '-')) {
1222 : // if operator was deterined last pass and this character is a -, then insert a 0 before the minus and treat as subtraction
1223 : // example: change "Var == -1" to "Var == 0-1"
1224 0 : OperatorProcessing = false;
1225 0 : String.insert(Pos, "0");
1226 0 : ++LastPos;
1227 0 : StringToken = "0";
1228 0 : MultFound = false;
1229 0 : DivFound = false;
1230 : } else {
1231 776 : StringToken = NextChar;
1232 776 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Type = Token::Operator;
1233 : }
1234 : } else { // any other character process as operator
1235 8174 : StringToken = NextChar;
1236 8174 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Type = Token::Operator;
1237 : }
1238 :
1239 : // parse an operator if found,
1240 : // returns true and increments position, other wise returns false and leaves state untouched
1241 59319 : const auto parse = [&](const char *string, ErlFunc op, bool case_insensitive) {
1242 59319 : const auto len = strlen(string);
1243 124392 : const auto potential_match = String.substr(Pos, len);
1244 :
1245 59319 : if ((case_insensitive && UtilityRoutines::SameString(potential_match, string)) || (!case_insensitive && potential_match == string)) {
1246 8631 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "OPERATOR \"{}\"\n", potential_match);
1247 8631 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Operator = op;
1248 5754 : state.dataRuntimeLangProcessor->PEToken(NumTokens).String = potential_match;
1249 5754 : Pos += (len - 1);
1250 2877 : return true;
1251 : } else {
1252 56442 : return false;
1253 : }
1254 8950 : };
1255 :
1256 : // case insensitive wrapper call to parse
1257 19880 : const auto i_parse = [&](const char *string, const ErlFunc op) { return parse(string, op, true); };
1258 :
1259 : // First check for two character operators: == <> <= >= || &&
1260 17900 : std::string const cc(String.substr(Pos, 2));
1261 33960 : if (parse("==", ErlFunc::Equal, false) || parse("<>", ErlFunc::NotEqual, false) || parse("<=", ErlFunc::LessOrEqual, false) ||
1262 24365 : parse(">=", ErlFunc::GreaterOrEqual, false) || parse("||", ErlFunc::LogicalOR, false) || parse("&&", ErlFunc::LogicalAND, false)) {
1263 : // One of the comparision / logical operators
1264 2295 : OperatorProcessing = true;
1265 :
1266 6655 : } else if (String[Pos] == '@') { // next check for builtin functions signaled by "@"
1267 :
1268 2322 : if (i_parse("@Round", ErlFunc::Round) || i_parse("@Mod", ErlFunc::Mod) || i_parse("@Sin", ErlFunc::Sin) ||
1269 1728 : i_parse("@Cos", ErlFunc::Cos) || i_parse("@ArcCos", ErlFunc::ArcCos) || i_parse("@ArcSin", ErlFunc::ArcSin) ||
1270 1706 : i_parse("@DegToRad", ErlFunc::DegToRad) || i_parse("@RadToDeg", ErlFunc::RadToDeg) || i_parse("@Exp", ErlFunc::Exp) ||
1271 1322 : i_parse("@Ln", ErlFunc::Ln) || i_parse("@Max", ErlFunc::Max) || i_parse("@Min", ErlFunc::Min) || i_parse("@Abs", ErlFunc::ABS) ||
1272 603 : i_parse("@RANDOMUNIFORM", ErlFunc::RandU) || i_parse("@RANDOMNORMAL", ErlFunc::RandG) ||
1273 589 : i_parse("@SEEDRANDOM", ErlFunc::RandSeed) || i_parse("@RhoAirFnPbTdbW", ErlFunc::RhoAirFnPbTdbW) ||
1274 540 : i_parse("@CpAirFnW", ErlFunc::CpAirFnW) || i_parse("@HfgAirFnWTdb", ErlFunc::HfgAirFnWTdb) ||
1275 516 : i_parse("@HgAirFnWTdb", ErlFunc::HgAirFnWTdb) || i_parse("@TdpFnTdbTwbPb", ErlFunc::TdpFnTdbTwbPb) ||
1276 466 : i_parse("@TdpFnWPb", ErlFunc::TdpFnWPb) || i_parse("@HFnTdbW", ErlFunc::HFnTdbW) || i_parse("@HFnTdbRhPb", ErlFunc::HFnTdbRhPb) ||
1277 342 : i_parse("@TdbFnHW", ErlFunc::TdbFnHW) || i_parse("@RhovFnTdbRhLBnd0C", ErlFunc::RhovFnTdbRhLBnd0C) ||
1278 318 : i_parse("@RhovFnTdbRh", ErlFunc::RhovFnTdbRh) || i_parse("@RhovFnTdbWPb", ErlFunc::RhovFnTdbWPb) ||
1279 312 : i_parse("@RhFnTdbRhovLBnd0C", ErlFunc::RhFnTdbRhovLBnd0C) || i_parse("@RhFnTdbRhov", ErlFunc::RhFnTdbRhov) ||
1280 301 : i_parse("@RhFnTdbWPb", ErlFunc::RhFnTdbWPb) || i_parse("@TwbFnTdbWPb", ErlFunc::TwbFnTdbWPb) ||
1281 283 : i_parse("@VFnTdbWPb", ErlFunc::VFnTdbWPb) || i_parse("@WFnTdpPb", ErlFunc::WFnTdpPb) || i_parse("@WFnTdbH", ErlFunc::WFnTdbH) ||
1282 261 : i_parse("@WFnTdbTwbPb", ErlFunc::WFnTdbTwbPb) || i_parse("@WFnTdbRhPb", ErlFunc::WFnTdbRhPb) ||
1283 239 : i_parse("@PsatFnTemp", ErlFunc::PsatFnTemp) || i_parse("@TsatFnHPb", ErlFunc::TsatFnHPb) ||
1284 209 : i_parse("@TsatFnPb", ErlFunc::TsatFnPb) || i_parse("@CpCW", ErlFunc::CpCW) || i_parse("@CpHW", ErlFunc::CpHW) ||
1285 133 : i_parse("@RhoH2O", ErlFunc::RhoH2O) || i_parse("@FATALHALTEP", ErlFunc::FatalHaltEp) ||
1286 109 : i_parse("@SEVEREWARNEP", ErlFunc::SevereWarnEp) || i_parse("@WARNEP", ErlFunc::WarnEp) ||
1287 90 : i_parse("@TRENDVALUE", ErlFunc::TrendValue) || i_parse("@TRENDAVERAGE", ErlFunc::TrendAverage) ||
1288 72 : i_parse("@TRENDMAX", ErlFunc::TrendMax) || i_parse("@TRENDMIN", ErlFunc::TrendMin) ||
1289 59 : i_parse("@TRENDDIRECTION", ErlFunc::TrendDirection) || i_parse("@TRENDSUM", ErlFunc::TrendSum) ||
1290 17 : i_parse("@CURVEVALUE", ErlFunc::CurveValue) || i_parse("@TODAYISRAIN", ErlFunc::TodayIsRain) ||
1291 0 : i_parse("@TODAYISSNOW", ErlFunc::TodayIsSnow) || i_parse("@TODAYOUTDRYBULBTEMP", ErlFunc::TodayOutDryBulbTemp) ||
1292 0 : i_parse("@TODAYOUTDEWPOINTTEMP", ErlFunc::TodayOutDewPointTemp) || i_parse("@TODAYOUTBAROPRESS", ErlFunc::TodayOutBaroPress) ||
1293 0 : i_parse("@TODAYOUTRELHUM", ErlFunc::TodayOutRelHum) || i_parse("@TODAYWINDSPEED", ErlFunc::TodayWindSpeed) ||
1294 0 : i_parse("@TODAYWINDDIR", ErlFunc::TodayWindDir) || i_parse("@TODAYSKYTEMP", ErlFunc::TodaySkyTemp) ||
1295 0 : i_parse("@TODAYHORIZIRSKY", ErlFunc::TodayHorizIRSky) || i_parse("@TODAYBEAMSOLARRAD", ErlFunc::TodayBeamSolarRad) ||
1296 0 : i_parse("@TODAYDIFSOLARRAD", ErlFunc::TodayDifSolarRad) || i_parse("@TODAYALBEDO", ErlFunc::TodayAlbedo) ||
1297 0 : i_parse("@TODAYLIQUIDPRECIP", ErlFunc::TodayLiquidPrecip) || i_parse("@TOMORROWISRAIN", ErlFunc::TomorrowIsRain) ||
1298 0 : i_parse("@TOMORROWISSNOW", ErlFunc::TomorrowIsSnow) || i_parse("@TOMORROWOUTDRYBULBTEMP", ErlFunc::TomorrowOutDryBulbTemp) ||
1299 0 : i_parse("@TOMORROWOUTDEWPOINTTEMP", ErlFunc::TomorrowOutDewPointTemp) ||
1300 0 : i_parse("@TOMORROWOUTBAROPRESS", ErlFunc::TomorrowOutBaroPress) || i_parse("@TOMORROWOUTRELHUM", ErlFunc::TomorrowOutRelHum) ||
1301 0 : i_parse("@TOMORROWWINDSPEED", ErlFunc::TomorrowWindSpeed) || i_parse("@TOMORROWWINDDIR", ErlFunc::TomorrowWindDir) ||
1302 0 : i_parse("@TOMORROWSKYTEMP", ErlFunc::TomorrowSkyTemp) || i_parse("@TOMORROWHORIZIRSKY", ErlFunc::TomorrowHorizIRSky) ||
1303 0 : i_parse("@TOMORROWBEAMSOLARRAD", ErlFunc::TomorrowBeamSolarRad) ||
1304 582 : i_parse("@TOMORROWDIFSOLARRAD", ErlFunc::TomorrowDifSolarRad) || i_parse("@TOMORROWALBEDO", ErlFunc::TomorrowAlbedo) ||
1305 0 : i_parse("@TOMORROWLIQUIDPRECIP", ErlFunc::TomorrowLiquidPrecip)) {
1306 : // was a built in function operator
1307 : } else { // throw error
1308 0 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "ERROR \"{}\"\n", String);
1309 0 : ShowFatalError(state, "EMS Runtime Language: did not find valid input for built-in function =" + String);
1310 : }
1311 : } else {
1312 : // Check for remaining single character operators
1313 6073 : state.dataRuntimeLangProcessor->PEToken(NumTokens).String = StringToken;
1314 6073 : MultFound = false;
1315 6073 : DivFound = false;
1316 :
1317 6073 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "OPERATOR \"{}\"\n", StringToken);
1318 :
1319 6073 : if (StringToken == "+") {
1320 1638 : if (!OperatorProcessing) {
1321 1638 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Operator = ErlFunc::Add;
1322 1638 : OperatorProcessing = true;
1323 : } else {
1324 0 : PlusFound = true;
1325 0 : OperatorProcessing = false;
1326 : }
1327 4435 : } else if (StringToken == "-") {
1328 776 : if (!OperatorProcessing) {
1329 776 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Operator = ErlFunc::Subtract;
1330 776 : OperatorProcessing = true;
1331 : } else {
1332 0 : MinusFound = true;
1333 0 : OperatorProcessing = false;
1334 : }
1335 3659 : } else if (StringToken == "*") {
1336 1622 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Operator = ErlFunc::Multiply;
1337 1622 : MultFound = true;
1338 1622 : OperatorProcessing = true;
1339 2037 : } else if (StringToken == "/") {
1340 829 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Operator = ErlFunc::Divide;
1341 829 : DivFound = true;
1342 829 : OperatorProcessing = true;
1343 1208 : } else if (StringToken == "<") {
1344 151 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Operator = ErlFunc::LessThan;
1345 151 : OperatorProcessing = true;
1346 1057 : } else if (StringToken == ">") {
1347 897 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Operator = ErlFunc::GreaterThan;
1348 897 : OperatorProcessing = true;
1349 160 : } else if (StringToken == "^") {
1350 160 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Operator = ErlFunc::RaiseToPower;
1351 160 : OperatorProcessing = true;
1352 0 : } else if (StringToken == "0" && (NextChar == '-')) {
1353 : // process string insert = "0"
1354 0 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Type = Token::Number;
1355 0 : state.dataRuntimeLangProcessor->PEToken(NumTokens).String = StringToken;
1356 : } else {
1357 : // Uh OH, this should never happen! throw error
1358 0 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "ERROR \"{}\"\n", StringToken);
1359 0 : ShowFatalError(state, "EMS, caught unexpected token = \"" + StringToken + "\" ; while parsing string=" + String);
1360 : }
1361 : }
1362 :
1363 8950 : ++Pos;
1364 :
1365 5326 : } else if (is_any_of(NextChar, "()")) {
1366 : // Parse a parenthesis token
1367 5326 : ++Pos;
1368 5326 : StringToken = NextChar;
1369 5326 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "PAREN \"{}\"\n", StringToken);
1370 5326 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Type = Token::Parenthesis;
1371 5326 : state.dataRuntimeLangProcessor->PEToken(NumTokens).String = StringToken;
1372 5326 : if (NextChar == '(') {
1373 2663 : state.dataRuntimeLangProcessor->PEToken(NumTokens).Parenthesis = Token::ParenthesisLeft;
1374 2663 : OperatorProcessing = true;
1375 : }
1376 5326 : if (NextChar == ')') state.dataRuntimeLangProcessor->PEToken(NumTokens).Parenthesis = Token::ParenthesisRight;
1377 :
1378 0 : } else if (is_any_of(NextChar, "\"")) {
1379 : // Parse a string literal token
1380 0 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "{}\n", "LITERAL STRING");
1381 0 : ++Pos;
1382 :
1383 : } else {
1384 : // Error: bad start to the token
1385 : }
1386 : }
1387 :
1388 7090 : if (NumErrors > 0) {
1389 0 : if (state.dataSysVars->DeveloperFlag) print(state.files.debug, "{}\n", "ERROR OUT");
1390 0 : ShowFatalError(state, "EMS, previous errors cause termination.");
1391 : }
1392 :
1393 7090 : ExpressionNum = ProcessTokens(state, state.dataRuntimeLangProcessor->PEToken, NumTokens, StackNum, String);
1394 7090 : }
1395 :
1396 9753 : int ProcessTokens(
1397 : EnergyPlusData &state, const Array1D<TokenType> &TokenIN, int const NumTokensIN, int const StackNum, std::string const &ParsingString)
1398 : {
1399 :
1400 : // SUBROUTINE INFORMATION:
1401 : // AUTHOR Peter Graham Ellis
1402 : // DATE WRITTEN June 2006
1403 : // MODIFIED na
1404 : // RE-ENGINEERED na
1405 :
1406 : // PURPOSE OF THIS SUBROUTINE:
1407 : // Processes tokens into expressions.
1408 :
1409 : // METHODOLOGY EMPLOYED:
1410 : // Uses recursion to handle tokens with compound expressions
1411 :
1412 : // Return value
1413 : int ExpressionNum;
1414 :
1415 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1416 : int Pos;
1417 : int LastPos;
1418 : int TokenNum;
1419 : int NumTokens;
1420 : int Depth;
1421 : int NumSubTokens;
1422 : int NewNumTokens;
1423 : int OperatorNum;
1424 : int NumOperands;
1425 : int ParenthWhileCounter; // used to trap for unbalanced parentheses
1426 :
1427 : // Object Data
1428 19506 : Array1D<TokenType> Token(TokenIN);
1429 19506 : Array1D<TokenType> SubTokenList;
1430 :
1431 9753 : ExpressionNum = 0;
1432 9753 : NumTokens = NumTokensIN;
1433 :
1434 : // Process parentheses
1435 9753 : Pos = 0;
1436 33424 : for (TokenNum = 1; TokenNum <= NumTokens; ++TokenNum) {
1437 25935 : if (Token(TokenNum).Type == Token::Parenthesis) {
1438 2264 : Pos = TokenNum;
1439 2264 : break;
1440 : }
1441 : }
1442 :
1443 9753 : ParenthWhileCounter = 0;
1444 :
1445 15079 : while ((Pos > 0) && (ParenthWhileCounter < 50)) {
1446 2663 : ++ParenthWhileCounter;
1447 2663 : Depth = 0;
1448 19923 : for (TokenNum = 1; TokenNum <= NumTokens; ++TokenNum) {
1449 19923 : if (Token(TokenNum).Type == Token::Parenthesis) {
1450 5956 : if (Token(TokenNum).Parenthesis == Token::ParenthesisLeft) {
1451 2978 : if (Depth == 0) Pos = TokenNum; // Record position of first left parenthesis
1452 2978 : ++Depth;
1453 : }
1454 5956 : if (Token(TokenNum).Parenthesis == Token::ParenthesisRight) {
1455 2978 : --Depth;
1456 2978 : if (Depth == 0) {
1457 2663 : LastPos = TokenNum;
1458 2663 : NumSubTokens = LastPos - Pos - 1;
1459 2663 : SubTokenList.allocate(NumSubTokens);
1460 2663 : SubTokenList({1, NumSubTokens}) = Token({Pos + 1, LastPos - 1}); // Need to check that these don't exceed bounds
1461 2663 : ExpressionNum = ProcessTokens(state, SubTokenList, NumSubTokens, StackNum, ParsingString);
1462 2663 : SubTokenList.deallocate();
1463 :
1464 : // Replace the parenthetical tokens with one expression token
1465 2663 : NewNumTokens = NumTokens - NumSubTokens - 1;
1466 2663 : if (NewNumTokens > 0) {
1467 2663 : if (LastPos + 1 <= NumTokens) {
1468 938 : Token({Pos + 1, NewNumTokens}) = Token({LastPos + 1, _});
1469 : }
1470 2663 : Token.redimension(NewNumTokens);
1471 2663 : Token(Pos).Type = Token::Expression;
1472 2663 : Token(Pos).Expression = ExpressionNum;
1473 2663 : Token(Pos).String = "Expr";
1474 2663 : NumTokens = NewNumTokens;
1475 : }
1476 :
1477 : // Reset loop for next parenthetical set
1478 2663 : break;
1479 : }
1480 : }
1481 : }
1482 : }
1483 :
1484 : // This repeats code again... Just checks to see if there are any more parentheses to be found
1485 2663 : Pos = 0;
1486 9826 : for (TokenNum = 1; TokenNum <= NumTokens; ++TokenNum) {
1487 7562 : if (Token(TokenNum).Type == Token::Parenthesis) {
1488 399 : Pos = TokenNum;
1489 399 : break;
1490 : }
1491 : }
1492 : }
1493 :
1494 9753 : if (ParenthWhileCounter == 50) { // symptom of mismatched parenthesis
1495 0 : ShowSevereError(state, "EMS error parsing parentheses, check that parentheses are balanced");
1496 0 : ShowContinueError(state, "String being parsed=\"" + ParsingString + "\".");
1497 0 : ShowFatalError(state, "Program terminates due to preceding error.");
1498 : }
1499 :
1500 9753 : SetupPossibleOperators(state); // includes built-in functions
1501 :
1502 : // Process operators and builtin functions
1503 : // Loop thru all operators and group expressions in the order of precedence
1504 946041 : for (OperatorNum = 1; OperatorNum <= NumPossibleOperators; ++OperatorNum) {
1505 :
1506 : // Find the next occurrence of the operator
1507 936288 : Pos = 0; // position in sequence of tokens
1508 2086092 : for (TokenNum = 1; TokenNum <= NumTokens; ++TokenNum) {
1509 1157747 : if ((Token(TokenNum).Type == Token::Operator) && (Token(TokenNum).Operator == static_cast<ErlFunc>(OperatorNum))) {
1510 7943 : Pos = TokenNum;
1511 7943 : break;
1512 : }
1513 : }
1514 :
1515 953024 : while (Pos > 0) {
1516 8950 : if (Pos == 1) {
1517 : // if first token is for a built-in function starting with "@" then okay, otherwise the operator needs a LHS
1518 582 : if (static_cast<int>(Token(TokenNum).Operator) > static_cast<int>(ErlFunc::LogicalOR)) { // we have a function expression to set up
1519 582 : ExpressionNum = NewExpression(state);
1520 582 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operator = static_cast<ErlFunc>(OperatorNum);
1521 582 : NumOperands = state.dataRuntimeLang->PossibleOperators(OperatorNum).NumOperands;
1522 582 : state.dataRuntimeLang->ErlExpression(ExpressionNum).NumOperands = NumOperands;
1523 582 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand.allocate(NumOperands);
1524 :
1525 582 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Type = static_cast<Value>(static_cast<int>(Token(Pos + 1).Type));
1526 582 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Number = Token(Pos + 1).Number;
1527 582 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Expression = Token(Pos + 1).Expression;
1528 582 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Variable = Token(Pos + 1).Variable;
1529 582 : if (Token(Pos + 1).Variable > 0) {
1530 311 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).TrendVariable =
1531 311 : state.dataRuntimeLang->ErlVariable(Token(Pos + 1).Variable).Value.TrendVariable;
1532 311 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).TrendVarPointer =
1533 311 : state.dataRuntimeLang->ErlVariable(Token(Pos + 1).Variable).Value.TrendVarPointer;
1534 : }
1535 582 : if ((NumOperands >= 2) && (NumTokens >= 3)) {
1536 483 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(2).Type =
1537 483 : static_cast<Value>(static_cast<int>(Token(Pos + 2).Type));
1538 483 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(2).Number = Token(Pos + 2).Number;
1539 483 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(2).Expression = Token(Pos + 2).Expression;
1540 483 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(2).Variable = Token(Pos + 2).Variable;
1541 : }
1542 :
1543 582 : if ((NumOperands >= 3) && (NumTokens >= 4)) {
1544 43 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(3).Type =
1545 43 : static_cast<Value>(static_cast<int>(Token(Pos + 3).Type));
1546 43 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(3).Number = Token(Pos + 3).Number;
1547 43 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(3).Expression = Token(Pos + 3).Expression;
1548 43 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(3).Variable = Token(Pos + 3).Variable;
1549 43 : if ((NumOperands == 3) && (NumTokens - 4 > 0)) { // too many tokens for this non-binary operator
1550 0 : ShowFatalError(state, "EMS error parsing tokens, too many for built-in function");
1551 : }
1552 : }
1553 :
1554 582 : if ((NumOperands >= 4) && (NumTokens >= 5)) {
1555 19 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(4).Type =
1556 19 : static_cast<Value>(static_cast<int>(Token(Pos + 4).Type));
1557 19 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(4).Number = Token(Pos + 4).Number;
1558 19 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(4).Expression = Token(Pos + 4).Expression;
1559 19 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(4).Variable = Token(Pos + 4).Variable;
1560 19 : if ((NumOperands == 4) && (NumTokens - 5 > 0)) { // too many tokens for this non-binary operator
1561 0 : ShowFatalError(state, "EMS error parsing tokens, too many for built-in function");
1562 : }
1563 : }
1564 :
1565 582 : if ((NumOperands == 5) && (NumTokens >= 6)) {
1566 0 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(5).Type =
1567 0 : static_cast<Value>(static_cast<int>(Token(Pos + 5).Type));
1568 0 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(5).Number = Token(Pos + 5).Number;
1569 0 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(5).Expression = Token(Pos + 5).Expression;
1570 0 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(5).Variable = Token(Pos + 5).Variable;
1571 0 : if ((NumOperands == 5) && (NumTokens - 6 > 0)) { // too many tokens for this non-binary operator
1572 0 : ShowFatalError(state, "EMS error parsing tokens, too many for built-in function");
1573 : }
1574 : }
1575 582 : break;
1576 : } else {
1577 0 : ShowSevereError(state,
1578 0 : "The operator \"" + state.dataRuntimeLang->PossibleOperators(OperatorNum).Symbol +
1579 : "\" is missing the left-hand operand!");
1580 0 : ShowContinueError(state, "String being parsed=\"" + ParsingString + "\".");
1581 0 : break;
1582 : }
1583 8368 : } else if (Pos == NumTokens) {
1584 0 : ShowSevereError(state,
1585 0 : "The operator \"" + state.dataRuntimeLang->PossibleOperators(OperatorNum).Symbol +
1586 : "\" is missing the right-hand operand!");
1587 0 : ShowContinueError(state, "String being parsed=\"" + ParsingString + "\".");
1588 0 : break;
1589 : } else {
1590 :
1591 8368 : ExpressionNum = NewExpression(state);
1592 8368 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operator = static_cast<ErlFunc>(OperatorNum);
1593 8368 : NumOperands = state.dataRuntimeLang->PossibleOperators(OperatorNum).NumOperands;
1594 8368 : state.dataRuntimeLang->ErlExpression(ExpressionNum).NumOperands = NumOperands;
1595 8368 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand.allocate(NumOperands);
1596 :
1597 : // PE commment: Need a right-hand and left-hand check for these, not just number of operators
1598 : // Unification of TYPEs would turn these into one-liners
1599 :
1600 8368 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Type = static_cast<Value>(static_cast<int>(Token(Pos - 1).Type));
1601 8368 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Number = Token(Pos - 1).Number;
1602 8368 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Expression = Token(Pos - 1).Expression;
1603 8368 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Variable = Token(Pos - 1).Variable;
1604 :
1605 8368 : if (NumOperands >= 2) {
1606 8368 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(2).Type = static_cast<Value>(static_cast<int>(Token(Pos + 1).Type));
1607 8368 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(2).Number = Token(Pos + 1).Number;
1608 8368 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(2).Expression = Token(Pos + 1).Expression;
1609 8368 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(2).Variable = Token(Pos + 1).Variable;
1610 : }
1611 :
1612 : // Replace the three tokens with one expression token
1613 8368 : if ((NumOperands == 2) && (NumTokens - 2 > 0)) {
1614 8368 : if (Pos + 2 <= NumTokens) {
1615 1384 : Token({Pos, NumTokens - 2}) = Token({Pos + 2, _});
1616 : }
1617 8368 : Token(Pos - 1).Type = Token::Expression;
1618 8368 : Token(Pos - 1).Expression = ExpressionNum;
1619 8368 : Token(Pos - 1).String = "Expr";
1620 8368 : NumTokens -= 2;
1621 8368 : Token.redimension(NumTokens);
1622 : }
1623 : }
1624 :
1625 : // Find the next occurrence of the operator (this repeats code, but don't have better idea)
1626 8368 : Pos = 0;
1627 23108 : for (TokenNum = 1; TokenNum <= NumTokens; ++TokenNum) {
1628 15747 : if ((Token(TokenNum).Type == Token::Operator) && (Token(TokenNum).Operator == static_cast<ErlFunc>(OperatorNum))) {
1629 1007 : Pos = TokenNum;
1630 1007 : break;
1631 : }
1632 : }
1633 : }
1634 : }
1635 :
1636 : // Should be down to just one token now
1637 9753 : if (Token(1).Type == Token::Number) {
1638 1341 : ExpressionNum = NewExpression(state);
1639 1341 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operator = ErlFunc::Literal;
1640 1341 : state.dataRuntimeLang->ErlExpression(ExpressionNum).NumOperands = 1;
1641 1341 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand.allocate(1);
1642 1341 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Type = static_cast<Value>(static_cast<int>(Token(1).Type));
1643 1341 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Number = Token(1).Number;
1644 8412 : } else if (Token(1).Type == Token::Variable) {
1645 1216 : ExpressionNum = NewExpression(state);
1646 1216 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operator = ErlFunc::Literal;
1647 1216 : state.dataRuntimeLang->ErlExpression(ExpressionNum).NumOperands = 1;
1648 1216 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand.allocate(1);
1649 1216 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Type = static_cast<Value>(static_cast<int>(Token(1).Type));
1650 1216 : state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(1).Variable = Token(1).Variable;
1651 : }
1652 :
1653 9753 : Token.deallocate();
1654 :
1655 19506 : return ExpressionNum;
1656 : }
1657 :
1658 11507 : int NewExpression(EnergyPlusData &state)
1659 : {
1660 :
1661 : // FUNCTION INFORMATION:
1662 : // AUTHOR Peter Graham Ellis
1663 : // DATE WRITTEN June 2006
1664 : // MODIFIED na
1665 : // RE-ENGINEERED na
1666 :
1667 : // PURPOSE OF THIS FUNCTION:
1668 : // Creates a new expression.
1669 :
1670 : // METHODOLOGY EMPLOYED:
1671 :
1672 : // Return value
1673 :
1674 : // Locals
1675 : // FUNCTION ARGUMENT DEFINITIONS:
1676 :
1677 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1678 :
1679 : // Object Data
1680 :
1681 11507 : if (state.dataRuntimeLang->NumExpressions == 0) {
1682 52 : state.dataRuntimeLang->ErlExpression.allocate(1);
1683 52 : state.dataRuntimeLang->NumExpressions = 1;
1684 : } else {
1685 11455 : state.dataRuntimeLang->ErlExpression.redimension(++state.dataRuntimeLang->NumExpressions);
1686 : }
1687 :
1688 11507 : return state.dataRuntimeLang->NumExpressions;
1689 : }
1690 :
1691 31735891 : ErlValueType EvaluateExpression(EnergyPlusData &state, int const ExpressionNum, bool &seriousErrorFound)
1692 : {
1693 :
1694 : // FUNCTION INFORMATION:
1695 : // AUTHOR Peter Graham Ellis
1696 : // DATE WRITTEN June 2006
1697 : // MODIFIED Brent Griffith, May 2009
1698 : // RE-ENGINEERED na
1699 :
1700 : // PURPOSE OF THIS FUNCTION:
1701 : // Evaluates an expression.
1702 :
1703 : // METHODOLOGY EMPLOYED:
1704 :
1705 : // USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY : IEEE_IS_NAN ! Use IEEE_IS_NAN when GFortran supports it
1706 : // Using/Aliasing
1707 : using namespace Psychrometrics;
1708 : using Curve::CurveValue;
1709 :
1710 : // Return value
1711 31735891 : ErlValueType ReturnValue;
1712 :
1713 : // Locals
1714 : // FUNCTION ARGUMENT DEFINITIONS:
1715 :
1716 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1717 : int thisTrend; // local temporary
1718 : int thisIndex; // local temporary
1719 : Real64 thisAverage; // local temporary
1720 : int loop; // local temporary
1721 : Real64 thisSlope; // local temporary
1722 : Real64 thisMax; // local temporary
1723 : Real64 thisMin; // local temporary
1724 : int OperandNum;
1725 : int SeedN; // number of digits in the number used to seed the generator
1726 63471782 : Array1D_int SeedIntARR; // local temporary for random seed
1727 : Real64 tmpRANDU1; // local temporary for uniform random number
1728 : Real64 tmpRANDU2; // local temporary for uniform random number
1729 : Real64 tmpRANDG; // local temporary for gaussian random number
1730 : Real64 UnitCircleTest; // local temporary for Box-Muller algo
1731 : Real64 TestValue; // local temporary
1732 :
1733 : // Object Data
1734 63471782 : Array1D<ErlValueType> Operand;
1735 :
1736 31735891 : auto constexpr EMSBuiltInFunction("EMS Built-In Function");
1737 :
1738 31735891 : ReturnValue.Type = Value::Number;
1739 31735891 : ReturnValue.Number = 0.0;
1740 :
1741 31735891 : if (ExpressionNum > 0) {
1742 : // is there a way to keep these and not allocate and deallocate all the time?
1743 31735891 : Operand.allocate(state.dataRuntimeLang->ErlExpression(ExpressionNum).NumOperands);
1744 : // Reduce operands down to literals
1745 85896527 : for (OperandNum = 1; OperandNum <= state.dataRuntimeLang->ErlExpression(ExpressionNum).NumOperands; ++OperandNum) {
1746 54160636 : Operand(OperandNum) = state.dataRuntimeLang->ErlExpression(ExpressionNum).Operand(OperandNum);
1747 54160636 : if (Operand(OperandNum).Type == Value::Expression) {
1748 9781723 : Operand(OperandNum) = EvaluateExpression(state, Operand(OperandNum).Expression, seriousErrorFound); // recursive call
1749 : // check if recursive call found an error in nested expression, want to preserve error message from that
1750 9781723 : if (seriousErrorFound) {
1751 0 : ReturnValue.Type = Value::Error;
1752 0 : ReturnValue.Error = Operand(OperandNum).Error;
1753 : }
1754 :
1755 44378913 : } else if (Operand(OperandNum).Type == Value::Variable) {
1756 32727267 : if (state.dataRuntimeLang->ErlVariable(Operand(OperandNum).Variable).Value.initialized) { // check that value has been initialized
1757 30976856 : Operand(OperandNum) = state.dataRuntimeLang->ErlVariable(Operand(OperandNum).Variable).Value;
1758 : } else { // value has never been set
1759 1750411 : ReturnValue.Type = Value::Error;
1760 3500822 : ReturnValue.Error = "EvaluateExpression: Variable = '" + state.dataRuntimeLang->ErlVariable(Operand(OperandNum).Variable).Name +
1761 1750411 : "' used in expression has not been initialized!";
1762 1750411 : if (!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation && !state.dataEMSMgr->FinishProcessingUserInput) {
1763 :
1764 : // check if this is an arg in CurveValue,
1765 0 : if (state.dataRuntimeLang->ErlExpression(ExpressionNum).Operator !=
1766 : ErlFunc::CurveValue) { // padding the argument list for CurveValue is too common to fatal on. only reported to EDD
1767 0 : seriousErrorFound = true;
1768 : }
1769 : }
1770 : }
1771 : }
1772 : }
1773 :
1774 31735891 : if (ReturnValue.Type != Value::Error) {
1775 :
1776 : // Perform the operation
1777 :
1778 30237990 : switch (state.dataRuntimeLang->ErlExpression(ExpressionNum).Operator) {
1779 :
1780 9458872 : case ErlFunc::Literal:
1781 9458872 : ReturnValue = Operand(1);
1782 9458872 : ReturnValue.initialized = true;
1783 9458872 : break;
1784 :
1785 0 : case ErlFunc::Negative: // unary minus sign. parsing does not work yet
1786 0 : ReturnValue = SetErlValueNumber(-1.0 * Operand(1).Number);
1787 0 : break;
1788 :
1789 1361365 : case ErlFunc::Divide:
1790 1361365 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1791 1361271 : if (Operand(2).Number == 0.0) {
1792 27 : ReturnValue.Type = Value::Error;
1793 27 : ReturnValue.Error = "EvaluateExpression: Divide By Zero in EMS Program!";
1794 27 : if (!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation && !state.dataEMSMgr->FinishProcessingUserInput) {
1795 0 : seriousErrorFound = true;
1796 : }
1797 : } else {
1798 1361244 : ReturnValue = SetErlValueNumber(Operand(1).Number / Operand(2).Number);
1799 : }
1800 : }
1801 1361365 : break;
1802 :
1803 2801690 : case ErlFunc::Multiply:
1804 2801690 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1805 2792810 : ReturnValue = SetErlValueNumber(Operand(1).Number * Operand(2).Number);
1806 : }
1807 2801690 : break;
1808 :
1809 1593481 : case ErlFunc::Subtract:
1810 1593481 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1811 1593481 : ReturnValue = SetErlValueNumber(Operand(1).Number - Operand(2).Number);
1812 : }
1813 1593481 : break;
1814 :
1815 2289490 : case ErlFunc::Add:
1816 2289490 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1817 2269476 : ReturnValue = SetErlValueNumber(Operand(1).Number + Operand(2).Number);
1818 : }
1819 2289490 : break;
1820 :
1821 1656404 : case ErlFunc::Equal:
1822 1656404 : if (Operand(1).Type == Operand(2).Type) {
1823 1656404 : if (Operand(1).Type == Value::Null) {
1824 0 : ReturnValue = state.dataRuntimeLang->True;
1825 1656404 : } else if ((Operand(1).Type == Value::Number) && (Operand(1).Number == Operand(2).Number)) {
1826 1042604 : ReturnValue = state.dataRuntimeLang->True;
1827 : } else {
1828 613800 : ReturnValue = state.dataRuntimeLang->False;
1829 : }
1830 : } else {
1831 0 : ReturnValue = state.dataRuntimeLang->False;
1832 : }
1833 1656404 : break;
1834 :
1835 15539 : case ErlFunc::NotEqual:
1836 15539 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1837 15539 : if (Operand(1).Number != Operand(2).Number) {
1838 15538 : ReturnValue = state.dataRuntimeLang->True;
1839 : } else {
1840 1 : ReturnValue = state.dataRuntimeLang->False;
1841 : }
1842 : }
1843 15539 : break;
1844 :
1845 1413780 : case ErlFunc::LessOrEqual:
1846 1413780 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1847 1413780 : if (Operand(1).Number <= Operand(2).Number) {
1848 821661 : ReturnValue = state.dataRuntimeLang->True;
1849 : } else {
1850 592119 : ReturnValue = state.dataRuntimeLang->False;
1851 : }
1852 : }
1853 1413780 : break;
1854 :
1855 554855 : case ErlFunc::GreaterOrEqual:
1856 554855 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1857 554855 : if (Operand(1).Number >= Operand(2).Number) {
1858 268798 : ReturnValue = state.dataRuntimeLang->True;
1859 : } else {
1860 286057 : ReturnValue = state.dataRuntimeLang->False;
1861 : }
1862 : }
1863 554855 : break;
1864 :
1865 1005932 : case ErlFunc::LessThan:
1866 1005932 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1867 1005932 : if (Operand(1).Number < Operand(2).Number) {
1868 428928 : ReturnValue = state.dataRuntimeLang->True;
1869 : } else {
1870 577004 : ReturnValue = state.dataRuntimeLang->False;
1871 : }
1872 : }
1873 1005932 : break;
1874 :
1875 3432819 : case ErlFunc::GreaterThan:
1876 3432819 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1877 3431099 : if (Operand(1).Number > Operand(2).Number) {
1878 1121133 : ReturnValue = state.dataRuntimeLang->True;
1879 : } else {
1880 2309966 : ReturnValue = state.dataRuntimeLang->False;
1881 : }
1882 : }
1883 3432819 : break;
1884 :
1885 94289 : case ErlFunc::RaiseToPower:
1886 94289 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1887 94289 : TestValue = std::pow(Operand(1).Number, Operand(2).Number);
1888 94289 : if (std::isnan(TestValue)) {
1889 : // throw Error
1890 0 : ReturnValue.Type = Value::Error;
1891 0 : ReturnValue.Error =
1892 0 : format("EvaluateExpression: Attempted to raise to power with incompatible numbers: {:.6T} raised to {:.6T}",
1893 0 : Operand(1).Number,
1894 0 : Operand(2).Number);
1895 0 : if (!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation && !state.dataEMSMgr->FinishProcessingUserInput) {
1896 0 : seriousErrorFound = true;
1897 : }
1898 : } else {
1899 94289 : ReturnValue = SetErlValueNumber(TestValue);
1900 : }
1901 : }
1902 94289 : break;
1903 :
1904 2457001 : case ErlFunc::LogicalAND:
1905 2457001 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1906 2457001 : if ((Operand(1).Number == state.dataRuntimeLang->True.Number) && (Operand(2).Number == state.dataRuntimeLang->True.Number)) {
1907 425338 : ReturnValue = state.dataRuntimeLang->True;
1908 : } else {
1909 2031663 : ReturnValue = state.dataRuntimeLang->False;
1910 : }
1911 : }
1912 2457001 : break;
1913 :
1914 47 : case ErlFunc::LogicalOR:
1915 47 : if ((Operand(1).Type == Value::Number) && (Operand(2).Type == Value::Number)) {
1916 47 : if ((Operand(1).Number == state.dataRuntimeLang->True.Number) || (Operand(2).Number == state.dataRuntimeLang->True.Number)) {
1917 47 : ReturnValue = state.dataRuntimeLang->True;
1918 : } else {
1919 0 : ReturnValue = state.dataRuntimeLang->False;
1920 : }
1921 : }
1922 47 : break;
1923 :
1924 2 : case ErlFunc::Round:
1925 2 : ReturnValue = SetErlValueNumber(nint(Operand(1).Number));
1926 2 : break;
1927 :
1928 1 : case ErlFunc::Mod:
1929 1 : ReturnValue = SetErlValueNumber(mod(Operand(1).Number, Operand(2).Number));
1930 1 : break;
1931 :
1932 1 : case ErlFunc::Sin:
1933 1 : ReturnValue = SetErlValueNumber(std::sin(Operand(1).Number));
1934 1 : break;
1935 :
1936 1 : case ErlFunc::Cos:
1937 1 : ReturnValue = SetErlValueNumber(std::cos(Operand(1).Number));
1938 1 : break;
1939 :
1940 1 : case ErlFunc::ArcSin:
1941 1 : ReturnValue = SetErlValueNumber(std::asin(Operand(1).Number));
1942 1 : break;
1943 :
1944 22195 : case ErlFunc::ArcCos:
1945 22195 : ReturnValue = SetErlValueNumber(std::acos(Operand(1).Number));
1946 22195 : break;
1947 :
1948 2 : case ErlFunc::DegToRad:
1949 2 : ReturnValue = SetErlValueNumber(Operand(1).Number * DataGlobalConstants::DegToRadians);
1950 2 : break;
1951 :
1952 22196 : case ErlFunc::RadToDeg:
1953 22196 : ReturnValue = SetErlValueNumber(Operand(1).Number / DataGlobalConstants::DegToRadians);
1954 22196 : break;
1955 :
1956 11904 : case ErlFunc::Exp:
1957 11904 : if ((Operand(1).Number < 700.0) && (Operand(1).Number > -20.0)) {
1958 11904 : ReturnValue = SetErlValueNumber(std::exp(Operand(1).Number));
1959 0 : } else if (Operand(1).Number <= -20.0) {
1960 0 : ReturnValue = SetErlValueNumber(0.0);
1961 : } else {
1962 : // throw Error
1963 0 : ReturnValue.Error =
1964 0 : format("EvaluateExpression: Attempted to calculate exponential value of too large a number: {:.4T}", Operand(1).Number);
1965 0 : ReturnValue.Type = Value::Error;
1966 0 : if (!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation && !state.dataEMSMgr->FinishProcessingUserInput) {
1967 0 : seriousErrorFound = true;
1968 : }
1969 : }
1970 11904 : break;
1971 :
1972 10178 : case ErlFunc::Ln:
1973 10178 : if (Operand(1).Number > 0.0) {
1974 10177 : ReturnValue = SetErlValueNumber(std::log(Operand(1).Number));
1975 : } else {
1976 : // throw error,
1977 1 : ReturnValue.Type = Value::Error;
1978 1 : ReturnValue.Error = format("EvaluateExpression: Natural Log of zero or less! ln of value = {:.4T}", Operand(1).Number);
1979 1 : if (!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation && !state.dataEMSMgr->FinishProcessingUserInput) {
1980 0 : seriousErrorFound = true;
1981 : }
1982 : }
1983 10178 : break;
1984 :
1985 73096 : case ErlFunc::Max:
1986 73096 : ReturnValue = SetErlValueNumber(max(Operand(1).Number, Operand(2).Number));
1987 73096 : break;
1988 :
1989 176587 : case ErlFunc::Min:
1990 176587 : ReturnValue = SetErlValueNumber(min(Operand(1).Number, Operand(2).Number));
1991 176587 : break;
1992 :
1993 229011 : case ErlFunc::ABS:
1994 229011 : ReturnValue = SetErlValueNumber(std::abs(Operand(1).Number));
1995 229011 : break;
1996 :
1997 2 : case ErlFunc::RandU:
1998 2 : RANDOM_NUMBER(tmpRANDU1);
1999 2 : tmpRANDU1 = Operand(1).Number + (Operand(2).Number - Operand(1).Number) * tmpRANDU1;
2000 2 : ReturnValue = SetErlValueNumber(tmpRANDU1);
2001 2 : break;
2002 :
2003 2 : case ErlFunc::RandG:
2004 : while (true) { // Box-Muller algorithm
2005 2 : RANDOM_NUMBER(tmpRANDU1);
2006 2 : RANDOM_NUMBER(tmpRANDU2);
2007 2 : tmpRANDU1 = 2.0 * tmpRANDU1 - 1.0;
2008 2 : tmpRANDU2 = 2.0 * tmpRANDU2 - 1.0;
2009 2 : UnitCircleTest = square(tmpRANDU1) + square(tmpRANDU2);
2010 2 : if (UnitCircleTest > 0.0 && UnitCircleTest < 1.0) break;
2011 : }
2012 2 : tmpRANDG = std::sqrt(-2.0 * std::log(UnitCircleTest) / UnitCircleTest);
2013 2 : tmpRANDG *= tmpRANDU1; // standard normal ran
2014 : // x = ran * sigma + mean
2015 2 : tmpRANDG = tmpRANDG * Operand(2).Number + Operand(1).Number;
2016 2 : tmpRANDG = max(tmpRANDG, Operand(3).Number); // min limit
2017 2 : tmpRANDG = min(tmpRANDG, Operand(4).Number); // max limit
2018 2 : ReturnValue = SetErlValueNumber(tmpRANDG);
2019 2 : break;
2020 :
2021 0 : case ErlFunc::RandSeed:
2022 : // convert arg to an integer array for the seed.
2023 0 : RANDOM_SEED(SeedN); // obtains processor's use size as output
2024 0 : SeedIntARR.allocate(SeedN);
2025 0 : for (loop = 1; loop <= SeedN; ++loop) {
2026 0 : if (loop == 1) {
2027 0 : SeedIntARR(loop) = std::floor(Operand(1).Number);
2028 : } else {
2029 0 : SeedIntARR(loop) = std::floor(Operand(1).Number) * loop;
2030 : }
2031 : }
2032 0 : RANDOM_SEED(_, SeedIntARR);
2033 0 : ReturnValue = SetErlValueNumber(double(SeedIntARR(1))); // just return first number pass as seed
2034 0 : SeedIntARR.deallocate();
2035 0 : break;
2036 :
2037 11129 : case ErlFunc::RhoAirFnPbTdbW:
2038 44516 : ReturnValue = SetErlValueNumber(PsyRhoAirFnPbTdbW(state,
2039 11129 : Operand(1).Number,
2040 11129 : Operand(2).Number,
2041 11129 : Operand(3).Number,
2042 11129 : EMSBuiltInFunction)); // result => density of moist air (kg/m3) | pressure
2043 : // (Pa) | drybulb (C) | Humidity ratio (kg water
2044 : // vapor/kg dry air) | called from
2045 11129 : break;
2046 :
2047 14371 : case ErlFunc::CpAirFnW:
2048 14371 : ReturnValue = SetErlValueNumber(PsyCpAirFnW(Operand(1).Number)); // result => heat capacity of air
2049 : // {J/kg-C} | Humidity ratio (kg water vapor/kg dry air)
2050 14371 : break;
2051 :
2052 864 : case ErlFunc::HfgAirFnWTdb:
2053 : // BG comment these two psych funct seems confusing (?) is this the enthalpy of water in the air?
2054 864 : ReturnValue = SetErlValueNumber(PsyHfgAirFnWTdb(Operand(1).Number, Operand(2).Number)); // result => heat of vaporization
2055 : // for moist air {J/kg} | Humidity
2056 : // ratio (kg water vapor/kg dry air) |
2057 : // drybulb (C)
2058 864 : break;
2059 :
2060 0 : case ErlFunc::HgAirFnWTdb:
2061 : // confusing ? seems like this is really classical Hfg, heat of vaporization
2062 0 : ReturnValue = SetErlValueNumber(PsyHgAirFnWTdb(Operand(1).Number, Operand(2).Number)); // result => enthalpy of the gas
2063 : // {units?} | Humidity ratio (kg water
2064 : // vapor/kg dry air) | drybulb (C)
2065 0 : break;
2066 :
2067 0 : case ErlFunc::TdpFnTdbTwbPb:
2068 0 : ReturnValue = SetErlValueNumber(
2069 : PsyTdpFnTdbTwbPb(state,
2070 0 : Operand(1).Number,
2071 0 : Operand(2).Number,
2072 0 : Operand(3).Number,
2073 0 : EMSBuiltInFunction)); // result => dew-point temperature {C} | drybulb (C) | wetbulb (C) | pressure (Pa)
2074 0 : break;
2075 :
2076 48102 : case ErlFunc::TdpFnWPb:
2077 144306 : ReturnValue = SetErlValueNumber(PsyTdpFnWPb(
2078 : state,
2079 48102 : Operand(1).Number,
2080 48102 : Operand(2).Number,
2081 48102 : EMSBuiltInFunction)); // result => dew-point temperature {C} | Humidity ratio (kg water vapor/kg dry air) | pressure (Pa)
2082 48102 : break;
2083 :
2084 925582 : case ErlFunc::HFnTdbW:
2085 2776746 : ReturnValue = SetErlValueNumber(
2086 925582 : PsyHFnTdbW(Operand(1).Number,
2087 925582 : Operand(2).Number)); // result => enthalpy (J/kg) | drybulb (C) | Humidity ratio (kg water vapor/kg dry air)
2088 925582 : break;
2089 :
2090 0 : case ErlFunc::HFnTdbRhPb:
2091 0 : ReturnValue = SetErlValueNumber(PsyHFnTdbRhPb(
2092 : state,
2093 0 : Operand(1).Number,
2094 0 : Operand(2).Number,
2095 0 : Operand(3).Number,
2096 0 : EMSBuiltInFunction)); // result => enthalpy (J/kg) | drybulb (C) | relative humidity value (0.0 - 1.0) | pressure (Pa)
2097 0 : break;
2098 :
2099 306455 : case ErlFunc::TdbFnHW:
2100 919365 : ReturnValue = SetErlValueNumber(PsyTdbFnHW(
2101 306455 : Operand(1).Number,
2102 306455 : Operand(2).Number)); // result => dry-bulb temperature {C} | enthalpy (J/kg) | Humidity ratio (kg water vapor/kg dry air)
2103 306455 : break;
2104 :
2105 0 : case ErlFunc::RhovFnTdbRh:
2106 0 : ReturnValue = SetErlValueNumber(PsyRhovFnTdbRh(
2107 : state,
2108 0 : Operand(1).Number,
2109 0 : Operand(2).Number,
2110 0 : EMSBuiltInFunction)); // result => Vapor density in air (kg/m3) | drybulb (C) | relative humidity value (0.0 - 1.0)
2111 0 : break;
2112 :
2113 0 : case ErlFunc::RhovFnTdbRhLBnd0C:
2114 0 : ReturnValue = SetErlValueNumber(PsyRhovFnTdbRhLBnd0C(
2115 0 : Operand(1).Number,
2116 0 : Operand(2).Number)); // result => Vapor density in air (kg/m3) | drybulb (C) | relative humidity value (0.0 - 1.0)
2117 0 : break;
2118 :
2119 0 : case ErlFunc::RhovFnTdbWPb:
2120 0 : ReturnValue = SetErlValueNumber(
2121 0 : PsyRhovFnTdbWPb(Operand(1).Number, Operand(2).Number, Operand(3).Number)); // result => Vapor density in air (kg/m3) |
2122 : // drybulb (C) | Humidity ratio (kg water
2123 : // vapor/kg dry air) | pressure (Pa)
2124 0 : break;
2125 :
2126 0 : case ErlFunc::RhFnTdbRhov:
2127 0 : ReturnValue = SetErlValueNumber(
2128 : PsyRhFnTdbRhov(state,
2129 0 : Operand(1).Number,
2130 0 : Operand(2).Number,
2131 0 : EMSBuiltInFunction)); // result => relative humidity value (0.0-1.0) | drybulb (C) | vapor density in air (kg/m3)
2132 0 : break;
2133 :
2134 0 : case ErlFunc::RhFnTdbRhovLBnd0C:
2135 0 : ReturnValue = SetErlValueNumber(
2136 : PsyRhFnTdbRhovLBnd0C(state,
2137 0 : Operand(1).Number,
2138 0 : Operand(2).Number,
2139 0 : EMSBuiltInFunction)); // relative humidity value (0.0-1.0) | drybulb (C) | vapor density in air (kg/m3)
2140 0 : break;
2141 :
2142 876 : case ErlFunc::RhFnTdbWPb:
2143 3504 : ReturnValue = SetErlValueNumber(PsyRhFnTdbWPb(state,
2144 876 : Operand(1).Number,
2145 876 : Operand(2).Number,
2146 876 : Operand(3).Number,
2147 876 : EMSBuiltInFunction)); // result => relative humidity value (0.0-1.0) | drybulb
2148 : // (C) | Humidity ratio (kg water vapor/kg dry air) |
2149 : // pressure (Pa)
2150 876 : break;
2151 :
2152 11881 : case ErlFunc::TwbFnTdbWPb:
2153 47524 : ReturnValue = SetErlValueNumber(PsyTwbFnTdbWPb(state,
2154 11881 : Operand(1).Number,
2155 11881 : Operand(2).Number,
2156 11881 : Operand(3).Number,
2157 11881 : EMSBuiltInFunction)); // result=> Temperature Wet-Bulb {C} | drybulb (C) |
2158 : // Humidity ratio (kg water vapor/kg dry air) | pressure
2159 : // (Pa)
2160 11881 : break;
2161 :
2162 0 : case ErlFunc::VFnTdbWPb:
2163 0 : ReturnValue = SetErlValueNumber(PsyVFnTdbWPb(state,
2164 0 : Operand(1).Number,
2165 0 : Operand(2).Number,
2166 0 : Operand(3).Number,
2167 0 : EMSBuiltInFunction)); // result=> specific volume {m3/kg} | drybulb (C) |
2168 : // Humidity ratio (kg water vapor/kg dry air) | pressure
2169 : // (Pa)
2170 0 : break;
2171 :
2172 0 : case ErlFunc::WFnTdpPb:
2173 0 : ReturnValue = SetErlValueNumber(PsyWFnTdpPb(
2174 : state,
2175 0 : Operand(1).Number,
2176 0 : Operand(2).Number,
2177 0 : EMSBuiltInFunction)); // result=> humidity ratio (kg water vapor/kg dry air) | dew point temperature (C) | pressure (Pa)
2178 0 : break;
2179 :
2180 20350 : case ErlFunc::WFnTdbH:
2181 61050 : ReturnValue = SetErlValueNumber(
2182 : PsyWFnTdbH(state,
2183 20350 : Operand(1).Number,
2184 20350 : Operand(2).Number,
2185 20350 : EMSBuiltInFunction)); // result=> humidity ratio (kg water vapor/kg dry air) | drybulb (C) | enthalpy (J/kg)
2186 20350 : break;
2187 :
2188 0 : case ErlFunc::WFnTdbTwbPb:
2189 0 : ReturnValue = SetErlValueNumber(PsyWFnTdbTwbPb(state,
2190 0 : Operand(1).Number,
2191 0 : Operand(2).Number,
2192 0 : Operand(3).Number,
2193 0 : EMSBuiltInFunction)); // result=> humidity ratio (kg water vapor/kg dry air) |
2194 : // drybulb (C) | wet-bulb temperature {C} | pressure (Pa)
2195 0 : break;
2196 :
2197 116910 : case ErlFunc::WFnTdbRhPb:
2198 467640 : ReturnValue = SetErlValueNumber(PsyWFnTdbRhPb(state,
2199 116910 : Operand(1).Number,
2200 116910 : Operand(2).Number,
2201 116910 : Operand(3).Number,
2202 116910 : EMSBuiltInFunction)); // result=> humidity ratio (kg water vapor/kg dry air) |
2203 : // drybulb (C) | relative humidity value (0.0-1.0) |
2204 : // pressure (Pa)
2205 116910 : break;
2206 :
2207 0 : case ErlFunc::PsatFnTemp:
2208 0 : ReturnValue = SetErlValueNumber(
2209 0 : PsyPsatFnTemp(state, Operand(1).Number, EMSBuiltInFunction)); // result=> saturation pressure {Pascals} | drybulb (C)
2210 0 : break;
2211 :
2212 34231 : case ErlFunc::TsatFnHPb:
2213 34231 : ReturnValue =
2214 136924 : SetErlValueNumber(PsyTsatFnHPb(state,
2215 34231 : Operand(1).Number,
2216 34231 : Operand(2).Number,
2217 34231 : EMSBuiltInFunction)); // result=> saturation temperature {C} | enthalpy {J/kg} | pressure (Pa)
2218 34231 : break;
2219 :
2220 : // I'm not sure why FuncTsatFnPb was commented out, but it goes all the way back to the Fortran implementation, so it's staying like that
2221 : // for now.
2222 : // CASE (FuncTsatFnPb)
2223 : // ReturnValue = NumberValue( & ! result=> saturation temperature {C}
2224 : // PsyTsatFnPb(Operand(1)%Number, & ! pressure (Pa)
2225 : // 'EMS Built-In Function') )
2226 859 : case ErlFunc::CpCW:
2227 859 : ReturnValue =
2228 1718 : SetErlValueNumber(CPCW(Operand(1).Number)); // result => specific heat of water (J/kg-K) = 4180.d0 | temperature (C) unused
2229 859 : break;
2230 :
2231 0 : case ErlFunc::CpHW:
2232 0 : ReturnValue =
2233 0 : SetErlValueNumber(CPHW(Operand(1).Number)); // result => specific heat of water (J/kg-K) = 4180.d0 | temperature (C) unused
2234 0 : break;
2235 :
2236 859 : case ErlFunc::RhoH2O:
2237 859 : ReturnValue = SetErlValueNumber(RhoH2O(Operand(1).Number)); // result => density of water (kg/m3) | temperature (C)
2238 859 : break;
2239 :
2240 0 : case ErlFunc::FatalHaltEp:
2241 0 : ShowSevereError(state, "EMS user program found serious problem and is halting simulation");
2242 0 : ShowContinueErrorTimeStamp(state, "");
2243 0 : ShowFatalError(state, format("EMS user program halted simulation with error code = {:.2T}", Operand(1).Number));
2244 0 : ReturnValue = SetErlValueNumber(Operand(1).Number); // returns back the error code
2245 0 : break;
2246 :
2247 0 : case ErlFunc::SevereWarnEp:
2248 0 : ShowSevereError(state, format("EMS user program issued severe warning with error code = {:.2T}", Operand(1).Number));
2249 0 : ShowContinueErrorTimeStamp(state, "");
2250 0 : ReturnValue = SetErlValueNumber(Operand(1).Number); // returns back the error code
2251 0 : break;
2252 :
2253 0 : case ErlFunc::WarnEp:
2254 0 : ShowWarningError(state, format("EMS user program issued warning with error code = {:.2T}", Operand(1).Number));
2255 0 : ShowContinueErrorTimeStamp(state, "");
2256 0 : ReturnValue = SetErlValueNumber(Operand(1).Number); // returns back the error code
2257 0 : break;
2258 :
2259 6563 : case ErlFunc::TrendValue:
2260 : // find TrendVariable , first operand is ErlVariable
2261 6563 : if (Operand(1).TrendVariable) {
2262 6563 : thisTrend = Operand(1).TrendVarPointer;
2263 : // second operand is number for index
2264 6563 : thisIndex = std::floor(Operand(2).Number);
2265 6563 : if (thisIndex >= 1) {
2266 6563 : if (thisIndex <= state.dataRuntimeLang->TrendVariable(thisTrend).LogDepth) {
2267 6563 : ReturnValue = SetErlValueNumber(state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR(thisIndex), Operand(1));
2268 : } else {
2269 0 : ReturnValue.Type = Value::Error;
2270 0 : ReturnValue.Error = "Built-in trend function called with index larger than what is being logged";
2271 : }
2272 : } else {
2273 0 : ReturnValue.Type = Value::Error;
2274 0 : ReturnValue.Error = "Built-in trend function called with index less than 1";
2275 : }
2276 : } else { // not registered as a trend variable
2277 0 : ReturnValue.Type = Value::Error;
2278 0 : ReturnValue.Error = "Variable used with built-in trend function is not associated with a registered trend variable";
2279 : }
2280 6563 : break;
2281 :
2282 4049 : case ErlFunc::TrendAverage:
2283 : // find TrendVariable , first operand is ErlVariable
2284 4049 : if (Operand(1).TrendVariable) {
2285 4049 : thisTrend = Operand(1).TrendVarPointer;
2286 4049 : thisIndex = std::floor(Operand(2).Number);
2287 4049 : if (thisIndex >= 1) {
2288 4049 : if (thisIndex <= state.dataRuntimeLang->TrendVariable(thisTrend).LogDepth) {
2289 : // calculate average
2290 4049 : thisAverage = sum(state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR({1, thisIndex})) / double(thisIndex);
2291 4049 : ReturnValue = SetErlValueNumber(thisAverage, Operand(1));
2292 : } else {
2293 0 : ReturnValue.Type = Value::Error;
2294 0 : ReturnValue.Error = "Built-in trend function called with index larger than what is being logged";
2295 : }
2296 : } else {
2297 0 : ReturnValue.Type = Value::Error;
2298 0 : ReturnValue.Error = "Built-in trend function called with index less than 1";
2299 : }
2300 : } else { // not registered as a trend variable
2301 0 : ReturnValue.Type = Value::Error;
2302 0 : ReturnValue.Error = "Variable used with built-in trend function is not associated with a registered trend variable";
2303 : }
2304 4049 : break;
2305 :
2306 1 : case ErlFunc::TrendMax:
2307 1 : if (Operand(1).TrendVariable) {
2308 1 : thisTrend = Operand(1).TrendVarPointer;
2309 1 : thisIndex = std::floor(Operand(2).Number);
2310 1 : if (thisIndex >= 1) {
2311 1 : if (thisIndex <= state.dataRuntimeLang->TrendVariable(thisTrend).LogDepth) {
2312 1 : thisMax = 0.0;
2313 1 : if (thisIndex == 1) {
2314 0 : thisMax = state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR(1);
2315 : } else {
2316 5 : for (loop = 2; loop <= thisIndex; ++loop) {
2317 4 : if (loop == 2) {
2318 1 : thisMax = max(state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR(1),
2319 1 : state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR(2));
2320 : } else {
2321 3 : thisMax = max(thisMax, state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR(loop));
2322 : }
2323 : }
2324 : }
2325 1 : ReturnValue = SetErlValueNumber(thisMax, Operand(1));
2326 : } else {
2327 0 : ReturnValue.Type = Value::Error;
2328 0 : ReturnValue.Error = "Built-in trend function called with index larger than what is being logged";
2329 : }
2330 : } else {
2331 0 : ReturnValue.Type = Value::Error;
2332 0 : ReturnValue.Error = "Built-in trend function called with index less than 1";
2333 : }
2334 : } else { // not registered as a trend variable
2335 0 : ReturnValue.Type = Value::Error;
2336 0 : ReturnValue.Error = "Variable used with built-in trend function is not associated with a registered trend variable";
2337 : }
2338 1 : break;
2339 :
2340 1 : case ErlFunc::TrendMin:
2341 1 : if (Operand(1).TrendVariable) {
2342 1 : thisTrend = Operand(1).TrendVarPointer;
2343 1 : thisIndex = std::floor(Operand(2).Number);
2344 1 : if (thisIndex >= 1) {
2345 1 : if (thisIndex <= state.dataRuntimeLang->TrendVariable(thisTrend).LogDepth) {
2346 1 : thisMin = 0.0;
2347 1 : if (thisIndex == 1) {
2348 0 : thisMin = state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR(1);
2349 : } else {
2350 5 : for (loop = 2; loop <= thisIndex; ++loop) {
2351 4 : if (loop == 2) {
2352 1 : thisMin = min(state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR(1),
2353 1 : state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR(2));
2354 : } else {
2355 3 : thisMin = min(thisMin, state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR(loop));
2356 : }
2357 : }
2358 : }
2359 1 : ReturnValue = SetErlValueNumber(thisMin, Operand(1));
2360 :
2361 : } else {
2362 0 : ReturnValue.Type = Value::Error;
2363 0 : ReturnValue.Error = "Built-in trend function called with index larger than what is being logged";
2364 : }
2365 :
2366 : } else {
2367 0 : ReturnValue.Type = Value::Error;
2368 0 : ReturnValue.Error = "Built-in trend function called with index less than 1";
2369 : }
2370 : } else { // not registered as a trend variable
2371 0 : ReturnValue.Type = Value::Error;
2372 0 : ReturnValue.Error = "Variable used with built-in trend function is not associated with a registered trend variable";
2373 : }
2374 1 : break;
2375 :
2376 3282 : case ErlFunc::TrendDirection:
2377 3282 : if (Operand(1).TrendVariable) {
2378 : // do a linear least squares fit and get slope of line
2379 3282 : thisTrend = Operand(1).TrendVarPointer;
2380 3282 : thisIndex = std::floor(Operand(2).Number);
2381 3282 : if (thisIndex >= 1) {
2382 :
2383 3282 : if (thisIndex <= state.dataRuntimeLang->TrendVariable(thisTrend).LogDepth) {
2384 : // closed form solution for slope of linear least squares fit
2385 13128 : thisSlope = (sum(state.dataRuntimeLang->TrendVariable(thisTrend).TimeARR({1, thisIndex})) *
2386 9846 : sum(state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR({1, thisIndex})) -
2387 9846 : thisIndex * sum((state.dataRuntimeLang->TrendVariable(thisTrend).TimeARR({1, thisIndex}) *
2388 6564 : state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR({1, thisIndex})))) /
2389 9846 : (pow_2(sum(state.dataRuntimeLang->TrendVariable(thisTrend).TimeARR({1, thisIndex}))) -
2390 6564 : thisIndex * sum(pow(state.dataRuntimeLang->TrendVariable(thisTrend).TimeARR({1, thisIndex}), 2)));
2391 3282 : ReturnValue = SetErlValueNumber(thisSlope, Operand(1)); // rate of change per hour
2392 : } else {
2393 0 : ReturnValue.Type = Value::Error;
2394 0 : ReturnValue.Error = "Built-in trend function called with index larger than what is being logged";
2395 : }
2396 :
2397 : } else {
2398 0 : ReturnValue.Type = Value::Error;
2399 0 : ReturnValue.Error = "Built-in trend function called with index less than 1";
2400 : }
2401 : } else { // not registered as a trend variable
2402 0 : ReturnValue.Type = Value::Error;
2403 0 : ReturnValue.Error = "Variable used with built-in trend function is not associated with a registered trend variable";
2404 : }
2405 3282 : break;
2406 :
2407 2 : case ErlFunc::TrendSum:
2408 2 : if (Operand(1).TrendVariable) {
2409 :
2410 2 : thisTrend = Operand(1).TrendVarPointer;
2411 2 : thisIndex = std::floor(Operand(2).Number);
2412 2 : if (thisIndex >= 1) {
2413 2 : if (thisIndex <= state.dataRuntimeLang->TrendVariable(thisTrend).LogDepth) {
2414 2 : ReturnValue =
2415 4 : SetErlValueNumber(sum(state.dataRuntimeLang->TrendVariable(thisTrend).TrendValARR({1, thisIndex})), Operand(1));
2416 : } else {
2417 0 : ReturnValue.Type = Value::Error;
2418 0 : ReturnValue.Error = "Built-in trend function called with index larger than what is being logged";
2419 : }
2420 : } else {
2421 0 : ReturnValue.Type = Value::Error;
2422 0 : ReturnValue.Error = "Built-in trend function called with index less than 1";
2423 : }
2424 : } else { // not registered as a trend variable
2425 0 : ReturnValue.Type = Value::Error;
2426 0 : ReturnValue.Error = "Variable used with built-in trend function is not associated with a registered trend variable";
2427 : }
2428 2 : break;
2429 :
2430 50880 : case ErlFunc::CurveValue:
2431 50880 : if (Operand(3).Type == Value::Null && Operand(4).Type == Value::Null && Operand(5).Type == Value::Null &&
2432 0 : Operand(6).Type == Value::Null) {
2433 0 : ReturnValue =
2434 0 : SetErlValueNumber(CurveValue(state, std::floor(Operand(1).Number), Operand(2).Number)); // curve index | X value | Y
2435 : // value, 2nd independent | Z
2436 : // Value, 3rd independent | 4th
2437 : // independent | 5th independent
2438 50880 : } else if (Operand(4).Type == Value::Null && Operand(5).Type == Value::Null && Operand(6).Type == Value::Null) {
2439 0 : ReturnValue = SetErlValueNumber(CurveValue(state,
2440 0 : std::floor(Operand(1).Number),
2441 0 : Operand(2).Number,
2442 0 : Operand(3).Number)); // curve index | X value | Y value, 2nd independent | Z
2443 : // Value, 3rd independent | 4th independent | 5th
2444 : // independent
2445 50880 : } else if (Operand(5).Type == Value::Null && Operand(6).Type == Value::Null) {
2446 254401 : ReturnValue = SetErlValueNumber(CurveValue(state,
2447 50880 : std::floor(Operand(1).Number),
2448 50880 : Operand(2).Number,
2449 50880 : Operand(3).Number,
2450 50880 : Operand(4).Number)); // curve index | X value | Y value, 2nd independent | Z
2451 : // Value, 3rd independent | 4th independent | 5th
2452 : // independent
2453 0 : } else if (Operand(6).Type == Value::Null) {
2454 0 : ReturnValue = SetErlValueNumber(CurveValue(state,
2455 0 : std::floor(Operand(1).Number),
2456 0 : Operand(2).Number,
2457 0 : Operand(3).Number,
2458 0 : Operand(4).Number,
2459 0 : Operand(5).Number)); // curve index | X value | Y value, 2nd independent | Z Value,
2460 : // 3rd independent | 4th independent | 5th independent
2461 : } else {
2462 0 : ReturnValue = SetErlValueNumber(CurveValue(state,
2463 0 : std::floor(Operand(1).Number),
2464 0 : Operand(2).Number,
2465 0 : Operand(3).Number,
2466 0 : Operand(4).Number,
2467 0 : Operand(5).Number,
2468 0 : Operand(6).Number)); // curve index | X value | Y value, 2nd
2469 : // independent | Z Value, 3rd independent | 4th
2470 : // independent | 5th independent
2471 : }
2472 50879 : break;
2473 :
2474 0 : case ErlFunc::TodayIsRain:
2475 0 : TodayTomorrowWeather(
2476 0 : state, ErlFunc::TodayIsRain, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TodayIsRain, ReturnValue);
2477 0 : break;
2478 :
2479 0 : case ErlFunc::TodayIsSnow:
2480 0 : TodayTomorrowWeather(
2481 0 : state, ErlFunc::TodayIsSnow, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TodayIsSnow, ReturnValue);
2482 0 : break;
2483 :
2484 0 : case ErlFunc::TodayOutDryBulbTemp:
2485 0 : TodayTomorrowWeather(state,
2486 : ErlFunc::TodayOutDryBulbTemp,
2487 0 : Operand(1).Number,
2488 0 : Operand(2).Number,
2489 0 : state.dataWeatherManager->TodayOutDryBulbTemp,
2490 : ReturnValue);
2491 0 : break;
2492 :
2493 0 : case ErlFunc::TodayOutDewPointTemp:
2494 0 : TodayTomorrowWeather(state,
2495 : ErlFunc::TodayOutDewPointTemp,
2496 0 : Operand(1).Number,
2497 0 : Operand(2).Number,
2498 0 : state.dataWeatherManager->TodayOutDewPointTemp,
2499 : ReturnValue);
2500 0 : break;
2501 :
2502 0 : case ErlFunc::TodayOutBaroPress:
2503 0 : TodayTomorrowWeather(state,
2504 : ErlFunc::TodayOutBaroPress,
2505 0 : Operand(1).Number,
2506 0 : Operand(2).Number,
2507 0 : state.dataWeatherManager->TodayOutBaroPress,
2508 : ReturnValue);
2509 0 : break;
2510 :
2511 0 : case ErlFunc::TodayOutRelHum:
2512 0 : TodayTomorrowWeather(
2513 0 : state, ErlFunc::TodayOutRelHum, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TodayOutRelHum, ReturnValue);
2514 0 : break;
2515 :
2516 0 : case ErlFunc::TodayWindSpeed:
2517 0 : TodayTomorrowWeather(
2518 0 : state, ErlFunc::TodayWindSpeed, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TodayWindSpeed, ReturnValue);
2519 0 : break;
2520 :
2521 0 : case ErlFunc::TodayWindDir:
2522 0 : TodayTomorrowWeather(
2523 0 : state, ErlFunc::TodayWindDir, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TodayWindDir, ReturnValue);
2524 0 : break;
2525 :
2526 0 : case ErlFunc::TodaySkyTemp:
2527 0 : TodayTomorrowWeather(
2528 0 : state, ErlFunc::TodaySkyTemp, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TodaySkyTemp, ReturnValue);
2529 0 : break;
2530 :
2531 0 : case ErlFunc::TodayHorizIRSky:
2532 0 : TodayTomorrowWeather(
2533 0 : state, ErlFunc::TodayHorizIRSky, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TodayHorizIRSky, ReturnValue);
2534 0 : break;
2535 :
2536 0 : case ErlFunc::TodayBeamSolarRad:
2537 0 : TodayTomorrowWeather(state,
2538 : ErlFunc::TodayBeamSolarRad,
2539 0 : Operand(1).Number,
2540 0 : Operand(2).Number,
2541 0 : state.dataWeatherManager->TodayBeamSolarRad,
2542 : ReturnValue);
2543 0 : break;
2544 :
2545 0 : case ErlFunc::TodayDifSolarRad:
2546 0 : TodayTomorrowWeather(
2547 0 : state, ErlFunc::TodayDifSolarRad, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TodayDifSolarRad, ReturnValue);
2548 0 : break;
2549 :
2550 0 : case ErlFunc::TodayAlbedo:
2551 0 : TodayTomorrowWeather(
2552 0 : state, ErlFunc::TodayAlbedo, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TodayAlbedo, ReturnValue);
2553 0 : break;
2554 :
2555 0 : case ErlFunc::TodayLiquidPrecip:
2556 0 : TodayTomorrowWeather(state,
2557 : ErlFunc::TodayLiquidPrecip,
2558 0 : Operand(1).Number,
2559 0 : Operand(2).Number,
2560 0 : state.dataWeatherManager->TodayLiquidPrecip,
2561 : ReturnValue);
2562 0 : break;
2563 :
2564 0 : case ErlFunc::TomorrowIsRain:
2565 0 : TodayTomorrowWeather(
2566 0 : state, ErlFunc::TomorrowIsRain, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TomorrowIsRain, ReturnValue);
2567 0 : break;
2568 :
2569 0 : case ErlFunc::TomorrowIsSnow:
2570 0 : TodayTomorrowWeather(
2571 0 : state, ErlFunc::TomorrowIsSnow, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TomorrowIsSnow, ReturnValue);
2572 0 : break;
2573 :
2574 0 : case ErlFunc::TomorrowOutDryBulbTemp:
2575 0 : TodayTomorrowWeather(state,
2576 : ErlFunc::TomorrowOutDryBulbTemp,
2577 0 : Operand(1).Number,
2578 0 : Operand(2).Number,
2579 0 : state.dataWeatherManager->TomorrowOutDryBulbTemp,
2580 : ReturnValue);
2581 0 : break;
2582 :
2583 0 : case ErlFunc::TomorrowOutDewPointTemp:
2584 0 : TodayTomorrowWeather(state,
2585 : ErlFunc::TomorrowOutDewPointTemp,
2586 0 : Operand(1).Number,
2587 0 : Operand(2).Number,
2588 0 : state.dataWeatherManager->TomorrowOutDewPointTemp,
2589 : ReturnValue);
2590 0 : break;
2591 :
2592 0 : case ErlFunc::TomorrowOutBaroPress:
2593 0 : TodayTomorrowWeather(state,
2594 : ErlFunc::TomorrowOutBaroPress,
2595 0 : Operand(1).Number,
2596 0 : Operand(2).Number,
2597 0 : state.dataWeatherManager->TomorrowOutBaroPress,
2598 : ReturnValue);
2599 0 : break;
2600 :
2601 0 : case ErlFunc::TomorrowOutRelHum:
2602 0 : TodayTomorrowWeather(state,
2603 : ErlFunc::TomorrowOutRelHum,
2604 0 : Operand(1).Number,
2605 0 : Operand(2).Number,
2606 0 : state.dataWeatherManager->TomorrowOutRelHum,
2607 : ReturnValue);
2608 0 : break;
2609 :
2610 0 : case ErlFunc::TomorrowWindSpeed:
2611 0 : TodayTomorrowWeather(state,
2612 : ErlFunc::TomorrowWindSpeed,
2613 0 : Operand(1).Number,
2614 0 : Operand(2).Number,
2615 0 : state.dataWeatherManager->TomorrowWindSpeed,
2616 : ReturnValue);
2617 0 : break;
2618 :
2619 0 : case ErlFunc::TomorrowWindDir:
2620 0 : TodayTomorrowWeather(
2621 0 : state, ErlFunc::TomorrowWindDir, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TomorrowWindDir, ReturnValue);
2622 0 : break;
2623 :
2624 0 : case ErlFunc::TomorrowSkyTemp:
2625 0 : TodayTomorrowWeather(
2626 0 : state, ErlFunc::TomorrowSkyTemp, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TomorrowSkyTemp, ReturnValue);
2627 0 : break;
2628 :
2629 0 : case ErlFunc::TomorrowHorizIRSky:
2630 0 : TodayTomorrowWeather(state,
2631 : ErlFunc::TomorrowHorizIRSky,
2632 0 : Operand(1).Number,
2633 0 : Operand(2).Number,
2634 0 : state.dataWeatherManager->TomorrowHorizIRSky,
2635 : ReturnValue);
2636 0 : break;
2637 :
2638 0 : case ErlFunc::TomorrowBeamSolarRad:
2639 0 : TodayTomorrowWeather(state,
2640 : ErlFunc::TomorrowBeamSolarRad,
2641 0 : Operand(1).Number,
2642 0 : Operand(2).Number,
2643 0 : state.dataWeatherManager->TomorrowBeamSolarRad,
2644 : ReturnValue);
2645 0 : break;
2646 :
2647 0 : case ErlFunc::TomorrowDifSolarRad:
2648 0 : TodayTomorrowWeather(state,
2649 : ErlFunc::TomorrowDifSolarRad,
2650 0 : Operand(1).Number,
2651 0 : Operand(2).Number,
2652 0 : state.dataWeatherManager->TomorrowDifSolarRad,
2653 : ReturnValue);
2654 0 : break;
2655 :
2656 0 : case ErlFunc::TomorrowAlbedo:
2657 0 : TodayTomorrowWeather(
2658 0 : state, ErlFunc::TomorrowAlbedo, Operand(1).Number, Operand(2).Number, state.dataWeatherManager->TomorrowAlbedo, ReturnValue);
2659 0 : break;
2660 :
2661 0 : case ErlFunc::TomorrowLiquidPrecip:
2662 0 : TodayTomorrowWeather(state,
2663 : ErlFunc::TomorrowLiquidPrecip,
2664 0 : Operand(1).Number,
2665 0 : Operand(2).Number,
2666 0 : state.dataWeatherManager->TomorrowLiquidPrecip,
2667 : ReturnValue);
2668 0 : break;
2669 0 : case ErlFunc::Invalid:
2670 : case ErlFunc::Null:
2671 : case ErlFunc::TsatFnPb:
2672 : case ErlFunc::Num:
2673 : // throw Error, these cases are not supported -- they all make sense except TsatFnPb which was commented out above a long time ago
2674 0 : ShowFatalError(state, "caught unexpected Expression(ExpressionNum)%Operator in EvaluateExpression");
2675 : }
2676 : }
2677 31735890 : Operand.deallocate();
2678 : }
2679 :
2680 63471780 : return ReturnValue;
2681 : }
2682 :
2683 0 : void TodayTomorrowWeather(EnergyPlusData &state,
2684 : ErlFunc const FunctionCode,
2685 : Real64 const Operand1,
2686 : Real64 const Operand2,
2687 : Array2D<Real64> &TodayTomorrowWeatherSource,
2688 : ErlValueType &ReturnVal)
2689 : {
2690 0 : int iHour = (Operand1 + 1); // Operand 1 is hour from 0:23
2691 0 : int iTimeStep = Operand2;
2692 0 : if ((iHour > 0) && (iHour <= 24) && (iTimeStep > 0) && (iTimeStep <= state.dataGlobal->NumOfTimeStepInHour)) {
2693 0 : ReturnVal = SetErlValueNumber(TodayTomorrowWeatherSource(iTimeStep, iHour));
2694 : } else {
2695 0 : ReturnVal.Type = DataRuntimeLanguage::Value::Error;
2696 0 : ReturnVal.Error = format("{} function called with invalid arguments: Hour={:.1R}, Timestep={:.1R}",
2697 0 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(FunctionCode)).Symbol,
2698 : Operand1,
2699 0 : Operand2);
2700 : }
2701 0 : }
2702 :
2703 0 : void TodayTomorrowWeather(EnergyPlusData &state,
2704 : ErlFunc const FunctionCode,
2705 : Real64 const Operand1,
2706 : Real64 const Operand2,
2707 : Array2D_bool &TodayTomorrowWeatherSource,
2708 : ErlValueType &ReturnVal)
2709 : {
2710 0 : int iHour = (Operand1 + 1); // Operand 1 is hour from 0:23
2711 0 : int iTimeStep = Operand2;
2712 0 : if ((iHour > 0) && (iHour <= 24) && (iTimeStep > 0) && (iTimeStep <= state.dataGlobal->NumOfTimeStepInHour)) {
2713 : // For logicals return 1 or 0
2714 0 : if (TodayTomorrowWeatherSource(iTimeStep, iHour)) {
2715 0 : ReturnVal = SetErlValueNumber(1.0);
2716 : } else {
2717 0 : ReturnVal = SetErlValueNumber(0.0);
2718 : }
2719 : } else {
2720 0 : ReturnVal.Type = DataRuntimeLanguage::Value::Error;
2721 0 : ReturnVal.Error = format("{} function called with invalid arguments: Hour={:.1R}, Timestep={:.1R}",
2722 0 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(FunctionCode)).Symbol,
2723 : Operand1,
2724 0 : Operand2);
2725 : }
2726 0 : }
2727 :
2728 288 : int TodayTomorrowWeather(EnergyPlusData &state, int hour, int timestep, Array2D<Real64> &TodayTomorrowWeatherSource, Real64 &value)
2729 : {
2730 288 : int iHour = hour + 1;
2731 288 : if ((iHour > 0) && (iHour <= 24) && (timestep > 0) && (timestep <= state.dataGlobal->NumOfTimeStepInHour)) {
2732 288 : value = TodayTomorrowWeatherSource(timestep, iHour);
2733 288 : return 0;
2734 : } else {
2735 0 : return 1;
2736 : }
2737 : }
2738 :
2739 0 : int TodayTomorrowWeather(EnergyPlusData &state, int hour, int timestep, Array2D<bool> &TodayTomorrowWeatherSource, int &value)
2740 : {
2741 0 : int iHour = hour + 1;
2742 0 : if ((iHour > 0) && (iHour <= 24) && (timestep > 0) && (timestep <= state.dataGlobal->NumOfTimeStepInHour)) {
2743 0 : if (TodayTomorrowWeatherSource(timestep, iHour)) {
2744 0 : value = 1.0;
2745 : } else {
2746 0 : value = 0.0;
2747 : }
2748 0 : return 0;
2749 : } else {
2750 0 : return 1;
2751 : }
2752 : }
2753 :
2754 71 : void GetRuntimeLanguageUserInput(EnergyPlusData &state)
2755 : {
2756 :
2757 : // SUBROUTINE INFORMATION:
2758 : // AUTHOR Peter Graham Ellis
2759 : // DATE WRITTEN June 2006
2760 : // MODIFIED Brent Griffith April 2009
2761 : // RE-ENGINEERED na
2762 :
2763 : // PURPOSE OF THIS SUBROUTINE:
2764 : // Gets the runtime language objects from the input file.
2765 : // GetInput is called from other modules that reference runtime language objects.
2766 : // The runtime language objects are all loaded in one pass
2767 :
2768 : // METHODOLOGY EMPLOYED:
2769 : // The runtime language objects are all loaded in one step, names registered, etc. They are parsed in a second step
2770 : // once all the object names are known.
2771 :
2772 : // Using/Aliasing
2773 : using Curve::GetCurveIndex;
2774 :
2775 : // Locals
2776 : // SUBROUTINE PARAMETER DEFINITIONS:
2777 71 : auto constexpr RoutineName("GetRuntimeLanguageUserInput: ");
2778 :
2779 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2780 : int GlobalNum;
2781 : int StackNum;
2782 : int ErrorNum;
2783 : int NumAlphas; // Number of elements in the alpha array
2784 : int NumNums; // Number of elements in the numeric array
2785 : int IOStat; // IO Status when calling get input subroutine
2786 71 : bool ErrorsFound(false);
2787 71 : int VariableNum(0); // temporary
2788 : int RuntimeReportVarNum;
2789 : bool Found;
2790 : OutputProcessor::SOVTimeStepType FreqString; // temporary
2791 : OutputProcessor::SOVStoreType VarTypeString; // temporary
2792 142 : std::string ResourceTypeString;
2793 142 : std::string GroupTypeString;
2794 142 : std::string EndUseTypeString;
2795 142 : std::string EndUseSubCatString;
2796 :
2797 : int TrendNum;
2798 : int NumTrendSteps;
2799 : int loop;
2800 : int ErlVarLoop;
2801 : int CurveIndexNum;
2802 71 : int MaxNumAlphas(0); // argument for call to GetObjectDefMaxArgs
2803 71 : int MaxNumNumbers(0); // argument for call to GetObjectDefMaxArgs
2804 71 : int TotalArgs(0); // argument for call to GetObjectDefMaxArgs
2805 142 : Array1D_string cAlphaFieldNames;
2806 142 : Array1D_string cNumericFieldNames;
2807 142 : Array1D_bool lNumericFieldBlanks;
2808 142 : Array1D_bool lAlphaFieldBlanks;
2809 142 : Array1D_string cAlphaArgs;
2810 142 : Array1D<Real64> rNumericArgs;
2811 142 : std::string cCurrentModuleObject;
2812 : int ConstructNum;
2813 : bool errFlag;
2814 : std::string::size_type lbracket;
2815 142 : std::string UnitsA;
2816 142 : std::string UnitsB;
2817 71 : OutputProcessor::Unit curUnit(OutputProcessor::Unit::None);
2818 : std::string::size_type ptr;
2819 :
2820 71 : if (state.dataRuntimeLangProcessor->GetInput) { // GetInput check is redundant with the InitializeRuntimeLanguage routine
2821 71 : state.dataRuntimeLangProcessor->GetInput = false;
2822 :
2823 71 : cCurrentModuleObject = "EnergyManagementSystem:Sensor";
2824 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2825 71 : MaxNumNumbers = NumNums;
2826 71 : MaxNumAlphas = NumAlphas;
2827 71 : cCurrentModuleObject = "EnergyManagementSystem:Actuator";
2828 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2829 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2830 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2831 71 : cCurrentModuleObject = "EnergyManagementSystem:ProgramCallingManager";
2832 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2833 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2834 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2835 71 : cCurrentModuleObject = "EnergyManagementSystem:Program";
2836 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2837 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2838 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2839 71 : cCurrentModuleObject = "EnergyManagementSystem:Subroutine";
2840 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2841 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2842 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2843 71 : cCurrentModuleObject = "EnergyManagementSystem:OutputVariable";
2844 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2845 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2846 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2847 71 : cCurrentModuleObject = "EnergyManagementSystem:MeteredOutputVariable";
2848 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2849 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2850 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2851 71 : cCurrentModuleObject = "ExternalInterface:Variable";
2852 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2853 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2854 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2855 71 : cCurrentModuleObject = "ExternalInterface:Actuator";
2856 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2857 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2858 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2859 71 : cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitImport:To:Variable";
2860 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2861 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2862 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2863 71 : cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitImport:To:Actuator";
2864 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2865 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2866 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2867 71 : cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitExport:To:Variable";
2868 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2869 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2870 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2871 71 : cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitExport:To:Actuator";
2872 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2873 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2874 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2875 : // cCurrentModuleObject = 'EnergyManagementSystem:Sensor'
2876 : // CALL state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(cCurrentModuleObject,TotalArgs,NumAlphas,NumNums)
2877 : // MaxNumNumbers=MAX(MaxNumNumbers,NumNums)
2878 : // MaxNumAlphas=MAX(MaxNumAlphas,NumAlphas)
2879 71 : cCurrentModuleObject = "EnergyManagementSystem:GlobalVariable";
2880 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2881 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2882 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2883 71 : cCurrentModuleObject = "EnergyManagementSystem:CurveOrTableIndexVariable";
2884 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2885 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2886 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2887 71 : cCurrentModuleObject = "EnergyManagementSystem:ConstructionIndexVariable";
2888 71 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNums);
2889 71 : MaxNumNumbers = max(MaxNumNumbers, NumNums);
2890 71 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
2891 :
2892 71 : cAlphaFieldNames.allocate(MaxNumAlphas);
2893 71 : cAlphaArgs.allocate(MaxNumAlphas);
2894 71 : lAlphaFieldBlanks.dimension(MaxNumAlphas, false);
2895 71 : cNumericFieldNames.allocate(MaxNumNumbers);
2896 71 : rNumericArgs.dimension(MaxNumNumbers, 0.0);
2897 71 : lNumericFieldBlanks.dimension(MaxNumNumbers, false);
2898 :
2899 71 : cCurrentModuleObject = "EnergyManagementSystem:GlobalVariable";
2900 :
2901 213 : if (state.dataRuntimeLang->NumUserGlobalVariables + state.dataRuntimeLang->NumExternalInterfaceGlobalVariables +
2902 142 : state.dataRuntimeLang->NumExternalInterfaceFunctionalMockupUnitImportGlobalVariables +
2903 142 : state.dataRuntimeLang->NumExternalInterfaceFunctionalMockupUnitExportGlobalVariables >
2904 : 0) {
2905 182 : for (GlobalNum = 1;
2906 546 : GlobalNum <= state.dataRuntimeLang->NumUserGlobalVariables + state.dataRuntimeLang->NumExternalInterfaceGlobalVariables +
2907 364 : state.dataRuntimeLang->NumExternalInterfaceFunctionalMockupUnitImportGlobalVariables +
2908 182 : state.dataRuntimeLang->NumExternalInterfaceFunctionalMockupUnitExportGlobalVariables;
2909 : ++GlobalNum) {
2910 : // If we process the ExternalInterface actuators, all we need to do is to change the
2911 : // name of the module object, and add an offset for the variable number
2912 : // This is done in the following IF/THEN section.
2913 142 : if (GlobalNum <= state.dataRuntimeLang->NumUserGlobalVariables) {
2914 141 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2915 : cCurrentModuleObject,
2916 : GlobalNum,
2917 : cAlphaArgs,
2918 : NumAlphas,
2919 : rNumericArgs,
2920 : NumNums,
2921 : IOStat,
2922 : lNumericFieldBlanks,
2923 : lAlphaFieldBlanks,
2924 : cAlphaFieldNames,
2925 : cNumericFieldNames);
2926 2 : } else if (GlobalNum > state.dataRuntimeLang->NumUserGlobalVariables &&
2927 1 : GlobalNum <= state.dataRuntimeLang->NumUserGlobalVariables + state.dataRuntimeLang->NumExternalInterfaceGlobalVariables) {
2928 0 : cCurrentModuleObject = "ExternalInterface:Variable";
2929 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2930 : cCurrentModuleObject,
2931 0 : GlobalNum - state.dataRuntimeLang->NumUserGlobalVariables,
2932 : cAlphaArgs,
2933 : NumAlphas,
2934 : rNumericArgs,
2935 : NumNums,
2936 : IOStat,
2937 : lNumericFieldBlanks,
2938 : lAlphaFieldBlanks,
2939 : cAlphaFieldNames,
2940 : cNumericFieldNames);
2941 2 : } else if (GlobalNum > state.dataRuntimeLang->NumUserGlobalVariables + state.dataRuntimeLang->NumExternalInterfaceGlobalVariables &&
2942 2 : GlobalNum <= state.dataRuntimeLang->NumUserGlobalVariables + state.dataRuntimeLang->NumExternalInterfaceGlobalVariables +
2943 1 : state.dataRuntimeLang->NumExternalInterfaceFunctionalMockupUnitImportGlobalVariables) {
2944 1 : cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitImport:To:Variable";
2945 2 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2946 : cCurrentModuleObject,
2947 1 : GlobalNum - state.dataRuntimeLang->NumUserGlobalVariables -
2948 1 : state.dataRuntimeLang->NumExternalInterfaceGlobalVariables,
2949 : cAlphaArgs,
2950 : NumAlphas,
2951 : rNumericArgs,
2952 : NumNums,
2953 : IOStat,
2954 : lNumericFieldBlanks,
2955 : lAlphaFieldBlanks,
2956 : cAlphaFieldNames,
2957 : cNumericFieldNames);
2958 :
2959 0 : } else if (GlobalNum > state.dataRuntimeLang->NumUserGlobalVariables + state.dataRuntimeLang->NumExternalInterfaceGlobalVariables +
2960 0 : state.dataRuntimeLang->NumExternalInterfaceFunctionalMockupUnitImportGlobalVariables &&
2961 0 : GlobalNum <= state.dataRuntimeLang->NumUserGlobalVariables + state.dataRuntimeLang->NumExternalInterfaceGlobalVariables +
2962 0 : state.dataRuntimeLang->NumExternalInterfaceFunctionalMockupUnitImportGlobalVariables +
2963 0 : state.dataRuntimeLang->NumExternalInterfaceFunctionalMockupUnitExportGlobalVariables) {
2964 0 : cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitExport:To:Variable";
2965 0 : state.dataInputProcessing->inputProcessor->getObjectItem(
2966 : state,
2967 : cCurrentModuleObject,
2968 0 : GlobalNum - state.dataRuntimeLang->NumUserGlobalVariables - state.dataRuntimeLang->NumExternalInterfaceGlobalVariables -
2969 0 : state.dataRuntimeLang->NumExternalInterfaceFunctionalMockupUnitImportGlobalVariables,
2970 : cAlphaArgs,
2971 : NumAlphas,
2972 : rNumericArgs,
2973 : NumNums,
2974 : IOStat,
2975 : lNumericFieldBlanks,
2976 : lAlphaFieldBlanks,
2977 : cAlphaFieldNames,
2978 : cNumericFieldNames);
2979 : }
2980 :
2981 : // loop over each alpha and register variable named as global Erl variable
2982 818 : for (ErlVarLoop = 1; ErlVarLoop <= NumAlphas; ++ErlVarLoop) {
2983 676 : if ((cCurrentModuleObject.compare("ExternalInterface:FunctionalMockupUnitImport:To:Variable") == 0)) {
2984 4 : if (ErlVarLoop == 1) {
2985 : // Only validate first field of object ExternalInterface:FunctionalMockupUnitImport:To:Variable.
2986 : // This object is allowed to contain fields that do not need to be valid EMS fields (e.g. path to the FMU).
2987 1 : ValidateEMSVariableName(
2988 1 : state, cCurrentModuleObject, cAlphaArgs(ErlVarLoop), cAlphaFieldNames(ErlVarLoop), errFlag, ErrorsFound);
2989 : }
2990 : } else {
2991 672 : ValidateEMSVariableName(
2992 672 : state, cCurrentModuleObject, cAlphaArgs(ErlVarLoop), cAlphaFieldNames(ErlVarLoop), errFlag, ErrorsFound);
2993 : }
2994 676 : if (lAlphaFieldBlanks(ErlVarLoop)) {
2995 0 : ShowWarningError(state, std::string{RoutineName} + cCurrentModuleObject);
2996 0 : ShowContinueError(state, "Blank " + cAlphaFieldNames(1));
2997 0 : ShowContinueError(state, "Blank entry will be skipped, and the simulation continues");
2998 676 : } else if (!errFlag) {
2999 676 : VariableNum = FindEMSVariable(state, cAlphaArgs(ErlVarLoop), 0);
3000 : // Still need to check for conflicts with program and function names too
3001 :
3002 676 : if (VariableNum > 0) {
3003 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + ", invalid entry.");
3004 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(ErlVarLoop) + '=' + cAlphaArgs(ErlVarLoop));
3005 0 : ShowContinueError(state, "Name conflicts with an existing global variable name");
3006 0 : ErrorsFound = true;
3007 : } else {
3008 676 : VariableNum = NewEMSVariable(state, cAlphaArgs(ErlVarLoop), 0);
3009 676 : if (GlobalNum > state.dataRuntimeLang->NumUserGlobalVariables) {
3010 : // Initialize variables for the ExternalInterface variables.
3011 : // This object requires an initial value.
3012 4 : ExternalInterfaceInitializeErlVariable(state, VariableNum, SetErlValueNumber(rNumericArgs(1)), false);
3013 : }
3014 : }
3015 : }
3016 : }
3017 : }
3018 : }
3019 :
3020 71 : cCurrentModuleObject = "EnergyManagementSystem:CurveOrTableIndexVariable";
3021 71 : state.dataRuntimeLang->NumEMSCurveIndices = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
3022 71 : if (state.dataRuntimeLang->NumEMSCurveIndices > 0) {
3023 3 : state.dataRuntimeLangProcessor->CurveIndexVariableNums.dimension(state.dataRuntimeLang->NumEMSCurveIndices, 0);
3024 16 : for (loop = 1; loop <= state.dataRuntimeLang->NumEMSCurveIndices; ++loop) {
3025 13 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3026 : cCurrentModuleObject,
3027 : loop,
3028 : cAlphaArgs,
3029 : NumAlphas,
3030 : rNumericArgs,
3031 : NumNums,
3032 : IOStat,
3033 : lNumericFieldBlanks,
3034 : lAlphaFieldBlanks,
3035 : cAlphaFieldNames,
3036 : cNumericFieldNames);
3037 :
3038 : // check if variable name is unique and well formed
3039 13 : ValidateEMSVariableName(state, cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(1), errFlag, ErrorsFound);
3040 13 : if (lAlphaFieldBlanks(1)) {
3041 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject);
3042 0 : ShowContinueError(state, "Blank " + cAlphaFieldNames(1));
3043 0 : ShowContinueError(state, "Blank entry for Erl variable name is not allowed");
3044 0 : ErrorsFound = true;
3045 13 : } else if (!errFlag) {
3046 13 : VariableNum = FindEMSVariable(state, cAlphaArgs(1), 0);
3047 13 : if (VariableNum > 0) {
3048 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3049 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(1));
3050 0 : ShowContinueError(state, "Name conflicts with an existing variable name");
3051 0 : ErrorsFound = true;
3052 : } else {
3053 : // create new EMS variable
3054 13 : VariableNum = NewEMSVariable(state, cAlphaArgs(1), 0);
3055 : // store variable num
3056 13 : state.dataRuntimeLangProcessor->CurveIndexVariableNums(loop) = VariableNum;
3057 : }
3058 : }
3059 :
3060 13 : CurveIndexNum = GetCurveIndex(state, cAlphaArgs(2)); // curve name
3061 13 : if (CurveIndexNum == 0) {
3062 0 : if (lAlphaFieldBlanks(2)) {
3063 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " blank field.");
3064 0 : ShowContinueError(state, "Blank " + cAlphaFieldNames(2));
3065 0 : ShowContinueError(state, "Blank entry for curve or table name is not allowed");
3066 : } else {
3067 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3068 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(2) + '=' + cAlphaArgs(2));
3069 0 : ShowContinueError(state, "Curve or table was not found.");
3070 : }
3071 0 : ErrorsFound = true;
3072 : } else {
3073 : // fill Erl variable with curve index
3074 13 : state.dataRuntimeLang->ErlVariable(VariableNum).Value = SetErlValueNumber(double(CurveIndexNum));
3075 : }
3076 : }
3077 :
3078 : } // NumEMSCurveIndices > 0
3079 :
3080 71 : cCurrentModuleObject = "EnergyManagementSystem:ConstructionIndexVariable";
3081 71 : state.dataRuntimeLang->NumEMSConstructionIndices = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
3082 71 : if (state.dataRuntimeLang->NumEMSConstructionIndices > 0) {
3083 1 : state.dataRuntimeLangProcessor->ConstructionIndexVariableNums.dimension(state.dataRuntimeLang->NumEMSConstructionIndices, 0);
3084 20 : for (loop = 1; loop <= state.dataRuntimeLang->NumEMSConstructionIndices; ++loop) {
3085 19 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3086 : cCurrentModuleObject,
3087 : loop,
3088 : cAlphaArgs,
3089 : NumAlphas,
3090 : rNumericArgs,
3091 : NumNums,
3092 : IOStat,
3093 : lNumericFieldBlanks,
3094 : lAlphaFieldBlanks,
3095 : cAlphaFieldNames,
3096 : cNumericFieldNames);
3097 :
3098 : // check if variable name is unique and well formed
3099 19 : ValidateEMSVariableName(state, cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(1), errFlag, ErrorsFound);
3100 19 : if (lAlphaFieldBlanks(1)) {
3101 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject);
3102 0 : ShowContinueError(state, "Blank " + cAlphaFieldNames(1));
3103 0 : ShowContinueError(state, "Blank entry for Erl variable name is not allowed");
3104 0 : ErrorsFound = true;
3105 19 : } else if (!errFlag) {
3106 19 : VariableNum = FindEMSVariable(state, cAlphaArgs(1), 0);
3107 19 : if (VariableNum > 0) {
3108 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3109 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(1));
3110 0 : ShowContinueError(state, "Name conflicts with an existing variable name");
3111 0 : ErrorsFound = true;
3112 : } else {
3113 : // create new EMS variable
3114 19 : VariableNum = NewEMSVariable(state, cAlphaArgs(1), 0);
3115 : // store variable num
3116 19 : state.dataRuntimeLangProcessor->ConstructionIndexVariableNums(loop) = VariableNum;
3117 : }
3118 : } else {
3119 0 : continue;
3120 : }
3121 :
3122 19 : ConstructNum = UtilityRoutines::FindItemInList(cAlphaArgs(2), state.dataConstruction->Construct);
3123 :
3124 19 : if (ConstructNum == 0) {
3125 0 : if (lAlphaFieldBlanks(2)) {
3126 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " blank field.");
3127 0 : ShowContinueError(state, "Blank " + cAlphaFieldNames(2));
3128 0 : ShowContinueError(state, "Blank entry for construction name is not allowed");
3129 : } else {
3130 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3131 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(2) + '=' + cAlphaArgs(2));
3132 0 : ShowContinueError(state, "Construction was not found.");
3133 : }
3134 0 : ErrorsFound = true;
3135 : } else {
3136 : // fill Erl variable with curve index
3137 19 : state.dataRuntimeLang->ErlVariable(VariableNum).Value = SetErlValueNumber(double(ConstructNum));
3138 : }
3139 : }
3140 :
3141 : } // NumEMSConstructionIndices > 0
3142 :
3143 71 : state.dataRuntimeLang->NumErlStacks = state.dataRuntimeLang->NumErlPrograms + state.dataRuntimeLang->NumErlSubroutines;
3144 71 : state.dataRuntimeLang->ErlStack.allocate(state.dataRuntimeLang->NumErlStacks);
3145 71 : state.dataRuntimeLangProcessor->ErlStackUniqueNames.reserve(static_cast<unsigned>(state.dataRuntimeLang->NumErlStacks));
3146 :
3147 71 : if (state.dataRuntimeLang->NumErlPrograms > 0) {
3148 52 : cCurrentModuleObject = "EnergyManagementSystem:Program";
3149 662 : for (StackNum = 1; StackNum <= state.dataRuntimeLang->NumErlPrograms; ++StackNum) {
3150 610 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3151 : cCurrentModuleObject,
3152 : StackNum,
3153 : cAlphaArgs,
3154 : NumAlphas,
3155 : rNumericArgs,
3156 : NumNums,
3157 : IOStat,
3158 : lNumericFieldBlanks,
3159 : lAlphaFieldBlanks,
3160 : cAlphaFieldNames,
3161 : cNumericFieldNames);
3162 1220 : GlobalNames::VerifyUniqueInterObjectName(state,
3163 610 : state.dataRuntimeLangProcessor->ErlStackUniqueNames,
3164 610 : cAlphaArgs(1),
3165 : cCurrentModuleObject,
3166 610 : cAlphaFieldNames(1),
3167 : ErrorsFound);
3168 :
3169 610 : ValidateEMSProgramName(state, cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(1), "Programs", errFlag, ErrorsFound);
3170 610 : if (!errFlag) {
3171 610 : state.dataRuntimeLang->ErlStack(StackNum).Name = cAlphaArgs(1);
3172 : }
3173 :
3174 610 : if (NumAlphas > 1) {
3175 610 : state.dataRuntimeLang->ErlStack(StackNum).Line.allocate(NumAlphas - 1);
3176 610 : state.dataRuntimeLang->ErlStack(StackNum).NumLines = NumAlphas - 1;
3177 610 : state.dataRuntimeLang->ErlStack(StackNum).Line({1, NumAlphas - 1}) = cAlphaArgs({2, NumAlphas}); // note array assignment
3178 : }
3179 :
3180 : } // ProgramNum
3181 : }
3182 :
3183 71 : if (state.dataRuntimeLang->NumErlSubroutines > 0) {
3184 5 : cCurrentModuleObject = "EnergyManagementSystem:Subroutine";
3185 24 : for (StackNum = state.dataRuntimeLang->NumErlPrograms + 1; StackNum <= state.dataRuntimeLang->NumErlStacks; ++StackNum) {
3186 38 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3187 : cCurrentModuleObject,
3188 19 : StackNum - state.dataRuntimeLang->NumErlPrograms,
3189 : cAlphaArgs,
3190 : NumAlphas,
3191 : rNumericArgs,
3192 : NumNums,
3193 : IOStat,
3194 : lNumericFieldBlanks,
3195 : lAlphaFieldBlanks,
3196 : cAlphaFieldNames,
3197 : cNumericFieldNames);
3198 38 : GlobalNames::VerifyUniqueInterObjectName(state,
3199 19 : state.dataRuntimeLangProcessor->ErlStackUniqueNames,
3200 19 : cAlphaArgs(1),
3201 : cCurrentModuleObject,
3202 19 : cAlphaFieldNames(1),
3203 : ErrorsFound);
3204 :
3205 19 : ValidateEMSProgramName(state, cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(1), "Subroutines", errFlag, ErrorsFound);
3206 19 : if (!errFlag) {
3207 19 : state.dataRuntimeLang->ErlStack(StackNum).Name = cAlphaArgs(1);
3208 : }
3209 :
3210 19 : if (NumAlphas > 1) {
3211 19 : state.dataRuntimeLang->ErlStack(StackNum).Line.allocate(NumAlphas - 1);
3212 19 : state.dataRuntimeLang->ErlStack(StackNum).NumLines = NumAlphas - 1;
3213 19 : state.dataRuntimeLang->ErlStack(StackNum).Line({1, NumAlphas - 1}) = cAlphaArgs({2, NumAlphas}); // note array assignment
3214 : }
3215 : }
3216 : }
3217 :
3218 71 : cCurrentModuleObject = "EnergyManagementSystem:TrendVariable";
3219 71 : state.dataRuntimeLang->NumErlTrendVariables = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
3220 71 : if (state.dataRuntimeLang->NumErlTrendVariables > 0) {
3221 3 : state.dataRuntimeLang->TrendVariable.allocate(state.dataRuntimeLang->NumErlTrendVariables);
3222 8 : for (TrendNum = 1; TrendNum <= state.dataRuntimeLang->NumErlTrendVariables; ++TrendNum) {
3223 5 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3224 : cCurrentModuleObject,
3225 : TrendNum,
3226 : cAlphaArgs,
3227 : NumAlphas,
3228 : rNumericArgs,
3229 : NumNums,
3230 : IOStat,
3231 : lNumericFieldBlanks,
3232 : lAlphaFieldBlanks,
3233 : cAlphaFieldNames,
3234 : cNumericFieldNames);
3235 5 : UtilityRoutines::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
3236 :
3237 5 : ValidateEMSVariableName(state, cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(1), errFlag, ErrorsFound);
3238 5 : if (!errFlag) {
3239 5 : state.dataRuntimeLang->TrendVariable(TrendNum).Name = cAlphaArgs(1);
3240 : }
3241 :
3242 5 : VariableNum = FindEMSVariable(state, cAlphaArgs(2), 0);
3243 : // Still need to check for conflicts with program and function names too
3244 5 : if (VariableNum == 0) { // did not find it
3245 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3246 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(2) + '=' + cAlphaArgs(2));
3247 0 : ShowContinueError(state, "Did not find a match with an EMS variable name");
3248 0 : ErrorsFound = true;
3249 : } else { // found it.
3250 5 : state.dataRuntimeLang->TrendVariable(TrendNum).ErlVariablePointer = VariableNum;
3251 : // register the trend pointer in ErlVariable.
3252 5 : state.dataRuntimeLang->ErlVariable(VariableNum).Value.TrendVariable = true;
3253 5 : state.dataRuntimeLang->ErlVariable(VariableNum).Value.TrendVarPointer = TrendNum;
3254 5 : state.dataRuntimeLang->ErlVariable(VariableNum).Value.initialized = true; // Cannot figure out how to get around needing this,
3255 : }
3256 :
3257 5 : NumTrendSteps = std::floor(rNumericArgs(1));
3258 5 : if (NumTrendSteps > 0) {
3259 5 : state.dataRuntimeLang->TrendVariable(TrendNum).LogDepth = NumTrendSteps;
3260 : // setup data arrays using NumTrendSteps
3261 5 : state.dataRuntimeLang->TrendVariable(TrendNum).TrendValARR.allocate(NumTrendSteps);
3262 5 : state.dataRuntimeLang->TrendVariable(TrendNum).TrendValARR = 0.0; // array init
3263 5 : state.dataRuntimeLang->TrendVariable(TrendNum).tempTrendARR.allocate(NumTrendSteps);
3264 5 : state.dataRuntimeLang->TrendVariable(TrendNum).tempTrendARR = 0.0; // array init
3265 5 : state.dataRuntimeLang->TrendVariable(TrendNum).TimeARR.allocate(NumTrendSteps);
3266 : // construct time data array for use with other calculations later
3267 : // current time is zero, each value in trend log array is one zone timestep further back in time
3268 : // units are hours. all terms negative, getting increasingly negative the further back in time
3269 : // further back in time is higher index in array
3270 1805 : for (loop = 1; loop <= NumTrendSteps; ++loop) {
3271 1805 : if (loop == 1) {
3272 5 : state.dataRuntimeLang->TrendVariable(TrendNum).TimeARR(loop) = -state.dataGlobal->TimeStepZone;
3273 5 : continue;
3274 : } else {
3275 1795 : state.dataRuntimeLang->TrendVariable(TrendNum).TimeARR(loop) =
3276 1795 : state.dataRuntimeLang->TrendVariable(TrendNum).TimeARR(loop - 1) - state.dataGlobal->TimeStepZone; // fractional hours
3277 : }
3278 : }
3279 : } else {
3280 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3281 0 : ShowContinueError(state, format("Invalid {}={:.2T}", cNumericFieldNames(1), rNumericArgs(1)));
3282 0 : ShowContinueError(state, "must be greater than zero");
3283 0 : ErrorsFound = true;
3284 : }
3285 :
3286 : } // trendnum
3287 : }
3288 :
3289 71 : if (ErrorsFound) {
3290 0 : ShowFatalError(state, "Errors found in getting EMS Runtime Language input. Preceding condition causes termination.");
3291 : }
3292 :
3293 : // Parse the runtime language code
3294 700 : for (StackNum = 1; StackNum <= state.dataRuntimeLang->NumErlStacks; ++StackNum) {
3295 629 : ParseStack(state, StackNum);
3296 :
3297 629 : if (state.dataRuntimeLang->ErlStack(StackNum).NumErrors > 0) {
3298 0 : ShowSevereError(
3299 0 : state, "Errors found parsing EMS Runtime Language program or subroutine = " + state.dataRuntimeLang->ErlStack(StackNum).Name);
3300 0 : for (ErrorNum = 1; ErrorNum <= state.dataRuntimeLang->ErlStack(StackNum).NumErrors; ++ErrorNum) {
3301 0 : ShowContinueError(state, state.dataRuntimeLang->ErlStack(StackNum).Error(ErrorNum));
3302 : }
3303 0 : ErrorsFound = true;
3304 : }
3305 : } // StackNum
3306 :
3307 71 : if (ErrorsFound) {
3308 0 : ShowFatalError(state, "Errors found in parsing EMS Runtime Language input. Preceding condition causes termination.");
3309 : }
3310 :
3311 71 : if ((state.dataRuntimeLang->NumEMSOutputVariables > 0) || (state.dataRuntimeLang->NumEMSMeteredOutputVariables > 0)) {
3312 111 : state.dataRuntimeLangProcessor->RuntimeReportVar.allocate(state.dataRuntimeLang->NumEMSOutputVariables +
3313 111 : state.dataRuntimeLang->NumEMSMeteredOutputVariables);
3314 : }
3315 :
3316 71 : if (state.dataRuntimeLang->NumEMSOutputVariables > 0) {
3317 37 : cCurrentModuleObject = "EnergyManagementSystem:OutputVariable";
3318 373 : for (RuntimeReportVarNum = 1; RuntimeReportVarNum <= state.dataRuntimeLang->NumEMSOutputVariables; ++RuntimeReportVarNum) {
3319 336 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3320 : cCurrentModuleObject,
3321 : RuntimeReportVarNum,
3322 : cAlphaArgs,
3323 : NumAlphas,
3324 : rNumericArgs,
3325 : NumNums,
3326 : IOStat,
3327 : lNumericFieldBlanks,
3328 : lAlphaFieldBlanks,
3329 : cAlphaFieldNames,
3330 : cNumericFieldNames);
3331 672 : GlobalNames::VerifyUniqueInterObjectName(state,
3332 336 : state.dataRuntimeLangProcessor->RuntimeReportVarUniqueNames,
3333 336 : cAlphaArgs(1),
3334 : cCurrentModuleObject,
3335 336 : cAlphaFieldNames(1),
3336 : ErrorsFound);
3337 :
3338 336 : lbracket = index(cAlphaArgs(1), '[');
3339 336 : if (lbracket == std::string::npos) {
3340 336 : UnitsA = "";
3341 : // if (lAlphaFieldBlanks(6)) then
3342 : // CALL ShowWarningError(state, RoutineName//TRIM(cCurrentModuleObject)//'="'//TRIM(cAlphaArgs(1))//' no units
3343 : // indicated.') CALL ShowContinueError(state, '...no units indicated for this variable. [] is assumed.')
3344 : // cAlphaArgs(1)=TRIM(cAlphaArgs(1))//' []'
3345 : // endif
3346 336 : UnitsB = cAlphaArgs(6);
3347 336 : lbracket = index(UnitsB, '[');
3348 336 : ptr = index(UnitsB, ']');
3349 336 : if (lbracket != std::string::npos) {
3350 0 : UnitsB[lbracket] = ' ';
3351 0 : if (ptr != std::string::npos) {
3352 0 : UnitsB[ptr] = ' ';
3353 : }
3354 0 : strip(UnitsB);
3355 : }
3356 : } else { // units shown on Name field (7.2 and pre versions)
3357 0 : ptr = index(cAlphaArgs(1), ']');
3358 0 : if (ptr != std::string::npos) {
3359 0 : UnitsA = cAlphaArgs(1).substr(lbracket + 1, ptr - lbracket - 1);
3360 : } else {
3361 0 : UnitsA = cAlphaArgs(1).substr(lbracket + 1);
3362 : }
3363 0 : cAlphaArgs(1).erase(lbracket - 1);
3364 0 : UnitsB = cAlphaArgs(6);
3365 0 : lbracket = index(UnitsB, '[');
3366 0 : ptr = index(UnitsB, ']');
3367 0 : if (lbracket != std::string::npos) {
3368 0 : UnitsB[lbracket] = ' ';
3369 0 : if (ptr != std::string::npos) {
3370 0 : UnitsB[ptr] = ' ';
3371 : }
3372 0 : strip(UnitsB);
3373 : }
3374 0 : if (UnitsA != "" && UnitsB != "") {
3375 0 : if (UnitsA != UnitsB) {
3376 0 : ShowWarningError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " mismatched units.");
3377 0 : ShowContinueError(state, "...Units entered in " + cAlphaFieldNames(1) + " (deprecated use)=\"" + UnitsA + "\"");
3378 0 : ShowContinueError(state, "..." + cAlphaFieldNames(6) + "=\"" + UnitsB + "\" (will be used)");
3379 : }
3380 0 : } else if (UnitsB == "" && UnitsA != "") {
3381 0 : UnitsB = UnitsA;
3382 0 : ShowWarningError(state,
3383 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) +
3384 : "\" using deprecated units designation.");
3385 0 : ShowContinueError(state, "...Units entered in " + cAlphaFieldNames(1) + " (deprecated use)=\"" + UnitsA + "\"");
3386 : }
3387 : }
3388 336 : curUnit = OutputProcessor::unitStringToEnum(UnitsB);
3389 :
3390 336 : state.dataRuntimeLangProcessor->RuntimeReportVar(RuntimeReportVarNum).Name = cAlphaArgs(1);
3391 :
3392 336 : if (!lAlphaFieldBlanks(5)) {
3393 : // Lookup the Runtime Language Context, i.e., PROGRAM, FUNCTION, or global
3394 241 : Found = false;
3395 10989 : for (StackNum = 1; StackNum <= state.dataRuntimeLang->NumErlStacks; ++StackNum) {
3396 10989 : if (state.dataRuntimeLang->ErlStack(StackNum).Name == cAlphaArgs(5)) {
3397 241 : Found = true;
3398 241 : break;
3399 : }
3400 : }
3401 241 : if (!Found) {
3402 0 : StackNum = 0;
3403 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3404 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(5) + '=' + cAlphaArgs(5));
3405 0 : ShowContinueError(state, "EMS program or subroutine not found.");
3406 0 : ErrorsFound = true;
3407 : }
3408 : } else {
3409 95 : StackNum = 0;
3410 : }
3411 :
3412 336 : VariableNum = FindEMSVariable(state, cAlphaArgs(2), StackNum);
3413 :
3414 336 : if (VariableNum == 0) {
3415 0 : if (lAlphaFieldBlanks(5)) {
3416 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3417 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(2) + '=' + cAlphaArgs(2));
3418 0 : ShowContinueError(state, "EMS variable not found among global variables.");
3419 0 : } else if (StackNum != 0) {
3420 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3421 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(2) + '=' + cAlphaArgs(2));
3422 0 : ShowContinueError(state, "EMS variable not found among local variables in " + cAlphaArgs(5));
3423 : }
3424 0 : ErrorsFound = true;
3425 : // ELSEIF (INDEX('0123456789',cAlphaArgs(2)(1:1)) > 0) THEN
3426 : // CALL ShowSevereError(state, 'Invalid '//TRIM(cAlphaFieldNames(2))//'='//TRIM(cAlphaArgs(2)))
3427 : // CALL ShowContinueError(state, 'Entered in '//TRIM(cCurrentModuleObject)//'='//TRIM(cAlphaArgs(1)))
3428 : // CALL ShowContinueError(state, 'Names used as Erl output variables cannot start with numeric characters.')
3429 : // ErrorsFound = .TRUE.
3430 : } else {
3431 336 : state.dataRuntimeLangProcessor->RuntimeReportVar(RuntimeReportVarNum).VariableNum = VariableNum;
3432 : }
3433 :
3434 : {
3435 672 : auto const SELECT_CASE_var(cAlphaArgs(3));
3436 :
3437 336 : if (SELECT_CASE_var == "AVERAGED") {
3438 142 : VarTypeString = OutputProcessor::SOVStoreType::Average;
3439 194 : } else if (SELECT_CASE_var == "SUMMED") {
3440 194 : VarTypeString = OutputProcessor::SOVStoreType::Summed;
3441 : } else {
3442 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3443 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(3) + '=' + cAlphaArgs(3));
3444 0 : ShowContinueError(state, "...valid values are Averaged or Summed.");
3445 0 : ErrorsFound = true;
3446 : }
3447 : }
3448 :
3449 : {
3450 672 : auto const SELECT_CASE_var(cAlphaArgs(4));
3451 :
3452 336 : if (SELECT_CASE_var == "ZONETIMESTEP") {
3453 236 : FreqString = OutputProcessor::SOVTimeStepType::Zone;
3454 100 : } else if (SELECT_CASE_var == "SYSTEMTIMESTEP") {
3455 100 : FreqString = OutputProcessor::SOVTimeStepType::System;
3456 : } else {
3457 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3458 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(4) + '=' + cAlphaArgs(4));
3459 0 : ShowContinueError(state, "...valid values are ZoneTimestep or SystemTimestep.");
3460 0 : ErrorsFound = true;
3461 : }
3462 : }
3463 :
3464 336 : if (curUnit != OutputProcessor::Unit::unknown) {
3465 990 : SetupOutputVariable(state,
3466 330 : cAlphaArgs(1),
3467 : curUnit,
3468 330 : state.dataRuntimeLangProcessor->RuntimeReportVar(RuntimeReportVarNum).Value,
3469 : FreqString,
3470 : VarTypeString,
3471 330 : "EMS");
3472 : } else {
3473 18 : SetupOutputVariable(state,
3474 6 : cAlphaArgs(1),
3475 : OutputProcessor::Unit::customEMS,
3476 6 : state.dataRuntimeLangProcessor->RuntimeReportVar(RuntimeReportVarNum).Value,
3477 : FreqString,
3478 : VarTypeString,
3479 : "EMS",
3480 : _,
3481 : _,
3482 : _,
3483 : _,
3484 : _,
3485 : _,
3486 : _,
3487 : _,
3488 : _,
3489 6 : UnitsB);
3490 : }
3491 : // Last field is index key, no indexing here so mimic weather output data
3492 :
3493 : } // RuntimeReportVarNum
3494 : } // NumEMSOutputVariables > 0
3495 :
3496 71 : if (state.dataRuntimeLang->NumEMSMeteredOutputVariables > 0) {
3497 4 : cCurrentModuleObject = "EnergyManagementSystem:MeteredOutputVariable";
3498 15 : for (loop = 1; loop <= state.dataRuntimeLang->NumEMSMeteredOutputVariables; ++loop) {
3499 11 : RuntimeReportVarNum = state.dataRuntimeLang->NumEMSOutputVariables + loop;
3500 11 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3501 : cCurrentModuleObject,
3502 : loop,
3503 : cAlphaArgs,
3504 : NumAlphas,
3505 : rNumericArgs,
3506 : NumNums,
3507 : IOStat,
3508 : lNumericFieldBlanks,
3509 : lAlphaFieldBlanks,
3510 : cAlphaFieldNames,
3511 : cNumericFieldNames);
3512 :
3513 22 : GlobalNames::VerifyUniqueInterObjectName(state,
3514 11 : state.dataRuntimeLangProcessor->RuntimeReportVarUniqueNames,
3515 11 : cAlphaArgs(1),
3516 : cCurrentModuleObject,
3517 11 : cAlphaFieldNames(1),
3518 : ErrorsFound);
3519 :
3520 11 : lbracket = index(cAlphaArgs(1), '[');
3521 11 : if (lbracket == std::string::npos) {
3522 10 : UnitsA = "";
3523 : // if (lAlphaFieldBlanks(9)) then
3524 : // CALL ShowWarningError(state, RoutineName//TRIM(cCurrentModuleObject)//'="'//TRIM(cAlphaArgs(1))//' no units
3525 : // indicated.') CALL ShowContinueError(state, '...no units indicated for this variable. [] is assumed.')
3526 : // cAlphaArgs(1)=TRIM(cAlphaArgs(1))//' []'
3527 : // endif
3528 10 : UnitsB = cAlphaArgs(9);
3529 10 : lbracket = index(UnitsB, '[');
3530 10 : ptr = index(UnitsB, ']');
3531 10 : if (lbracket != std::string::npos) {
3532 0 : UnitsB[lbracket] = ' ';
3533 0 : if (ptr != std::string::npos) {
3534 0 : UnitsB[ptr] = ' ';
3535 : }
3536 0 : strip(UnitsB);
3537 : }
3538 : } else { // units shown on Name field (7.2 and pre versions)
3539 1 : ptr = index(cAlphaArgs(1), ']');
3540 1 : if (ptr != std::string::npos) {
3541 1 : UnitsA = cAlphaArgs(1).substr(lbracket + 1, ptr - lbracket - 1);
3542 : } else {
3543 0 : UnitsA = cAlphaArgs(1).substr(lbracket + 1);
3544 : }
3545 1 : cAlphaArgs(1).erase(lbracket - 1);
3546 1 : UnitsB = cAlphaArgs(9);
3547 1 : lbracket = index(UnitsB, '[');
3548 1 : ptr = index(UnitsB, ']');
3549 1 : if (lbracket != std::string::npos) {
3550 0 : UnitsB[lbracket] = ' ';
3551 0 : if (ptr != std::string::npos) {
3552 0 : UnitsB[ptr] = ' ';
3553 : }
3554 0 : strip(UnitsB);
3555 : }
3556 1 : if (UnitsA != "" && UnitsB != "") {
3557 0 : if (UnitsA != UnitsB) {
3558 0 : ShowWarningError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " mismatched units.");
3559 0 : ShowContinueError(state, "...Units entered in " + cAlphaFieldNames(1) + " (deprecated use)=\"" + UnitsA + "\"");
3560 0 : ShowContinueError(state, "..." + cAlphaFieldNames(9) + "=\"" + UnitsB + "\" (will be used)");
3561 : }
3562 1 : } else if (UnitsB == "" && UnitsA != "") {
3563 1 : UnitsB = UnitsA;
3564 3 : ShowWarningError(state,
3565 2 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) +
3566 : "\" using deprecated units designation.");
3567 1 : ShowContinueError(state, "...Units entered in " + cAlphaFieldNames(1) + " (deprecated use)=\"" + UnitsA + "\"");
3568 : }
3569 : }
3570 11 : curUnit = OutputProcessor::unitStringToEnum(UnitsB);
3571 :
3572 11 : state.dataRuntimeLangProcessor->RuntimeReportVar(RuntimeReportVarNum).Name = cAlphaArgs(1);
3573 :
3574 11 : if (!lAlphaFieldBlanks(4)) {
3575 : // Lookup the Runtime Language Context, i.e., PROGRAM, FUNCTION, or global
3576 11 : Found = false;
3577 63 : for (StackNum = 1; StackNum <= state.dataRuntimeLang->NumErlStacks; ++StackNum) {
3578 63 : if (state.dataRuntimeLang->ErlStack(StackNum).Name == cAlphaArgs(4)) {
3579 11 : Found = true;
3580 11 : break;
3581 : }
3582 : }
3583 11 : if (!Found) {
3584 0 : StackNum = 0;
3585 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3586 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(4) + '=' + cAlphaArgs(4));
3587 0 : ShowContinueError(state, "EMS program or subroutine not found.");
3588 0 : ErrorsFound = true;
3589 : }
3590 : } else {
3591 0 : StackNum = 0;
3592 : }
3593 :
3594 11 : VariableNum = FindEMSVariable(state, cAlphaArgs(2), StackNum);
3595 11 : if (VariableNum == 0) {
3596 0 : if (lAlphaFieldBlanks(4)) {
3597 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3598 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(2) + '=' + cAlphaArgs(2));
3599 0 : ShowContinueError(state, "EMS variable not found among global variables.");
3600 0 : } else if (StackNum != 0) {
3601 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3602 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(2) + '=' + cAlphaArgs(2));
3603 0 : ShowContinueError(state, "EMS variable not found among local variables in " + cAlphaArgs(5));
3604 : }
3605 0 : ErrorsFound = true;
3606 : // ELSEIF (INDEX('0123456789',cAlphaArgs(2)(1:1)) > 0) THEN
3607 : // CALL ShowSevereError(state, 'Invalid '//TRIM(cAlphaFieldNames(2))//'='//TRIM(cAlphaArgs(2)))
3608 : // CALL ShowContinueError(state, 'Entered in '//TRIM(cCurrentModuleObject)//'='//TRIM(cAlphaArgs(1)))
3609 : // CALL ShowContinueError(state, 'Names used as Erl output variables cannot start with numeric characters.')
3610 : // ErrorsFound = .TRUE.
3611 : } else {
3612 11 : state.dataRuntimeLangProcessor->RuntimeReportVar(RuntimeReportVarNum).VariableNum = VariableNum;
3613 : }
3614 :
3615 11 : VarTypeString = OutputProcessor::SOVStoreType::Summed; // all metered vars are sum type
3616 :
3617 : {
3618 22 : auto const SELECT_CASE_var(cAlphaArgs(3));
3619 :
3620 11 : if (SELECT_CASE_var == "ZONETIMESTEP") {
3621 0 : FreqString = OutputProcessor::SOVTimeStepType::Zone;
3622 11 : } else if (SELECT_CASE_var == "SYSTEMTIMESTEP") {
3623 11 : FreqString = OutputProcessor::SOVTimeStepType::System;
3624 : } else {
3625 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3626 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(4) + '=' + cAlphaArgs(4));
3627 0 : ShowContinueError(state, "...valid values are ZoneTimestep or SystemTimestep.");
3628 0 : ErrorsFound = true;
3629 : }
3630 : }
3631 :
3632 : // Resource Type
3633 : {
3634 22 : auto const SELECT_CASE_var(cAlphaArgs(5));
3635 :
3636 11 : if (SELECT_CASE_var == "ELECTRICITY") {
3637 5 : ResourceTypeString = "Electricity";
3638 6 : } else if (SELECT_CASE_var == "NATURALGAS") {
3639 0 : ResourceTypeString = "NaturalGas";
3640 6 : } else if (SELECT_CASE_var == "GASOLINE") {
3641 0 : ResourceTypeString = "Gasoline";
3642 6 : } else if (SELECT_CASE_var == "DIESEL") {
3643 0 : ResourceTypeString = "Diesel";
3644 6 : } else if (SELECT_CASE_var == "COAL") {
3645 0 : ResourceTypeString = "Coal";
3646 6 : } else if (SELECT_CASE_var == "FUELOILNO1") {
3647 0 : ResourceTypeString = "FuelOilNo1";
3648 6 : } else if (SELECT_CASE_var == "FUELOILNO2") {
3649 0 : ResourceTypeString = "FuelOilNo2";
3650 6 : } else if (SELECT_CASE_var == "OTHERFUEL1") {
3651 0 : ResourceTypeString = "OtherFuel1";
3652 6 : } else if (SELECT_CASE_var == "OTHERFUEL2") {
3653 0 : ResourceTypeString = "OtherFuel2";
3654 6 : } else if (SELECT_CASE_var == "PROPANE") {
3655 0 : ResourceTypeString = "Propane";
3656 6 : } else if (SELECT_CASE_var == "WATERUSE") {
3657 0 : ResourceTypeString = "Water";
3658 6 : } else if (SELECT_CASE_var == "ONSITEWATERPRODUCED") {
3659 0 : ResourceTypeString = "OnSiteWater";
3660 6 : } else if (SELECT_CASE_var == "MAINSWATERSUPPLY") {
3661 0 : ResourceTypeString = "MainsWater";
3662 6 : } else if (SELECT_CASE_var == "RAINWATERCOLLECTED") {
3663 0 : ResourceTypeString = "RainWater";
3664 6 : } else if (SELECT_CASE_var == "WELLWATERDRAWN") {
3665 0 : ResourceTypeString = "WellWater";
3666 6 : } else if (SELECT_CASE_var == "CONDENSATEWATERCOLLECTED") {
3667 0 : ResourceTypeString = "Condensate";
3668 6 : } else if (SELECT_CASE_var == "ENERGYTRANSFER") {
3669 6 : ResourceTypeString = "EnergyTransfer";
3670 0 : } else if (SELECT_CASE_var == "STEAM") {
3671 0 : ResourceTypeString = "Steam";
3672 0 : } else if (SELECT_CASE_var == "DISTRICTCOOLING") {
3673 0 : ResourceTypeString = "DistrictCooling";
3674 0 : } else if (SELECT_CASE_var == "DISTRICTHEATING") {
3675 0 : ResourceTypeString = "DistrictHeating";
3676 0 : } else if (SELECT_CASE_var == "ELECTRICITYPRODUCEDONSITE") {
3677 0 : ResourceTypeString = "ElectricityProduced";
3678 0 : } else if (SELECT_CASE_var == "SOLARWATERHEATING") {
3679 0 : ResourceTypeString = "SolarWater";
3680 0 : } else if (SELECT_CASE_var == "SOLARAIRHEATING") {
3681 0 : ResourceTypeString = "SolarAir";
3682 : } else {
3683 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3684 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(5) + '=' + cAlphaArgs(5));
3685 0 : ErrorsFound = true;
3686 : }
3687 : }
3688 :
3689 : // Group Type
3690 : {
3691 22 : auto const SELECT_CASE_var(cAlphaArgs(6));
3692 :
3693 11 : if (SELECT_CASE_var == "BUILDING") {
3694 0 : GroupTypeString = "Building";
3695 11 : } else if (SELECT_CASE_var == "HVAC") {
3696 5 : GroupTypeString = "HVAC";
3697 6 : } else if (SELECT_CASE_var == "PLANT") {
3698 0 : GroupTypeString = "Plant";
3699 6 : } else if (SELECT_CASE_var == "SYSTEM") {
3700 6 : GroupTypeString = "System";
3701 : } else {
3702 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3703 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(6) + '=' + cAlphaArgs(6));
3704 0 : ErrorsFound = true;
3705 : }
3706 : }
3707 :
3708 : // End Use Type
3709 : {
3710 22 : auto const SELECT_CASE_var(cAlphaArgs(7));
3711 :
3712 11 : if (SELECT_CASE_var == "HEATING") {
3713 0 : EndUseTypeString = "Heating";
3714 11 : } else if (SELECT_CASE_var == "COOLING") {
3715 5 : EndUseTypeString = "Cooling";
3716 6 : } else if (SELECT_CASE_var == "INTERIORLIGHTS") {
3717 0 : EndUseTypeString = "InteriorLights";
3718 6 : } else if (SELECT_CASE_var == "EXTERIORLIGHTS") {
3719 0 : EndUseTypeString = "ExteriorLights";
3720 6 : } else if (SELECT_CASE_var == "INTERIOREQUIPMENT") {
3721 0 : EndUseTypeString = "InteriorEquipment";
3722 6 : } else if (SELECT_CASE_var == "EXTERIOREQUIPMENT") {
3723 0 : EndUseTypeString = "ExteriorEquipment";
3724 6 : } else if (SELECT_CASE_var == "FANS") {
3725 0 : EndUseTypeString = "Fans";
3726 6 : } else if (SELECT_CASE_var == "PUMPS") {
3727 0 : EndUseTypeString = "Pumps";
3728 6 : } else if (SELECT_CASE_var == "HEATREJECTION") {
3729 0 : EndUseTypeString = "HeatRejection";
3730 6 : } else if (SELECT_CASE_var == "HUMIDIFIER") {
3731 0 : EndUseTypeString = "Humidifier";
3732 6 : } else if (SELECT_CASE_var == "HEATRECOVERY") {
3733 0 : EndUseTypeString = "HeatRecovery";
3734 6 : } else if (SELECT_CASE_var == "WATERSYSTEMS") {
3735 0 : EndUseTypeString = "WaterSystems";
3736 6 : } else if (SELECT_CASE_var == "REFRIGERATION") {
3737 0 : EndUseTypeString = "Refrigeration";
3738 6 : } else if (SELECT_CASE_var == "ONSITEGENERATION") {
3739 0 : EndUseTypeString = "Cogeneration";
3740 6 : } else if (SELECT_CASE_var == "HEATINGCOILS") {
3741 2 : EndUseTypeString = "HeatingCoils";
3742 4 : } else if (SELECT_CASE_var == "COOLINGCOILS") {
3743 4 : EndUseTypeString = "CoolingCoils";
3744 0 : } else if (SELECT_CASE_var == "CHILLERS") {
3745 0 : EndUseTypeString = "Chillers";
3746 0 : } else if (SELECT_CASE_var == "BOILERS") {
3747 0 : EndUseTypeString = "Boilers";
3748 0 : } else if (SELECT_CASE_var == "BASEBOARD") {
3749 0 : EndUseTypeString = "Baseboard";
3750 0 : } else if (SELECT_CASE_var == "HEATRECOVERYFORCOOLING") {
3751 0 : EndUseTypeString = "HeatRecoveryForCooling";
3752 0 : } else if (SELECT_CASE_var == "HEATRECOVERYFORHEATING") {
3753 0 : EndUseTypeString = "HeatRecoveryForHeating";
3754 : } else {
3755 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3756 0 : ShowContinueError(state, "Invalid " + cAlphaFieldNames(7) + '=' + cAlphaArgs(7));
3757 0 : ErrorsFound = true;
3758 : }
3759 : }
3760 :
3761 : // Additional End Use Types Only Used for EnergyTransfer
3762 16 : if ((ResourceTypeString != "EnergyTransfer") &&
3763 15 : (EndUseTypeString == "HeatingCoils" || EndUseTypeString == "CoolingCoils" || EndUseTypeString == "Chillers" ||
3764 15 : EndUseTypeString == "Boilers" || EndUseTypeString == "Baseboard" || EndUseTypeString == "HeatRecoveryForCooling" ||
3765 5 : EndUseTypeString == "HeatRecoveryForHeating")) {
3766 0 : ShowWarningError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid field.");
3767 0 : ShowContinueError(state,
3768 0 : "Invalid " + cAlphaFieldNames(5) + "=" + cAlphaArgs(5) + " for " + cAlphaFieldNames(7) + "=" + cAlphaArgs(7));
3769 0 : ShowContinueError(state, "Field " + cAlphaFieldNames(5) + " is reset from " + cAlphaArgs(5) + " to EnergyTransfer");
3770 0 : ResourceTypeString = "EnergyTransfer";
3771 : }
3772 :
3773 11 : if (!lAlphaFieldBlanks(8)) {
3774 5 : EndUseSubCatString = cAlphaArgs(8);
3775 :
3776 15 : SetupOutputVariable(state,
3777 5 : cAlphaArgs(1),
3778 : curUnit,
3779 5 : state.dataRuntimeLangProcessor->RuntimeReportVar(RuntimeReportVarNum).Value,
3780 : FreqString,
3781 : VarTypeString,
3782 : "EMS",
3783 : _,
3784 : ResourceTypeString,
3785 : EndUseTypeString,
3786 : EndUseSubCatString,
3787 5 : GroupTypeString);
3788 : } else { // no subcat
3789 18 : SetupOutputVariable(state,
3790 6 : cAlphaArgs(1),
3791 : curUnit,
3792 6 : state.dataRuntimeLangProcessor->RuntimeReportVar(RuntimeReportVarNum).Value,
3793 : FreqString,
3794 : VarTypeString,
3795 : "EMS",
3796 : _,
3797 : ResourceTypeString,
3798 : EndUseTypeString,
3799 : _,
3800 6 : GroupTypeString);
3801 : }
3802 : }
3803 : } // NumEMSMeteredOutputVariables > 0
3804 :
3805 71 : cAlphaFieldNames.deallocate();
3806 71 : cAlphaArgs.deallocate();
3807 71 : lAlphaFieldBlanks.deallocate();
3808 71 : cNumericFieldNames.deallocate();
3809 71 : rNumericArgs.deallocate();
3810 71 : lNumericFieldBlanks.deallocate();
3811 :
3812 71 : if (ErrorsFound) {
3813 0 : ShowFatalError(state, "Errors found in getting EMS Runtime Language input. Preceding condition causes termination.");
3814 : }
3815 :
3816 : } // GetInput
3817 71 : }
3818 :
3819 1069041 : void ReportRuntimeLanguage(EnergyPlusData &state)
3820 : {
3821 :
3822 : // SUBROUTINE INFORMATION:
3823 : // AUTHOR Peter Graham Ellis
3824 : // DATE WRITTEN June 2006
3825 : // MODIFIED na
3826 : // RE-ENGINEERED na
3827 :
3828 : // PURPOSE OF THIS SUBROUTINE:
3829 :
3830 : // METHODOLOGY EMPLOYED:
3831 :
3832 : // USE STATEMENTS:
3833 :
3834 : // Locals
3835 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3836 : int RuntimeReportVarNum;
3837 : int VariableNum;
3838 :
3839 6446780 : for (RuntimeReportVarNum = 1;
3840 6446780 : RuntimeReportVarNum <= state.dataRuntimeLang->NumEMSOutputVariables + state.dataRuntimeLang->NumEMSMeteredOutputVariables;
3841 : ++RuntimeReportVarNum) {
3842 5377739 : VariableNum = state.dataRuntimeLangProcessor->RuntimeReportVar(RuntimeReportVarNum).VariableNum;
3843 5377739 : if (state.dataRuntimeLang->ErlVariable(VariableNum).Value.Type == Value::Number) {
3844 4761940 : state.dataRuntimeLangProcessor->RuntimeReportVar(RuntimeReportVarNum).Value =
3845 4761940 : state.dataRuntimeLang->ErlVariable(VariableNum).Value.Number;
3846 : } else {
3847 615799 : state.dataRuntimeLangProcessor->RuntimeReportVar(RuntimeReportVarNum).Value = 0.0;
3848 : }
3849 : }
3850 1069041 : }
3851 :
3852 172934876 : ErlValueType SetErlValueNumber(Real64 const Number, Optional<ErlValueType const> OrigValue)
3853 : {
3854 : // FUNCTION INFORMATION:
3855 : // AUTHOR P. Ellis
3856 : // DATE WRITTEN unknown
3857 : // MODIFIED na
3858 : // RE-ENGINEERED na
3859 :
3860 : // PURPOSE OF THIS FUNCTION:
3861 : // <description>
3862 :
3863 : // METHODOLOGY EMPLOYED:
3864 : // <description>
3865 :
3866 : // REFERENCES:
3867 : // na
3868 :
3869 : // USE STATEMENTS:
3870 : // na
3871 :
3872 : // Return value
3873 172934876 : ErlValueType newValue;
3874 :
3875 : // Locals
3876 : // FUNCTION ARGUMENT DEFINITIONS:
3877 : // na
3878 :
3879 : // FUNCTION PARAMETER DEFINITIONS:
3880 : // na
3881 :
3882 : // INTERFACE BLOCK SPECIFICATIONS:
3883 : // na
3884 :
3885 : // DERIVED TYPE DEFINITIONS:
3886 : // na
3887 :
3888 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3889 : // na
3890 :
3891 172934876 : if (present(OrigValue)) { // preserve other parts of structure and only updated Value%Number
3892 71149181 : newValue = OrigValue;
3893 71149181 : newValue.Number = Number;
3894 : } else {
3895 101785695 : newValue.Type = Value::Number;
3896 101785695 : newValue.Number = Number;
3897 : }
3898 :
3899 172934876 : newValue.initialized = true;
3900 172934876 : return newValue;
3901 : }
3902 :
3903 0 : ErlValueType StringValue(std::string const &String)
3904 : {
3905 : // FUNCTION INFORMATION:
3906 : // AUTHOR P. Ellis
3907 : // DATE WRITTEN unkown
3908 : // MODIFIED na
3909 : // RE-ENGINEERED na
3910 :
3911 : // PURPOSE OF THIS FUNCTION:
3912 : // convert string to Erl Value structure
3913 :
3914 : // METHODOLOGY EMPLOYED:
3915 : // <description>
3916 :
3917 : // REFERENCES:
3918 : // na
3919 :
3920 : // USE STATEMENTS:
3921 : // na
3922 :
3923 : // Return value
3924 0 : ErlValueType Value;
3925 :
3926 : // Locals
3927 : // FUNCTION ARGUMENT DEFINITIONS:
3928 : // na
3929 :
3930 : // FUNCTION PARAMETER DEFINITIONS:
3931 : // na
3932 :
3933 : // INTERFACE BLOCK SPECIFICATIONS:
3934 : // na
3935 :
3936 : // DERIVED TYPE DEFINITIONS:
3937 : // na
3938 :
3939 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3940 : // na
3941 :
3942 0 : Value.Type = Value::String;
3943 0 : Value.String = String;
3944 :
3945 0 : return Value;
3946 : }
3947 :
3948 1912803 : std::string ValueToString(ErlValueType const &Value)
3949 : {
3950 : // FUNCTION INFORMATION:
3951 : // AUTHOR P. Ellis
3952 : // DATE WRITTEN Unknown
3953 : // MODIFIED na
3954 : // RE-ENGINEERED na
3955 :
3956 : // PURPOSE OF THIS FUNCTION:
3957 : // <description>
3958 :
3959 : // METHODOLOGY EMPLOYED:
3960 : // <description>
3961 :
3962 : // REFERENCES:
3963 : // na
3964 :
3965 : // Using/Aliasing
3966 :
3967 : // Return value
3968 1912803 : std::string String;
3969 :
3970 : // Locals
3971 : // FUNCTION ARGUMENT DEFINITIONS:
3972 :
3973 1912803 : String = "";
3974 :
3975 1912803 : switch (Value.Type) {
3976 1451639 : case Value::Number:
3977 1451639 : if (Value.Number == 0.0) {
3978 531020 : String = "0.0";
3979 : } else {
3980 920619 : String = format("{:.6T}", Value.Number); //(String)
3981 : }
3982 1451639 : break;
3983 :
3984 352904 : case Value::String:
3985 352904 : String = Value.String;
3986 352904 : break;
3987 :
3988 0 : case Value::Array:
3989 : // TBD
3990 0 : break;
3991 :
3992 417 : case Value::Error:
3993 417 : String = " *** Error: " + Value.Error + " *** ";
3994 417 : break;
3995 :
3996 107843 : default:
3997 : // Nothing to do
3998 107843 : break;
3999 : }
4000 :
4001 1912803 : return String;
4002 : }
4003 :
4004 25458 : int FindEMSVariable(EnergyPlusData &state,
4005 : std::string const &VariableName, // variable name in Erl
4006 : int const StackNum)
4007 : {
4008 :
4009 : // FUNCTION INFORMATION:
4010 : // AUTHOR Peter Graham Ellis
4011 : // DATE WRITTEN June 2006
4012 : // MODIFIED na
4013 : // RE-ENGINEERED na
4014 :
4015 : // PURPOSE OF THIS FUNCTION:
4016 :
4017 : // Return value
4018 : int VariableNum;
4019 :
4020 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
4021 : bool Found;
4022 : int TrendVarNum;
4023 :
4024 25458 : Found = false;
4025 50916 : std::string const UppercaseName = UtilityRoutines::MakeUPPERCase(VariableName);
4026 :
4027 : // check in ErlVariables
4028 7733275 : for (VariableNum = 1; VariableNum <= state.dataRuntimeLang->NumErlVariables; ++VariableNum) {
4029 7722314 : if (state.dataRuntimeLang->ErlVariable(VariableNum).Name == UppercaseName) {
4030 27942 : if ((state.dataRuntimeLang->ErlVariable(VariableNum).StackNum == StackNum) ||
4031 12403 : (state.dataRuntimeLang->ErlVariable(VariableNum).StackNum == 0)) {
4032 14497 : Found = true;
4033 14497 : break;
4034 : }
4035 : }
4036 : }
4037 :
4038 : // check in Trend variables
4039 27242 : for (TrendVarNum = 1; TrendVarNum <= state.dataRuntimeLang->NumErlTrendVariables; ++TrendVarNum) {
4040 1803 : if (state.dataRuntimeLang->TrendVariable(TrendVarNum).Name == UppercaseName) {
4041 19 : VariableNum = state.dataRuntimeLang->TrendVariable(TrendVarNum).ErlVariablePointer;
4042 38 : if ((state.dataRuntimeLang->ErlVariable(VariableNum).StackNum == StackNum) ||
4043 19 : (state.dataRuntimeLang->ErlVariable(VariableNum).StackNum == 0)) {
4044 19 : Found = true;
4045 19 : break;
4046 : }
4047 : }
4048 : }
4049 :
4050 25458 : if (!Found) VariableNum = 0;
4051 :
4052 50916 : return VariableNum;
4053 : }
4054 :
4055 21342 : int NewEMSVariable(EnergyPlusData &state, std::string const &VariableName, int const StackNum, Optional<ErlValueType const> Value)
4056 : {
4057 :
4058 : // FUNCTION INFORMATION:
4059 : // AUTHOR Peter Graham Ellis
4060 : // DATE WRITTEN June 2006
4061 : // MODIFIED na
4062 : // RE-ENGINEERED na
4063 :
4064 : // PURPOSE OF THIS FUNCTION:
4065 : // Creates new variable if it doesn't exist. If exists, returns existing variable number.
4066 :
4067 21342 : int VariableNum = FindEMSVariable(state, VariableName, StackNum);
4068 :
4069 21342 : if (VariableNum == 0) { // Variable does not exist anywhere yet
4070 7180 : if (state.dataRuntimeLang->NumErlVariables == 0) {
4071 71 : state.dataRuntimeLang->ErlVariable.allocate(1);
4072 71 : state.dataRuntimeLang->NumErlVariables = 1;
4073 : } else { // Extend the variable array
4074 7109 : state.dataRuntimeLang->ErlVariable.redimension(++state.dataRuntimeLang->NumErlVariables);
4075 : }
4076 :
4077 : // Add the new variable
4078 7180 : VariableNum = state.dataRuntimeLang->NumErlVariables;
4079 7180 : state.dataRuntimeLang->ErlVariable(VariableNum).Name = UtilityRoutines::MakeUPPERCase(VariableName);
4080 7180 : state.dataRuntimeLang->ErlVariable(VariableNum).StackNum = StackNum;
4081 7180 : state.dataRuntimeLang->ErlVariable(VariableNum).Value.Type = Value::Number; // ErlVariable values are numbers
4082 : }
4083 :
4084 21342 : if (present(Value)) state.dataRuntimeLang->ErlVariable(VariableNum).Value = Value;
4085 :
4086 21342 : return VariableNum;
4087 : }
4088 :
4089 9753 : void SetupPossibleOperators(EnergyPlusData &state)
4090 : {
4091 :
4092 : // SUBROUTINE INFORMATION:
4093 : // AUTHOR Brent Griffith
4094 : // DATE WRITTEN May 2009
4095 : // MODIFIED na
4096 : // RE-ENGINEERED na
4097 :
4098 : // PURPOSE OF THIS SUBROUTINE:
4099 : // setup hard coded list of possible operands
4100 :
4101 : // METHODOLOGY EMPLOYED:
4102 : // Allocate structure and fill basic info on opertors and operands
4103 : // operators include built-in functions where operands are function arguments
4104 :
4105 : // REFERENCES:
4106 : // na
4107 :
4108 : // USE STATEMENTS:
4109 : // na
4110 :
4111 : // Locals
4112 : // SUBROUTINE ARGUMENT DEFINITIONS:
4113 : // na
4114 :
4115 : // SUBROUTINE PARAMETER DEFINITIONS:
4116 : // na
4117 :
4118 : // INTERFACE BLOCK SPECIFICATIONS:
4119 : // na
4120 :
4121 : // DERIVED TYPE DEFINITIONS:
4122 : // na
4123 :
4124 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4125 :
4126 9753 : if (state.dataRuntimeLangProcessor->AlreadyDidOnce) return;
4127 :
4128 52 : state.dataRuntimeLang->PossibleOperators.allocate(NumPossibleOperators);
4129 :
4130 : // Build operator table
4131 : // Order in this table is the order of precedence
4132 :
4133 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Literal)).NumOperands = 1;
4134 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Literal)).Code = ErlFunc::Literal;
4135 :
4136 : // not sure how to distinguish from subtract in parsing of tokens, not yet available
4137 : // PossibleOperators(OperatorNegative)%NumOperands = 1
4138 : // PossibleOperators(OperatorNegative)%Code = OperatorNegative
4139 : // PossibleOperators(OperatorNegative)%Symbol = '-'
4140 :
4141 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Divide)).Symbol = "/";
4142 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Divide)).NumOperands = 2;
4143 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Divide)).Code = ErlFunc::Divide;
4144 :
4145 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Multiply)).Symbol = "*";
4146 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Multiply)).NumOperands = 2;
4147 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Multiply)).Code = ErlFunc::Multiply;
4148 :
4149 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Subtract)).Symbol = "-";
4150 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Subtract)).NumOperands = 2;
4151 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Subtract)).Code = ErlFunc::Subtract;
4152 :
4153 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Add)).Symbol = "+";
4154 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Add)).NumOperands = 2;
4155 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Add)).Code = ErlFunc::Add;
4156 :
4157 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Equal)).Symbol = "==";
4158 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Equal)).NumOperands = 2;
4159 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Equal)).Code = ErlFunc::Equal;
4160 :
4161 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::NotEqual)).Symbol = "<>";
4162 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::NotEqual)).NumOperands = 2;
4163 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::NotEqual)).Code = ErlFunc::NotEqual;
4164 :
4165 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LessOrEqual)).Symbol = "<=";
4166 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LessOrEqual)).NumOperands = 2;
4167 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LessOrEqual)).Code = ErlFunc::LessOrEqual;
4168 :
4169 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::GreaterOrEqual)).Symbol = ">=";
4170 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::GreaterOrEqual)).NumOperands = 2;
4171 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::GreaterOrEqual)).Code = ErlFunc::GreaterOrEqual;
4172 :
4173 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LessThan)).Symbol = "<";
4174 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LessThan)).NumOperands = 2;
4175 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LessThan)).Code = ErlFunc::LessThan;
4176 :
4177 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::GreaterThan)).Symbol = ">";
4178 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::GreaterThan)).NumOperands = 2;
4179 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::GreaterThan)).Code = ErlFunc::GreaterThan;
4180 :
4181 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RaiseToPower)).Symbol = "^";
4182 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RaiseToPower)).NumOperands = 2;
4183 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RaiseToPower)).Code = ErlFunc::RaiseToPower;
4184 :
4185 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LogicalAND)).Symbol = "&&";
4186 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LogicalAND)).NumOperands = 2;
4187 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LogicalAND)).Code = ErlFunc::LogicalAND;
4188 :
4189 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LogicalOR)).Symbol = "||";
4190 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LogicalOR)).NumOperands = 2;
4191 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::LogicalOR)).Code = ErlFunc::LogicalOR;
4192 :
4193 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Round)).Symbol = "@ROUND";
4194 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Round)).NumOperands = 1;
4195 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Round)).Code = ErlFunc::Round;
4196 :
4197 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Mod)).Symbol = "@MOD";
4198 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Mod)).NumOperands = 2;
4199 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Mod)).Code = ErlFunc::Mod;
4200 :
4201 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Sin)).Symbol = "@SIN";
4202 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Sin)).NumOperands = 1;
4203 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Sin)).Code = ErlFunc::Sin;
4204 :
4205 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Cos)).Symbol = "@COS";
4206 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Cos)).NumOperands = 1;
4207 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Cos)).Code = ErlFunc::Cos;
4208 :
4209 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::ArcSin)).Symbol = "@ARCSIN";
4210 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::ArcSin)).NumOperands = 1;
4211 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::ArcSin)).Code = ErlFunc::ArcSin;
4212 :
4213 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::ArcCos)).Symbol = "@ARCCOS";
4214 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::ArcCos)).NumOperands = 1;
4215 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::ArcCos)).Code = ErlFunc::ArcCos;
4216 :
4217 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::DegToRad)).Symbol = "@DEGTORAD";
4218 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::DegToRad)).NumOperands = 1;
4219 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::DegToRad)).Code = ErlFunc::DegToRad;
4220 :
4221 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RadToDeg)).Symbol = "@RADTODEG";
4222 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RadToDeg)).NumOperands = 1;
4223 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RadToDeg)).Code = ErlFunc::RadToDeg;
4224 :
4225 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Exp)).Symbol = "@EXP";
4226 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Exp)).NumOperands = 1;
4227 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Exp)).Code = ErlFunc::Exp;
4228 :
4229 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Ln)).Symbol = "@LN";
4230 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Ln)).NumOperands = 1;
4231 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Ln)).Code = ErlFunc::Ln;
4232 :
4233 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Max)).Symbol = "@MAX";
4234 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Max)).NumOperands = 2;
4235 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Max)).Code = ErlFunc::Max;
4236 :
4237 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Min)).Symbol = "@MIN";
4238 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Min)).NumOperands = 2;
4239 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::Min)).Code = ErlFunc::Min;
4240 :
4241 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::ABS)).Symbol = "@ABS";
4242 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::ABS)).NumOperands = 1;
4243 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::ABS)).Code = ErlFunc::ABS;
4244 :
4245 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RandU)).Symbol = "@RANDOMUNIFORM";
4246 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RandU)).NumOperands = 2;
4247 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RandU)).Code = ErlFunc::RandU;
4248 :
4249 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RandG)).Symbol = "@RANDOMNORMAL";
4250 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RandG)).NumOperands = 4;
4251 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RandG)).Code = ErlFunc::RandG;
4252 :
4253 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RandSeed)).Symbol = "@SEEDRANDOM";
4254 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RandSeed)).NumOperands = 1;
4255 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RandSeed)).Code = ErlFunc::RandSeed;
4256 :
4257 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhoAirFnPbTdbW)).Symbol = "@RHOAIRFNPBTDBW";
4258 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhoAirFnPbTdbW)).NumOperands = 3;
4259 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhoAirFnPbTdbW)).Code = ErlFunc::RhoAirFnPbTdbW;
4260 :
4261 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CpAirFnW)).Symbol = "@CPAIRFNW";
4262 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CpAirFnW)).NumOperands = 1;
4263 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CpAirFnW)).Code = ErlFunc::CpAirFnW;
4264 :
4265 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HfgAirFnWTdb)).Symbol = "@HFGAIRFNWTDB";
4266 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HfgAirFnWTdb)).NumOperands = 2;
4267 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HfgAirFnWTdb)).Code = ErlFunc::HfgAirFnWTdb;
4268 :
4269 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HgAirFnWTdb)).Symbol = "@HGAIRFNWTDB";
4270 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HgAirFnWTdb)).NumOperands = 2;
4271 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HgAirFnWTdb)).Code = ErlFunc::HgAirFnWTdb;
4272 :
4273 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TdpFnTdbTwbPb)).Symbol = "@TDPFNTDBTWBPB";
4274 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TdpFnTdbTwbPb)).NumOperands = 3;
4275 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TdpFnTdbTwbPb)).Code = ErlFunc::TdpFnTdbTwbPb;
4276 :
4277 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TdpFnWPb)).Symbol = "@TDPFNWPB";
4278 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TdpFnWPb)).NumOperands = 2;
4279 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TdpFnWPb)).Code = ErlFunc::TdpFnWPb;
4280 :
4281 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HFnTdbW)).Symbol = "@HFNTDBW";
4282 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HFnTdbW)).NumOperands = 2;
4283 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HFnTdbW)).Code = ErlFunc::HFnTdbW;
4284 :
4285 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HFnTdbRhPb)).Symbol = "@HFNTDBRHPB";
4286 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HFnTdbRhPb)).NumOperands = 3;
4287 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::HFnTdbRhPb)).Code = ErlFunc::HFnTdbRhPb;
4288 :
4289 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TdbFnHW)).Symbol = "@TDBFNHW";
4290 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TdbFnHW)).NumOperands = 2;
4291 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TdbFnHW)).Code = ErlFunc::TdbFnHW;
4292 :
4293 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhovFnTdbRh)).Symbol = "@RHOVFNTDBR";
4294 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhovFnTdbRh)).NumOperands = 2;
4295 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhovFnTdbRh)).Code = ErlFunc::RhovFnTdbRh;
4296 :
4297 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhovFnTdbRhLBnd0C)).Symbol = "@RhovFnTdbRhLBnd0C";
4298 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhovFnTdbRhLBnd0C)).NumOperands = 2;
4299 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhovFnTdbRhLBnd0C)).Code = ErlFunc::RhovFnTdbRhLBnd0C;
4300 :
4301 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhovFnTdbWPb)).Symbol = "@RHOVFNTDBWPB";
4302 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhovFnTdbWPb)).NumOperands = 3;
4303 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhovFnTdbWPb)).Code = ErlFunc::RhovFnTdbWPb;
4304 :
4305 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhFnTdbRhov)).Symbol = "@RHFNTDBRHOV";
4306 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhFnTdbRhov)).NumOperands = 2;
4307 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhFnTdbRhov)).Code = ErlFunc::RhFnTdbRhov;
4308 :
4309 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhFnTdbRhovLBnd0C)).Symbol = "@RHFNTDBRHOVLBND0C";
4310 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhFnTdbRhovLBnd0C)).NumOperands = 2;
4311 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhFnTdbRhovLBnd0C)).Code = ErlFunc::RhFnTdbRhovLBnd0C;
4312 :
4313 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhFnTdbWPb)).Symbol = "@RHFNTDBWPB";
4314 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhFnTdbWPb)).NumOperands = 3;
4315 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhFnTdbWPb)).Code = ErlFunc::RhFnTdbWPb;
4316 :
4317 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TwbFnTdbWPb)).Symbol = "@TWBFNTDBWPB";
4318 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TwbFnTdbWPb)).NumOperands = 3;
4319 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TwbFnTdbWPb)).Code = ErlFunc::TwbFnTdbWPb;
4320 :
4321 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::VFnTdbWPb)).Symbol = "@VFNTDBWPB";
4322 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::VFnTdbWPb)).NumOperands = 3;
4323 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::VFnTdbWPb)).Code = ErlFunc::VFnTdbWPb;
4324 :
4325 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdpPb)).Symbol = "@WFNTDPPB";
4326 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdpPb)).NumOperands = 2;
4327 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdpPb)).Code = ErlFunc::WFnTdpPb;
4328 :
4329 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdbH)).Symbol = "@WFNTDBH";
4330 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdbH)).NumOperands = 2;
4331 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdbH)).Code = ErlFunc::WFnTdbH;
4332 :
4333 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdbTwbPb)).Symbol = "@WFNTDBTWBPB";
4334 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdbTwbPb)).NumOperands = 3;
4335 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdbTwbPb)).Code = ErlFunc::WFnTdbTwbPb;
4336 :
4337 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdbRhPb)).Symbol = "@WFNTDBRHPB";
4338 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdbRhPb)).NumOperands = 4;
4339 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WFnTdbRhPb)).Code = ErlFunc::WFnTdbRhPb;
4340 :
4341 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::PsatFnTemp)).Symbol = "@PSATFNTEMP";
4342 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::PsatFnTemp)).NumOperands = 1;
4343 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::PsatFnTemp)).Code = ErlFunc::PsatFnTemp;
4344 :
4345 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TsatFnHPb)).Symbol = "@TSATFNHPB";
4346 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TsatFnHPb)).NumOperands = 2;
4347 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TsatFnHPb)).Code = ErlFunc::TsatFnHPb;
4348 :
4349 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TsatFnPb)).Symbol = "@TSATFNPB";
4350 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TsatFnPb)).NumOperands = 1;
4351 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TsatFnPb)).Code = ErlFunc::TsatFnPb;
4352 :
4353 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CpCW)).Symbol = "@CPCW";
4354 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CpCW)).NumOperands = 1;
4355 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CpCW)).Code = ErlFunc::CpCW;
4356 :
4357 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CpHW)).Symbol = "@CPHW";
4358 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CpHW)).NumOperands = 1;
4359 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CpHW)).Code = ErlFunc::CpHW;
4360 :
4361 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhoH2O)).Symbol = "@RHOH2O";
4362 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhoH2O)).NumOperands = 1;
4363 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::RhoH2O)).Code = ErlFunc::RhoH2O;
4364 :
4365 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::FatalHaltEp)).Symbol = "@FATALHALTEP";
4366 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::FatalHaltEp)).NumOperands = 1;
4367 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::FatalHaltEp)).Code = ErlFunc::FatalHaltEp;
4368 :
4369 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::SevereWarnEp)).Symbol = "@SEVEREWARNEP";
4370 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::SevereWarnEp)).NumOperands = 1;
4371 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::SevereWarnEp)).Code = ErlFunc::SevereWarnEp;
4372 :
4373 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WarnEp)).Symbol = "@WARNEP";
4374 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WarnEp)).NumOperands = 1;
4375 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::WarnEp)).Code = ErlFunc::WarnEp;
4376 :
4377 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendValue)).Symbol = "@TRENDVALUE";
4378 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendValue)).NumOperands = 2;
4379 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendValue)).Code = ErlFunc::TrendValue;
4380 :
4381 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendAverage)).Symbol = "@TRENDAVERAGE";
4382 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendAverage)).NumOperands = 2;
4383 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendAverage)).Code = ErlFunc::TrendAverage;
4384 :
4385 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendMax)).Symbol = "@TRENDMAX";
4386 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendMax)).NumOperands = 2;
4387 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendMax)).Code = ErlFunc::TrendMax;
4388 :
4389 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendMin)).Symbol = "@TRENDMIN";
4390 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendMin)).NumOperands = 2;
4391 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendMin)).Code = ErlFunc::TrendMin;
4392 :
4393 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendDirection)).Symbol = "@TRENDDIRECTION";
4394 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendDirection)).NumOperands = 2;
4395 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendDirection)).Code = ErlFunc::TrendDirection;
4396 :
4397 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendSum)).Symbol = "@TRENDSUM";
4398 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendSum)).NumOperands = 2;
4399 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TrendSum)).Code = ErlFunc::TrendSum;
4400 :
4401 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CurveValue)).Symbol = "@CURVEVALUE";
4402 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CurveValue)).NumOperands = 6;
4403 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::CurveValue)).Code = ErlFunc::CurveValue;
4404 :
4405 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayIsRain)).Symbol = "@TODAYISRAIN";
4406 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayIsRain)).NumOperands = 2;
4407 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayIsRain)).Code = ErlFunc::TodayIsRain;
4408 :
4409 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayIsSnow)).Symbol = "@TODAYISSNOW";
4410 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayIsSnow)).NumOperands = 2;
4411 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayIsSnow)).Code = ErlFunc::TodayIsSnow;
4412 :
4413 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutDryBulbTemp)).Symbol = "@TODAYOUTDRYBULBTEMP";
4414 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutDryBulbTemp)).NumOperands = 2;
4415 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutDryBulbTemp)).Code = ErlFunc::TodayOutDryBulbTemp;
4416 :
4417 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutDewPointTemp)).Symbol = "@TODAYOUTDEWPOINTTEMP";
4418 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutDewPointTemp)).NumOperands = 2;
4419 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutDewPointTemp)).Code = ErlFunc::TodayOutDewPointTemp;
4420 :
4421 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutBaroPress)).Symbol = "@TODAYOUTBAROPRESS";
4422 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutBaroPress)).NumOperands = 2;
4423 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutBaroPress)).Code = ErlFunc::TodayOutBaroPress;
4424 :
4425 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutRelHum)).Symbol = "@TODAYOUTRELHUM";
4426 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutRelHum)).NumOperands = 2;
4427 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayOutRelHum)).Code = ErlFunc::TodayOutRelHum;
4428 :
4429 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayWindSpeed)).Symbol = "@TODAYWINDSPEED";
4430 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayWindSpeed)).NumOperands = 2;
4431 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayWindSpeed)).Code = ErlFunc::TodayWindSpeed;
4432 :
4433 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayWindDir)).Symbol = "@TODAYWINDDIR";
4434 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayWindDir)).NumOperands = 2;
4435 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayWindDir)).Code = ErlFunc::TodayWindDir;
4436 :
4437 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodaySkyTemp)).Symbol = "@TODAYSKYTEMP";
4438 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodaySkyTemp)).NumOperands = 2;
4439 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodaySkyTemp)).Code = ErlFunc::TodaySkyTemp;
4440 :
4441 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayHorizIRSky)).Symbol = "@TODAYHORIZIRSKY";
4442 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayHorizIRSky)).NumOperands = 2;
4443 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayHorizIRSky)).Code = ErlFunc::TodayHorizIRSky;
4444 :
4445 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayBeamSolarRad)).Symbol = "@TODAYBEAMSOLARRAD";
4446 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayBeamSolarRad)).NumOperands = 2;
4447 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayBeamSolarRad)).Code = ErlFunc::TodayBeamSolarRad;
4448 :
4449 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayDifSolarRad)).Symbol = "@TODAYDIFSOLARRAD";
4450 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayDifSolarRad)).NumOperands = 2;
4451 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayDifSolarRad)).Code = ErlFunc::TodayDifSolarRad;
4452 :
4453 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayAlbedo)).Symbol = "@TODAYALBEDO";
4454 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayAlbedo)).NumOperands = 2;
4455 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayAlbedo)).Code = ErlFunc::TodayAlbedo;
4456 :
4457 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayLiquidPrecip)).Symbol = "@TODAYLIQUIDPRECIP";
4458 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayLiquidPrecip)).NumOperands = 2;
4459 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TodayLiquidPrecip)).Code = ErlFunc::TodayLiquidPrecip;
4460 :
4461 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowIsRain)).Symbol = "@TOMORROWISRAIN";
4462 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowIsRain)).NumOperands = 2;
4463 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowIsRain)).Code = ErlFunc::TomorrowIsRain;
4464 :
4465 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowIsSnow)).Symbol = "@TOMORROWISSNOW";
4466 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowIsSnow)).NumOperands = 2;
4467 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowIsSnow)).Code = ErlFunc::TomorrowIsSnow;
4468 :
4469 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutDryBulbTemp)).Symbol = "@TOMORROWOUTDRYBULBTEMP";
4470 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutDryBulbTemp)).NumOperands = 2;
4471 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutDryBulbTemp)).Code = ErlFunc::TomorrowOutDryBulbTemp;
4472 :
4473 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutDewPointTemp)).Symbol = "@TOMORROWOUTDEWPOINTTEMP";
4474 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutDewPointTemp)).NumOperands = 2;
4475 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutDewPointTemp)).Code = ErlFunc::TomorrowOutDewPointTemp;
4476 :
4477 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutBaroPress)).Symbol = "@TOMORROWOUTBAROPRESS";
4478 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutBaroPress)).NumOperands = 2;
4479 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutBaroPress)).Code = ErlFunc::TomorrowOutBaroPress;
4480 :
4481 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutRelHum)).Symbol = "@TOMORROWOUTRELHUM";
4482 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutRelHum)).NumOperands = 2;
4483 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowOutRelHum)).Code = ErlFunc::TomorrowOutRelHum;
4484 :
4485 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowWindSpeed)).Symbol = "@TOMORROWWINDSPEED";
4486 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowWindSpeed)).NumOperands = 2;
4487 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowWindSpeed)).Code = ErlFunc::TomorrowWindSpeed;
4488 :
4489 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowWindDir)).Symbol = "@TOMORROWWINDDIR";
4490 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowWindDir)).NumOperands = 2;
4491 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowWindDir)).Code = ErlFunc::TomorrowWindDir;
4492 :
4493 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowSkyTemp)).Symbol = "@TOMORROWSKYTEMP";
4494 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowSkyTemp)).NumOperands = 2;
4495 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowSkyTemp)).Code = ErlFunc::TomorrowSkyTemp;
4496 :
4497 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowHorizIRSky)).Symbol = "@TOMORROWHORIZIRSKY";
4498 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowHorizIRSky)).NumOperands = 2;
4499 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowHorizIRSky)).Code = ErlFunc::TomorrowHorizIRSky;
4500 :
4501 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowBeamSolarRad)).Symbol = "@TOMORROWBEAMSOLARRAD";
4502 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowBeamSolarRad)).NumOperands = 2;
4503 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowBeamSolarRad)).Code = ErlFunc::TomorrowBeamSolarRad;
4504 :
4505 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowDifSolarRad)).Symbol = "@TOMORROWDIFSOLARRAD";
4506 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowDifSolarRad)).NumOperands = 2;
4507 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowDifSolarRad)).Code = ErlFunc::TomorrowDifSolarRad;
4508 :
4509 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowAlbedo)).Symbol = "@TOMORROWALBEDO";
4510 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowAlbedo)).NumOperands = 2;
4511 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowAlbedo)).Code = ErlFunc::TomorrowAlbedo;
4512 :
4513 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowLiquidPrecip)).Symbol = "@TOMORROWLIQUIDPRECIP";
4514 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowLiquidPrecip)).NumOperands = 2;
4515 52 : state.dataRuntimeLang->PossibleOperators(static_cast<int>(ErlFunc::TomorrowLiquidPrecip)).Code = ErlFunc::TomorrowLiquidPrecip;
4516 :
4517 52 : state.dataRuntimeLangProcessor->AlreadyDidOnce = true;
4518 : }
4519 :
4520 0 : void ExternalInterfaceSetErlVariable(EnergyPlusData &state,
4521 : int const varNum, // The variable index to be written during run time
4522 : Real64 const value // The real time value of the vairable to be set
4523 : )
4524 : {
4525 :
4526 : // SUBROUTINE INFORMATION:
4527 : // AUTHOR Rui Zhang
4528 : // DATE WRITTEN February 2010
4529 : // MODIFIED na
4530 : // RE-ENGINEERED na
4531 :
4532 : // PURPOSE OF THIS SUBROUTINE:
4533 : // This is the ExternalInterface runtime write ErlVariable function
4534 :
4535 : // METHODOLOGY EMPLOYED:
4536 : // USE STATEMENTS:
4537 :
4538 : // Locals
4539 : // SUBROUTINE ARGUMENT DEFINITIONS:
4540 :
4541 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4542 :
4543 0 : state.dataRuntimeLang->ErlVariable(varNum).Value = SetErlValueNumber(value);
4544 0 : }
4545 :
4546 5 : void ExternalInterfaceInitializeErlVariable(EnergyPlusData &state,
4547 : int const varNum, // The variable index to be written during run time
4548 : ErlValueType const &initialValue, // The initial value
4549 : bool const setToNull // Flag, if true, value will be initialized to Null
4550 : )
4551 : {
4552 :
4553 : // SUBROUTINE INFORMATION:
4554 : // AUTHOR Michael Wetter
4555 : // DATE WRITTEN February 2010
4556 : // MODIFIED na
4557 : // RE-ENGINEERED na
4558 :
4559 : // PURPOSE OF THIS SUBROUTINE:
4560 : // This subroutine sets flags for ExternalInterface variables
4561 :
4562 : // METHODOLOGY EMPLOYED:
4563 : // USE STATEMENTS:
4564 :
4565 : // Locals
4566 : // SUBROUTINE ARGUMENT DEFINITIONS:
4567 :
4568 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4569 : // Set initial value
4570 5 : if (setToNull) {
4571 0 : state.dataRuntimeLang->ErlVariable(varNum).Value.Type = Value::Null;
4572 : } else {
4573 5 : state.dataRuntimeLang->ErlVariable(varNum).Value = initialValue;
4574 : }
4575 :
4576 : // Set variables to read-only as we don't want that other programs write to them
4577 5 : state.dataRuntimeLang->ErlVariable(varNum).ReadOnly = true;
4578 : // Set flag that it is used by the ExternalInterface. This is needed to make sure that the ExternalInterface
4579 : // interface writes only to ExternalInterface variables, and not to other ErlVariable
4580 5 : state.dataRuntimeLang->ErlVariable(varNum).SetByExternalInterface = true;
4581 5 : }
4582 :
4583 0 : bool isExternalInterfaceErlVariable(EnergyPlusData &state, int const varNum) // The variable index to be written during run time
4584 : {
4585 :
4586 : // SUBROUTINE INFORMATION:
4587 : // AUTHOR Michael Wetter
4588 : // DATE WRITTEN February 2010
4589 : // MODIFIED na
4590 : // RE-ENGINEERED na
4591 :
4592 : // PURPOSE OF THIS SUBROUTINE:
4593 : // This function checks if an Erl name obtained from the xml file
4594 : // is indeed specified as a ExternalInterface variable in the idf file
4595 :
4596 : // METHODOLOGY EMPLOYED:
4597 : // USE STATEMENTS:
4598 :
4599 : // Return value
4600 : bool isExternalInterfaceVar; // Set to true if the variable is a ExternalInterface variable
4601 :
4602 : // Locals
4603 : // SUBROUTINE ARGUMENT DEFINITIONS:
4604 :
4605 0 : isExternalInterfaceVar = state.dataRuntimeLang->ErlVariable(varNum).SetByExternalInterface;
4606 :
4607 0 : return isExternalInterfaceVar;
4608 : }
4609 :
4610 2313 : } // namespace EnergyPlus::RuntimeLanguageProcessor
|