Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, 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 <memory>
50 :
51 : // ObjexxFCL Headers
52 :
53 : // EnergyPlus Headers
54 : #include <EnergyPlus/Data/EnergyPlusData.hh>
55 : #include <EnergyPlus/DataIPShortCuts.hh>
56 : #include <EnergyPlus/GroundTemperatureModeling/GroundTemperatureModelManager.hh>
57 : #include <EnergyPlus/GroundTemperatureModeling/KusudaAchenbachGroundTemperatureModel.hh>
58 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
59 : #include <EnergyPlus/UtilityRoutines.hh>
60 : #include <EnergyPlus/WeatherManager.hh>
61 :
62 : namespace EnergyPlus {
63 :
64 : //******************************************************************************
65 :
66 : // Kusuda model factory
67 33 : std::shared_ptr<KusudaGroundTempsModel> KusudaGroundTempsModel::KusudaGTMFactory(EnergyPlusData &state, std::string objectName)
68 : {
69 : // SUBROUTINE INFORMATION:
70 : // AUTHOR Matt Mitchell
71 : // DATE WRITTEN Summer 2015
72 : // MODIFIED na
73 : // RE-ENGINEERED na
74 :
75 : // PURPOSE OF THIS SUBROUTINE:
76 : // Reads input and creates instance of Kusuda ground temps model
77 :
78 : // USE STATEMENTS:
79 : using namespace GroundTemperatureManager;
80 :
81 : // Locals
82 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
83 33 : bool found = false;
84 : int NumNums;
85 : int NumAlphas;
86 : int IOStat;
87 33 : bool ErrorsFound = false;
88 :
89 : // New shared pointer for this model object
90 66 : std::shared_ptr<KusudaGroundTempsModel> thisModel(new KusudaGroundTempsModel());
91 :
92 33 : GroundTempObjType objType = GroundTempObjType::KusudaGroundTemp;
93 :
94 33 : std::string_view const cCurrentModuleObject = GroundTemperatureManager::groundTempModelNamesUC[static_cast<int>(objType)];
95 33 : int numCurrModels = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
96 :
97 33 : for (int modelNum = 1; modelNum <= numCurrModels; ++modelNum) {
98 :
99 99 : state.dataInputProcessing->inputProcessor->getObjectItem(
100 66 : state, cCurrentModuleObject, modelNum, state.dataIPShortCut->cAlphaArgs, NumAlphas, state.dataIPShortCut->rNumericArgs, NumNums, IOStat);
101 :
102 33 : if (objectName == state.dataIPShortCut->cAlphaArgs(1)) {
103 :
104 : // Read input into object here
105 33 : thisModel->objectName = state.dataIPShortCut->cAlphaArgs(1);
106 33 : thisModel->objectType = objType;
107 33 : thisModel->groundThermalDiffisivity =
108 33 : state.dataIPShortCut->rNumericArgs(1) / (state.dataIPShortCut->rNumericArgs(2) * state.dataIPShortCut->rNumericArgs(3));
109 :
110 : bool useGroundTempDataForKusuda =
111 33 : state.dataIPShortCut->rNumericArgs(4) || state.dataIPShortCut->rNumericArgs(5) || state.dataIPShortCut->rNumericArgs(6);
112 :
113 33 : if (useGroundTempDataForKusuda) {
114 : // Use Kusuda Parameters
115 33 : thisModel->aveGroundTemp = state.dataIPShortCut->rNumericArgs(4);
116 33 : thisModel->aveGroundTempAmplitude = state.dataIPShortCut->rNumericArgs(5);
117 33 : thisModel->phaseShiftInSecs = state.dataIPShortCut->rNumericArgs(6) * DataGlobalConstants::SecsInDay;
118 : } else {
119 : // Use data from Site:GroundTemperature:Shallow to generate parameters
120 :
121 0 : int monthsInYear(12);
122 0 : int avgDaysInMonth(30);
123 0 : int monthOfMinSurfTemp(0);
124 0 : Real64 averageGroundTemp(0);
125 0 : Real64 amplitudeOfGroundTemp(0);
126 0 : Real64 phaseShiftOfMinGroundTempDays(0);
127 0 : Real64 minSurfTemp(100); // Set high month 1 temp will be lower and actually get updated
128 0 : Real64 maxSurfTemp(-100); // Set low initially but will get updated
129 :
130 : std::shared_ptr<BaseGroundTempsModel> shallowObj = GetGroundTempModelAndInit(
131 : state,
132 0 : static_cast<std::string>(
133 0 : GroundTemperatureManager::groundTempModelNamesUC[static_cast<int>(GroundTempObjType::SiteShallowGroundTemp)]),
134 0 : "");
135 :
136 0 : for (int monthIndex = 1; monthIndex <= 12; ++monthIndex) {
137 0 : Real64 currMonthTemp = shallowObj->getGroundTempAtTimeInMonths(state, 0.0, monthIndex);
138 :
139 : // Calculate Average Ground Temperature for all 12 months of the year:
140 0 : averageGroundTemp += currMonthTemp;
141 :
142 : // Need max temp, min temp, and month of min surf temp to set amplitude and month of min surf temp
143 0 : if (currMonthTemp <= minSurfTemp) {
144 0 : monthOfMinSurfTemp = monthIndex;
145 0 : minSurfTemp = currMonthTemp;
146 : }
147 :
148 0 : if (currMonthTemp >= maxSurfTemp) {
149 0 : maxSurfTemp = currMonthTemp;
150 : }
151 : }
152 :
153 0 : averageGroundTemp /= monthsInYear;
154 :
155 0 : amplitudeOfGroundTemp = (maxSurfTemp - minSurfTemp) / 2.0;
156 :
157 0 : phaseShiftOfMinGroundTempDays = monthOfMinSurfTemp * avgDaysInMonth;
158 :
159 : // Assign to KA Model
160 0 : thisModel->aveGroundTemp = averageGroundTemp;
161 0 : thisModel->aveGroundTempAmplitude = amplitudeOfGroundTemp;
162 0 : thisModel->phaseShiftInSecs = phaseShiftOfMinGroundTempDays * DataGlobalConstants::SecsInDay;
163 : }
164 :
165 33 : found = true;
166 33 : break;
167 : }
168 : }
169 :
170 33 : if (found && !ErrorsFound) {
171 33 : state.dataGrndTempModelMgr->groundTempModels.push_back(thisModel);
172 33 : return thisModel;
173 : } else {
174 0 : ShowFatalError(state,
175 0 : fmt::format("{}--Errors getting input for ground temperature model",
176 0 : GroundTemperatureManager::groundTempModelNames[static_cast<int>(objType)]));
177 0 : return nullptr;
178 : }
179 : }
180 :
181 : //******************************************************************************
182 :
183 82264718 : Real64 KusudaGroundTempsModel::getGroundTemp(EnergyPlusData &state)
184 : {
185 : // AUTHOR Matt Mitchell
186 : // DATE WRITTEN June 2015
187 : // MODIFIED na
188 : // RE-ENGINEERED na
189 :
190 : // PURPOSE OF THIS FUNCTION:
191 : // Returns a ground temperature
192 :
193 : // METHODOLOGY EMPLOYED:
194 : // Kusuda and Achenbach correlation is used
195 :
196 : // Using/Aliasing
197 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
198 : Real64 term1;
199 : Real64 term2;
200 : Real64 secsInYear;
201 : Real64 retVal;
202 :
203 82264718 : secsInYear = DataGlobalConstants::SecsInDay * state.dataWeatherManager->NumDaysInYear;
204 :
205 82264718 : term1 = -depth * std::sqrt(DataGlobalConstants::Pi / (secsInYear * groundThermalDiffisivity));
206 164529436 : term2 = (2 * DataGlobalConstants::Pi / secsInYear) *
207 82264718 : (simTimeInSeconds - phaseShiftInSecs - (depth / 2) * std::sqrt(secsInYear / (DataGlobalConstants::Pi * groundThermalDiffisivity)));
208 :
209 82264718 : retVal = aveGroundTemp - aveGroundTempAmplitude * std::exp(term1) * std::cos(term2);
210 :
211 82264718 : return retVal;
212 : }
213 :
214 : //******************************************************************************
215 :
216 82264718 : Real64 KusudaGroundTempsModel::getGroundTempAtTimeInSeconds(EnergyPlusData &state, Real64 const _depth, Real64 const _seconds)
217 : {
218 : // SUBROUTINE INFORMATION:
219 : // AUTHOR Matt Mitchell
220 : // DATE WRITTEN Summer 2015
221 : // MODIFIED na
222 : // RE-ENGINEERED na
223 :
224 : // PURPOSE OF THIS SUBROUTINE:
225 : // Returns the ground temperature when input time is in seconds
226 :
227 : // Using/Aliasing
228 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
229 82264718 : Real64 secondsInYear = state.dataWeatherManager->NumDaysInYear * DataGlobalConstants::SecsInDay;
230 :
231 82264718 : depth = _depth;
232 :
233 82264718 : simTimeInSeconds = _seconds;
234 :
235 82264718 : if (simTimeInSeconds > secondsInYear) {
236 0 : simTimeInSeconds = remainder(simTimeInSeconds, secondsInYear);
237 : }
238 :
239 : // Get and return ground temperature
240 82264718 : return getGroundTemp(state);
241 : }
242 :
243 : //******************************************************************************
244 :
245 0 : Real64 KusudaGroundTempsModel::getGroundTempAtTimeInMonths(EnergyPlusData &state, Real64 const _depth, int const _month)
246 : {
247 : // SUBROUTINE INFORMATION:
248 : // AUTHOR Matt Mitchell
249 : // DATE WRITTEN Summer 2015
250 : // MODIFIED na
251 : // RE-ENGINEERED na
252 :
253 : // Using/Aliasing
254 : // PURPOSE OF THIS SUBROUTINE:
255 : // Returns the ground temperature when input time is in months
256 :
257 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
258 0 : Real64 const aveSecondsInMonth = (state.dataWeatherManager->NumDaysInYear / 12) * DataGlobalConstants::SecsInDay;
259 0 : Real64 const secondsPerYear = state.dataWeatherManager->NumDaysInYear * DataGlobalConstants::SecsInDay;
260 :
261 0 : depth = _depth;
262 :
263 0 : simTimeInSeconds = aveSecondsInMonth * ((_month - 1) + 0.5);
264 :
265 0 : if (simTimeInSeconds > secondsPerYear) {
266 0 : simTimeInSeconds = remainder(simTimeInSeconds, secondsPerYear);
267 : }
268 :
269 : // Get and return ground temperature
270 0 : return getGroundTemp(state);
271 : }
272 :
273 : //******************************************************************************
274 :
275 2313 : } // namespace EnergyPlus
|