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 : // C++ Headers
49 : #include <cmath>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Fmath.hh>
53 :
54 : // EnergyPlus Headers
55 : #include <EnergyPlus/Data/EnergyPlusData.hh>
56 : #include <EnergyPlus/DataIPShortCuts.hh>
57 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
58 : #include <EnergyPlus/MatrixDataManager.hh>
59 : #include <EnergyPlus/UtilityRoutines.hh>
60 :
61 : namespace EnergyPlus {
62 :
63 : namespace MatrixDataManager {
64 :
65 : // Module containing the routines dealing with Matrix input objects and services
66 :
67 : // MODULE INFORMATION:
68 : // AUTHOR B. Griffith
69 : // DATE WRITTEN June 2010
70 :
71 : // PURPOSE OF THIS MODULE:
72 : // Process user input for Matrix: input data objects
73 : // Provide central services for other routines to access
74 : // matrix input data.
75 :
76 : // METHODOLOGY EMPLOYED:
77 : // Basic calls to InputProcessor, series of simple get and set routines
78 :
79 : // REFERENCES:
80 : // none
81 :
82 : // OTHER NOTES:
83 : // first implemented for complex fenestration
84 :
85 : // Data
86 : // MODULE PARAMETER DEFINITIONS:
87 :
88 : // SUBROUTINE SPECIFICATIONS FOR MODULE <module_name>:
89 :
90 : // todo, flush out the following routines, see CurveManager for patterns
91 : // PUBLIC GetMatrixValue
92 : // PUBLIC GetMatrixCheck
93 : // PUBLIC GetMatrixType
94 : // PUBLIC GetMatrixMinMaxValues
95 : // PUBLIC SetMatrixOutputMinMaxValues
96 : // PUBLIC GetMatrixName
97 :
98 : // Object Data
99 :
100 : // MSVC was complaining that it detected a divide by zero in the Row = (El - 1) / NumCols + 1 line, indicating it thought NumCols was zero
101 : // the compiler should never have been able to identify that, as NumCols is based directly on rNumericArgs, which is based on input values
102 : // Apparently, interaction between the high level optimizer that does flow-graph transformations and backend that emits warnings can cause
103 : // false positives. The warning simply needs to be muted. Placing the pragma at the statement itself was not sufficient for muting, so I
104 : // placed the pragma out here at this level and it worked. Note that this warning was only showing up on release builds, not debug builds
105 : #pragma warning(push)
106 : #pragma warning(disable : 4723)
107 1 : void GetMatrixInput(EnergyPlusData &state)
108 : {
109 :
110 : // SUBROUTINE INFORMATION:
111 : // AUTHOR B. Griffith
112 : // DATE WRITTEN June 2010
113 : // MODIFIED na
114 : // RE-ENGINEERED na
115 :
116 : // PURPOSE OF THIS SUBROUTINE:
117 : // get input for Matrix objects
118 :
119 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
120 : int NumTwoDimMatrix; // count of Matrix:TwoDimension objects
121 : int MatIndex; // do loop counter
122 : int MatNum; // index management
123 : int NumAlphas; // Number of Alphas for each GetObjectItem call
124 : int NumNumbers; // Number of Numbers for each GetObjectItem call
125 : int IOStatus; // Used in GetObjectItem
126 1 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
127 1 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
128 :
129 1 : cCurrentModuleObject = "Matrix:TwoDimension";
130 1 : NumTwoDimMatrix = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
131 :
132 1 : state.dataMatrixDataManager->NumMats = NumTwoDimMatrix;
133 :
134 1 : state.dataMatrixDataManager->MatData.allocate(state.dataMatrixDataManager->NumMats);
135 :
136 1 : MatNum = 0;
137 10 : for (MatIndex = 1; MatIndex <= NumTwoDimMatrix; ++MatIndex) {
138 27 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
139 : cCurrentModuleObject,
140 : MatIndex,
141 9 : state.dataIPShortCut->cAlphaArgs,
142 : NumAlphas,
143 9 : state.dataIPShortCut->rNumericArgs,
144 : NumNumbers,
145 : IOStatus,
146 9 : state.dataIPShortCut->lNumericFieldBlanks,
147 : _,
148 9 : state.dataIPShortCut->cAlphaFieldNames,
149 9 : state.dataIPShortCut->cNumericFieldNames);
150 9 : ++MatNum;
151 9 : Util::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
152 :
153 9 : state.dataMatrixDataManager->MatData(MatNum).Name = state.dataIPShortCut->cAlphaArgs(1);
154 9 : int NumRows = std::floor(state.dataIPShortCut->rNumericArgs(1));
155 9 : int NumCols = std::floor(state.dataIPShortCut->rNumericArgs(2));
156 9 : int NumElements = NumRows * NumCols;
157 :
158 : // test
159 9 : if (NumElements < 1) {
160 0 : ShowSevereError(state, format("GetMatrixInput: for {}: {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
161 0 : ShowContinueError(state,
162 0 : format("Check {} and {} total number of elements in matrix must be 1 or more",
163 0 : state.dataIPShortCut->cNumericFieldNames(1),
164 0 : state.dataIPShortCut->cNumericFieldNames(2)));
165 0 : ErrorsFound = true;
166 : }
167 9 : if ((NumNumbers - 2) < NumElements) {
168 0 : ShowSevereError(state, format("GetMatrixInput: for {}: {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
169 0 : ShowContinueError(state,
170 0 : format("Check input, total number of elements does not agree with {} and {}",
171 0 : state.dataIPShortCut->cNumericFieldNames(1),
172 0 : state.dataIPShortCut->cNumericFieldNames(2)));
173 0 : ErrorsFound = true;
174 : }
175 9 : state.dataMatrixDataManager->MatData(MatNum).MatrixType = TwoDimensional;
176 : // Note With change to row-major arrays the "row" and "col" usage here is transposed
177 9 : auto &matrix(state.dataMatrixDataManager->MatData(MatNum).Mat2D);
178 9 : matrix.allocate(NumCols, NumRows); // This is standard order for a NumRows X NumCols matrix
179 9 : Array2<Real64>::size_type l(0);
180 3627 : for (int ElementNum = 1; ElementNum <= NumElements; ++ElementNum, l += matrix.size()) {
181 3618 : int const RowIndex = (ElementNum - 1) / NumCols + 1;
182 3618 : int const ColIndex = mod((ElementNum - 1), NumCols) + 1;
183 3618 : matrix(ColIndex, RowIndex) = state.dataIPShortCut->rNumericArgs(ElementNum + 2); // Matrix is read in row-by-row
184 : }
185 : }
186 :
187 1 : if (ErrorsFound) {
188 0 : ShowFatalError(state, "GetMatrixInput: Errors found in Matrix objects. Preceding condition(s) cause termination.");
189 : }
190 1 : }
191 : #pragma warning(pop)
192 :
193 11 : int MatrixIndex(EnergyPlusData &state, std::string const &MatrixName)
194 : {
195 :
196 : // FUNCTION INFORMATION:
197 : // AUTHOR B. Griffith
198 : // DATE WRITTEN June 2010
199 : // MODIFIED na
200 : // RE-ENGINEERED na
201 :
202 : // PURPOSE OF THIS FUNCTION:
203 : // Return integer index or pointer to MatData structure array
204 :
205 : // METHODOLOGY EMPLOYED:
206 : // inputs name of matrix and returns integer index
207 : // currently uses Util::FindItemInList( which is case sensitive
208 :
209 : // Return value
210 : int MatrixIndexPtr; // Function result
211 :
212 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
213 :
214 11 : if (state.dataUtilityRoutines->GetMatrixInputFlag) {
215 1 : GetMatrixInput(state);
216 1 : state.dataUtilityRoutines->GetMatrixInputFlag = false;
217 : }
218 :
219 11 : if (state.dataMatrixDataManager->NumMats > 0) {
220 11 : MatrixIndexPtr = Util::FindItemInList(MatrixName, state.dataMatrixDataManager->MatData);
221 : } else {
222 0 : MatrixIndexPtr = 0;
223 : }
224 :
225 11 : return MatrixIndexPtr;
226 : }
227 :
228 11 : void Get2DMatrix(EnergyPlusData &state,
229 : int const Idx, // pointer index to location in MatData
230 : Array2S<Real64> Mat2D)
231 : {
232 :
233 : // SUBROUTINE INFORMATION:
234 : // AUTHOR B. Griffith
235 : // DATE WRITTEN June 2010
236 : // MODIFIED na
237 : // RE-ENGINEERED na
238 :
239 : // PURPOSE OF THIS SUBROUTINE:
240 : // pass matrix to calling routine
241 :
242 11 : if (Idx > 0) { // protect hard crash
243 11 : Mat2D = state.dataMatrixDataManager->MatData(Idx).Mat2D;
244 : } else {
245 : // do nothing (?) throw dev error
246 : }
247 11 : }
248 :
249 11 : void Get2DMatrixDimensions(EnergyPlusData &state,
250 : int const Idx, // pointer index to location in MatData
251 : int &NumRows,
252 : int &NumCols)
253 : {
254 :
255 : // SUBROUTINE INFORMATION:
256 : // AUTHOR B. Griffith
257 : // DATE WRITTEN June 2010
258 : // MODIFIED na
259 : // RE-ENGINEERED na
260 :
261 : // PURPOSE OF THIS SUBROUTINE:
262 : // <description>
263 :
264 11 : if (Idx > 0) {
265 11 : NumRows = state.dataMatrixDataManager->MatData(Idx).Mat2D.isize(2);
266 11 : NumCols = state.dataMatrixDataManager->MatData(Idx).Mat2D.isize(1);
267 : } else {
268 : // do nothing (?) throw dev error?
269 : }
270 11 : }
271 :
272 : } // namespace MatrixDataManager
273 :
274 : } // namespace EnergyPlus
|