Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #ifndef General_hh_INCLUDED
49 : #define General_hh_INCLUDED
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array1A.hh>
53 : #include <ObjexxFCL/Array1D.hh>
54 : #include <ObjexxFCL/Array1S.hh>
55 : #include <ObjexxFCL/Array2A.hh>
56 : #include <ObjexxFCL/Optional.hh>
57 :
58 : // EnergyPlus Headers
59 : #include <EnergyPlus/Data/BaseData.hh>
60 : #include <EnergyPlus/EPVector.hh>
61 : #include <EnergyPlus/EnergyPlus.hh>
62 :
63 : namespace EnergyPlus {
64 :
65 : // Forward declarations
66 : struct EnergyPlusData;
67 :
68 : namespace Weather {
69 : enum class DateType;
70 : struct ReportPeriodData;
71 : } // namespace Weather
72 :
73 : namespace General {
74 :
75 : // A second version that does not require a payload -- use lambdas
76 : void SolveRoot(const EnergyPlusData &state,
77 : Real64 Eps, // required absolute accuracy
78 : int MaxIte, // maximum number of allowed iterations
79 : int &Flag, // integer storing exit status
80 : Real64 &XRes, // value of x that solves f(x,Par) = 0
81 : const std::function<Real64(Real64)> &f,
82 : Real64 X_0, // 1st bound of interval that contains the solution
83 : Real64 X_1); // 2nd bound of interval that contains the solution
84 :
85 : void MovingAvg(Array1D<Real64> &DataIn, int NumItemsInAvg);
86 :
87 : void ProcessDateString(EnergyPlusData &state,
88 : std::string const &String,
89 : int &PMonth,
90 : int &PDay,
91 : int &PWeekDay,
92 : Weather::DateType &DateType, // DateType found (-1=invalid, 1=month/day, 2=nth day in month, 3=last day in month)
93 : bool &ErrorsFound,
94 : ObjexxFCL::Optional_int PYear = _);
95 :
96 : void DetermineDateTokens(EnergyPlusData &state,
97 : std::string const &String,
98 : int &NumTokens, // Number of tokens found in string
99 : int &TokenDay, // Value of numeric field found
100 : int &TokenMonth, // Value of Month field found (1=Jan, 2=Feb, etc)
101 : int &TokenWeekday, // Value of Weekday field found (1=Sunday, 2=Monday, etc), 0 if none
102 : Weather::DateType &DateType, // DateType found (-1=invalid, 1=month/day, 2=nth day in month, 3=last day in month)
103 : bool &ErrorsFound, // Set to true if cannot process this string as a date
104 : ObjexxFCL::Optional_int TokenYear = _ // Value of Year if one appears to be present and this argument is present
105 : );
106 :
107 : void ValidateMonthDay(EnergyPlusData &state,
108 : std::string const &String, // REAL(r64) string being processed
109 : int Day,
110 : int Month,
111 : bool &ErrorsFound);
112 :
113 : int OrdinalDay(int Month, // Month, 1..12
114 : int Day, // Day of Month, not validated by month
115 : int LeapYearValue // 1 if leap year indicated, 0 if not
116 : );
117 :
118 : void InvOrdinalDay(int Number, int &PMonth, int &PDay, int LeapYr);
119 :
120 : bool BetweenDateHoursLeftInclusive(int TestDate, int TestHour, int StartDate, int StartHour, int EndDate, int EndHour);
121 :
122 : bool BetweenDates(int TestDate, // Date to test
123 : int StartDate, // Start date in sequence
124 : int EndDate // End date in sequence
125 : );
126 :
127 : std::string CreateSysTimeIntervalString(EnergyPlusData &state);
128 :
129 : int nthDayOfWeekOfMonth(const EnergyPlusData &state,
130 : int dayOfWeek, // day of week (Sunday=1, Monday=2, ...)
131 : int nthTime, // nth time the day of the week occurs (first monday, third tuesday, ..)
132 : int monthNumber // January = 1
133 : );
134 :
135 : Real64 SafeDivide(Real64 a, Real64 b);
136 :
137 : void Iterate(Real64 &ResultX, // ResultX is the final Iteration result passed back to the calling routine
138 : Real64 Tol, // Tolerance for Convergence
139 : Real64 X0, // Current value of X
140 : Real64 Y0, // Current value of the function Y(X)
141 : Real64 &X1, // First Previous values of X
142 : Real64 &Y1, // First Previous values of Y(X1)
143 : int Iter, // Number of iterations
144 : int &Cnvg // Convergence flag Cnvg = 0: Not converged
145 : );
146 :
147 : int FindNumberInList(int WhichNumber, Array1A_int ListOfItems, int NumItems);
148 :
149 : template <typename A> inline int FindNumberInList(int const WhichNumber, MArray1<A, int> const &ListOfItems, int const NumItems)
150 : {
151 : return FindNumberInList(WhichNumber, Array1D_int(ListOfItems), NumItems);
152 : }
153 :
154 : template <typename Container,
155 : class = typename std::enable_if<
156 : !std::is_same<typename Container::value_type, std::string>::value>::type> // Container needs isize() and operator(i) and value_type
157 0 : inline int FindNumberInList(int const WhichNumber, Container const &ListOfItems, int Container::value_type::*num_p)
158 : {
159 0 : int FindNumberInList(0);
160 0 : for (int Count = 1, NumItems = ListOfItems.isize(); Count <= NumItems; ++Count) {
161 0 : if (WhichNumber == ListOfItems(Count).*num_p) {
162 0 : FindNumberInList = Count;
163 0 : break;
164 : }
165 : }
166 0 : return FindNumberInList;
167 : }
168 :
169 : void DecodeMonDayHrMin(int Item, // word containing encoded month, day, hour, minute
170 : int &Month, // month in integer format (1-12)
171 : int &Day, // day in integer format (1-31)
172 : int &Hour, // hour in integer format (1-24)
173 : int &Minute // minute in integer format (0:59)
174 : );
175 :
176 : void EncodeMonDayHrMin(int &Item, // word containing encoded month, day, hour, minute
177 : int Month, // month in integer format (1:12)
178 : int Day, // day in integer format (1:31)
179 : int Hour, // hour in integer format (1:24)
180 : int Minute // minute in integer format (0:59)
181 : );
182 :
183 : std::string CreateTimeString(Real64 Time); // Time in seconds
184 :
185 : void ParseTime(Real64 Time, // Time value in seconds
186 : int &Hours, // Number of hours
187 : int &Minutes, // Number of minutes < 60
188 : Real64 &Seconds // Number of seconds < 60
189 : );
190 :
191 : void ScanForReports(EnergyPlusData &state,
192 : std::string const &reportName,
193 : bool &DoReport,
194 : ObjexxFCL::Optional_string_const ReportKey = _,
195 : ObjexxFCL::Optional_string Option1 = _,
196 : ObjexxFCL::Optional_string Option2 = _);
197 :
198 : void CheckCreatedZoneItemName(EnergyPlusData &state,
199 : std::string_view calledFrom, // routine called from
200 : std::string const &CurrentObject, // object being parsed
201 : std::string const &ZoneName, // Zone Name associated
202 : std::string::size_type MaxZoneNameLength, // maximum length of zonelist zone names
203 : std::string const &ItemName, // Item name (People, Lights, etc object)
204 : Array1_string const &ItemNames, // Item Names to check for duplication
205 : int NumItems, // Number of items in ItemNames array
206 : std::string &ResultName, // Resultant name
207 : bool &errFlag // Error flag set to true if error found here.
208 : );
209 :
210 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
211 27 : inline void CheckCreatedZoneItemName(EnergyPlusData &state,
212 : std::string_view const calledFrom, // routine called from
213 : std::string const &CurrentObject, // object being parsed
214 : std::string const &ZoneName, // Zone Name associated
215 : std::string::size_type const MaxZoneNameLength, // maximum length of zonelist zone names
216 : std::string const &ItemName, // Item name (People, Lights, etc object)
217 : Container const &Items, // Items to check for duplication Names
218 : int const NumItems, // Number of items in ItemNames array
219 : std::string &ResultName, // Resultant name
220 : bool &errFlag // Error flag set to true if error found here.
221 : )
222 : {
223 27 : Array1D_string ItemNames(Items.size());
224 612 : for (std::size_t i = 0, e = Items.size(); i < e; ++i)
225 585 : ItemNames[i] = Items[i].Name;
226 27 : CheckCreatedZoneItemName(state, calledFrom, CurrentObject, ZoneName, MaxZoneNameLength, ItemName, ItemNames, NumItems, ResultName, errFlag);
227 27 : }
228 :
229 : bool isReportPeriodBeginning(EnergyPlusData &state, int periodIdx);
230 :
231 : void findReportPeriodIdx(EnergyPlusData &state,
232 : const Array1D<Weather::ReportPeriodData> &ReportPeriodInputData,
233 : int nReportPeriods,
234 : Array1D_bool &inReportPeriodFlags);
235 :
236 : Real64 rotAzmDiffDeg(Real64 AzmA, Real64 AzmB);
237 :
238 642530 : inline Real64 epexp(const Real64 numerator, const Real64 denominator)
239 : {
240 642530 : if (denominator == 0.0) {
241 2 : return 0.0;
242 : } else {
243 642528 : return std::exp(numerator / denominator);
244 : }
245 : }
246 : } // namespace General
247 :
248 8000 : constexpr Real64 Interp(Real64 const Lower, Real64 const Upper, Real64 const InterpFac)
249 : {
250 8000 : return Lower + InterpFac * (Upper - Lower);
251 : }
252 :
253 : struct InterpCoeffs
254 : {
255 : Real64 x1;
256 : Real64 x2;
257 : };
258 :
259 : inline void GetInterpCoeffs(Real64 X, Real64 X1, Real64 X2, InterpCoeffs &c)
260 : {
261 : c.x1 = (X - X1) / (X2 - X1);
262 : c.x2 = (X2 - X) / (X2 - X1);
263 : }
264 :
265 : inline Real64 Interp2(Real64 Fx1, Real64 Fx2, InterpCoeffs const &c)
266 : {
267 : return c.x1 * Fx1 + c.x2 * Fx2;
268 : }
269 :
270 : // Disaggregated implementation of bilinear interpolation so that coefficients can be used with multiple variables
271 : struct BilinearInterpCoeffs
272 : {
273 : Real64 denom;
274 : Real64 x1y1;
275 : Real64 x1y2;
276 : Real64 x2y1;
277 : Real64 x2y2;
278 : };
279 :
280 0 : inline void GetBilinearInterpCoeffs(
281 : Real64 const X, Real64 const Y, Real64 const X1, Real64 const X2, Real64 const Y1, Real64 const Y2, BilinearInterpCoeffs &coeffs)
282 : {
283 0 : if (X1 == X2 && Y1 == Y2) {
284 0 : coeffs.denom = coeffs.x1y1 = 1.0;
285 0 : coeffs.x1y2 = coeffs.x2y1 = coeffs.x2y2 = 0.0;
286 0 : } else if (X1 == X2) {
287 0 : coeffs.denom = (Y2 - Y1);
288 0 : coeffs.x1y1 = (Y2 - Y);
289 0 : coeffs.x1y2 = (Y - Y1);
290 0 : coeffs.x2y1 = coeffs.x2y2 = 0.0;
291 0 : } else if (Y1 == Y2) {
292 0 : coeffs.denom = (X2 - X1);
293 0 : coeffs.x1y1 = (X2 - X);
294 0 : coeffs.x2y1 = (X - X1);
295 0 : coeffs.x1y2 = coeffs.x2y2 = 0.0;
296 : } else {
297 0 : coeffs.denom = (X2 - X1) * (Y2 - Y1);
298 0 : coeffs.x1y1 = (X2 - X) * (Y2 - Y);
299 0 : coeffs.x2y1 = (X - X1) * (Y2 - Y);
300 0 : coeffs.x1y2 = (X2 - X) * (Y - Y1);
301 0 : coeffs.x2y2 = (X - X1) * (Y - Y1);
302 : }
303 0 : }
304 :
305 0 : inline Real64 BilinearInterp(Real64 const Fx1y1, Real64 const Fx1y2, Real64 const Fx2y1, Real64 const Fx2y2, BilinearInterpCoeffs const &coeffs)
306 : {
307 0 : return (coeffs.x1y1 * Fx1y1 + coeffs.x2y1 * Fx2y1 + coeffs.x1y2 * Fx1y2 + coeffs.x2y2 * Fx2y2) / coeffs.denom;
308 : }
309 :
310 : struct GeneralData : BaseGlobalStruct
311 : {
312 : bool GetReportInput = true;
313 : bool SurfVert = false;
314 : bool SurfDet = false;
315 : bool SurfDetWVert = false;
316 : bool DXFReport = false;
317 : bool DXFWFReport = false;
318 : bool VRMLReport = false;
319 : bool CostInfo = false;
320 : bool ViewFactorInfo = false;
321 : bool Constructions = false;
322 : bool Materials = false;
323 : bool LineRpt = false;
324 : bool VarDict = false;
325 : bool EMSoutput = false;
326 : Real64 XNext = 0.0; // used in root finder
327 : std::string DXFOption1;
328 : std::string DXFOption2;
329 : std::string DXFWFOption1;
330 : std::string DXFWFOption2;
331 : std::string VRMLOption1;
332 : std::string VRMLOption2;
333 : std::string ViewRptOption1;
334 : std::string LineRptOption1;
335 : std::string VarDictOption1;
336 : std::string VarDictOption2;
337 :
338 2126 : void init_constant_state([[maybe_unused]] EnergyPlusData &state) override
339 : {
340 2126 : }
341 :
342 1152 : void init_state([[maybe_unused]] EnergyPlusData &state) override
343 : {
344 1152 : }
345 :
346 2100 : void clear_state() override
347 : {
348 2100 : new (this) GeneralData();
349 2100 : }
350 : };
351 :
352 : } // namespace EnergyPlus
353 :
354 : #endif
|