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 : // ObjexxFCL Headers
49 : #include <ObjexxFCL/Array.functions.hh>
50 : #include <ObjexxFCL/Fmath.hh>
51 :
52 : // EnergyPlus Headers
53 : #include <EnergyPlus/Data/EnergyPlusData.hh>
54 : #include <EnergyPlus/DataEnvironment.hh>
55 : #include <EnergyPlus/DataHeatBalFanSys.hh>
56 : #include <EnergyPlus/DataHeatBalSurface.hh>
57 : #include <EnergyPlus/DataHeatBalance.hh>
58 : #include <EnergyPlus/DataLoopNode.hh>
59 : #include <EnergyPlus/DataRoomAirModel.hh>
60 : #include <EnergyPlus/DataSurfaces.hh>
61 : #include <EnergyPlus/DataZoneEquipment.hh>
62 : #include <EnergyPlus/InternalHeatGains.hh>
63 : #include <EnergyPlus/MundtSimMgr.hh>
64 : #include <EnergyPlus/OutputProcessor.hh>
65 : #include <EnergyPlus/Psychrometrics.hh>
66 : #include <EnergyPlus/UtilityRoutines.hh>
67 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
68 :
69 : namespace EnergyPlus {
70 :
71 : namespace RoomAir {
72 :
73 : // MODULE INFORMATION:
74 : // AUTHOR Brent Griffith
75 : // DATE WRITTEN February 2002
76 : // RE-ENGINEERED June 2003, EnergyPlus Implementation (CC)
77 : // MODIFIED February 2004, fix allocate-deallocate problem (CC)
78 :
79 : // PURPOSE OF THIS MODULE:
80 : // This module is the main module for running the
81 : // nodal air Mundt model...
82 :
83 : // METHODOLOGY EMPLOYED:
84 : // This module contains all subroutines required by the mundt model.
85 : // The following modules from AirToolkit included in this module are:
86 : // 1) MundtSimMgr Module,
87 : // 2) MundtInputMgr Module, and
88 : // 3) DataMundt Module,
89 :
90 : // REFERENCES:
91 : // AirToolkit source code
92 :
93 : // OTHER NOTES:
94 : // na
95 :
96 : // Data
97 : // MODULE PARAMETER DEFINITIONS:
98 : Real64 constexpr CpAir(1005.0); // Specific heat of air
99 : Real64 constexpr MinSlope(0.001); // Bound on result from Mundt model
100 : Real64 constexpr MaxSlope(5.0); // Bound on result from Mundt Model
101 :
102 : // MODULE VARIABLE DECLARATIONS:
103 :
104 17080 : void ManageDispVent1Node(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
105 : {
106 :
107 : // SUBROUTINE INFORMATION:
108 : // AUTHOR Chanvit Chantrasrisalai
109 : // DATE WRITTEN July 2003
110 : // MODIFIED February 2004, fix allocate-deallocate problem (CC)
111 : // RE-ENGINEERED na
112 :
113 : // PURPOSE OF THIS SUBROUTINE:
114 : // manage the Mundt model
115 :
116 : bool ErrorsFound;
117 :
118 : // initialize Mundt model data
119 17080 : if (state.dataHeatBal->MundtFirstTimeFlag) {
120 2 : InitDispVent1Node(state);
121 2 : state.dataHeatBal->MundtFirstTimeFlag = false;
122 : }
123 :
124 : // identify the current zone index for zones using Mundt model
125 17080 : state.dataMundtSimMgr->MundtZoneNum = state.dataMundtSimMgr->ZoneData(ZoneNum).MundtZoneIndex;
126 :
127 : // transfer data from surface domain to air domain for the specified zone
128 17080 : GetSurfHBDataForDispVent1Node(state, ZoneNum);
129 :
130 : // use the Mundt model only for cooling case
131 17080 : if ((state.dataMundtSimMgr->SupplyAirVolumeRate > 0.0001) && (state.dataMundtSimMgr->QsysCoolTot > 0.0001)) {
132 :
133 : // setup Mundt model
134 8626 : ErrorsFound = false;
135 8626 : SetupDispVent1Node(state, ZoneNum, ErrorsFound);
136 8626 : if (ErrorsFound) ShowFatalError(state, "ManageMundtModel: Errors in setting up Mundt Model. Preceding condition(s) cause termination.");
137 :
138 : // perform Mundt model calculations
139 8626 : CalcDispVent1Node(state, ZoneNum);
140 : }
141 :
142 : // transfer data from air domain back to surface domain for the specified zone
143 17080 : SetSurfHBDataForDispVent1Node(state, ZoneNum);
144 17080 : }
145 :
146 : //*****************************************************************************************
147 :
148 2 : void InitDispVent1Node(EnergyPlusData &state)
149 : {
150 :
151 : // SUBROUTINE INFORMATION:
152 : // AUTHOR Chanvit Chantrasrisalai
153 : // DATE WRITTEN February 2004
154 : // MODIFIED na
155 : // RE-ENGINEERED na
156 :
157 : // PURPOSE OF THIS SUBROUTINE:
158 : // initialize Mundt-model variables
159 :
160 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
161 : int NodeNum; // index for air nodes
162 : int ZoneIndex; // index for zones
163 : int NumOfAirNodes; // total number of nodes in each zone
164 : int NumOfMundtZones; // number of zones using the Mundt model
165 : int MundtZoneIndex; // index for zones using the Mundt model
166 : int MaxNumOfSurfs; // maximum of number of surfaces
167 : int MaxNumOfFloorSurfs; // maximum of number of surfaces
168 : int MaxNumOfAirNodes; // maximum of number of air nodes
169 : int MaxNumOfRoomNodes; // maximum of number of nodes connected to walls
170 : int RoomNodesCount; // number of nodes connected to walls
171 : int FloorSurfCount; // number of nodes connected to walls
172 : int AirNodeBeginNum; // index number of the first air node for this zone
173 : int AirNodeNum; // index for air nodes
174 : bool AirNodeFoundFlag; // flag used for error check
175 : bool ErrorsFound; // true if errors found in init
176 :
177 : // allocate and initialize zone data
178 2 : state.dataMundtSimMgr->ZoneData.allocate(state.dataGlobal->NumOfZones);
179 10 : for (auto &e : state.dataMundtSimMgr->ZoneData) {
180 8 : e.NumOfSurfs = 0;
181 8 : e.MundtZoneIndex = 0;
182 : }
183 :
184 : // get zone data
185 2 : NumOfMundtZones = 0;
186 2 : MaxNumOfSurfs = 0;
187 2 : MaxNumOfFloorSurfs = 0;
188 2 : MaxNumOfAirNodes = 0;
189 2 : MaxNumOfRoomNodes = 0;
190 2 : ErrorsFound = false;
191 10 : for (ZoneIndex = 1; ZoneIndex <= state.dataGlobal->NumOfZones; ++ZoneIndex) {
192 8 : auto &thisZone = state.dataHeatBal->Zone(ZoneIndex);
193 8 : if (state.dataRoomAir->AirModel(ZoneIndex).AirModel == RoomAir::RoomAirModel::DispVent1Node) {
194 : // find number of zones using the Mundt model
195 4 : ++NumOfMundtZones;
196 : // find maximum number of surfaces in zones using the Mundt model
197 4 : int NumOfSurfs = 0;
198 8 : for (int spaceNum : thisZone.spaceIndexes) {
199 4 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
200 92 : for (int surfNum = thisSpace.HTSurfaceFirst; surfNum <= thisSpace.HTSurfaceLast; ++surfNum) {
201 88 : state.dataMundtSimMgr->ZoneData(ZoneIndex).HBsurfaceIndexes.emplace_back(surfNum);
202 88 : ++NumOfSurfs;
203 : }
204 4 : MaxNumOfSurfs = max(MaxNumOfSurfs, NumOfSurfs);
205 : // find maximum number of air nodes in zones using the Mundt model
206 4 : NumOfAirNodes = state.dataRoomAir->TotNumOfZoneAirNodes(ZoneIndex);
207 4 : MaxNumOfAirNodes = max(MaxNumOfAirNodes, NumOfAirNodes);
208 : // assign zone data
209 4 : state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs = NumOfSurfs;
210 4 : state.dataMundtSimMgr->ZoneData(ZoneIndex).MundtZoneIndex = NumOfMundtZones;
211 4 : }
212 : }
213 : }
214 :
215 : // allocate and initialize surface and air-node data
216 2 : state.dataMundtSimMgr->ID1dSurf.allocate(MaxNumOfSurfs);
217 2 : state.dataMundtSimMgr->TheseSurfIDs.allocate(MaxNumOfSurfs);
218 2 : state.dataMundtSimMgr->MundtAirSurf.allocate(MaxNumOfSurfs, NumOfMundtZones);
219 2 : state.dataMundtSimMgr->LineNode.allocate(MaxNumOfAirNodes, NumOfMundtZones);
220 46 : for (int SurfNum = 1; SurfNum <= MaxNumOfSurfs; ++SurfNum)
221 44 : state.dataMundtSimMgr->ID1dSurf(SurfNum) = SurfNum;
222 90 : for (auto &e : state.dataMundtSimMgr->MundtAirSurf) {
223 88 : e.Area = 0.0;
224 88 : e.Temp = 25.0;
225 88 : e.Hc = 0.0;
226 88 : e.TMeanAir = 25.0;
227 : }
228 38 : for (auto &e : state.dataMundtSimMgr->LineNode) {
229 36 : e.AirNodeName.clear();
230 36 : e.ClassType = RoomAir::AirNodeType::Invalid;
231 36 : e.Height = 0.0;
232 36 : e.Temp = 25.0;
233 : }
234 :
235 : // get constant data (unchanged over time) for surfaces and air nodes
236 6 : for (MundtZoneIndex = 1; MundtZoneIndex <= NumOfMundtZones; ++MundtZoneIndex) {
237 10 : for (ZoneIndex = 1; ZoneIndex <= state.dataGlobal->NumOfZones; ++ZoneIndex) {
238 10 : auto &thisZone = state.dataHeatBal->Zone(ZoneIndex);
239 10 : if (state.dataMundtSimMgr->ZoneData(ZoneIndex).MundtZoneIndex == MundtZoneIndex) {
240 : // get surface data
241 92 : for (int surfNum = 1; surfNum <= state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs; ++surfNum) {
242 88 : state.dataMundtSimMgr->MundtAirSurf(surfNum, MundtZoneIndex).Area =
243 88 : state.dataSurface->Surface(state.dataMundtSimMgr->ZoneData(ZoneIndex).HBsurfaceIndexes(surfNum)).Area;
244 : }
245 :
246 : // get air node data
247 4 : RoomNodesCount = 0;
248 4 : FloorSurfCount = 0;
249 40 : for (NodeNum = 1; NodeNum <= state.dataRoomAir->TotNumOfZoneAirNodes(ZoneIndex); ++NodeNum) {
250 :
251 36 : state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex)
252 36 : .SurfMask.allocate(state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs);
253 :
254 36 : if (NodeNum == 1) {
255 4 : AirNodeBeginNum = NodeNum;
256 : }
257 :
258 : // error check for debugging
259 36 : if (AirNodeBeginNum > state.dataRoomAir->TotNumOfAirNodes) {
260 0 : ShowFatalError(state, "An array bound exceeded. Error in InitMundtModel subroutine of MundtSimMgr.");
261 : }
262 :
263 36 : AirNodeFoundFlag = false;
264 54 : for (AirNodeNum = AirNodeBeginNum; AirNodeNum <= state.dataRoomAir->TotNumOfAirNodes; ++AirNodeNum) {
265 54 : if (Util::SameString(state.dataRoomAir->AirNode(AirNodeNum).ZoneName, thisZone.Name)) {
266 36 : state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).ClassType = state.dataRoomAir->AirNode(AirNodeNum).ClassType;
267 36 : state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).AirNodeName = state.dataRoomAir->AirNode(AirNodeNum).Name;
268 36 : state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).Height = state.dataRoomAir->AirNode(AirNodeNum).Height;
269 36 : state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).SurfMask = state.dataRoomAir->AirNode(AirNodeNum).SurfMask;
270 72 : SetupOutputVariable(state,
271 : "Room Air Node Air Temperature",
272 : Constant::Units::C,
273 36 : state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).Temp,
274 : OutputProcessor::TimeStepType::System,
275 : OutputProcessor::StoreType::Average,
276 36 : state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).AirNodeName);
277 :
278 36 : AirNodeBeginNum = AirNodeNum + 1;
279 36 : AirNodeFoundFlag = true;
280 :
281 36 : break;
282 : }
283 : }
284 :
285 : // error check for debugging
286 36 : if (!AirNodeFoundFlag) {
287 0 : ShowSevereError(state, format("InitMundtModel: Air Node in Zone=\"{}\" is not found.", thisZone.Name));
288 0 : ErrorsFound = true;
289 0 : continue;
290 : }
291 :
292 : // count air nodes connected to walls in each zone
293 36 : if (state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).ClassType == RoomAir::AirNodeType::Mundt) {
294 16 : ++RoomNodesCount;
295 : }
296 :
297 : // count floors in each zone
298 36 : if (state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).ClassType == RoomAir::AirNodeType::Floor) {
299 4 : FloorSurfCount += count(state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).SurfMask);
300 : }
301 : }
302 : // got data for this zone so exit the zone loop
303 4 : if (AirNodeFoundFlag) break;
304 : }
305 : }
306 :
307 4 : MaxNumOfRoomNodes = max(MaxNumOfRoomNodes, RoomNodesCount);
308 4 : MaxNumOfFloorSurfs = max(MaxNumOfFloorSurfs, FloorSurfCount);
309 : }
310 :
311 2 : if (ErrorsFound) ShowFatalError(state, "InitMundtModel: Preceding condition(s) cause termination.");
312 :
313 : // allocate arrays
314 2 : state.dataMundtSimMgr->RoomNodeIDs.allocate(MaxNumOfRoomNodes);
315 2 : state.dataMundtSimMgr->FloorSurfSetIDs.allocate(MaxNumOfFloorSurfs);
316 2 : state.dataMundtSimMgr->FloorSurf.allocate(MaxNumOfFloorSurfs);
317 2 : }
318 :
319 : //*****************************************************************************************
320 :
321 17080 : void GetSurfHBDataForDispVent1Node(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
322 : {
323 :
324 : // SUBROUTINE INFORMATION:
325 : // AUTHOR Weixiu Kong
326 : // DATE WRITTEN April 2003
327 : // MODIFIED July 2003 (CC)
328 : // February 2004, fix allocate-deallocate problem (CC)
329 :
330 : // PURPOSE OF THIS SUBROUTINE:
331 : // map data from surface domain to air domain for each particular zone
332 :
333 : using Psychrometrics::PsyCpAirFnW;
334 : using Psychrometrics::PsyRhoAirFnPbTdbW;
335 : using Psychrometrics::PsyWFnTdpPb;
336 :
337 : Real64 CpAir; // specific heat
338 : int NodeNum; // index for air nodes
339 : Real64 SumSysMCp; // zone sum of air system MassFlowRate*Cp
340 : Real64 SumSysMCpT; // zone sum of air system MassFlowRate*Cp*T
341 : Real64 MassFlowRate; // mass flowrate
342 : Real64 NodeTemp; // node temperature
343 : int ZoneNode; // index number for specified zone node
344 : Real64 ZoneMassFlowRate; // zone mass flowrate
345 : int ZoneEquipConfigNum; // index number for zone equipment configuration
346 : Real64 ZoneMult; // total zone multiplier
347 : Real64 RetAirConvGain;
348 :
349 17080 : auto &Zone(state.dataHeatBal->Zone);
350 :
351 : // determine ZoneEquipConfigNum for this zone
352 17080 : ZoneEquipConfigNum = ZoneNum;
353 : // check whether this zone is a controlled zone or not
354 17080 : if (!Zone(ZoneNum).IsControlled) {
355 0 : ShowFatalError(state, format("Zones must be controlled for Mundt air model. No system serves zone {}", Zone(ZoneNum).Name));
356 0 : return;
357 : }
358 :
359 : // determine information required by Mundt model
360 17080 : state.dataMundtSimMgr->ZoneHeight = Zone(ZoneNum).CeilingHeight;
361 17080 : state.dataMundtSimMgr->ZoneFloorArea = Zone(ZoneNum).FloorArea;
362 17080 : ZoneMult = Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier;
363 :
364 : // supply air flowrate is the same as zone air flowrate
365 17080 : ZoneNode = Zone(ZoneNum).SystemZoneNodeNumber;
366 34160 : state.dataMundtSimMgr->ZoneAirDensity =
367 34160 : PsyRhoAirFnPbTdbW(state,
368 17080 : state.dataEnvrn->OutBaroPress,
369 17080 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT,
370 17080 : PsyWFnTdpPb(state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT, state.dataEnvrn->OutBaroPress));
371 17080 : ZoneMassFlowRate = state.dataLoopNodes->Node(ZoneNode).MassFlowRate;
372 17080 : state.dataMundtSimMgr->SupplyAirVolumeRate = ZoneMassFlowRate / state.dataMundtSimMgr->ZoneAirDensity;
373 17080 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
374 17080 : if (ZoneMassFlowRate <= 0.0001) {
375 : // system is off
376 351 : state.dataMundtSimMgr->QsysCoolTot = 0.0;
377 : } else {
378 : // determine supply air conditions
379 16729 : SumSysMCp = 0.0;
380 16729 : SumSysMCpT = 0.0;
381 33458 : for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).NumInletNodes; ++NodeNum) {
382 16729 : NodeTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).Temp;
383 16729 : MassFlowRate = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).MassFlowRate;
384 16729 : CpAir = PsyCpAirFnW(thisZoneHB.airHumRat);
385 16729 : SumSysMCp += MassFlowRate * CpAir;
386 16729 : SumSysMCpT += MassFlowRate * CpAir * NodeTemp;
387 : }
388 : // prevent dividing by zero due to zero supply air flow rate
389 16729 : if (SumSysMCp <= 0.0) {
390 0 : state.dataMundtSimMgr->SupplyAirTemp =
391 0 : state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(1)).Temp;
392 : } else {
393 : // a weighted average of the inlet temperatures
394 16729 : state.dataMundtSimMgr->SupplyAirTemp = SumSysMCpT / SumSysMCp;
395 : }
396 : // determine cooling load
397 16729 : CpAir = PsyCpAirFnW(thisZoneHB.airHumRat);
398 16729 : state.dataMundtSimMgr->QsysCoolTot =
399 16729 : -(SumSysMCpT - ZoneMassFlowRate * CpAir * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
400 : }
401 : // determine heat gains
402 17080 : state.dataMundtSimMgr->ConvIntGain = InternalHeatGains::zoneSumAllInternalConvectionGains(state, ZoneNum);
403 17080 : state.dataMundtSimMgr->ConvIntGain += state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumConvPool(ZoneNum) +
404 17080 : thisZoneHB.SysDepZoneLoadsLagged + thisZoneHB.NonAirSystemResponse / ZoneMult;
405 :
406 : // Add heat to return air if zonal system (no return air) or cycling system (return air frequently very
407 : // low or zero)
408 17080 : if (Zone(ZoneNum).NoHeatToReturnAir) {
409 0 : RetAirConvGain = InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, ZoneNum, 0);
410 0 : state.dataMundtSimMgr->ConvIntGain += RetAirConvGain;
411 : }
412 :
413 34160 : state.dataMundtSimMgr->QventCool =
414 17080 : -thisZoneHB.MCPI * (Zone(ZoneNum).OutDryBulbTemp - state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
415 :
416 : // get surface data
417 392840 : for (int SurfNum = 1; SurfNum <= state.dataMundtSimMgr->ZoneData(ZoneNum).NumOfSurfs; ++SurfNum) {
418 375760 : state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).Temp =
419 375760 : state.dataHeatBalSurf->SurfTempIn(state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum));
420 375760 : state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).Hc =
421 375760 : state.dataHeatBalSurf->SurfHConvInt(state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum));
422 : }
423 : }
424 :
425 : //*****************************************************************************************
426 :
427 8626 : void SetupDispVent1Node(EnergyPlusData &state,
428 : int const ZoneNum, // index number for the specified zone
429 : bool &ErrorsFound // true if problems setting up model
430 : )
431 : {
432 :
433 : // SUBROUTINE INFORMATION:
434 : // AUTHOR Brent Griffith
435 : // DATE WRITTEN Febraury 2002
436 : // RE-ENGINEERED June 2003, EnergyPlus Implementation (CC)
437 : // MODIFIED February 2004, fix allocate-deallocate problem (CC)
438 :
439 : // PURPOSE OF THIS SUBROUTINE:
440 : // Subroutine must be called once before main model calculation
441 : // need to pass some zone characteristics only once
442 : // initializes module level variables, collect info from Air Data Manager
443 :
444 : // METHODOLOGY EMPLOYED:
445 : // na
446 :
447 : // REFERENCES:
448 : // na
449 :
450 : // Locals
451 : // SUBROUTINE ARGUMENT DEFINITIONS:
452 :
453 : // SUBROUTINE PARAMETER DEFINITIONS:
454 : // na
455 :
456 : // INTERFACE BLOCK SPECIFICATIONS:
457 : // na
458 :
459 : // DERIVED TYPE DEFINITIONS:
460 : // na
461 :
462 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
463 : int NodeNum; // index for air nodes
464 : int SurfNum; // index for surfaces
465 :
466 : // set up air node ID
467 8626 : state.dataMundtSimMgr->NumRoomNodes = 0;
468 86260 : for (NodeNum = 1; NodeNum <= state.dataRoomAir->TotNumOfZoneAirNodes(ZoneNum); ++NodeNum) {
469 77634 : switch (state.dataMundtSimMgr->LineNode(NodeNum, state.dataMundtSimMgr->MundtZoneNum).ClassType) {
470 8626 : case RoomAir::AirNodeType::Inlet: { // inlet
471 8626 : state.dataMundtSimMgr->SupplyNodeID = NodeNum;
472 8626 : } break;
473 8626 : case RoomAir::AirNodeType::Floor: { // floor
474 8626 : state.dataMundtSimMgr->MundtFootAirID = NodeNum;
475 8626 : } break;
476 8626 : case RoomAir::AirNodeType::Control: { // thermostat
477 8626 : state.dataMundtSimMgr->TstatNodeID = NodeNum;
478 8626 : } break;
479 8626 : case RoomAir::AirNodeType::Ceiling: { // ceiling
480 8626 : state.dataMundtSimMgr->MundtCeilAirID = NodeNum;
481 8626 : } break;
482 34504 : case RoomAir::AirNodeType::Mundt: { // wall
483 34504 : ++state.dataMundtSimMgr->NumRoomNodes;
484 34504 : state.dataMundtSimMgr->RoomNodeIDs(state.dataMundtSimMgr->NumRoomNodes) = NodeNum;
485 34504 : } break;
486 8626 : case RoomAir::AirNodeType::Return: { // return
487 8626 : state.dataMundtSimMgr->ReturnNodeID = NodeNum;
488 8626 : } break;
489 0 : default: {
490 0 : ShowSevereError(state, "SetupMundtModel: Non-Standard Type of Air Node for Mundt Model");
491 0 : ErrorsFound = true;
492 0 : } break;
493 : }
494 : }
495 :
496 : // get number of floors in the zone and setup FloorSurfSetIDs
497 8626 : if (state.dataMundtSimMgr->MundtFootAirID > 0) {
498 17252 : state.dataMundtSimMgr->NumFloorSurfs =
499 8626 : count(state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
500 8626 : state.dataMundtSimMgr->FloorSurfSetIDs =
501 17252 : pack(state.dataMundtSimMgr->ID1dSurf,
502 17252 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
503 : // initialize floor surface data (a must since NumFloorSurfs is varied among zones)
504 25878 : for (auto &e : state.dataMundtSimMgr->FloorSurf) {
505 17252 : e.Temp = 25.0;
506 17252 : e.Hc = 0.0;
507 17252 : e.Area = 0.0;
508 : }
509 : // get floor surface data
510 25878 : for (SurfNum = 1; SurfNum <= state.dataMundtSimMgr->NumFloorSurfs; ++SurfNum) {
511 17252 : state.dataMundtSimMgr->FloorSurf(SurfNum).Temp =
512 17252 : state.dataMundtSimMgr->MundtAirSurf(state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), state.dataMundtSimMgr->MundtZoneNum).Temp;
513 17252 : state.dataMundtSimMgr->FloorSurf(SurfNum).Hc =
514 17252 : state.dataMundtSimMgr->MundtAirSurf(state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), state.dataMundtSimMgr->MundtZoneNum).Hc;
515 17252 : state.dataMundtSimMgr->FloorSurf(SurfNum).Area =
516 17252 : state.dataMundtSimMgr->MundtAirSurf(state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), state.dataMundtSimMgr->MundtZoneNum).Area;
517 : }
518 : } else {
519 0 : ShowSevereError(state, format("SetupMundtModel: Mundt model has no FloorAirNode, Zone={}", state.dataHeatBal->Zone(ZoneNum).Name));
520 0 : ErrorsFound = true;
521 : }
522 8626 : }
523 :
524 : //*****************************************************************************************
525 :
526 8626 : void CalcDispVent1Node(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
527 : {
528 :
529 : // SUBROUTINE INFORMATION:
530 : // AUTHOR Brent Griffith
531 : // DATE WRITTEN September 2001
532 : // RE-ENGINEERED July 2003, EnergyPlus Implementation (CC)
533 : // MODIFIED February 2004, fix allocate-deallocate problem (CC)
534 :
535 : // PURPOSE OF THIS SUBROUTINE:
536 : // Compute the simplified version of Mundt and store results in Air data Manager
537 : // argument passing is plentiful but are IN and nothing out.
538 : // these variables are scaler conditions at current HB day,timestep, and iteration
539 : // This subroutine is USE'ed by heat balance driver (top level module)
540 :
541 : // METHODOLOGY EMPLOYED:
542 : // apply Mundt's simple model for delta Temp head-foot and update values in Air data manager.
543 :
544 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
545 : Real64 TAirFoot; // air temperature at the floor
546 : Real64 TAirCeil; // air temperature at the ceiling
547 : Real64 TLeaving; // air temperature leaving zone (= return air temp)
548 : Real64 TControlPoint; // air temperature at thermostat
549 : Real64 Slope; // vertical air temperature gradient (slope) from Mundt equations
550 : Real64 QequipConvFloor; // convective gain at the floor due to internal heat sources
551 : Real64 QSensInfilFloor; // convective gain at the floor due to infiltration
552 : Real64 FloorSumHAT; // sum of hci*area*temp at the floor
553 : Real64 FloorSumHA; // sum of hci*area at the floor
554 : Real64 TThisNode; // dummy variable for air node temp
555 : int NodeNum; // index for air nodes
556 : int SurfNum; // index for surfaces
557 : int SurfCounted; // number of surfaces assciated with an air node
558 :
559 : // apply floor splits
560 8626 : QequipConvFloor = state.dataRoomAir->ConvectiveFloorSplit(ZoneNum) * state.dataMundtSimMgr->ConvIntGain;
561 8626 : QSensInfilFloor = -state.dataRoomAir->InfiltratFloorSplit(ZoneNum) * state.dataMundtSimMgr->QventCool;
562 :
563 : // Begin computations for Mundt model
564 :
565 : // do summations for floor surfaces of this zone
566 8626 : FloorSumHAT = 0.0;
567 8626 : FloorSumHA = 0.0;
568 25878 : for (auto const &s : state.dataMundtSimMgr->FloorSurf) {
569 17252 : FloorSumHAT += s.Area * s.Hc * s.Temp;
570 17252 : FloorSumHA += s.Area * s.Hc;
571 : }
572 :
573 : // Eq 2.2 in ASHRAE RP 1222 Final report
574 8626 : TAirFoot =
575 8626 : ((state.dataMundtSimMgr->ZoneAirDensity * CpAir * state.dataMundtSimMgr->SupplyAirVolumeRate * state.dataMundtSimMgr->SupplyAirTemp) +
576 8626 : (FloorSumHAT) + QequipConvFloor + QSensInfilFloor) /
577 8626 : ((state.dataMundtSimMgr->ZoneAirDensity * CpAir * state.dataMundtSimMgr->SupplyAirVolumeRate) + (FloorSumHA));
578 :
579 : // prevent dividing by zero due to zero cooling load (or zero supply air flow rate)
580 8626 : if (state.dataMundtSimMgr->QsysCoolTot <= 0.0) {
581 0 : TLeaving = state.dataMundtSimMgr->SupplyAirTemp;
582 : } else {
583 : // Eq 2.3 in ASHRAE RP 1222 Final report
584 8626 : TLeaving =
585 8626 : (state.dataMundtSimMgr->QsysCoolTot / (state.dataMundtSimMgr->ZoneAirDensity * CpAir * state.dataMundtSimMgr->SupplyAirVolumeRate)) +
586 8626 : state.dataMundtSimMgr->SupplyAirTemp;
587 : }
588 :
589 : // Eq 2.4 in ASHRAE RP 1222 Final report
590 17252 : Slope = (TLeaving - TAirFoot) /
591 8626 : (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
592 8626 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).Height);
593 : // check slope
594 8626 : if (Slope > MaxSlope) {
595 0 : Slope = MaxSlope;
596 0 : TAirFoot = TLeaving -
597 0 : (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
598 0 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).Height));
599 : }
600 8626 : if (Slope < MinSlope) { // pretty much vertical
601 3 : Slope = MinSlope;
602 3 : TAirFoot = TLeaving;
603 : }
604 :
605 : // Eq 2.4 in ASHRAE RP 1222 Final report
606 8626 : TAirCeil =
607 8626 : TLeaving - (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
608 8626 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtCeilAirID, state.dataMundtSimMgr->MundtZoneNum).Height));
609 :
610 8626 : TControlPoint =
611 8626 : TLeaving - (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
612 8626 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Height));
613 :
614 : // determine air node temperatures in this zone
615 8626 : SetNodeResult(state, state.dataMundtSimMgr->SupplyNodeID, state.dataMundtSimMgr->SupplyAirTemp);
616 8626 : SetNodeResult(state, state.dataMundtSimMgr->ReturnNodeID, TLeaving);
617 8626 : SetNodeResult(state, state.dataMundtSimMgr->MundtCeilAirID, TAirCeil);
618 8626 : SetNodeResult(state, state.dataMundtSimMgr->MundtFootAirID, TAirFoot);
619 8626 : SetNodeResult(state, state.dataMundtSimMgr->TstatNodeID, TControlPoint);
620 :
621 25878 : for (SurfNum = 1; SurfNum <= state.dataMundtSimMgr->NumFloorSurfs; ++SurfNum) {
622 17252 : SetSurfTmeanAir(state, state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), TAirFoot);
623 : }
624 :
625 8626 : SurfCounted = count(state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtCeilAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
626 8626 : state.dataMundtSimMgr->TheseSurfIDs =
627 17252 : pack(state.dataMundtSimMgr->ID1dSurf,
628 17252 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtCeilAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
629 25878 : for (SurfNum = 1; SurfNum <= SurfCounted; ++SurfNum) {
630 17252 : SetSurfTmeanAir(state, state.dataMundtSimMgr->TheseSurfIDs(SurfNum), TAirCeil);
631 : }
632 :
633 43130 : for (NodeNum = 1; NodeNum <= state.dataMundtSimMgr->NumRoomNodes; ++NodeNum) {
634 34504 : TThisNode =
635 : TLeaving -
636 34504 : (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
637 34504 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->RoomNodeIDs(NodeNum), state.dataMundtSimMgr->MundtZoneNum).Height));
638 34504 : SetNodeResult(state, state.dataMundtSimMgr->RoomNodeIDs(NodeNum), TThisNode);
639 34504 : SurfCounted =
640 34504 : count(state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->RoomNodeIDs(NodeNum), state.dataMundtSimMgr->MundtZoneNum).SurfMask);
641 34504 : state.dataMundtSimMgr->TheseSurfIDs =
642 69008 : pack(state.dataMundtSimMgr->ID1dSurf,
643 69008 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->RoomNodeIDs(NodeNum), state.dataMundtSimMgr->MundtZoneNum).SurfMask);
644 189772 : for (SurfNum = 1; SurfNum <= SurfCounted; ++SurfNum) {
645 155268 : SetSurfTmeanAir(state, state.dataMundtSimMgr->TheseSurfIDs(SurfNum), TThisNode);
646 : }
647 : }
648 8626 : }
649 :
650 : //*****************************************************************************************
651 :
652 77634 : void SetNodeResult(EnergyPlusData &state,
653 : int const NodeID, // node ID
654 : Real64 const TempResult // temperature for the specified air node
655 : )
656 : {
657 :
658 : // SUBROUTINE INFORMATION:
659 : // AUTHOR Brent Griffith
660 : // DATE WRITTEN September 2002
661 : // RE-ENGINEERED April 2003, Weixiu Kong, EnergyPlus Implementation
662 : // MODIFIED February 2004, fix allocate-deallocate problem (CC)
663 :
664 : // PURPOSE OF THIS SUBROUTINE:
665 : // provide set routine for reporting results
666 : // to AirDataManager from air model
667 :
668 : // METHODOLOGY EMPLOYED:
669 : // na
670 :
671 : // REFERENCES:
672 : // na
673 :
674 : // USE STATEMENTS:
675 : // na
676 :
677 : // Locals
678 : // SUBROUTINE ARGUMENT DEFINITIONS:
679 :
680 : // SUBROUTINE PARAMETER DEFINITIONS:
681 : // na
682 :
683 : // INTERFACE BLOCK SPECIFICATIONS:
684 : // na
685 :
686 : // DERIVED TYPE DEFINITIONS:
687 : // na
688 :
689 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
690 : // na
691 :
692 77634 : state.dataMundtSimMgr->LineNode(NodeID, state.dataMundtSimMgr->MundtZoneNum).Temp = TempResult;
693 77634 : }
694 :
695 : //*****************************************************************************************
696 :
697 189772 : void SetSurfTmeanAir(EnergyPlusData &state,
698 : int const SurfID, // surface ID
699 : Real64 const TeffAir // temperature of air node adjacent to the specified surface
700 : )
701 : {
702 :
703 : // SUBROUTINE INFORMATION:
704 : // AUTHOR Brent Griffith
705 : // DATE WRITTEN September 2002
706 : // RE-ENGINEERED April 2003, Wiexiu Kong, EnergyPlus Implementation
707 : // MODIFIED February 2004, fix allocate-deallocate problem (CC)
708 :
709 : // PURPOSE OF THIS SUBROUTINE:
710 : // provide set routine for air model prediction of
711 : // effective air for single surface
712 :
713 189772 : state.dataMundtSimMgr->MundtAirSurf(SurfID, state.dataMundtSimMgr->MundtZoneNum).TMeanAir = TeffAir;
714 189772 : }
715 :
716 : //*****************************************************************************************
717 :
718 17080 : void SetSurfHBDataForDispVent1Node(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
719 : {
720 :
721 : // SUBROUTINE INFORMATION:
722 : // AUTHOR Chanvit Chantrasrisalai
723 : // DATE WRITTEN July 2003
724 : // MODIFIED February 2004, fix allocate-deallocate problem (CC)
725 : // RE-ENGINEERED na
726 :
727 : // PURPOSE OF THIS SUBROUTINE:
728 : // map data from air domain back to surface domain for each particular zone
729 :
730 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
731 : int ZoneNodeNum; // index number of the zone node
732 : Real64 DeltaTemp; // dummy variable for temperature difference
733 :
734 : // get surface info
735 17080 : int NumOfSurfs = state.dataMundtSimMgr->ZoneData(ZoneNum).NumOfSurfs;
736 :
737 33809 : if ((state.dataMundtSimMgr->SupplyAirVolumeRate > 0.0001) &&
738 16729 : (state.dataMundtSimMgr->QsysCoolTot > 0.0001)) { // Controlled zone when the system is on
739 :
740 8626 : if (state.dataRoomAir->AirModel(ZoneNum).TempCoupleScheme == RoomAir::CouplingScheme::Direct) {
741 : // Use direct coupling scheme to report air temperatures back to surface/system domains
742 : // a) Bulk air temperatures -> TempEffBulkAir(SurfNum)
743 198398 : for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) {
744 189772 : int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum);
745 189772 : state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) =
746 189772 : state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).TMeanAir;
747 : // set flag for reference air temperature
748 189772 : state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
749 189772 : state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)];
750 : }
751 : // b) Average zone air temperature -> ZT(ZoneNum)
752 : // For Mundt model, average room air is the weighted value of floor and ceiling air temps
753 : // TRoomAverage = ( LineNode( MundtCeilAirID, MundtZoneNum ).Temp + LineNode( MundtFootAirID, MundtZoneNum ).Temp ) / 2;
754 : // ZT(ZoneNum) = TRoomAverage
755 : // c) Leaving-zone air temperature -> Node(ZoneNode)%Temp
756 8626 : ZoneNodeNum = state.dataHeatBal->Zone(ZoneNum).SystemZoneNodeNumber;
757 8626 : state.dataLoopNodes->Node(ZoneNodeNum).Temp =
758 8626 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
759 : // d) Thermostat air temperature -> TempTstatAir(ZoneNum)
760 8626 : state.dataHeatBalFanSys->TempTstatAir(ZoneNum) =
761 8626 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
762 : } else {
763 : // Use indirect coupling scheme to report air temperatures back to surface/system domains
764 : // a) Bulk air temperatures -> TempEffBulkAir(SurfNum)
765 0 : for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) {
766 0 : int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum);
767 0 : DeltaTemp = state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).TMeanAir -
768 0 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
769 0 : state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + DeltaTemp;
770 : // set flag for reference air temperature
771 0 : state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
772 0 : state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)];
773 : }
774 : // b) Average zone air temperature -> ZT(ZoneNum)
775 : // For Mundt model, average room air is the weighted value of floor and ceiling air temps
776 : // TRoomAverage = ( LineNode( MundtCeilAirID, MundtZoneNum ).Temp + LineNode( MundtFootAirID, MundtZoneNum ).Temp ) / 2;
777 : // DeltaTemp = TRoomAverage - LineNode( TstatNodeID, MundtZoneNum ).Temp;
778 : // ZT(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum) + DeltaTemp
779 : // c) Leaving-zone air temperature -> Node(ZoneNode)%Temp
780 0 : ZoneNodeNum = state.dataHeatBal->Zone(ZoneNum).SystemZoneNodeNumber;
781 0 : DeltaTemp = state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp -
782 0 : state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
783 0 : state.dataLoopNodes->Node(ZoneNodeNum).Temp = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + DeltaTemp;
784 : // d) Thermostat air temperature -> TempTstatAir(ZoneNum)
785 0 : state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum)
786 0 : .ZT; // for indirect coupling, control air temp is equal to mean air temp?
787 : }
788 : // set flag to indicate that Mundt model is used for this zone at the present time
789 8626 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
790 : } else { // Controlled zone when the system is off --> Use the mixing model instead of the Mundt model
791 : // Bulk air temperatures -> TempEffBulkAir(SurfNum)
792 194442 : for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) {
793 185988 : int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum);
794 185988 : state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
795 : // set flag for reference air temperature
796 185988 : state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp;
797 185988 : state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)];
798 : }
799 : // set flag to indicate that Mundt model is NOT used for this zone at the present time
800 8454 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = false;
801 : }
802 17080 : }
803 :
804 : //*****************************************************************************************
805 :
806 : } // namespace RoomAir
807 :
808 : } // namespace EnergyPlus
|