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