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 CurveManager_hh_INCLUDED
49 : #define CurveManager_hh_INCLUDED
50 :
51 : // C++ Headers
52 : #include <map>
53 : #include <vector>
54 :
55 : // ObjexxFCL Headers
56 : #include <ObjexxFCL/Array1D.hh>
57 : #include <ObjexxFCL/Array2D.hh>
58 : #include <ObjexxFCL/Array2S.hh>
59 :
60 : #include <nlohmann/json.hpp>
61 :
62 : // Btwxt Headers
63 : #include <btwxt/btwxt.h>
64 : #include <btwxt/grid-axis.h>
65 :
66 : // EnergyPlus Headers
67 : #include <EnergyPlus/Data/BaseData.hh>
68 : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
69 : #include <EnergyPlus/DataGlobals.hh>
70 : #include <EnergyPlus/EPVector.hh>
71 : #include <EnergyPlus/EnergyPlus.hh>
72 : #include <EnergyPlus/EnergyPlusLogger.hh>
73 : #include <EnergyPlus/FileSystem.hh>
74 : #include <EnergyPlus/UtilityRoutines.hh>
75 :
76 : namespace EnergyPlus {
77 :
78 : // Forward declarations
79 : struct EnergyPlusData;
80 :
81 : namespace Curve {
82 :
83 : // Curve Type parameters, these can differ from object types (e.g. a CurveType_TableOneIV can be linear, quadratic, etc)
84 :
85 : enum class CurveType
86 : {
87 : Invalid = -1,
88 : Linear,
89 : Quadratic,
90 : BiQuadratic,
91 : Cubic,
92 : QuadraticLinear,
93 : BiCubic,
94 : TriQuadratic,
95 : Exponent,
96 : Quartic,
97 : FanPressureRise,
98 : ExponentialSkewNormal,
99 : Sigmoid,
100 : RectangularHyperbola1,
101 : RectangularHyperbola2,
102 : ExponentialDecay,
103 : DoubleExponentialDecay,
104 : QuadLinear,
105 : QuintLinear,
106 : CubicLinear,
107 : ChillerPartLoadWithLift,
108 : Num
109 : };
110 :
111 : constexpr std::array<std::string_view, static_cast<int>(CurveType::Num)> objectNames = {
112 : "Curve:Linear",
113 : "Curve:Quadratic",
114 : "Curve:Biquadratic",
115 : "Curve:Cubic",
116 : "Curve:QuadLinear",
117 : "Curve:Bicubic",
118 : "Curve:Triquadratic",
119 : "Curve:Exponent",
120 : "Curve:Quartic",
121 : "Curve:FanPressureRise",
122 : "Curve:ExponentialSkewNormal",
123 : "Curve:Sigmoid",
124 : "Curve:RectangularHyperbola1",
125 : "Curve:RectangularHyperbola2",
126 : "Curve:ExponentialDecay",
127 : "Curve:DoubleExponentialDecay",
128 : "Curve:QuadraticLinear",
129 : "Curve:QuintLinear",
130 : "Curve:CubicLinear",
131 : "Curve:ChillerPartLoadWithLift",
132 : }; // namespace Curve
133 :
134 : enum class InterpType
135 : {
136 : Invalid = -1,
137 : EvaluateCurveToLimits,
138 : BtwxtMethod,
139 : Num
140 : };
141 :
142 : struct Limits
143 : {
144 : Real64 min = 0.0;
145 : Real64 max = 0.0;
146 : bool minPresent = false;
147 : bool maxPresent = false;
148 : };
149 :
150 : struct Curve
151 : {
152 : // Basic data
153 : std::string Name; // Curve Name
154 : CurveType curveType = CurveType::Invalid; // Curve type (see parameter definitions above)
155 : // Table data stuff
156 : InterpType interpolationType = InterpType::Invalid; // Table interpolation method
157 : int TableIndex = 0; // Index to tabular data (0 if a standard curve object) OR Index of RGI for new Table:Lookup
158 : int numDims = 0; // Number of dimensions (AKA, independent variables)
159 : int GridValueIndex = 0; // Index of output within RGI for new Table:Lookup
160 : // input coefficients
161 : std::array<Real64, 27> coeff = {0.0}; // curve coefficients
162 : // independent variables
163 : std::array<Real64, 6> inputs = {0.0}; // curve inputs
164 : std::array<Limits, 6> inputLimits; // min/max of independent variables
165 : // dependent (output) variable
166 : Real64 output = 0.0; // curve output or result
167 : Limits outputLimits; // min/max of curve output
168 : // EMS override
169 : bool EMSOverrideOn = false; // if TRUE, then EMS is calling to override curve value
170 : Real64 EMSOverrideCurveValue = 0.0; // Value of curve result EMS is directing to use
171 : Real64 value(EnergyPlusData &state, Real64 V1);
172 : Real64 value(EnergyPlusData &state, Real64 V1, Real64 V2);
173 : Real64 value(EnergyPlusData &state, Real64 V1, Real64 V2, Real64 V3);
174 : Real64 value(EnergyPlusData &state, Real64 V1, Real64 V2, Real64 V3, Real64 V4);
175 : Real64 value(EnergyPlusData &state, Real64 V1, Real64 V2, Real64 V3, Real64 V4, Real64 V5);
176 : Real64 value(EnergyPlusData &state, Real64 V1, Real64 V2, Real64 V3, Real64 V4, Real64 V5, Real64 V6);
177 : Real64 valueFallback(EnergyPlusData &state, Real64 V1, Real64 V2, Real64 V3, Real64 V4, Real64 V5);
178 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
179 : const Real64 Var1 // 1st independent variable
180 : );
181 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
182 : const Real64 Var1, // 1st independent variable
183 : const Real64 Var2 // 2nd independent variable
184 : );
185 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
186 : const Real64 Var1, // 1st independent variable
187 : const Real64 Var2, // 2nd independent variable
188 : const Real64 Var3 // 3rd independent variable
189 : );
190 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
191 : const Real64 Var1, // 1st independent variable
192 : const Real64 Var2, // 2nd independent variable
193 : const Real64 Var3, // 3rd independent variable
194 : const Real64 Var4 // 4th independent variable
195 : );
196 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
197 : const Real64 Var1, // 1st independent variable
198 : const Real64 Var2, // 2nd independent variable
199 : const Real64 Var3, // 3rd independent variable
200 : const Real64 Var4, // 4th independent variable
201 : const Real64 Var5 // 5th independent variable
202 : );
203 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
204 : const Real64 Var1, // 1st independent variable
205 : const Real64 Var2, // 2nd independent variable
206 : const Real64 Var3, // 3rd independent variable
207 : const Real64 Var4, // 4th independent variable
208 : const Real64 Var5, // 5th independent variable
209 : const Real64 Var6);
210 : };
211 :
212 : // Table file objects
213 : class TableFile
214 : {
215 : public:
216 : fs::path filePath;
217 : std::vector<std::vector<std::string>> contents;
218 : std::map<std::pair<std::size_t, std::size_t>, std::vector<double>> arrays;
219 : bool load(EnergyPlusData &state, fs::path const &path); // Note: this returns 'True' if ErrorsFound
220 : std::vector<double> &getArray(EnergyPlusData &state, std::pair<std::size_t, std::size_t> colAndRow);
221 :
222 : private:
223 : std::size_t numRows = 0u;
224 : std::size_t numColumns = 0u;
225 : };
226 :
227 : // Container for Btwxt N-d Objects
228 : class BtwxtManager
229 : {
230 : public:
231 : // Map RGI collection to string name of independent variable list
232 222 : int addGrid(const std::string &indVarListName, const std::vector<Btwxt::GridAxis> grid)
233 : {
234 222 : grids.emplace_back(grid, btwxt_logger);
235 222 : gridMap.emplace(indVarListName, grids.size() - 1);
236 222 : return static_cast<int>(grids.size()) - 1;
237 : }
238 10910215 : void setLoggingContext(void *context)
239 : {
240 49973464 : for (auto &btwxt : grids) {
241 39063249 : btwxt.get_logger()->set_message_context(context); // TODO: set_context can be its own function
242 10910215 : }
243 10910215 : }
244 : double normalizeGridValues(int gridIndex, int outputIndex, const std::vector<double> &target, double scalar = 1.0);
245 : int addOutputValues(int gridIndex, std::vector<double> values);
246 : int getGridIndex(EnergyPlusData &state, std::string &indVarListName, bool &ErrorsFound);
247 : int getNumGridDims(int gridIndex);
248 : double getGridValue(int gridIndex, int outputIndex, const std::vector<double> &target);
249 : std::map<std::string, const nlohmann::json &> independentVarRefs;
250 : std::map<fs::path, TableFile> tableFiles;
251 : static std::shared_ptr<EnergyPlusLogger> btwxt_logger;
252 : void clear();
253 :
254 : private:
255 : std::map<std::string, std::size_t> gridMap;
256 : std::vector<Btwxt::RegularGridInterpolator> grids;
257 : };
258 :
259 : void ResetPerformanceCurveOutput(const EnergyPlusData &state);
260 :
261 : Real64 CurveValue(EnergyPlusData &state,
262 : int CurveIndex, // index of curve in curve array
263 : Real64 Var1 // 1st independent variable
264 : );
265 :
266 : Real64 CurveValue(EnergyPlusData &state,
267 : int CurveIndex, // index of curve in curve array
268 : Real64 Var1, // 1st independent variable
269 : Real64 Var2 // 1st independent variable
270 : );
271 :
272 : Real64 CurveValue(EnergyPlusData &state,
273 : int CurveIndex, // index of curve in curve array
274 : Real64 Var1, // 1st independent variable
275 : Real64 Var2, // 1st independent variable
276 : Real64 Var3 // 1st independent variable
277 : );
278 :
279 : Real64 CurveValue(EnergyPlusData &state,
280 : int CurveIndex, // index of curve in curve array
281 : Real64 Var1, // 1st independent variable
282 : Real64 Var2, // 1st independent variable
283 : Real64 Var3, // 1st independent variable
284 : Real64 Var4 // 1st independent variable
285 : );
286 :
287 : Real64 CurveValue(EnergyPlusData &state,
288 : int CurveIndex, // index of curve in curve array
289 : Real64 Var1, // 1st independent variable
290 : Real64 Var2, // 1st independent variable
291 : Real64 Var3, // 1st independent variable
292 : Real64 Var4, // 1st independent variable
293 : Real64 Var5 // 1st independent variable
294 : );
295 :
296 : Real64 CurveValue(EnergyPlusData &state,
297 : int CurveIndex, // index of curve in curve array
298 : Real64 Var1, // 1st independent variable
299 : Real64 Var2, // 1st independent variable
300 : Real64 Var3, // 1st independent variable
301 : Real64 Var4, // 1st independent variable
302 : Real64 Var5, // 1st independent variable
303 : Real64 Var6 // 1st independent variable
304 : );
305 :
306 : void GetCurveInput(EnergyPlusData &state);
307 :
308 : void GetCurveInputData(EnergyPlusData &state, bool &ErrorsFound);
309 :
310 : void InitCurveReporting(EnergyPlusData &state);
311 :
312 : bool IsCurveInputTypeValid(std::string const &InInputType); // index of curve in curve array
313 :
314 : bool IsCurveOutputTypeValid(std::string const &InOutputType); // index of curve in curve array
315 :
316 : void ShowErrorCurveDims(EnergyPlusData &state,
317 : ErrorObjectHeader const &eoh,
318 : std::string_view fieldName,
319 : std::string_view curveName,
320 : std::string_view validDims,
321 : int dim);
322 :
323 : bool CheckCurveDims(EnergyPlusData &state,
324 : int CurveIndex,
325 : std::vector<int> const &validDims,
326 : std::string_view routineName,
327 : std::string_view objectType,
328 : std::string_view objectName,
329 : std::string_view curveFieldText);
330 :
331 : std::string GetCurveName(EnergyPlusData &state, int CurveIndex); // index of curve in curve array
332 :
333 : Real64 GetNormalPoint(int CurveIndex);
334 :
335 : int GetCurveIndex(EnergyPlusData &state, std::string const &CurveName); // name of the curve
336 :
337 : // This utility function grabs a curve index and performs the
338 : // error checking
339 :
340 : int GetCurveCheck(EnergyPlusData &state,
341 : std::string const &alph, // curve name
342 : bool &errFlag,
343 : std::string const &ObjName // parent object of curve
344 : );
345 :
346 : void GetCurveMinMaxValues(EnergyPlusData &state,
347 : int const CurveIndex, // index of curve in curve array
348 : Real64 &Var1Min, // Minimum values of 1st independent variable
349 : Real64 &Var1Max // Maximum values of 1st independent variable
350 : );
351 :
352 : void GetCurveMinMaxValues(EnergyPlusData &state,
353 : int const CurveIndex, // index of curve in curve array
354 : Real64 &Var1Min, // Minimum values of 1st independent variable
355 : Real64 &Var1Max, // Maximum values of 1st independent variable
356 : Real64 &Var2Min, // Minimum values of 2nd independent variable
357 : Real64 &Var2Max // Maximum values of 2nd independent variable
358 : );
359 :
360 : void GetCurveMinMaxValues(EnergyPlusData &state,
361 : int const CurveIndex, // index of curve in curve array
362 : Real64 &Var1Min, // Minimum values of 1st independent variable
363 : Real64 &Var1Max, // Maximum values of 1st independent variable
364 : Real64 &Var2Min, // Minimum values of 2nd independent variable
365 : Real64 &Var2Max, // Maximum values of 2nd independent variable
366 : Real64 &Var3Min, // Minimum values of 3rd independent variable
367 : Real64 &Var3Max // Maximum values of 3rd independent variable
368 : );
369 :
370 : void GetCurveMinMaxValues(EnergyPlusData &state,
371 : int const CurveIndex, // index of curve in curve array
372 : Real64 &Var1Min, // Minimum values of 1st independent variable
373 : Real64 &Var1Max, // Maximum values of 1st independent variable
374 : Real64 &Var2Min, // Minimum values of 2nd independent variable
375 : Real64 &Var2Max, // Maximum values of 2nd independent variable
376 : Real64 &Var3Min, // Minimum values of 3rd independent variable
377 : Real64 &Var3Max, // Maximum values of 3rd independent variable
378 : Real64 &Var4Min, // Minimum values of 4th independent variable
379 : Real64 &Var4Max // Maximum values of 4th independent variable
380 : );
381 :
382 : void GetCurveMinMaxValues(EnergyPlusData &state,
383 : int const CurveIndex, // index of curve in curve array
384 : Real64 &Var1Min, // Minimum values of 1st independent variable
385 : Real64 &Var1Max, // Maximum values of 1st independent variable
386 : Real64 &Var2Min, // Minimum values of 2nd independent variable
387 : Real64 &Var2Max, // Maximum values of 2nd independent variable
388 : Real64 &Var3Min, // Minimum values of 3rd independent variable
389 : Real64 &Var3Max, // Maximum values of 3rd independent variable
390 : Real64 &Var4Min, // Minimum values of 4th independent variable
391 : Real64 &Var4Max, // Maximum values of 4th independent variable
392 : Real64 &Var5Min, // Minimum values of 5th independent variable
393 : Real64 &Var5Max // Maximum values of 5th independent variable
394 : );
395 :
396 : void GetCurveMinMaxValues(EnergyPlusData &state,
397 : int const CurveIndex, // index of curve in curve array
398 : Real64 &Var1Min, // Minimum values of 1st independent variable
399 : Real64 &Var1Max, // Maximum values of 1st independent variable
400 : Real64 &Var2Min, // Minimum values of 2nd independent variable
401 : Real64 &Var2Max, // Maximum values of 2nd independent variable
402 : Real64 &Var3Min, // Minimum values of 3rd independent variable
403 : Real64 &Var3Max, // Maximum values of 3rd independent variable
404 : Real64 &Var4Min, // Minimum values of 4th independent variable
405 : Real64 &Var4Max, // Maximum values of 4th independent variable
406 : Real64 &Var5Min, // Minimum values of 5th independent variable
407 : Real64 &Var5Max, // Maximum values of 5th independent variable
408 : Real64 &Var6Min, // Minimum values of 6th independent variable
409 : Real64 &Var6Max // Maximum values of 6th independent variable
410 : );
411 :
412 : void SetCurveOutputMinValue(EnergyPlusData &state,
413 : int CurveIndex, // index of curve in curve array
414 : bool &ErrorsFound, // TRUE when errors occur
415 : const Real64 CurveMin // Minimum value of curve output
416 : );
417 :
418 : void SetCurveOutputMaxValue(EnergyPlusData &state,
419 : int CurveIndex, // index of curve in curve array
420 : bool &ErrorsFound, // TRUE when errors occur
421 : const Real64 CurveMax // Maximum values of curve output
422 : );
423 :
424 : void GetPressureSystemInput(EnergyPlusData &state);
425 :
426 : void GetPressureCurveTypeAndIndex(EnergyPlusData &state,
427 : std::string const &PressureCurveName, // name of the curve
428 : DataBranchAirLoopPlant::PressureCurveType &PressureCurveType,
429 : int &PressureCurveIndex);
430 :
431 : Real64 PressureCurveValue(EnergyPlusData &state, int PressureCurveIndex, Real64 MassFlow, Real64 Density, Real64 Viscosity);
432 :
433 : Real64 CalculateMoodyFrictionFactor(EnergyPlusData &state, Real64 ReynoldsNumber, Real64 RoughnessRatio);
434 :
435 : void checkCurveIsNormalizedToOne(EnergyPlusData &state,
436 : const std::string &callingRoutineObj, // calling routine with object type
437 : const std::string &objectName, // parent object where curve is used
438 : int curveIndex, // index to curve object
439 : const std::string &cFieldName, // object field name
440 : const std::string &cFieldValue, // user input curve name
441 : Real64 Var1); // required 1st independent variable
442 :
443 : void checkCurveIsNormalizedToOne(EnergyPlusData &state,
444 : const std::string &callingRoutineObj, // calling routine with object type
445 : const std::string &objectName, // parent object where curve is used
446 : int curveIndex, // index to curve object
447 : const std::string &cFieldName, // object field name
448 : const std::string &cFieldValue, // user input curve name
449 : Real64 Var1, // required 1st independent variable
450 : Real64 Var2); // 2nd independent variable
451 :
452 : } // namespace Curve
453 :
454 : struct CurveManagerData : BaseGlobalStruct
455 : {
456 : int NumCurves = 0;
457 : bool GetCurvesInputFlag = true;
458 : bool CurveValueMyBeginTimeStepFlag = false;
459 : bool FrictionFactorErrorHasOccurred = false;
460 : bool showFallbackMessage = true;
461 : EPVector<Curve::Curve *> PerfCurve;
462 : Curve::BtwxtManager btwxtManager;
463 : std::unordered_map<std::string, std::string> UniqueCurveNames;
464 :
465 : void allocateCurveVector(int const count)
466 : {
467 : this->NumCurves = count;
468 : for (int curveIndex = 1; curveIndex <= count; curveIndex++)
469 : this->PerfCurve.push_back(new EnergyPlus::Curve::Curve);
470 : }
471 :
472 796 : void init_state([[maybe_unused]] EnergyPlusData &state) override
473 : {
474 796 : }
475 :
476 0 : void clear_state() override
477 : {
478 0 : for (Curve::Curve *p : PerfCurve) {
479 0 : delete p;
480 0 : }
481 0 : new (this) CurveManagerData();
482 0 : }
483 : };
484 :
485 : } // namespace EnergyPlus
486 :
487 : #endif
|