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 : #include <ObjexxFCL/Array1D.hh>
49 :
50 : #include <EnergyPlus/Data/EnergyPlusData.hh>
51 : #include <EnergyPlus/DataHeatBalance.hh>
52 : #include <EnergyPlus/DataIPShortCuts.hh>
53 : #include <EnergyPlus/EnergyPlus.hh>
54 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
55 : #include <EnergyPlus/PhaseChangeModeling/HysteresisModel.hh>
56 : #include <EnergyPlus/UtilityRoutines.hh>
57 :
58 : namespace EnergyPlus {
59 :
60 : namespace HysteresisPhaseChange {
61 :
62 13079 : HysteresisPhaseChange *HysteresisPhaseChange::factory(EnergyPlusData &state, const std::string &objectName)
63 : {
64 13079 : if (state.dataHysteresisPhaseChange->getHysteresisModels) {
65 764 : readAllHysteresisModels(state);
66 764 : state.dataHysteresisPhaseChange->getHysteresisModels = false;
67 : }
68 13081 : for (auto &hm : state.dataHysteresisPhaseChange->hysteresisPhaseChangeModels) {
69 3 : if (hm.name == objectName) {
70 1 : return &hm;
71 : }
72 13080 : }
73 : // because of the passive linking between materials and material property objects,
74 : // we don't know ahead of time for sure whether we will have a material property
75 : // so we can't return fatal here if it isn't found, just leave it null
76 13078 : return nullptr;
77 : }
78 :
79 1099700 : Real64 HysteresisPhaseChange::getEnthalpy(Real64 T, Real64 Tc, Real64 tau1, Real64 tau2)
80 : {
81 : // Looks up the enthalpy on the characteristic curve defined by the parameters Tc, tau1, and tau2,
82 : // and the position on that curve defined by T.
83 1099700 : Real64 eta1 = (this->totalLatentHeat / 2) * exp(-2 * std::abs(T - Tc) / tau1);
84 1099700 : Real64 eta2 = (this->totalLatentHeat / 2) * exp(-2 * std::abs(T - Tc) / tau2);
85 1099700 : if (T <= Tc) {
86 899914 : return (this->specificHeatSolid * T) + eta1;
87 : } else {
88 199786 : return (this->specificHeatSolid * Tc) + this->totalLatentHeat + this->specificHeatLiquid * (T - Tc) - eta2;
89 : }
90 : }
91 :
92 549850 : Real64 HysteresisPhaseChange::getCurrentSpecificHeat(
93 : Real64 prevTempTD, Real64 updatedTempTDT, Real64 phaseChangeTempReverse, int prevPhaseChangeState, int &phaseChangeState)
94 : {
95 : // Main public facing function; returns the current specific heat based on input properties, and current and previous conditions.
96 : // In a future version, this could be compartmentalized to track all states and histories, but it would require some further modification to
97 : // the HBFDManager
98 549850 : Real64 TempLowPCM = this->peakTempMelting - this->deltaTempMeltingLow;
99 549850 : Real64 TempHighPCM = this->peakTempMelting + this->deltaTempMeltingHigh;
100 : Real64 Tc; // assigned later
101 : Real64 Tau1; // assigned later
102 : Real64 Tau2; // assigned later
103 549850 : Real64 TempLowPCF = this->peakTempFreezing - this->deltaTempFreezingLow;
104 549850 : Real64 TempHighPCF = this->peakTempFreezing + this->deltaTempFreezingHigh;
105 : Real64 Cp;
106 549850 : Real64 phaseChangeDeltaT = prevTempTD - updatedTempTDT;
107 :
108 : // determine phase change state and curve characteristics based on delta T direction, updated temp, and previous state
109 549850 : if (phaseChangeDeltaT <= 0) {
110 169781 : Tc = this->peakTempMelting;
111 169781 : Tau1 = this->deltaTempMeltingLow;
112 169781 : Tau2 = this->deltaTempMeltingHigh;
113 169781 : if (updatedTempTDT < TempLowPCM) {
114 55442 : phaseChangeState = PhaseChangeStates::CRYSTALLIZED;
115 114339 : } else if (updatedTempTDT >= TempLowPCM && updatedTempTDT <= TempHighPCM) {
116 114339 : phaseChangeState = PhaseChangeStates::MELTING;
117 114339 : if (prevPhaseChangeState == PhaseChangeStates::FREEZING || prevPhaseChangeState == PhaseChangeStates::TRANSITION) {
118 4271 : phaseChangeState = PhaseChangeStates::TRANSITION;
119 : }
120 0 : } else if (updatedTempTDT > TempHighPCM) {
121 0 : phaseChangeState = PhaseChangeStates::LIQUID;
122 : }
123 : } else { // phaseChangeDeltaT > 0
124 380069 : Tc = this->peakTempFreezing;
125 380069 : Tau1 = this->deltaTempFreezingLow;
126 380069 : Tau2 = this->deltaTempFreezingHigh;
127 380069 : if (updatedTempTDT < TempLowPCF) {
128 286070 : phaseChangeState = PhaseChangeStates::CRYSTALLIZED;
129 93999 : } else if (updatedTempTDT >= TempLowPCF && updatedTempTDT <= TempHighPCF) {
130 14390 : phaseChangeState = PhaseChangeStates::FREEZING;
131 14390 : if (prevPhaseChangeState == PhaseChangeStates::MELTING || prevPhaseChangeState == PhaseChangeStates::TRANSITION) {
132 0 : phaseChangeState = PhaseChangeStates::TRANSITION;
133 : }
134 79609 : } else if (updatedTempTDT > TempHighPCF) {
135 79609 : phaseChangeState = PhaseChangeStates::LIQUID;
136 : }
137 : }
138 :
139 : // determine if we are transitioning or not
140 549850 : if (prevPhaseChangeState == PhaseChangeStates::TRANSITION && phaseChangeState == PhaseChangeStates::CRYSTALLIZED) {
141 0 : this->phaseChangeTransition = true;
142 549850 : } else if (prevPhaseChangeState == PhaseChangeStates::TRANSITION && phaseChangeState == PhaseChangeStates::FREEZING) {
143 0 : this->phaseChangeTransition = true;
144 : // this->phaseChangeState = 0; ?????
145 549850 : } else if (prevPhaseChangeState == PhaseChangeStates::FREEZING && phaseChangeState == PhaseChangeStates::TRANSITION) {
146 0 : this->phaseChangeTransition = true;
147 549850 : } else if (prevPhaseChangeState == PhaseChangeStates::CRYSTALLIZED && phaseChangeState == PhaseChangeStates::TRANSITION) {
148 0 : this->phaseChangeTransition = true;
149 : } else {
150 549850 : this->phaseChangeTransition = false;
151 : }
152 :
153 : // now calculate the enthalpy appropriately
154 549850 : if (!this->phaseChangeTransition) {
155 549850 : this->enthOld = this->getEnthalpy(prevTempTD, Tc, Tau1, Tau2);
156 549850 : this->enthNew = this->getEnthalpy(updatedTempTDT, Tc, Tau1, Tau2);
157 : } else {
158 0 : if (prevPhaseChangeState == PhaseChangeStates::FREEZING && phaseChangeState == PhaseChangeStates::TRANSITION) {
159 0 : this->enthRev =
160 0 : this->getEnthalpy(phaseChangeTempReverse, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
161 0 : this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthOld - (this->specHeatTransition * prevTempTD));
162 0 : this->enthalpyM = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
163 0 : this->enthalpyF = this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
164 0 : if (this->enthNew < this->enthRev && this->enthNew >= this->enthalpyF && updatedTempTDT <= prevTempTD) {
165 0 : phaseChangeState = PhaseChangeStates::FREEZING;
166 0 : this->enthNew =
167 0 : this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
168 0 : } else if ((this->enthNew < this->enthalpyF) && (this->enthNew > this->enthalpyM)) {
169 0 : phaseChangeState = PhaseChangeStates::TRANSITION;
170 0 : this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthOld - (this->specHeatTransition * prevTempTD));
171 0 : } else if ((this->enthNew < this->enthalpyF) && (updatedTempTDT > phaseChangeTempReverse)) {
172 0 : phaseChangeState = PhaseChangeStates::TRANSITION;
173 0 : this->enthNew =
174 0 : (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
175 0 : } else if ((this->enthNew <= this->enthalpyM) && (updatedTempTDT <= phaseChangeTempReverse)) {
176 0 : phaseChangeState = PhaseChangeStates::TRANSITION;
177 0 : this->enthNew =
178 0 : (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
179 : }
180 0 : } else if (prevPhaseChangeState == PhaseChangeStates::TRANSITION && phaseChangeState == PhaseChangeStates::TRANSITION) {
181 0 : if (updatedTempTDT < phaseChangeTempReverse) {
182 0 : Tc = this->peakTempMelting;
183 0 : Tau1 = this->deltaTempMeltingLow;
184 0 : Tau2 = this->deltaTempMeltingHigh;
185 0 : } else if (updatedTempTDT > phaseChangeTempReverse) {
186 0 : Tc = this->peakTempFreezing;
187 0 : Tau1 = this->deltaTempFreezingLow;
188 0 : Tau2 = this->deltaTempFreezingHigh;
189 : }
190 0 : this->enthRev = this->getEnthalpy(phaseChangeTempReverse, Tc, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
191 0 : this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthOld - (this->specHeatTransition * prevTempTD));
192 0 : this->enthalpyM = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
193 0 : this->enthalpyF = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
194 0 : if ((updatedTempTDT < phaseChangeTempReverse) && (this->enthNew > this->enthalpyF)) {
195 0 : phaseChangeState = PhaseChangeStates::FREEZING;
196 0 : this->enthNew =
197 0 : this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
198 0 : } else if ((this->enthNew < this->enthalpyF) && (this->enthNew > this->enthalpyM) &&
199 0 : (updatedTempTDT < prevTempTD || updatedTempTDT > prevTempTD)) {
200 0 : phaseChangeState = PhaseChangeStates::TRANSITION;
201 0 : this->enthNew =
202 0 : (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
203 0 : } else if (this->enthNew <= this->enthalpyM && updatedTempTDT >= prevTempTD && this->enthNew > this->enthOld) {
204 0 : phaseChangeState = PhaseChangeStates::MELTING;
205 0 : this->enthNew =
206 0 : (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
207 : }
208 0 : } else if (prevPhaseChangeState == PhaseChangeStates::TRANSITION && phaseChangeState == PhaseChangeStates::CRYSTALLIZED) {
209 0 : this->enthRev =
210 0 : this->getEnthalpy(phaseChangeTempReverse, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
211 0 : this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
212 0 : this->enthalpyM = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
213 0 : this->enthalpyF = this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
214 0 : if ((this->enthNew < this->enthalpyF) && (this->enthNew > this->enthalpyM)) {
215 0 : phaseChangeState = PhaseChangeStates::TRANSITION;
216 0 : this->enthNew =
217 0 : (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
218 0 : } else if (this->enthNew <= this->enthalpyM && updatedTempTDT >= prevTempTD) {
219 0 : phaseChangeState = PhaseChangeStates::MELTING;
220 0 : this->enthNew = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
221 : }
222 0 : } else if (prevPhaseChangeState == PhaseChangeStates::MELTING && phaseChangeState == PhaseChangeStates::TRANSITION) {
223 0 : this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthOld - (this->specHeatTransition * prevTempTD));
224 0 : this->enthalpyM = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
225 0 : this->enthalpyF = this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
226 0 : if ((this->enthNew < this->enthOld) && (updatedTempTDT < prevTempTD)) {
227 0 : phaseChangeState = PhaseChangeStates::TRANSITION;
228 0 : this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthOld - (this->specHeatTransition * prevTempTD));
229 0 : } else if ((this->enthNew < this->enthalpyF) && (this->enthNew > this->enthalpyM) && (updatedTempTDT < prevTempTD)) {
230 0 : phaseChangeState = PhaseChangeStates::TRANSITION;
231 0 : this->enthNew =
232 0 : (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
233 0 : } else if ((this->enthNew >= this->enthalpyF) && (updatedTempTDT <= phaseChangeTempReverse)) {
234 0 : phaseChangeState = PhaseChangeStates::TRANSITION;
235 0 : this->enthNew =
236 0 : (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
237 : }
238 0 : } else if (prevPhaseChangeState == PhaseChangeStates::TRANSITION && phaseChangeState == PhaseChangeStates::FREEZING) {
239 0 : this->enthalpyM = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
240 0 : this->enthalpyF = this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
241 0 : this->enthRev =
242 0 : this->getEnthalpy(phaseChangeTempReverse, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
243 0 : this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
244 : }
245 : }
246 :
247 : // then calculate the specific heat and return it
248 549850 : if (!this->phaseChangeTransition) {
249 549850 : if (this->enthNew == this->enthOld) {
250 74919 : Cp = this->CpOld;
251 : } else {
252 474931 : Cp = this->specHeat(prevTempTD, updatedTempTDT, Tc, Tau1, Tau2, this->enthOld, this->enthNew);
253 : }
254 : } else {
255 0 : Cp = this->specHeatTransition;
256 : }
257 549850 : this->CpOld = Cp;
258 549850 : return Cp;
259 : }
260 :
261 474931 : Real64 HysteresisPhaseChange::specHeat(Real64 temperaturePrev,
262 : Real64 temperatureCurrent,
263 : Real64 criticalTemperature,
264 : Real64 tau1,
265 : Real64 tau2,
266 : Real64 EnthalpyOld,
267 : Real64 EnthalpyNew)
268 : {
269 :
270 : // Tc ! Critical (Melting/Freezing) Temperature of PCM
271 : // Tau1 ! Width of Melting Zone low
272 : // Tau2 ! Width of Melting Zone high
273 : // EnthalpyOld ! Previous Timestep Nodal Enthalpy
274 : // EnthalpyNew ! Current Timestep Nodal Enthalpy
275 :
276 474931 : Real64 T = temperatureCurrent;
277 :
278 474931 : if (T < criticalTemperature) {
279 376132 : Real64 DEta1 = -(this->totalLatentHeat * (T - criticalTemperature) * exp(-2 * std::abs(T - criticalTemperature) / tau1)) /
280 376132 : (tau1 * std::abs(T - criticalTemperature));
281 376132 : Real64 Cp1 = this->specificHeatSolid;
282 376132 : return (Cp1 + DEta1);
283 98799 : } else if (T == criticalTemperature) {
284 0 : return (EnthalpyNew - EnthalpyOld) / (temperatureCurrent - temperaturePrev);
285 98799 : } else if (T > criticalTemperature) {
286 98799 : Real64 DEta2 = (this->totalLatentHeat * (T - criticalTemperature) * exp(-2 * std::abs(T - criticalTemperature) / tau2)) /
287 98799 : (tau2 * std::abs(T - criticalTemperature));
288 98799 : Real64 Cp2 = this->specificHeatLiquid;
289 98799 : return Cp2 + DEta2;
290 : } else {
291 0 : return 0;
292 : }
293 : }
294 :
295 1209670 : Real64 HysteresisPhaseChange::getConductivity(Real64 T)
296 : {
297 1209670 : if (T < this->peakTempMelting) {
298 1154717 : return this->fullySolidThermalConductivity;
299 54953 : } else if (T > this->peakTempFreezing) {
300 54953 : return this->fullyLiquidThermalConductivity;
301 : } else {
302 0 : return (this->fullySolidThermalConductivity + this->fullyLiquidThermalConductivity) / 2.0;
303 : }
304 : }
305 :
306 549850 : Real64 HysteresisPhaseChange::getDensity(Real64 T)
307 : {
308 549850 : if (T < this->peakTempMelting) {
309 520422 : return this->fullySolidDensity;
310 29428 : } else if (T > this->peakTempFreezing) {
311 29428 : return this->fullyLiquidDensity;
312 : } else {
313 0 : return (this->fullySolidDensity + this->fullyLiquidDensity) / 2.0;
314 : }
315 : }
316 :
317 764 : void readAllHysteresisModels(EnergyPlusData &state)
318 : {
319 :
320 : // convenience variables
321 764 : state.dataIPShortCut->cCurrentModuleObject = "MaterialProperty:PhaseChangeHysteresis";
322 1528 : state.dataHysteresisPhaseChange->numHysteresisModels =
323 764 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
324 :
325 : // loop over all hysteresis input instances, if zero, this will simply not do anything
326 765 : for (int hmNum = 1; hmNum <= state.dataHysteresisPhaseChange->numHysteresisModels; ++hmNum) {
327 :
328 : // just a few vars to pass in and out to GetObjectItem
329 : int ioStatus;
330 : int numAlphas;
331 : int numNumbers;
332 :
333 : // get the input data and store it in the Shortcuts structures
334 2 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
335 1 : state.dataIPShortCut->cCurrentModuleObject,
336 : hmNum,
337 1 : state.dataIPShortCut->cAlphaArgs,
338 : numAlphas,
339 1 : state.dataIPShortCut->rNumericArgs,
340 : numNumbers,
341 : ioStatus,
342 1 : state.dataIPShortCut->lNumericFieldBlanks,
343 1 : state.dataIPShortCut->lAlphaFieldBlanks,
344 1 : state.dataIPShortCut->cAlphaFieldNames,
345 1 : state.dataIPShortCut->cNumericFieldNames);
346 :
347 : // the input processor validates the numeric inputs based on the IDD definition
348 : // still validate the name to make sure there aren't any duplicates or blanks
349 : // blanks are easy: fatal if blank
350 1 : if (state.dataIPShortCut->lAlphaFieldBlanks[0]) {
351 0 : ShowFatalError(state, "Invalid input for " + state.dataIPShortCut->cCurrentModuleObject + " object: Name cannot be blank");
352 : }
353 :
354 : // we just need to loop over the existing vector elements to check for duplicates since we haven't add this one yet
355 1 : for (auto &existingHysteresisModel : state.dataHysteresisPhaseChange->hysteresisPhaseChangeModels) {
356 0 : if (state.dataIPShortCut->cAlphaArgs(1) == existingHysteresisModel.name) {
357 0 : ShowFatalError(state,
358 0 : "Invalid input for " + state.dataIPShortCut->cCurrentModuleObject +
359 0 : " object: Duplicate name found: " + existingHysteresisModel.name);
360 : }
361 1 : }
362 :
363 : // now build out a new hysteresis instance and add it to the vector
364 1 : HysteresisPhaseChange thisHM;
365 1 : thisHM.name = state.dataIPShortCut->cAlphaArgs(1);
366 1 : thisHM.totalLatentHeat = state.dataIPShortCut->rNumericArgs(1);
367 1 : thisHM.fullyLiquidThermalConductivity = state.dataIPShortCut->rNumericArgs(2);
368 1 : thisHM.fullyLiquidDensity = state.dataIPShortCut->rNumericArgs(3);
369 1 : thisHM.specificHeatLiquid = state.dataIPShortCut->rNumericArgs(4);
370 1 : thisHM.deltaTempMeltingHigh = state.dataIPShortCut->rNumericArgs(5);
371 1 : thisHM.peakTempMelting = state.dataIPShortCut->rNumericArgs(6);
372 1 : thisHM.deltaTempMeltingLow = state.dataIPShortCut->rNumericArgs(7);
373 1 : thisHM.fullySolidThermalConductivity = state.dataIPShortCut->rNumericArgs(8);
374 1 : thisHM.fullySolidDensity = state.dataIPShortCut->rNumericArgs(9);
375 1 : thisHM.specificHeatSolid = state.dataIPShortCut->rNumericArgs(10);
376 1 : thisHM.deltaTempFreezingHigh = state.dataIPShortCut->rNumericArgs(11);
377 1 : thisHM.peakTempFreezing = state.dataIPShortCut->rNumericArgs(12);
378 1 : thisHM.deltaTempFreezingLow = state.dataIPShortCut->rNumericArgs(13);
379 1 : thisHM.specHeatTransition = (thisHM.specificHeatSolid + thisHM.specificHeatLiquid) / 2.0;
380 1 : thisHM.CpOld = thisHM.specificHeatSolid;
381 1 : state.dataHysteresisPhaseChange->hysteresisPhaseChangeModels.push_back(thisHM);
382 1 : }
383 764 : }
384 :
385 : } // namespace HysteresisPhaseChange
386 :
387 : } // namespace EnergyPlus
|