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 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 : BtwxtTableLookup,
109 : Num
110 : };
111 :
112 : constexpr std::array<std::string_view, static_cast<int>(CurveType::Num)> objectNames = {"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 : "Table:Lookup"}; // namespace Curve
133 :
134 : struct Limits
135 : {
136 : Real64 min = 0.0;
137 : Real64 max = 0.0;
138 : bool minPresent = false;
139 : bool maxPresent = false;
140 : };
141 :
142 : struct Curve
143 : {
144 : // Basic data
145 : std::string Name; // Curve Name
146 : int Num = 0;
147 :
148 : CurveType curveType = CurveType::Invalid; // Curve type (see parameter definitions above)
149 : // Table data stuff
150 : int TableIndex = 0; // Index to tabular data (0 if a standard curve object) OR Index of RGI for new Table:Lookup
151 : int numDims = 0; // Number of dimensions (AKA, independent variables)
152 : int GridValueIndex = 0; // Index of output within RGI for new Table:Lookup
153 : std::string contextString; // For passing to callback
154 :
155 : // input coefficients
156 : std::array<Real64, 27> coeff = {0.0}; // curve coefficients
157 : // independent variables
158 : std::array<Real64, 6> inputs = {0.0}; // curve inputs
159 : std::array<Limits, 6> inputLimits; // min/max of independent variables
160 : // dependent (output) variable
161 : Real64 output = 0.0; // curve output or result
162 : Limits outputLimits; // min/max of curve output
163 : // EMS override
164 : bool EMSOverrideOn = false; // if TRUE, then EMS is calling to override curve value
165 : Real64 EMSOverrideCurveValue = 0.0; // Value of curve result EMS is directing to use
166 :
167 : Real64 value(EnergyPlusData &state, Real64 V1);
168 : Real64 value(EnergyPlusData &state, Real64 V1, Real64 V2);
169 : Real64 value(EnergyPlusData &state, Real64 V1, Real64 V2, Real64 V3);
170 : Real64 value(EnergyPlusData &state, Real64 V1, Real64 V2, Real64 V3, Real64 V4);
171 : Real64 value(EnergyPlusData &state, Real64 V1, Real64 V2, Real64 V3, Real64 V4, Real64 V5);
172 : Real64 value(EnergyPlusData &state, Real64 V1, Real64 V2, Real64 V3, Real64 V4, Real64 V5, Real64 V6);
173 : Real64 valueFallback(EnergyPlusData &state, Real64 V1, Real64 V2, Real64 V3, Real64 V4, Real64 V5);
174 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
175 : const Real64 Var1 // 1st independent variable
176 : );
177 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
178 : const Real64 Var1, // 1st independent variable
179 : const Real64 Var2 // 2nd independent variable
180 : );
181 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
182 : const Real64 Var1, // 1st independent variable
183 : const Real64 Var2, // 2nd independent variable
184 : const Real64 Var3 // 3rd independent variable
185 : );
186 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
187 : const Real64 Var1, // 1st independent variable
188 : const Real64 Var2, // 2nd independent variable
189 : const Real64 Var3, // 3rd independent variable
190 : const Real64 Var4 // 4th independent variable
191 : );
192 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
193 : const Real64 Var1, // 1st independent variable
194 : const Real64 Var2, // 2nd independent variable
195 : const Real64 Var3, // 3rd independent variable
196 : const Real64 Var4, // 4th independent variable
197 : const Real64 Var5 // 5th independent variable
198 : );
199 : Real64 BtwxtTableInterpolation(EnergyPlusData &state,
200 : const Real64 Var1, // 1st independent variable
201 : const Real64 Var2, // 2nd independent variable
202 : const Real64 Var3, // 3rd independent variable
203 : const Real64 Var4, // 4th independent variable
204 : const Real64 Var5, // 5th independent variable
205 : const Real64 Var6);
206 : };
207 :
208 : // Table file objects
209 : class TableFile
210 : {
211 : public:
212 : fs::path filePath;
213 : std::vector<std::vector<std::string>> contents;
214 : std::map<std::pair<std::size_t, std::size_t>, std::vector<double>> arrays;
215 : bool load(EnergyPlusData &state, fs::path const &path); // Note: this returns 'True' if ErrorsFound
216 : std::vector<double> &getArray(EnergyPlusData &state, std::pair<std::size_t, std::size_t> colAndRow);
217 :
218 : private:
219 : std::size_t numRows = 0u;
220 : std::size_t numColumns = 0u;
221 : };
222 :
223 : // Container for Btwxt N-d Objects
224 : class BtwxtManager
225 : {
226 : public:
227 : // Map RGI collection to string name of independent variable list
228 101 : int addGrid(const std::string &indVarListName, const std::vector<Btwxt::GridAxis> grid)
229 : {
230 101 : grids.emplace_back(grid, btwxt_logger);
231 101 : gridMap.emplace(indVarListName, grids.size() - 1);
232 101 : return static_cast<int>(grids.size()) - 1;
233 : }
234 454565 : void setLoggingContext(void *context)
235 : {
236 917099 : for (auto &btwxt : grids) {
237 462534 : btwxt.get_logger()->set_message_context(context); // TODO: set_context can be its own function
238 : }
239 454565 : }
240 : double normalizeGridValues(int gridIndex, int outputIndex, const std::vector<double> &target, double scalar = 1.0);
241 : int addOutputValues(int gridIndex, std::vector<double> values);
242 : int getGridIndex(EnergyPlusData &state, std::string &indVarListName, bool &ErrorsFound);
243 : int getNumGridDims(int gridIndex);
244 : double getGridValue(int gridIndex, int outputIndex, const std::vector<double> &target);
245 : std::map<std::string, const nlohmann::json &> independentVarRefs;
246 : std::map<fs::path, TableFile> tableFiles;
247 : static std::shared_ptr<EnergyPlusLogger> btwxt_logger;
248 : void clear();
249 :
250 : private:
251 : std::map<std::string, std::size_t> gridMap;
252 : std::vector<Btwxt::RegularGridInterpolator> grids;
253 : };
254 :
255 : void ResetPerformanceCurveOutput(const EnergyPlusData &state);
256 :
257 : Real64 CurveValue(EnergyPlusData &state,
258 : int CurveIndex, // index of curve in curve array
259 : Real64 Var1 // 1st independent variable
260 : );
261 :
262 : Real64 CurveValue(EnergyPlusData &state,
263 : int CurveIndex, // index of curve in curve array
264 : Real64 Var1, // 1st independent variable
265 : Real64 Var2 // 1st independent variable
266 : );
267 :
268 : Real64 CurveValue(EnergyPlusData &state,
269 : int CurveIndex, // index of curve in curve array
270 : Real64 Var1, // 1st independent variable
271 : Real64 Var2, // 1st independent variable
272 : Real64 Var3 // 1st independent variable
273 : );
274 :
275 : Real64 CurveValue(EnergyPlusData &state,
276 : int CurveIndex, // index of curve in curve array
277 : Real64 Var1, // 1st independent variable
278 : Real64 Var2, // 1st independent variable
279 : Real64 Var3, // 1st independent variable
280 : Real64 Var4 // 1st independent variable
281 : );
282 :
283 : Real64 CurveValue(EnergyPlusData &state,
284 : int CurveIndex, // index of curve in curve array
285 : Real64 Var1, // 1st independent variable
286 : Real64 Var2, // 1st independent variable
287 : Real64 Var3, // 1st independent variable
288 : Real64 Var4, // 1st independent variable
289 : Real64 Var5 // 1st independent variable
290 : );
291 :
292 : Real64 CurveValue(EnergyPlusData &state,
293 : int CurveIndex, // index of curve in curve array
294 : Real64 Var1, // 1st independent variable
295 : Real64 Var2, // 1st independent variable
296 : Real64 Var3, // 1st independent variable
297 : Real64 Var4, // 1st independent variable
298 : Real64 Var5, // 1st independent variable
299 : Real64 Var6 // 1st independent variable
300 : );
301 :
302 : void GetCurveInput(EnergyPlusData &state);
303 :
304 : void GetCurveInputData(EnergyPlusData &state, bool &ErrorsFound);
305 :
306 : void InitCurveReporting(EnergyPlusData &state);
307 :
308 : bool IsCurveInputTypeValid(std::string const &InInputType); // index of curve in curve array
309 :
310 : bool IsCurveOutputTypeValid(std::string const &InOutputType); // index of curve in curve array
311 :
312 : void ShowSevereCurveDims(EnergyPlusData &state,
313 : ErrorObjectHeader const &eoh,
314 : std::string_view const fieldName,
315 : std::string_view const curveName,
316 : std::string_view const validDims,
317 : int dim);
318 :
319 : bool CheckCurveDims(EnergyPlusData &state,
320 : int CurveIndex,
321 : std::vector<int> const &validDims,
322 : std::string_view routineName,
323 : std::string_view objectType,
324 : std::string_view objectName,
325 : std::string_view curveFieldText);
326 :
327 : std::string GetCurveName(EnergyPlusData &state, int CurveIndex); // index of curve in curve array
328 :
329 : Real64 GetNormalPoint(int CurveIndex);
330 :
331 : int GetCurveIndex(EnergyPlusData &state, std::string const &CurveName); // name of the curve
332 :
333 : Curve *GetCurve(EnergyPlusData &state, std::string const &curveName);
334 :
335 : Curve *AddCurve(EnergyPlusData &state, std::string const &curveName);
336 :
337 : // This utility function grabs a curve index and performs the
338 : // error checking
339 : void GetCurveMinMaxValues(EnergyPlusData &state,
340 : int const CurveIndex, // index of curve in curve array
341 : Real64 &Var1Min, // Minimum values of 1st independent variable
342 : Real64 &Var1Max // Maximum values of 1st independent variable
343 : );
344 :
345 : void GetCurveMinMaxValues(EnergyPlusData &state,
346 : int const CurveIndex, // index of curve in curve array
347 : Real64 &Var1Min, // Minimum values of 1st independent variable
348 : Real64 &Var1Max, // Maximum values of 1st independent variable
349 : Real64 &Var2Min, // Minimum values of 2nd independent variable
350 : Real64 &Var2Max // Maximum values of 2nd independent variable
351 : );
352 :
353 : void GetCurveMinMaxValues(EnergyPlusData &state,
354 : int const CurveIndex, // index of curve in curve array
355 : Real64 &Var1Min, // Minimum values of 1st independent variable
356 : Real64 &Var1Max, // Maximum values of 1st independent variable
357 : Real64 &Var2Min, // Minimum values of 2nd independent variable
358 : Real64 &Var2Max, // Maximum values of 2nd independent variable
359 : Real64 &Var3Min, // Minimum values of 3rd independent variable
360 : Real64 &Var3Max // Maximum values of 3rd independent variable
361 : );
362 :
363 : void GetCurveMinMaxValues(EnergyPlusData &state,
364 : int const CurveIndex, // index of curve in curve array
365 : Real64 &Var1Min, // Minimum values of 1st independent variable
366 : Real64 &Var1Max, // Maximum values of 1st independent variable
367 : Real64 &Var2Min, // Minimum values of 2nd independent variable
368 : Real64 &Var2Max, // Maximum values of 2nd independent variable
369 : Real64 &Var3Min, // Minimum values of 3rd independent variable
370 : Real64 &Var3Max, // Maximum values of 3rd independent variable
371 : Real64 &Var4Min, // Minimum values of 4th independent variable
372 : Real64 &Var4Max // Maximum values of 4th independent variable
373 : );
374 :
375 : void GetCurveMinMaxValues(EnergyPlusData &state,
376 : int const CurveIndex, // index of curve in curve array
377 : Real64 &Var1Min, // Minimum values of 1st independent variable
378 : Real64 &Var1Max, // Maximum values of 1st independent variable
379 : Real64 &Var2Min, // Minimum values of 2nd independent variable
380 : Real64 &Var2Max, // Maximum values of 2nd independent variable
381 : Real64 &Var3Min, // Minimum values of 3rd independent variable
382 : Real64 &Var3Max, // Maximum values of 3rd independent variable
383 : Real64 &Var4Min, // Minimum values of 4th independent variable
384 : Real64 &Var4Max, // Maximum values of 4th independent variable
385 : Real64 &Var5Min, // Minimum values of 5th independent variable
386 : Real64 &Var5Max // Maximum values of 5th independent variable
387 : );
388 :
389 : void GetCurveMinMaxValues(EnergyPlusData &state,
390 : int const CurveIndex, // index of curve in curve array
391 : Real64 &Var1Min, // Minimum values of 1st independent variable
392 : Real64 &Var1Max, // Maximum values of 1st independent variable
393 : Real64 &Var2Min, // Minimum values of 2nd independent variable
394 : Real64 &Var2Max, // Maximum values of 2nd independent variable
395 : Real64 &Var3Min, // Minimum values of 3rd independent variable
396 : Real64 &Var3Max, // Maximum values of 3rd independent variable
397 : Real64 &Var4Min, // Minimum values of 4th independent variable
398 : Real64 &Var4Max, // Maximum values of 4th independent variable
399 : Real64 &Var5Min, // Minimum values of 5th independent variable
400 : Real64 &Var5Max, // Maximum values of 5th independent variable
401 : Real64 &Var6Min, // Minimum values of 6th independent variable
402 : Real64 &Var6Max // Maximum values of 6th independent variable
403 : );
404 :
405 : void SetCurveOutputMinValue(EnergyPlusData &state,
406 : int CurveIndex, // index of curve in curve array
407 : bool &ErrorsFound, // TRUE when errors occur
408 : const Real64 CurveMin // Minimum value of curve output
409 : );
410 :
411 : void SetCurveOutputMaxValue(EnergyPlusData &state,
412 : int CurveIndex, // index of curve in curve array
413 : bool &ErrorsFound, // TRUE when errors occur
414 : const Real64 CurveMax // Maximum values of curve output
415 : );
416 :
417 : void GetPressureSystemInput(EnergyPlusData &state);
418 :
419 : void GetPressureCurveTypeAndIndex(EnergyPlusData &state,
420 : std::string const &PressureCurveName, // name of the curve
421 : DataBranchAirLoopPlant::PressureCurveType &PressureCurveType,
422 : int &PressureCurveIndex);
423 :
424 : Real64 PressureCurveValue(EnergyPlusData &state, int PressureCurveIndex, Real64 MassFlow, Real64 Density, Real64 Viscosity);
425 :
426 : Real64 CalculateMoodyFrictionFactor(EnergyPlusData &state, Real64 ReynoldsNumber, Real64 RoughnessRatio);
427 :
428 : void checkCurveIsNormalizedToOne(EnergyPlusData &state,
429 : const std::string &callingRoutineObj, // calling routine with object type
430 : const std::string &objectName, // parent object where curve is used
431 : int curveIndex, // index to curve object
432 : const std::string &cFieldName, // object field name
433 : const std::string &cFieldValue, // user input curve name
434 : Real64 Var1); // required 1st independent variable
435 :
436 : void checkCurveIsNormalizedToOne(EnergyPlusData &state,
437 : const std::string &callingRoutineObj, // calling routine with object type
438 : const std::string &objectName, // parent object where curve is used
439 : int curveIndex, // index to curve object
440 : const std::string &cFieldName, // object field name
441 : const std::string &cFieldValue, // user input curve name
442 : Real64 Var1, // required 1st independent variable
443 : Real64 Var2); // 2nd independent variable
444 :
445 : } // namespace Curve
446 :
447 : struct CurveManagerData : BaseGlobalStruct
448 : {
449 : bool CurveValueMyBeginTimeStepFlag = false;
450 : bool FrictionFactorErrorHasOccurred = false;
451 : bool showFallbackMessage = true;
452 : Array1D<Curve::Curve *> curves;
453 : std::map<std::string, int> curveMap;
454 :
455 : Curve::BtwxtManager btwxtManager;
456 :
457 2126 : void init_constant_state([[maybe_unused]] EnergyPlusData &state) override
458 : {
459 2126 : }
460 :
461 1152 : void init_state(EnergyPlusData &state) override
462 : {
463 1152 : Curve::GetCurveInput(state);
464 1152 : Curve::GetPressureSystemInput(state);
465 1152 : }
466 :
467 2100 : void clear_state() override
468 : {
469 5023 : for (Curve::Curve *c : curves)
470 2923 : delete c;
471 2100 : curves.clear();
472 2100 : curveMap.clear();
473 2100 : }
474 : };
475 :
476 : } // namespace EnergyPlus
477 :
478 : #endif
|