Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, 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 237712 : constexpr Real64 Interp(Real64 const Lower, Real64 const Upper, Real64 const InterpFac)
86 : {
87 237712 : return Lower + InterpFac * (Upper - Lower);
88 : }
89 :
90 : // Disaggregated implementation of bilinear interpolation so that coefficients can be used with multiple variables
91 : struct BilinearInterpCoeffs
92 : {
93 : Real64 denom;
94 : Real64 x1y1;
95 : Real64 x1y2;
96 : Real64 x2y1;
97 : Real64 x2y2;
98 : };
99 :
100 4692 : inline void GetBilinearInterpCoeffs(
101 : Real64 const X, Real64 const Y, Real64 const X1, Real64 const X2, Real64 const Y1, Real64 const Y2, BilinearInterpCoeffs &coeffs)
102 : {
103 4692 : if (X1 == X2 && Y1 == Y2) {
104 0 : coeffs.denom = coeffs.x1y1 = 1.0;
105 0 : coeffs.x1y2 = coeffs.x2y1 = coeffs.x2y2 = 0.0;
106 4692 : } else if (X1 == X2) {
107 0 : coeffs.denom = (Y2 - Y1);
108 0 : coeffs.x1y1 = (Y2 - Y);
109 0 : coeffs.x1y2 = (Y - Y1);
110 0 : coeffs.x2y1 = coeffs.x2y2 = 0.0;
111 4692 : } else if (Y1 == Y2) {
112 0 : coeffs.denom = (X2 - X1);
113 0 : coeffs.x1y1 = (X2 - X);
114 0 : coeffs.x2y1 = (X - X1);
115 0 : coeffs.x1y2 = coeffs.x2y2 = 0.0;
116 : } else {
117 4692 : coeffs.denom = (X2 - X1) * (Y2 - Y1);
118 4692 : coeffs.x1y1 = (X2 - X) * (Y2 - Y);
119 4692 : coeffs.x2y1 = (X - X1) * (Y2 - Y);
120 4692 : coeffs.x1y2 = (X2 - X) * (Y - Y1);
121 4692 : coeffs.x2y2 = (X - X1) * (Y - Y1);
122 : }
123 4692 : }
124 :
125 12812 : inline Real64 BilinearInterp(Real64 const Fx1y1, Real64 const Fx1y2, Real64 const Fx2y1, Real64 const Fx2y2, BilinearInterpCoeffs const &coeffs)
126 : {
127 12812 : return (coeffs.x1y1 * Fx1y1 + coeffs.x2y1 * Fx2y1 + coeffs.x1y2 * Fx1y2 + coeffs.x2y2 * Fx2y2) / coeffs.denom;
128 : }
129 :
130 66403387 : constexpr Real64 POLYF(Real64 const X, // Cosine of angle of incidence
131 : Array1D<Real64> const &A // Polynomial coefficients
132 : )
133 : {
134 66403387 : if (X < 0.0 || X > 1.0) {
135 85226 : return 0.0;
136 : } else {
137 66318161 : return X * (A(1) + X * (A(2) + X * (A(3) + X * (A(4) + X * (A(5) + X * A(6))))));
138 : }
139 : }
140 :
141 : void MovingAvg(Array1D<Real64> &DataIn, int NumItemsInAvg);
142 :
143 : void ProcessDateString(EnergyPlusData &state,
144 : std::string const &String,
145 : int &PMonth,
146 : int &PDay,
147 : int &PWeekDay,
148 : Weather::DateType &DateType, // DateType found (-1=invalid, 1=month/day, 2=nth day in month, 3=last day in month)
149 : bool &ErrorsFound,
150 : ObjexxFCL::Optional_int PYear = _);
151 :
152 : void DetermineDateTokens(EnergyPlusData &state,
153 : std::string const &String,
154 : int &NumTokens, // Number of tokens found in string
155 : int &TokenDay, // Value of numeric field found
156 : int &TokenMonth, // Value of Month field found (1=Jan, 2=Feb, etc)
157 : int &TokenWeekday, // Value of Weekday field found (1=Sunday, 2=Monday, etc), 0 if none
158 : Weather::DateType &DateType, // DateType found (-1=invalid, 1=month/day, 2=nth day in month, 3=last day in month)
159 : bool &ErrorsFound, // Set to true if cannot process this string as a date
160 : ObjexxFCL::Optional_int TokenYear = _ // Value of Year if one appears to be present and this argument is present
161 : );
162 :
163 : void ValidateMonthDay(EnergyPlusData &state,
164 : std::string const &String, // REAL(r64) string being processed
165 : int Day,
166 : int Month,
167 : bool &ErrorsFound);
168 :
169 : int OrdinalDay(int Month, // Month, 1..12
170 : int Day, // Day of Month, not validated by month
171 : int LeapYearValue // 1 if leap year indicated, 0 if not
172 : );
173 :
174 : void InvOrdinalDay(int Number, int &PMonth, int &PDay, int LeapYr);
175 :
176 : bool BetweenDateHoursLeftInclusive(int TestDate, int TestHour, int StartDate, int StartHour, int EndDate, int EndHour);
177 :
178 : bool BetweenDates(int TestDate, // Date to test
179 : int StartDate, // Start date in sequence
180 : int EndDate // End date in sequence
181 : );
182 :
183 : std::string CreateSysTimeIntervalString(EnergyPlusData &state);
184 :
185 : int nthDayOfWeekOfMonth(const EnergyPlusData &state,
186 : int dayOfWeek, // day of week (Sunday=1, Monday=2, ...)
187 : int nthTime, // nth time the day of the week occurs (first monday, third tuesday, ..)
188 : int monthNumber // January = 1
189 : );
190 :
191 : Real64 SafeDivide(Real64 a, Real64 b);
192 :
193 : void Iterate(Real64 &ResultX, // ResultX is the final Iteration result passed back to the calling routine
194 : Real64 Tol, // Tolerance for Convergence
195 : Real64 X0, // Current value of X
196 : Real64 Y0, // Current value of the function Y(X)
197 : Real64 &X1, // First Previous values of X
198 : Real64 &Y1, // First Previous values of Y(X1)
199 : int Iter, // Number of iterations
200 : int &Cnvg // Convergence flag Cnvg = 0: Not converged
201 : );
202 :
203 : int FindNumberInList(int WhichNumber, Array1A_int ListOfItems, int NumItems);
204 :
205 : template <typename A> inline int FindNumberInList(int const WhichNumber, MArray1<A, int> const &ListOfItems, int const NumItems)
206 : {
207 : return FindNumberInList(WhichNumber, Array1D_int(ListOfItems), NumItems);
208 : }
209 :
210 : template <typename Container,
211 : class = typename std::enable_if<
212 : !std::is_same<typename Container::value_type, std::string>::value>::type> // Container needs isize() and operator(i) and value_type
213 33799 : inline int FindNumberInList(int const WhichNumber, Container const &ListOfItems, int Container::value_type::*num_p)
214 : {
215 33799 : int FindNumberInList(0);
216 234193 : for (int Count = 1, NumItems = ListOfItems.isize(); Count <= NumItems; ++Count) {
217 234193 : if (WhichNumber == ListOfItems(Count).*num_p) {
218 33799 : FindNumberInList = Count;
219 33799 : break;
220 : }
221 : }
222 33799 : return FindNumberInList;
223 : }
224 :
225 : void DecodeMonDayHrMin(int Item, // word containing encoded month, day, hour, minute
226 : int &Month, // month in integer format (1-12)
227 : int &Day, // day in integer format (1-31)
228 : int &Hour, // hour in integer format (1-24)
229 : int &Minute // minute in integer format (0:59)
230 : );
231 :
232 : void EncodeMonDayHrMin(int &Item, // word containing encoded month, day, hour, minute
233 : int Month, // month in integer format (1:12)
234 : int Day, // day in integer format (1:31)
235 : int Hour, // hour in integer format (1:24)
236 : int Minute // minute in integer format (0:59)
237 : );
238 :
239 : std::string CreateTimeString(Real64 Time); // Time in seconds
240 :
241 : void ParseTime(Real64 Time, // Time value in seconds
242 : int &Hours, // Number of hours
243 : int &Minutes, // Number of minutes < 60
244 : Real64 &Seconds // Number of seconds < 60
245 : );
246 :
247 : void ScanForReports(EnergyPlusData &state,
248 : std::string const &reportName,
249 : bool &DoReport,
250 : ObjexxFCL::Optional_string_const ReportKey = _,
251 : ObjexxFCL::Optional_string Option1 = _,
252 : ObjexxFCL::Optional_string Option2 = _);
253 :
254 : void CheckCreatedZoneItemName(EnergyPlusData &state,
255 : std::string_view calledFrom, // routine called from
256 : std::string const &CurrentObject, // object being parsed
257 : std::string const &ZoneName, // Zone Name associated
258 : std::string::size_type MaxZoneNameLength, // maximum length of zonelist zone names
259 : std::string const &ItemName, // Item name (People, Lights, etc object)
260 : Array1_string const &ItemNames, // Item Names to check for duplication
261 : int NumItems, // Number of items in ItemNames array
262 : std::string &ResultName, // Resultant name
263 : bool &errFlag // Error flag set to true if error found here.
264 : );
265 :
266 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
267 54 : inline void CheckCreatedZoneItemName(EnergyPlusData &state,
268 : std::string_view const calledFrom, // routine called from
269 : std::string const &CurrentObject, // object being parsed
270 : std::string const &ZoneName, // Zone Name associated
271 : std::string::size_type const MaxZoneNameLength, // maximum length of zonelist zone names
272 : std::string const &ItemName, // Item name (People, Lights, etc object)
273 : Container const &Items, // Items to check for duplication Names
274 : int const NumItems, // Number of items in ItemNames array
275 : std::string &ResultName, // Resultant name
276 : bool &errFlag // Error flag set to true if error found here.
277 : )
278 : {
279 54 : Array1D_string ItemNames(Items.size());
280 749 : for (std::size_t i = 0, e = Items.size(); i < e; ++i)
281 695 : ItemNames[i] = Items[i].Name;
282 54 : CheckCreatedZoneItemName(state, calledFrom, CurrentObject, ZoneName, MaxZoneNameLength, ItemName, ItemNames, NumItems, ResultName, errFlag);
283 54 : }
284 :
285 : bool isReportPeriodBeginning(EnergyPlusData &state, int periodIdx);
286 :
287 : void findReportPeriodIdx(EnergyPlusData &state,
288 : const Array1D<Weather::ReportPeriodData> &ReportPeriodInputData,
289 : int nReportPeriods,
290 : Array1D_bool &inReportPeriodFlags);
291 :
292 : Real64 rotAzmDiffDeg(Real64 AzmA, Real64 AzmB);
293 :
294 12907941 : inline Real64 epexp(const Real64 numerator, const Real64 denominator)
295 : {
296 12907941 : if (denominator == 0.0) {
297 6756 : return 0.0;
298 : } else {
299 12901185 : return std::exp(numerator / denominator);
300 : }
301 : }
302 : } // namespace General
303 :
304 : struct GeneralData : BaseGlobalStruct
305 : {
306 : bool GetReportInput = true;
307 : bool SurfVert = false;
308 : bool SurfDet = false;
309 : bool SurfDetWVert = false;
310 : bool DXFReport = false;
311 : bool DXFWFReport = false;
312 : bool VRMLReport = false;
313 : bool CostInfo = false;
314 : bool ViewFactorInfo = false;
315 : bool Constructions = false;
316 : bool Materials = false;
317 : bool LineRpt = false;
318 : bool VarDict = false;
319 : bool EMSoutput = false;
320 : Real64 XNext = 0.0; // used in root finder
321 : std::string DXFOption1;
322 : std::string DXFOption2;
323 : std::string DXFWFOption1;
324 : std::string DXFWFOption2;
325 : std::string VRMLOption1;
326 : std::string VRMLOption2;
327 : std::string ViewRptOption1;
328 : std::string LineRptOption1;
329 : std::string VarDictOption1;
330 : std::string VarDictOption2;
331 :
332 796 : void init_state([[maybe_unused]] EnergyPlusData &state) override
333 : {
334 796 : }
335 :
336 0 : void clear_state() override
337 : {
338 0 : new (this) GeneralData();
339 0 : }
340 : };
341 :
342 : } // namespace EnergyPlus
343 :
344 : #endif
|