Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #include "AirflowNetwork/Solver.hpp"
49 :
50 : // C++ Headers
51 : #include <algorithm>
52 : #include <cmath>
53 : #include <set>
54 : #include <string>
55 :
56 : // ObjexxFCL Headers
57 : #include <ObjexxFCL/Array.functions.hh>
58 : #include <ObjexxFCL/Array2D.hh>
59 : // #include <ObjexxFCL/Fmath.hh>
60 :
61 : // EnergyPlus Headers
62 : #include <AirflowNetwork/Elements.hpp>
63 : #include <AirflowNetwork/Solver.hpp>
64 : #include <EnergyPlus/BranchNodeConnections.hh>
65 : #include <EnergyPlus/Coils/CoilCoolingDX.hh>
66 : #include <EnergyPlus/Construction.hh>
67 : #include <EnergyPlus/CurveManager.hh>
68 : #include <EnergyPlus/DXCoils.hh>
69 : #include <EnergyPlus/Data/EnergyPlusData.hh>
70 : #include <EnergyPlus/DataAirLoop.hh>
71 : #include <EnergyPlus/DataAirSystems.hh>
72 : #include <EnergyPlus/DataBranchNodeConnections.hh>
73 : #include <EnergyPlus/DataContaminantBalance.hh>
74 : #include <EnergyPlus/DataDefineEquip.hh>
75 : #include <EnergyPlus/DataEnvironment.hh>
76 : #include <EnergyPlus/DataHVACGlobals.hh>
77 : #include <EnergyPlus/DataHeatBalFanSys.hh>
78 : #include <EnergyPlus/DataHeatBalSurface.hh>
79 : #include <EnergyPlus/DataHeatBalance.hh>
80 : #include <EnergyPlus/DataLoopNode.hh>
81 : #include <EnergyPlus/DataRoomAirModel.hh>
82 : #include <EnergyPlus/DataSurfaces.hh>
83 : #include <EnergyPlus/DataZoneEquipment.hh>
84 : #include <EnergyPlus/EMSManager.hh>
85 : #include <EnergyPlus/Fans.hh>
86 : #include <EnergyPlus/General.hh>
87 : #include <EnergyPlus/GeneralRoutines.hh>
88 : #include <EnergyPlus/GlobalNames.hh>
89 : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
90 : #include <EnergyPlus/HVACStandAloneERV.hh>
91 : #include <EnergyPlus/HVACVariableRefrigerantFlow.hh>
92 : #include <EnergyPlus/HeatingCoils.hh>
93 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
94 : #include <EnergyPlus/MixedAir.hh>
95 : #include <EnergyPlus/NodeInputManager.hh>
96 : #include <EnergyPlus/OutAirNodeManager.hh>
97 : #include <EnergyPlus/OutputProcessor.hh>
98 : #include <EnergyPlus/Psychrometrics.hh>
99 : #include <EnergyPlus/RoomAirModelManager.hh>
100 : #include <EnergyPlus/ScheduleManager.hh>
101 : #include <EnergyPlus/SingleDuct.hh>
102 : #include <EnergyPlus/SplitterComponent.hh>
103 : #include <EnergyPlus/ThermalComfort.hh>
104 : #include <EnergyPlus/UnitarySystem.hh>
105 : #include <EnergyPlus/UtilityRoutines.hh>
106 : #include <EnergyPlus/WaterThermalTanks.hh>
107 : #include <EnergyPlus/WindowAC.hh>
108 : #include <EnergyPlus/ZoneDehumidifier.hh>
109 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
110 :
111 : namespace EnergyPlus {
112 :
113 : namespace AirflowNetwork {
114 :
115 : // MODULE INFORMATION:
116 : // AUTHOR Lixing Gu, Don Shirey, and Muthusamy V. Swami
117 : // DATE WRITTEN July 2005
118 : // MODIFIED na
119 : // RE-ENGINEERED na
120 :
121 : // PURPOSE OF THIS MODULE:
122 : // This module is used to simulate airflows and pressures. The module is modified to
123 : // meet requirements of EnergyPLus based on AIRNET, developed by
124 : // National Institute of Standards and Technology (NIST).
125 :
126 : // METHODOLOGY EMPLOYED:
127 : // An airflow network approach is used. It consists of nodes connected by airflow elements.
128 : // The Newton's method is applied to solve a sparse matrix. When a new solver is available, this
129 : // module will be replaced or updated.
130 :
131 : // REFERENCES:
132 : // Walton, G. N., 1989, "AIRNET - A Computer Program for Building Airflow Network Modeling,"
133 : // NISTIR 89-4072, National Institute of Standards and Technology, Gaithersburg, Maryland
134 :
135 : // Using/Aliasing
136 : using Curve::CurveValue;
137 : using Curve::GetCurveIndex;
138 : using DataEnvironment::OutDryBulbTempAt;
139 : using DataSurfaces::cExtBoundCondition;
140 : using DataSurfaces::ExternalEnvironment;
141 : using DataSurfaces::OtherSideCoefNoCalcExt;
142 : using DataSurfaces::SurfaceClass;
143 : using Fans::GetFanIndex;
144 : using Psychrometrics::PsyCpAirFnW;
145 : using Psychrometrics::PsyHFnTdbW;
146 : using Psychrometrics::PsyRhoAirFnPbTdbW;
147 :
148 2131 : Solver::Solver(EnergyPlusData &state) : m_state(state), properties(state)
149 : {
150 2131 : }
151 :
152 : int constexpr NumOfVentCtrTypes(6); // Number of zone level venting control types
153 :
154 16955 : void Solver::manage_balance(ObjexxFCL::Optional_bool_const FirstHVACIteration, // True when solution technique on first iteration
155 : ObjexxFCL::Optional_int_const Iter, // Iteration number
156 : ObjexxFCL::Optional_bool ResimulateAirZone // True when solution technique on third iteration
157 : )
158 : {
159 :
160 : // SUBROUTINE INFORMATION:
161 : // AUTHOR Lixing Gu
162 : // DATE WRITTEN July 28, 2005
163 :
164 : // PURPOSE OF THIS SUBROUTINE:
165 : // This subroutine performs simulation of air distribution system.
166 :
167 : // Locals
168 : int i;
169 16955 : HVAC::FanType AFNSupplyFanType = HVAC::FanType::Invalid;
170 :
171 16955 : if (AirflowNetworkGetInputFlag) {
172 102 : get_input();
173 102 : AirflowNetworkGetInputFlag = false;
174 102 : return;
175 : }
176 :
177 16853 : if (present(ResimulateAirZone)) {
178 8349 : ResimulateAirZone = false;
179 : }
180 :
181 16853 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) {
182 0 : return;
183 : }
184 :
185 16853 : if (m_state.dataGlobal->BeginEnvrnFlag) {
186 138 : m_state.dataHVACGlobal->TurnFansOn = false; // The FAN should be off when BeginEnvrnFlag = .True.
187 : }
188 :
189 16853 : initialize();
190 :
191 16853 : auto &NetworkNumOfNodes = ActualNumOfNodes;
192 16853 : auto &NetworkNumOfLinks = ActualNumOfLinks;
193 :
194 16853 : NetworkNumOfNodes = NumOfNodesMultiZone;
195 16853 : NetworkNumOfLinks = NumOfLinksMultiZone;
196 :
197 16853 : AirflowNetworkFanActivated = false;
198 :
199 16853 : if (present(FirstHVACIteration) && distribution_simulated) {
200 16852 : if (FirstHVACIteration) {
201 2820 : if (allocated(m_state.dataAirLoop->AirLoopAFNInfo)) {
202 5640 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
203 2820 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopHeatingCoilMaxRTF = 0.0;
204 2820 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopOnOffFanRTF = 0.0;
205 2820 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopDXCoilRTF = 0.0;
206 2820 : m_state.dataAirLoop->AirLoopAFNInfo(i).LoopOnOffFanPartLoadRatio = 0.0;
207 : }
208 : }
209 : }
210 16852 : Real64 FanMassFlowRate = 0.0;
211 16852 : HVAC::FanOp FanOperModeCyc = HVAC::FanOp::Invalid;
212 16852 : AFNSupplyFanType = HVAC::FanType::Invalid;
213 :
214 19888 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
215 16852 : AFNSupplyFanType = DisSysCompCVFData(i).fanType;
216 16852 : FanMassFlowRate = max(FanMassFlowRate, m_state.dataLoopNodes->Node(DisSysCompCVFData(i).OutletNode).MassFlowRate);
217 : // VAV take high priority
218 16852 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::VAV) {
219 0 : AFNSupplyFanType = DisSysCompCVFData(i).fanType;
220 0 : break;
221 : }
222 30668 : if (FanMassFlowRate > HVAC::VerySmallMassFlow &&
223 30668 : m_state.dataAirLoop->AirLoopAFNInfo(i).LoopFanOperationMode == HVAC::FanOp::Cycling &&
224 13816 : m_state.dataAirLoop->AirLoopAFNInfo(i).LoopSystemOnMassFlowrate > 0.0) {
225 13816 : FanOperModeCyc = HVAC::FanOp::Cycling;
226 13816 : AFNSupplyFanType = DisSysCompCVFData(i).fanType;
227 13816 : if (AFNSupplyFanType == HVAC::FanType::OnOff) {
228 13816 : break;
229 : }
230 : }
231 : }
232 : // Revised to meet heat exchanger requirement
233 16852 : if ((FanMassFlowRate > HVAC::VerySmallMassFlow) && (!FirstHVACIteration)) {
234 11054 : if (AFNSupplyFanType == HVAC::FanType::OnOff && FanOperModeCyc == HVAC::FanOp::Cycling) {
235 11054 : AirflowNetworkFanActivated = true;
236 0 : } else if (AFNSupplyFanType == HVAC::FanType::VAV) {
237 0 : if (present(Iter) && Iter > 1) {
238 0 : AirflowNetworkFanActivated = true;
239 : }
240 0 : } else if (AirflowNetworkUnitarySystem) {
241 0 : if (present(Iter) && Iter > 1) {
242 0 : AirflowNetworkFanActivated = true;
243 : }
244 : } else {
245 0 : AirflowNetworkFanActivated = true;
246 : }
247 : }
248 : }
249 16853 : if (allocated(m_state.dataZoneEquip->ZoneEquipConfig) && m_state.dataAvail->NumHybridVentSysAvailMgrs > 0 &&
250 0 : allocated(m_state.dataAirSystemsData->PrimaryAirSystems)) {
251 0 : hybrid_ventilation_control();
252 : }
253 16853 : if (ventCtrlStatus == Avail::VentCtrlStatus::Open && m_state.dataAvail->NumHybridVentSysAvailMgrs > 0) {
254 0 : AirflowNetworkFanActivated = false;
255 : }
256 :
257 16853 : if (present(Iter) && present(ResimulateAirZone) && distribution_simulated) {
258 8348 : if (AirflowNetworkFanActivated && Iter < 3 && AFNSupplyFanType == HVAC::FanType::OnOff) {
259 5528 : ResimulateAirZone = true;
260 : }
261 8348 : if (AFNSupplyFanType == HVAC::FanType::VAV) {
262 0 : if (!AirflowNetworkFanActivated && Iter < 3) {
263 0 : ResimulateAirZone = true;
264 : }
265 : }
266 8348 : if (AirflowNetworkUnitarySystem) {
267 0 : if (!AirflowNetworkFanActivated && Iter < 3) {
268 0 : ResimulateAirZone = true;
269 : }
270 : }
271 : }
272 16853 : if (AirflowNetworkFanActivated && distribution_simulated) {
273 11054 : NetworkNumOfNodes = AirflowNetworkNumOfNodes;
274 11054 : NetworkNumOfLinks = AirflowNetworkNumOfLinks;
275 : }
276 :
277 16853 : if (allocated(m_state.dataZoneEquip->ZoneEquipConfig)) {
278 16852 : validate_exhaust_fan_input();
279 : }
280 :
281 : // VAV terminal set only
282 16853 : if (present(FirstHVACIteration) && FirstHVACIteration) {
283 2820 : VAVTerminalRatio = 0.0;
284 : }
285 :
286 16853 : if (AirflowNetworkFanActivated && distribution_simulated) {
287 11054 : if (ValidateDistributionSystemFlag) {
288 1 : validate_distribution();
289 1 : validate_fan_flowrate();
290 1 : ValidateDistributionSystemFlag = false;
291 1 : if (simulation_control.autosize_ducts) {
292 0 : SizeDucts();
293 : }
294 : }
295 : }
296 16853 : calculate_balance();
297 :
298 16853 : if (AirflowNetworkFanActivated && distribution_simulated) {
299 :
300 11054 : LoopOnOffFlag = false;
301 22108 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
302 11054 : if (DisSysCompCVFData(i).AirLoopNum > 0) {
303 11054 : if (m_state.dataLoopNodes->Node(DisSysCompCVFData(i).InletNode).MassFlowRate > 0.0) {
304 11054 : LoopOnOffFlag(DisSysCompCVFData(i).AirLoopNum) = true;
305 : }
306 : }
307 : }
308 :
309 11054 : calculate_heat_balance();
310 11054 : calculate_moisture_balance();
311 11054 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
312 0 : calculate_CO2_balance();
313 : }
314 11054 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
315 0 : calculate_GC_balance();
316 : }
317 : }
318 :
319 16853 : update(FirstHVACIteration);
320 : }
321 :
322 25 : bool Solver::get_element_input()
323 : {
324 : // SUBROUTINE INFORMATION:
325 : // AUTHOR Jason DeGraw
326 : // DATE WRITTEN Oct. 2018
327 : // MODIFIED na
328 : // RE-ENGINEERED na
329 :
330 : // PURPOSE OF THIS SUBROUTINE:
331 : // This subroutine reads airflow element inputs (eventually)
332 :
333 : static constexpr std::string_view RoutineName{"get_element_input"};
334 25 : std::string CurrentModuleObject;
335 25 : bool success{true};
336 :
337 : // *** Read AirflowNetwork simulation reference crack conditions
338 25 : std::unordered_map<std::string, ReferenceConditions> referenceConditions; // Map for lookups
339 25 : ReferenceConditions defaultReferenceConditions("Default"); // Defaulted conditions
340 25 : bool conditionsAreDefaulted(true); // Conditions are defaulted?
341 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:ReferenceCrackConditions";
342 25 : auto instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
343 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
344 : // globalSolverObject.referenceConditions.clear();
345 17 : auto &instancesValue = instances.value();
346 35 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
347 18 : auto const &fields = instance.value();
348 18 : auto const &thisObjectName = Util::makeUPPER(instance.key());
349 18 : Real64 temperature(20.0);
350 54 : if (fields.find("reference_temperature") != fields.end()) { // required field, has default value
351 36 : temperature = fields.at("reference_temperature").get<Real64>();
352 : }
353 18 : Real64 pressure(101325.0);
354 54 : if (fields.find("reference_barometric_pressure") != fields.end()) { // not required field, has default value
355 17 : pressure = fields.at("reference_barometric_pressure").get<Real64>();
356 17 : if (std::abs((pressure - m_state.dataEnvrn->StdBaroPress) / m_state.dataEnvrn->StdBaroPress) > 0.1) { // 10% off
357 2 : ShowWarningError(m_state,
358 2 : format("{}: {}: Pressure = {:.0R} differs by more than 10% from Standard Barometric Pressure = {:.0R}.",
359 : RoutineName,
360 : CurrentModuleObject,
361 : pressure,
362 1 : m_state.dataEnvrn->StdBaroPress));
363 1 : ShowContinueError(m_state, "...occurs in " + CurrentModuleObject + " = " + thisObjectName);
364 : }
365 17 : if (pressure <= 31000.0) {
366 0 : ShowSevereError(m_state,
367 0 : format("{}: {}: {}. Reference Barometric Pressure must be greater than 31000 Pa.",
368 : RoutineName,
369 : CurrentModuleObject,
370 : thisObjectName));
371 0 : success = false;
372 : }
373 : }
374 18 : Real64 humidity(0.0);
375 54 : if (fields.find("reference_humidity_ratio") != fields.end()) { // not required field, has default value
376 34 : humidity = fields.at("reference_humidity_ratio").get<Real64>();
377 : }
378 : // globalSolverObject.referenceConditions.emplace_back(thisObjectName, temperature, pressure, humidity);
379 18 : referenceConditions.emplace(std::piecewise_construct,
380 18 : std::forward_as_tuple(thisObjectName),
381 18 : std::forward_as_tuple(instance.key(), temperature, pressure, humidity));
382 35 : }
383 : // Check that there is more than one
384 17 : if (referenceConditions.size() == 1) {
385 32 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
386 32 : referenceConditions.begin()->second.name);
387 16 : defaultReferenceConditions = referenceConditions.begin()->second;
388 :
389 : } else {
390 1 : conditionsAreDefaulted = false;
391 : }
392 : }
393 25 : if (!success) {
394 0 : return false;
395 : }
396 :
397 : // *** Read AirflowNetwork simulation surface crack component
398 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface:Crack";
399 25 : AirflowNetworkNumOfSurCracks =
400 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
401 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
402 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
403 18 : int i = 1; // Temporary workaround
404 18 : MultizoneSurfaceCrackData.allocate(AirflowNetworkNumOfSurCracks); // Temporary workaround
405 18 : auto &instancesValue = instances.value();
406 54 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
407 36 : auto const &fields = instance.value();
408 36 : auto const &thisObjectName = Util::makeUPPER(instance.key());
409 36 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
410 :
411 36 : Real64 coeff{fields.at("air_mass_flow_coefficient_at_reference_conditions")}; // Required field
412 36 : Real64 expnt{0.65};
413 108 : if (fields.find("air_mass_flow_exponent") != fields.end()) { // not required field, has default value
414 72 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
415 : }
416 36 : Real64 refT = defaultReferenceConditions.temperature;
417 36 : Real64 refP = defaultReferenceConditions.pressure;
418 36 : Real64 refW = defaultReferenceConditions.humidity_ratio;
419 36 : if (!conditionsAreDefaulted) {
420 6 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
421 2 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
422 2 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
423 :
424 2 : if (result == referenceConditions.end()) {
425 0 : ShowSevereError(m_state,
426 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
427 : RoutineName,
428 : CurrentModuleObject,
429 : thisObjectName,
430 : refCrackCondName));
431 0 : success = false;
432 : } else {
433 2 : refT = result->second.temperature;
434 2 : refP = result->second.pressure;
435 2 : refW = result->second.humidity_ratio;
436 6 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
437 2 : result->second.name);
438 : }
439 2 : }
440 : }
441 : // globalSolverObject.cracks[thisObjectName] = SurfaceCrack(coeff, expnt, refT, refP, refW);
442 36 : MultizoneSurfaceCrackData(i).name = thisObjectName; // Name of surface crack component
443 36 : MultizoneSurfaceCrackData(i).coefficient = coeff; // Air Mass Flow Coefficient
444 36 : MultizoneSurfaceCrackData(i).exponent = expnt; // Air Mass Flow exponent
445 36 : MultizoneSurfaceCrackData(i).reference_density = properties.density(refP, refT, refW);
446 36 : MultizoneSurfaceCrackData(i).reference_viscosity = properties.dynamic_viscosity(refT);
447 :
448 : // This is the first element that is being added to the lookup table, so no check of naming overlaps
449 36 : elements[thisObjectName] = &MultizoneSurfaceCrackData(i); // Yet another workaround
450 :
451 36 : ++i;
452 54 : }
453 : }
454 :
455 : // *** Read AirflowNetwork simulation zone exhaust fan component
456 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:ZoneExhaustFan";
457 25 : AirflowNetworkNumOfExhFan =
458 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
459 25 : NumOfExhaustFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "Fan:ZoneExhaust"); // Temporary workaround
460 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
461 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
462 3 : int i = 1; // Temporary workaround
463 3 : MultizoneCompExhaustFanData.allocate(AirflowNetworkNumOfExhFan); // Temporary workaround
464 3 : auto &instancesValue = instances.value();
465 6 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
466 3 : auto const &fields = instance.value();
467 3 : auto const &thisObjectName = Util::makeUPPER(instance.key());
468 :
469 3 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
470 :
471 3 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_the_zone_exhaust_fan_is_off_at_reference_conditions")}; // Required field
472 3 : Real64 expnt{0.65};
473 9 : if (fields.find("air_mass_flow_exponent_when_the_zone_exhaust_fan_is_off") != fields.end()) { // not required field, has default value
474 6 : expnt = fields.at("air_mass_flow_exponent_when_the_zone_exhaust_fan_is_off").get<Real64>();
475 : }
476 :
477 : // This breaks the component model, need to fix
478 3 : int fanIndex = GetFanIndex(m_state, thisObjectName);
479 3 : if (fanIndex == 0) {
480 0 : ShowSevereError(m_state,
481 0 : format("{}: {} = {} is not found in Fan:ZoneExhaust objects.", RoutineName, CurrentModuleObject, thisObjectName));
482 0 : success = false;
483 : }
484 :
485 3 : auto *fan = m_state.dataFans->fans(fanIndex);
486 :
487 3 : Real64 flowRate = fan->maxAirFlowRate;
488 3 : flowRate *= m_state.dataEnvrn->StdRhoAir;
489 3 : int inletNode = fan->inletNodeNum;
490 3 : int outletNode = fan->outletNodeNum;
491 3 : HVAC::FanType fanType = fan->type;
492 3 : if (fanType != HVAC::FanType::Exhaust) {
493 0 : ShowSevereError(m_state,
494 0 : format("{}: {} = {}. The specified Name is not found as a valid Fan:ZoneExhaust object.",
495 : RoutineName,
496 : CurrentModuleObject,
497 : thisObjectName));
498 0 : success = false;
499 : }
500 :
501 3 : Real64 refT = defaultReferenceConditions.temperature;
502 3 : Real64 refP = defaultReferenceConditions.pressure;
503 3 : Real64 refW = defaultReferenceConditions.humidity_ratio;
504 3 : if (!conditionsAreDefaulted) {
505 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
506 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
507 0 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
508 0 : if (result == referenceConditions.end()) {
509 0 : ShowSevereError(m_state,
510 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
511 : RoutineName,
512 : CurrentModuleObject,
513 : thisObjectName,
514 0 : fields.at("reference_crack_conditions").get<std::string>()));
515 0 : success = false;
516 : } else {
517 0 : refT = result->second.temperature;
518 0 : refP = result->second.pressure;
519 0 : refW = result->second.humidity_ratio;
520 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
521 0 : result->second.name);
522 : }
523 0 : }
524 : }
525 :
526 3 : MultizoneCompExhaustFanData(i).name = thisObjectName; // Name of zone exhaust fan component
527 3 : MultizoneCompExhaustFanData(i).FlowCoef = coeff; // flow coefficient
528 3 : MultizoneCompExhaustFanData(i).FlowExpo = expnt; // Flow exponent
529 :
530 3 : MultizoneCompExhaustFanData(i).FlowRate = flowRate;
531 3 : MultizoneCompExhaustFanData(i).InletNode = inletNode;
532 3 : MultizoneCompExhaustFanData(i).OutletNode = outletNode;
533 :
534 3 : MultizoneCompExhaustFanData(i).StandardT = refT;
535 3 : MultizoneCompExhaustFanData(i).StandardP = refP;
536 3 : MultizoneCompExhaustFanData(i).StandardW = refW;
537 :
538 : // Add the element to the lookup table, check for name overlaps
539 3 : if (elements.find(thisObjectName) == elements.end()) {
540 3 : elements[thisObjectName] = &MultizoneCompExhaustFanData(i); // Yet another workaround
541 : } else {
542 0 : ShowSevereError(
543 : m_state,
544 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
545 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
546 0 : success = false;
547 : }
548 :
549 3 : ++i;
550 6 : }
551 : }
552 :
553 : // Read Outdoor Airflow object
554 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:OutdoorAirFlow";
555 25 : NumOfOAFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
556 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
557 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
558 2 : int i = 1; // Temporary workaround
559 2 : DisSysCompOutdoorAirData.allocate(NumOfOAFans); // Temporary workaround
560 2 : auto &instancesValue = instances.value();
561 5 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
562 3 : auto const &fields = instance.value();
563 3 : auto const &thisObjectName = Util::makeUPPER(instance.key());
564 3 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
565 :
566 6 : std::string mixer_name = Util::makeUPPER(fields.at("outdoor_air_mixer_name").get<std::string>());
567 3 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_no_outdoor_air_flow_at_reference_conditions")};
568 3 : Real64 expnt{0.65};
569 9 : if (fields.find("air_mass_flow_exponent_when_no_outdoor_air_flow") != fields.end()) {
570 6 : expnt = fields.at("air_mass_flow_exponent_when_no_outdoor_air_flow").get<Real64>();
571 : }
572 :
573 3 : int OAMixerNum = MixedAir::GetOAMixerNumber(m_state, mixer_name);
574 3 : if (OAMixerNum == 0) {
575 0 : ShowSevereError(m_state,
576 0 : format("{}: {}: {}. Invalid Outdoor Air Mixer Name \"{}\" given.",
577 : RoutineName,
578 : CurrentModuleObject,
579 : thisObjectName,
580 : mixer_name));
581 0 : success = false;
582 : }
583 :
584 3 : Real64 refT = defaultReferenceConditions.temperature;
585 3 : Real64 refP = defaultReferenceConditions.pressure;
586 3 : Real64 refW = defaultReferenceConditions.humidity_ratio;
587 3 : if (!conditionsAreDefaulted) {
588 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
589 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
590 0 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
591 0 : if (result == referenceConditions.end()) {
592 0 : ShowSevereError(m_state,
593 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
594 : RoutineName,
595 : CurrentModuleObject,
596 : thisObjectName,
597 : refCrackCondName));
598 0 : success = false;
599 : } else {
600 0 : refT = result->second.temperature;
601 0 : refP = result->second.pressure;
602 0 : refW = result->second.humidity_ratio;
603 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
604 0 : result->second.name);
605 : }
606 0 : }
607 : }
608 :
609 3 : DisSysCompOutdoorAirData(i).name = thisObjectName; // Name of zone exhaust fan component
610 3 : DisSysCompOutdoorAirData(i).FlowCoef = coeff; // flow coefficient
611 3 : DisSysCompOutdoorAirData(i).FlowExpo = expnt; // Flow exponent
612 :
613 3 : DisSysCompOutdoorAirData(i).OAMixerNum = OAMixerNum;
614 :
615 3 : DisSysCompOutdoorAirData(i).StandardT = refT;
616 3 : DisSysCompOutdoorAirData(i).StandardP = refP;
617 3 : DisSysCompOutdoorAirData(i).StandardW = refW;
618 :
619 : // Add the element to the lookup table, check for name overlaps
620 3 : if (elements.find(thisObjectName) == elements.end()) {
621 3 : elements[thisObjectName] = &DisSysCompOutdoorAirData(i); // Yet another workaround
622 : } else {
623 0 : ShowSevereError(
624 : m_state,
625 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
626 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
627 0 : success = false;
628 : }
629 :
630 3 : ++i;
631 5 : }
632 : }
633 :
634 : // Read Relief Airflow object
635 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ReliefAirFlow";
636 25 : NumOfReliefFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
637 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
638 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
639 2 : int i = 1; // Temporary workaround
640 2 : DisSysCompReliefAirData.allocate(m_state.afn->NumOfReliefFans); // Temporary workaround
641 2 : auto &instancesValue = instances.value();
642 4 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
643 2 : auto const &fields = instance.value();
644 2 : auto const &thisObjectName = Util::makeUPPER(instance.key());
645 2 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
646 :
647 4 : std::string mixer_name = Util::makeUPPER(fields.at("outdoor_air_mixer_name").get<std::string>());
648 2 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_no_outdoor_air_flow_at_reference_conditions")};
649 2 : Real64 expnt{0.65};
650 6 : if (fields.find("air_mass_flow_exponent_when_no_outdoor_air_flow") != fields.end()) {
651 4 : expnt = fields.at("air_mass_flow_exponent_when_no_outdoor_air_flow").get<Real64>();
652 : }
653 :
654 2 : int OAMixerNum{MixedAir::GetOAMixerNumber(m_state, mixer_name)};
655 2 : if (OAMixerNum == 0) {
656 0 : ShowSevereError(m_state,
657 0 : format(RoutineName) + ": " + CurrentModuleObject + " object " + thisObjectName + ". Invalid " +
658 0 : "Outdoor Air Mixer Name" + " \"" + mixer_name + "\" given.");
659 0 : success = false;
660 : }
661 :
662 2 : Real64 refT = defaultReferenceConditions.temperature;
663 2 : Real64 refP = defaultReferenceConditions.pressure;
664 2 : Real64 refW = defaultReferenceConditions.humidity_ratio;
665 2 : if (!conditionsAreDefaulted) {
666 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
667 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
668 0 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
669 0 : if (result == referenceConditions.end()) {
670 0 : ShowSevereError(m_state,
671 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
672 : RoutineName,
673 : CurrentModuleObject,
674 : thisObjectName,
675 : refCrackCondName));
676 0 : success = false;
677 : } else {
678 0 : refT = result->second.temperature;
679 0 : refP = result->second.pressure;
680 0 : refW = result->second.humidity_ratio;
681 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
682 0 : result->second.name);
683 : }
684 0 : }
685 : }
686 :
687 2 : DisSysCompReliefAirData(i).name = thisObjectName; // Name of zone exhaust fan component
688 2 : DisSysCompReliefAirData(i).FlowCoef = coeff; // flow coefficient
689 2 : DisSysCompReliefAirData(i).FlowExpo = expnt; // Flow exponent
690 2 : DisSysCompReliefAirData(i).OAMixerNum = OAMixerNum;
691 2 : DisSysCompReliefAirData(i).StandardT = refT;
692 2 : DisSysCompReliefAirData(i).StandardP = refP;
693 2 : DisSysCompReliefAirData(i).StandardW = refW;
694 :
695 : // Add the element to the lookup table, check for name overlaps
696 2 : if (elements.find(thisObjectName) == elements.end()) {
697 2 : elements[thisObjectName] = &DisSysCompReliefAirData(i); // Yet another workaround
698 : } else {
699 0 : ShowSevereError(
700 : m_state,
701 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
702 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
703 0 : success = false;
704 : }
705 :
706 2 : ++i;
707 4 : }
708 : }
709 :
710 : // Read AirflowNetwork simulation detailed openings
711 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:DetailedOpening";
712 25 : AirflowNetworkNumOfDetOpenings =
713 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
714 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
715 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
716 25 : int i = 1; // Temporary workaround
717 25 : MultizoneCompDetOpeningData.allocate(AirflowNetworkNumOfDetOpenings); // Temporary workaround
718 25 : auto &instancesValue = instances.value();
719 30 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
720 5 : auto const &fields = instance.value();
721 5 : auto const &thisObjectName = Util::makeUPPER(instance.key());
722 5 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
723 :
724 5 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
725 5 : Real64 expnt{0.65};
726 15 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
727 10 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
728 : }
729 :
730 5 : int LVOtype{1};
731 5 : std::string LVOstring;
732 15 : if (fields.find("type_of_rectangular_large_vertical_opening_lvo_") != fields.end()) {
733 5 : LVOstring = fields.at("type_of_rectangular_large_vertical_opening_lvo_").get<std::string>();
734 5 : if (Util::SameString(LVOstring, "NonPivoted") || Util::SameString(LVOstring, "1")) {
735 5 : LVOtype = 1; // Large vertical opening type number
736 0 : } else if (Util::SameString(LVOstring, "HorizontallyPivoted") || Util::SameString(LVOstring, "2")) {
737 0 : LVOtype = 2; // Large vertical opening type number
738 : } else {
739 : // Code will never be executed, validation will catch invalid input
740 0 : ShowSevereError(m_state,
741 0 : format(RoutineName) + "Invalid Type of Rectangular Large Vertical Opening (LVO) = " + LVOstring + "in " +
742 0 : CurrentModuleObject + " = " + thisObjectName);
743 0 : ShowContinueError(m_state, "Valid choices are NonPivoted and HorizontallyPivoted.");
744 0 : success = false;
745 : }
746 : }
747 :
748 5 : Real64 extra{0.0};
749 15 : if (fields.find("extra_crack_length_or_height_of_pivoting_axis") != fields.end()) {
750 10 : extra = fields.at("extra_crack_length_or_height_of_pivoting_axis").get<Real64>();
751 : }
752 :
753 10 : int N{fields.at("number_of_sets_of_opening_factor_data")};
754 :
755 10 : std::vector<Real64> factors(N);
756 10 : std::vector<Real64> cds(N);
757 10 : std::vector<Real64> width_factors(N);
758 10 : std::vector<Real64> height_factors(N);
759 5 : std::vector<Real64> start_height_factors(N);
760 :
761 : // Real64 factor{0.0};
762 : // if (fields.find("opening_factor_1") != fields.end()) {
763 : // factor = fields.at("opening_factor_1");
764 : //}
765 5 : Real64 cd{0.001};
766 15 : if (fields.find("discharge_coefficient_for_opening_factor_1") != fields.end()) {
767 10 : cd = fields.at("discharge_coefficient_for_opening_factor_1").get<Real64>();
768 : }
769 5 : Real64 width_factor{0.0};
770 15 : if (fields.find("width_factor_for_opening_factor_1") != fields.end()) {
771 10 : width_factor = fields.at("width_factor_for_opening_factor_1").get<Real64>();
772 : }
773 5 : Real64 height_factor{0.0};
774 15 : if (fields.find("height_factor_for_opening_factor_1") != fields.end()) {
775 10 : height_factor = fields.at("height_factor_for_opening_factor_1").get<Real64>();
776 : }
777 5 : Real64 start_height_factor{0.0};
778 15 : if (fields.find("start_height_factor_for_opening_factor_1") != fields.end()) {
779 10 : start_height_factor = fields.at("start_height_factor_for_opening_factor_1").get<Real64>();
780 : }
781 :
782 5 : factors[0] = 0.0; // factor; // This factor must be zero
783 5 : cds[0] = cd;
784 5 : width_factors[0] = width_factor;
785 5 : height_factors[0] = height_factor;
786 5 : start_height_factors[0] = start_height_factor;
787 :
788 5 : Real64 factor{fields.at("opening_factor_2")};
789 5 : cd = 1.0;
790 15 : if (fields.find("discharge_coefficient_for_opening_factor_2") != fields.end()) {
791 10 : cd = fields.at("discharge_coefficient_for_opening_factor_2").get<Real64>();
792 : }
793 5 : width_factor = 1.0;
794 15 : if (fields.find("width_factor_for_opening_factor_2") != fields.end()) {
795 10 : width_factor = fields.at("width_factor_for_opening_factor_2").get<Real64>();
796 : }
797 5 : height_factor = 1.0;
798 15 : if (fields.find("height_factor_for_opening_factor_2") != fields.end()) {
799 10 : height_factor = fields.at("height_factor_for_opening_factor_2").get<Real64>();
800 : }
801 5 : start_height_factor = 0.0;
802 15 : if (fields.find("start_height_factor_for_opening_factor_2") != fields.end()) {
803 10 : start_height_factor = fields.at("start_height_factor_for_opening_factor_2").get<Real64>();
804 : }
805 :
806 5 : factors[1] = factor;
807 5 : cds[1] = cd;
808 5 : width_factors[1] = width_factor;
809 5 : height_factors[1] = height_factor;
810 5 : start_height_factors[1] = start_height_factor;
811 :
812 5 : if (N >= 3) {
813 0 : factor = fields.at("opening_factor_3").get<Real64>();
814 0 : cd = 0.0;
815 0 : if (fields.find("discharge_coefficient_for_opening_factor_3") != fields.end()) {
816 0 : cd = fields.at("discharge_coefficient_for_opening_factor_3").get<Real64>();
817 : }
818 0 : width_factor = 0.0;
819 0 : if (fields.find("width_factor_for_opening_factor_3") != fields.end()) {
820 0 : width_factor = fields.at("width_factor_for_opening_factor_3").get<Real64>();
821 : }
822 0 : height_factor = 0.0;
823 0 : if (fields.find("height_factor_for_opening_factor_3") != fields.end()) {
824 0 : height_factor = fields.at("height_factor_for_opening_factor_3").get<Real64>();
825 : }
826 0 : start_height_factor = 0.0;
827 0 : if (fields.find("start_height_factor_for_opening_factor_3") != fields.end()) {
828 0 : start_height_factor = fields.at("start_height_factor_for_opening_factor_3").get<Real64>();
829 : }
830 :
831 0 : factors[2] = factor;
832 0 : cds[2] = cd;
833 0 : width_factors[2] = width_factor;
834 0 : height_factors[2] = height_factor;
835 0 : start_height_factors[2] = start_height_factor;
836 :
837 0 : if (N >= 4) {
838 0 : factor = fields.at("opening_factor_4").get<Real64>();
839 0 : cd = 0.0;
840 0 : if (fields.find("discharge_coefficient_for_opening_factor_4") != fields.end()) {
841 0 : cd = fields.at("discharge_coefficient_for_opening_factor_4").get<Real64>();
842 : }
843 0 : width_factor = 0.0;
844 0 : if (fields.find("width_factor_for_opening_factor_4") != fields.end()) {
845 0 : width_factor = fields.at("width_factor_for_opening_factor_4").get<Real64>();
846 : }
847 0 : height_factor = 0.0;
848 0 : if (fields.find("height_factor_for_opening_factor_4") != fields.end()) {
849 0 : height_factor = fields.at("height_factor_for_opening_factor_4").get<Real64>();
850 : }
851 0 : start_height_factor = 0.0;
852 0 : if (fields.find("start_height_factor_for_opening_factor_4") != fields.end()) {
853 0 : start_height_factor = fields.at("start_height_factor_for_opening_factor_4").get<Real64>();
854 : }
855 :
856 0 : factors[3] = factor;
857 0 : cds[3] = cd;
858 0 : width_factors[3] = width_factor;
859 0 : height_factors[3] = height_factor;
860 0 : start_height_factors[3] = start_height_factor;
861 : }
862 : }
863 :
864 5 : MultizoneCompDetOpeningData(i).name = thisObjectName; // Name of large detailed opening component
865 5 : MultizoneCompDetOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
866 5 : MultizoneCompDetOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
867 5 : MultizoneCompDetOpeningData(i).TypeName = LVOstring; // Large vertical opening type
868 5 : MultizoneCompDetOpeningData(i).LVOType = LVOtype; // Large vertical opening type number
869 5 : MultizoneCompDetOpeningData(i).LVOValue = extra; // Extra crack length for LVO type 1 with multiple openable
870 : // parts, or Height of pivoting axis for LVO type 2
871 :
872 5 : MultizoneCompDetOpeningData(i).NumFac = N; // Number of Opening Factor Values
873 :
874 5 : MultizoneCompDetOpeningData(i).OpenFac1 = factors[0]; // Opening factor #1
875 5 : MultizoneCompDetOpeningData(i).DischCoeff1 = cds[0]; // Discharge coefficient for opening factor #1
876 5 : MultizoneCompDetOpeningData(i).WidthFac1 = width_factors[0]; // Width factor for for Opening factor #1
877 5 : MultizoneCompDetOpeningData(i).HeightFac1 = height_factors[0]; // Height factor for opening factor #1
878 5 : MultizoneCompDetOpeningData(i).StartHFac1 = start_height_factors[0]; // Start height factor for opening factor #1
879 5 : MultizoneCompDetOpeningData(i).OpenFac2 = factors[1]; // Opening factor #2
880 5 : MultizoneCompDetOpeningData(i).DischCoeff2 = cds[1]; // Discharge coefficient for opening factor #2
881 5 : MultizoneCompDetOpeningData(i).WidthFac2 = width_factors[1]; // Width factor for for Opening factor #2
882 5 : MultizoneCompDetOpeningData(i).HeightFac2 = height_factors[1]; // Height factor for opening factor #2
883 5 : MultizoneCompDetOpeningData(i).StartHFac2 = start_height_factors[1]; // Start height factor for opening factor #2
884 :
885 5 : MultizoneCompDetOpeningData(i).OpenFac3 = 0.0; // Opening factor #3
886 5 : MultizoneCompDetOpeningData(i).DischCoeff3 = 0.0; // Discharge coefficient for opening factor #3
887 5 : MultizoneCompDetOpeningData(i).WidthFac3 = 0.0; // Width factor for for Opening factor #3
888 5 : MultizoneCompDetOpeningData(i).HeightFac3 = 0.0; // Height factor for opening factor #3
889 5 : MultizoneCompDetOpeningData(i).StartHFac3 = 0.0; // Start height factor for opening factor #3
890 5 : MultizoneCompDetOpeningData(i).OpenFac4 = 0.0; // Opening factor #4
891 5 : MultizoneCompDetOpeningData(i).DischCoeff4 = 0.0; // Discharge coefficient for opening factor #4
892 5 : MultizoneCompDetOpeningData(i).WidthFac4 = 0.0; // Width factor for for Opening factor #4
893 5 : MultizoneCompDetOpeningData(i).HeightFac4 = 0.0; // Height factor for opening factor #4
894 5 : MultizoneCompDetOpeningData(i).StartHFac4 = 0.0; // Start height factor for opening factor #4
895 5 : if (N == 2) {
896 5 : if (factors[1] != 1.0) {
897 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
898 0 : ShowContinueError(
899 : m_state,
900 : "..This object specifies that only 3 opening factors will be used. So, the value of Opening Factor #2 is set to 1.0.");
901 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac2));
902 0 : MultizoneCompDetOpeningData(i).OpenFac2 = 1.0;
903 : }
904 0 : } else if (N >= 3) {
905 0 : MultizoneCompDetOpeningData(i).OpenFac3 = factors[2]; // Opening factor #3
906 0 : MultizoneCompDetOpeningData(i).DischCoeff3 = cds[2]; // Discharge coefficient for opening factor #3
907 0 : MultizoneCompDetOpeningData(i).WidthFac3 = width_factors[2]; // Width factor for for Opening factor #3
908 0 : MultizoneCompDetOpeningData(i).HeightFac3 = height_factors[2]; // Height factor for opening factor #3
909 0 : MultizoneCompDetOpeningData(i).StartHFac3 = start_height_factors[2]; // Start height factor for opening factor #3
910 0 : if (N >= 4) {
911 0 : MultizoneCompDetOpeningData(i).OpenFac4 = factors[3]; // Opening factor #4
912 0 : if (factors[3] != 1.0) {
913 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
914 0 : ShowContinueError(m_state,
915 : "..This object specifies that 4 opening factors will be used. So, the value of Opening Factor #4 "
916 : "is set to 1.0.");
917 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac4));
918 0 : MultizoneCompDetOpeningData(i).OpenFac4 = 1.0;
919 : }
920 0 : MultizoneCompDetOpeningData(i).DischCoeff4 = cds[3]; // Discharge coefficient for opening factor #4
921 0 : MultizoneCompDetOpeningData(i).WidthFac4 = width_factors[3]; // Width factor for for Opening factor #4
922 0 : MultizoneCompDetOpeningData(i).HeightFac4 = height_factors[3]; // Height factor for opening factor #4
923 0 : MultizoneCompDetOpeningData(i).StartHFac4 = start_height_factors[3]; // Start height factor for opening factor #4
924 : } else {
925 0 : if (factors[2] != 1.0) {
926 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
927 0 : ShowContinueError(m_state,
928 : "..This object specifies that only 3 opening factors will be used. So, the value of Opening Factor #3 "
929 : "is set to 1.0.");
930 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac3));
931 0 : MultizoneCompDetOpeningData(i).OpenFac3 = 1.0;
932 : }
933 : }
934 : }
935 :
936 : // Sanity checks, check sum of Height Factor and the Start Height Factor
937 5 : if (MultizoneCompDetOpeningData(i).HeightFac1 + MultizoneCompDetOpeningData(i).StartHFac1 > 1.0) {
938 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
939 0 : ShowContinueError(
940 : m_state, "..The sum of Height Factor for Opening Factor 1 and Start Height Factor for Opening Factor 1 is greater than 1.0");
941 0 : success = false;
942 : }
943 5 : if (MultizoneCompDetOpeningData(i).HeightFac2 + MultizoneCompDetOpeningData(i).StartHFac2 > 1.0) {
944 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
945 0 : ShowContinueError(
946 : m_state, "..The sum of Height Factor for Opening Factor 2 and Start Height Factor for Opening Factor 2 is greater than 1.0");
947 0 : success = false;
948 : }
949 5 : if (MultizoneCompDetOpeningData(i).NumFac > 2) {
950 0 : if (MultizoneCompDetOpeningData(i).OpenFac2 >= MultizoneCompDetOpeningData(i).OpenFac3) {
951 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
952 0 : ShowContinueError(m_state, "..The value of Opening Factor #2 >= the value of Opening Factor #3");
953 0 : success = false;
954 : }
955 0 : if (MultizoneCompDetOpeningData(i).HeightFac3 + MultizoneCompDetOpeningData(i).StartHFac3 > 1.0) {
956 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
957 0 : ShowContinueError(
958 : m_state,
959 : "..The sum of Height Factor for Opening Factor 3 and Start Height Factor for Opening Factor 3 is greater than 1.0");
960 0 : success = false;
961 : }
962 0 : if (MultizoneCompDetOpeningData(i).NumFac == 4) {
963 0 : if (MultizoneCompDetOpeningData(i).OpenFac3 >= MultizoneCompDetOpeningData(i).OpenFac4) {
964 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
965 0 : ShowContinueError(m_state, "..The value of Opening Factor #3 >= the value of Opening Factor #4");
966 0 : success = false;
967 : }
968 0 : if (MultizoneCompDetOpeningData(i).HeightFac4 + MultizoneCompDetOpeningData(i).StartHFac4 > 1.0) {
969 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
970 0 : ShowContinueError(
971 : m_state,
972 : "..The sum of Height Factor for Opening Factor 4 and Start Height Factor for Opening Factor 4 is greater than 1.0");
973 0 : success = false;
974 : }
975 : }
976 : }
977 :
978 : // Add the element to the lookup table, check for name overlaps
979 5 : if (elements.find(thisObjectName) == elements.end()) {
980 5 : elements[thisObjectName] = &MultizoneCompDetOpeningData(i); // Yet another workaround
981 : } else {
982 0 : ShowSevereError(
983 : m_state,
984 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
985 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
986 0 : success = false;
987 : }
988 :
989 5 : ++i;
990 30 : }
991 : }
992 :
993 : // Read AirflowNetwork simulation simple openings
994 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:SimpleOpening";
995 25 : AirflowNetworkNumOfSimOpenings =
996 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
997 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
998 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
999 9 : int i = 1; // Temporary workaround
1000 9 : MultizoneCompSimpleOpeningData.allocate(AirflowNetworkNumOfSimOpenings); // Temporary workaround
1001 9 : auto &instancesValue = instances.value();
1002 18 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1003 9 : auto const &fields = instance.value();
1004 9 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1005 9 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1006 :
1007 9 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
1008 9 : Real64 expnt{0.65};
1009 27 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
1010 18 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
1011 : }
1012 18 : Real64 diff{fields.at("minimum_density_difference_for_two_way_flow")};
1013 9 : Real64 dischargeCoeff{fields.at("discharge_coefficient")};
1014 :
1015 9 : MultizoneCompSimpleOpeningData(i).name = thisObjectName; // Name of large simple opening component
1016 9 : MultizoneCompSimpleOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
1017 9 : MultizoneCompSimpleOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
1018 9 : MultizoneCompSimpleOpeningData(i).MinRhoDiff = diff; // Minimum density difference for two-way flow
1019 9 : MultizoneCompSimpleOpeningData(i).DischCoeff = dischargeCoeff; // Discharge coefficient at full opening
1020 :
1021 : // Add the element to the lookup table, check for name overlaps
1022 9 : if (elements.find(thisObjectName) == elements.end()) {
1023 9 : elements[thisObjectName] = &MultizoneCompSimpleOpeningData(i); // Yet another workaround
1024 : } else {
1025 0 : ShowSevereError(
1026 : m_state,
1027 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1028 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1029 0 : success = false;
1030 : }
1031 :
1032 9 : ++i;
1033 18 : }
1034 : }
1035 :
1036 : // Read AirflowNetwork simulation horizontal openings
1037 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:HorizontalOpening";
1038 25 : AirflowNetworkNumOfHorOpenings =
1039 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1040 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1041 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1042 1 : int i = 1; // Temporary workaround
1043 1 : MultizoneCompHorOpeningData.allocate(AirflowNetworkNumOfHorOpenings); // Temporary workaround
1044 1 : auto &instancesValue = instances.value();
1045 2 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1046 1 : auto const &fields = instance.value();
1047 1 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1048 1 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1049 :
1050 1 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
1051 1 : Real64 expnt{0.65};
1052 3 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
1053 2 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
1054 : }
1055 1 : Real64 angle{90.0};
1056 3 : if (fields.find("sloping_plane_angle") != fields.end()) {
1057 2 : angle = fields.at("sloping_plane_angle").get<Real64>();
1058 : }
1059 1 : Real64 dischargeCoeff{fields.at("discharge_coefficient")};
1060 :
1061 1 : MultizoneCompHorOpeningData(i).name = thisObjectName; // Name of large simple opening component
1062 1 : MultizoneCompHorOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
1063 1 : MultizoneCompHorOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
1064 1 : MultizoneCompHorOpeningData(i).Slope = angle; // Sloping plane angle
1065 1 : MultizoneCompHorOpeningData(i).DischCoeff = dischargeCoeff; // Discharge coefficient at full opening
1066 :
1067 : // Add the element to the lookup table, check for name overlaps
1068 1 : if (elements.find(thisObjectName) == elements.end()) {
1069 1 : elements[thisObjectName] = &MultizoneCompHorOpeningData(i); // Yet another workaround
1070 : } else {
1071 0 : ShowSevereError(
1072 : m_state,
1073 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1074 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1075 0 : success = false;
1076 : }
1077 :
1078 1 : ++i;
1079 2 : }
1080 : }
1081 :
1082 : // *** Read AirflowNetwork simulation surface effective leakage area component
1083 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea";
1084 25 : AirflowNetworkNumOfSurELA =
1085 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1086 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1087 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1088 3 : int i = 1; // Temporary workaround
1089 3 : MultizoneSurfaceELAData.allocate(AirflowNetworkNumOfSurELA); // Temporary workaround
1090 3 : auto &instancesValue = instances.value();
1091 11 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1092 8 : auto const &fields = instance.value();
1093 8 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1094 :
1095 8 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1096 :
1097 8 : Real64 ela{fields.at("effective_leakage_area")};
1098 8 : Real64 cd{1.0};
1099 24 : if (fields.find("discharge_coefficient") != fields.end()) {
1100 16 : cd = fields.at("discharge_coefficient").get<Real64>();
1101 : }
1102 8 : Real64 dp{4.0};
1103 24 : if (fields.find("reference_pressure_difference") != fields.end()) {
1104 16 : dp = fields.at("reference_pressure_difference").get<Real64>();
1105 : }
1106 8 : Real64 expnt{0.65};
1107 24 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1108 16 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1109 : }
1110 :
1111 8 : MultizoneSurfaceELAData(i).name = thisObjectName; // Name of surface effective leakage area component
1112 8 : MultizoneSurfaceELAData(i).ELA = ela; // Effective leakage area
1113 8 : MultizoneSurfaceELAData(i).DischCoeff = cd; // Discharge coefficient
1114 8 : MultizoneSurfaceELAData(i).RefDeltaP = dp; // Reference pressure difference
1115 8 : MultizoneSurfaceELAData(i).FlowExpo = expnt; // Air Mass Flow exponent
1116 8 : MultizoneSurfaceELAData(i).TestDeltaP = 0.0; // Testing pressure difference
1117 8 : MultizoneSurfaceELAData(i).TestDisCoef = 0.0; // Testing Discharge coefficient
1118 :
1119 : // Add the element to the lookup table, check for name overlaps
1120 8 : if (elements.find(thisObjectName) == elements.end()) {
1121 8 : elements[thisObjectName] = &MultizoneSurfaceELAData(i); // Yet another workaround
1122 : } else {
1123 0 : ShowSevereError(
1124 : m_state,
1125 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1126 0 : success = false;
1127 : }
1128 :
1129 8 : ++i;
1130 11 : }
1131 : }
1132 :
1133 : // *** Read AirflowNetwork simulation specified flow components
1134 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:SpecifiedFlowRate";
1135 25 : AirflowNetworkNumOfSFR =
1136 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1137 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1138 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1139 0 : int i_mass = 0; // Temporary workaround that increasingly looks like the long term solution
1140 0 : int i_vol = 0;
1141 0 : auto &instancesValue = instances.value();
1142 :
1143 0 : instancesValue = instances.value();
1144 0 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1145 0 : auto const &fields = instance.value();
1146 0 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1147 :
1148 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1149 :
1150 0 : Real64 flow_rate{fields.at("air_flow_value")};
1151 0 : bool is_mass_flow = true;
1152 0 : if (fields.find("air_flow_units") != fields.end()) {
1153 0 : if (fields.at("air_flow_units") != "MassFlow") {
1154 0 : is_mass_flow = false;
1155 : }
1156 : }
1157 :
1158 : // Check for name overlaps
1159 0 : if (elements.find(thisObjectName) != elements.end()) {
1160 0 : ShowSevereError(
1161 : m_state,
1162 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1163 0 : success = false;
1164 : }
1165 :
1166 0 : if (is_mass_flow) {
1167 0 : SpecifiedMassFlowData.emplace_back();
1168 0 : SpecifiedMassFlowData[i_mass].name = thisObjectName;
1169 0 : SpecifiedMassFlowData[i_mass].mass_flow = flow_rate;
1170 0 : ++i_mass;
1171 : } else {
1172 0 : SpecifiedVolumeFlowData.emplace_back();
1173 0 : SpecifiedVolumeFlowData[i_vol].name = thisObjectName;
1174 0 : SpecifiedVolumeFlowData[i_vol].volume_flow = flow_rate;
1175 0 : ++i_vol;
1176 : }
1177 0 : }
1178 0 : for (auto &afe : SpecifiedMassFlowData) {
1179 0 : elements[afe.name] = &afe; // Yet another workaround
1180 : }
1181 0 : for (auto &afe : SpecifiedVolumeFlowData) {
1182 0 : elements[afe.name] = &afe; // Yet another workaround
1183 : }
1184 : }
1185 :
1186 : // Read AirflowNetwork Distribution system component: duct leakage
1187 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Leak";
1188 25 : DisSysNumOfLeaks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1189 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1190 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1191 2 : int i = 1; // Temporary workaround
1192 2 : DisSysCompLeakData.allocate(DisSysNumOfLeaks); // Temporary workaround
1193 2 : auto &instancesValue = instances.value();
1194 7 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1195 5 : auto const &fields = instance.value();
1196 5 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1197 5 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1198 :
1199 5 : Real64 coeff{fields.at("air_mass_flow_coefficient")};
1200 5 : Real64 expnt{0.65};
1201 15 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1202 10 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1203 : }
1204 :
1205 5 : DisSysCompLeakData(i).name = thisObjectName; // Name of duct leak component
1206 5 : DisSysCompLeakData(i).FlowCoef = coeff; // Air Mass Flow Coefficient
1207 5 : DisSysCompLeakData(i).FlowExpo = expnt; // Air Mass Flow exponent
1208 :
1209 : // Add the element to the lookup table, check for name overlaps
1210 5 : if (elements.find(thisObjectName) == elements.end()) {
1211 5 : elements[thisObjectName] = &DisSysCompLeakData(i); // Yet another workaround
1212 : } else {
1213 0 : ShowSevereError(
1214 : m_state,
1215 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1216 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1217 0 : success = false;
1218 : }
1219 :
1220 5 : ++i;
1221 7 : }
1222 : }
1223 :
1224 : // Read AirflowNetwork Distribution system component: duct effective leakage ratio
1225 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:LeakageRatio";
1226 25 : DisSysNumOfELRs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1227 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1228 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1229 5 : int i = 1; // Temporary workaround
1230 5 : DisSysCompELRData.allocate(DisSysNumOfELRs); // Temporary workaround
1231 5 : auto &instancesValue = instances.value();
1232 25 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1233 20 : auto const &fields = instance.value();
1234 20 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1235 20 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1236 :
1237 40 : Real64 elr{fields.at("effective_leakage_ratio")};
1238 40 : Real64 maxflow{fields.at("maximum_flow_rate")};
1239 20 : Real64 dp{fields.at("reference_pressure_difference")};
1240 20 : Real64 expnt{0.65};
1241 60 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1242 40 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1243 : }
1244 :
1245 20 : DisSysCompELRData(i).name = thisObjectName; // Name of duct effective leakage ratio component
1246 20 : DisSysCompELRData(i).ELR = elr; // Value of effective leakage ratio
1247 20 : DisSysCompELRData(i).FlowRate = maxflow * m_state.dataEnvrn->StdRhoAir; // Maximum airflow rate
1248 20 : DisSysCompELRData(i).RefPres = dp; // Reference pressure difference
1249 20 : DisSysCompELRData(i).FlowExpo = expnt; // Air Mass Flow exponent
1250 :
1251 : // Add the element to the lookup table, check for name overlaps
1252 20 : if (elements.find(thisObjectName) == elements.end()) {
1253 20 : elements[thisObjectName] = &DisSysCompELRData(i); // Yet another workaround
1254 : } else {
1255 0 : ShowSevereError(
1256 : m_state,
1257 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1258 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1259 0 : success = false;
1260 : }
1261 :
1262 20 : ++i;
1263 25 : }
1264 : }
1265 :
1266 : // Read AirflowNetwork Distribution system component: duct
1267 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Duct";
1268 25 : DisSysNumOfDucts = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1269 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1270 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1271 7 : int i = 1; // Temporary workaround
1272 7 : DisSysCompDuctData.allocate(DisSysNumOfDucts); // Temporary workaround
1273 7 : auto &instancesValue = instances.value();
1274 71 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1275 64 : auto const &fields = instance.value();
1276 64 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1277 64 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1278 :
1279 128 : Real64 L{fields.at("duct_length")};
1280 128 : Real64 D{fields.at("hydraulic_diameter")};
1281 64 : Real64 A{fields.at("cross_section_area")};
1282 64 : Real64 e{0.0009};
1283 192 : if (fields.find("surface_roughness") != fields.end()) {
1284 128 : e = fields.at("surface_roughness").get<Real64>();
1285 : }
1286 64 : Real64 dlc{0.0};
1287 192 : if (fields.find("coefficient_for_local_dynamic_loss_due_to_fitting") != fields.end()) {
1288 128 : dlc = fields.at("coefficient_for_local_dynamic_loss_due_to_fitting").get<Real64>();
1289 : }
1290 64 : Real64 U{0.943};
1291 192 : if (fields.find("heat_transmittance_coefficient_u_factor_for_duct_wall_construction") != fields.end()) {
1292 128 : U = fields.at("heat_transmittance_coefficient_u_factor_for_duct_wall_construction").get<Real64>();
1293 : }
1294 64 : Real64 Um{0.001};
1295 192 : if (fields.find("overall_moisture_transmittance_coefficient_from_air_to_air") != fields.end()) {
1296 128 : Um = fields.at("overall_moisture_transmittance_coefficient_from_air_to_air").get<Real64>();
1297 : }
1298 64 : Real64 hout{0.0};
1299 192 : if (fields.find("outside_convection_coefficient") != fields.end()) {
1300 80 : hout = fields.at("outside_convection_coefficient").get<Real64>();
1301 : }
1302 64 : Real64 hin{0.0};
1303 192 : if (fields.find("inside_convection_coefficient") != fields.end()) {
1304 80 : hin = fields.at("inside_convection_coefficient").get<Real64>();
1305 : }
1306 :
1307 64 : DisSysCompDuctData(i).name = thisObjectName; // Name of duct effective leakage ratio component
1308 64 : DisSysCompDuctData(i).L = L; // Duct length [m]
1309 64 : DisSysCompDuctData(i).hydraulicDiameter = D; // Hydraulic diameter [m]
1310 64 : DisSysCompDuctData(i).A = A; // Cross section area [m2]
1311 64 : DisSysCompDuctData(i).roughness = e; // Surface roughness [m]
1312 64 : DisSysCompDuctData(i).TurDynCoef = dlc; // Turbulent dynamic loss coefficient
1313 64 : DisSysCompDuctData(i).UThermConduct = U; // Conduction heat transmittance [W/m2.K]
1314 64 : DisSysCompDuctData(i).UMoisture = Um; // Overall moisture transmittance [kg/m2]
1315 64 : DisSysCompDuctData(i).OutsideConvCoeff = hout; // Outside convection coefficient [W/m2.K]
1316 64 : DisSysCompDuctData(i).InsideConvCoeff = hin; // Inside convection coefficient [W/m2.K]
1317 64 : DisSysCompDuctData(i).MThermal = 0.0; // Thermal capacity [J/K]
1318 64 : DisSysCompDuctData(i).MMoisture = 0.0; // Moisture capacity [kg]
1319 64 : DisSysCompDuctData(i).LamDynCoef = 64.0; // Laminar dynamic loss coefficient
1320 64 : DisSysCompDuctData(i).LamFriCoef = dlc; // Laminar friction loss coefficient
1321 64 : DisSysCompDuctData(i).InitLamCoef = 128.0; // Coefficient of linear initialization
1322 64 : DisSysCompDuctData(i).RelRough = e / D; // e/D: relative roughness
1323 64 : DisSysCompDuctData(i).RelL = L / D; // L/D: relative length
1324 64 : DisSysCompDuctData(i).A1 = 1.14 - 0.868589 * std::log(DisSysCompDuctData(i).RelRough); // 1.14 - 0.868589*ln(e/D)
1325 64 : DisSysCompDuctData(i).g = DisSysCompDuctData(i).A1; // 1/sqrt(Darcy friction factor)
1326 :
1327 : // Add the element to the lookup table, check for name overlaps
1328 64 : if (elements.find(thisObjectName) == elements.end()) {
1329 64 : elements[thisObjectName] = &DisSysCompDuctData(i); // Yet another workaround
1330 : } else {
1331 0 : ShowSevereError(
1332 : m_state,
1333 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1334 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1335 0 : success = false;
1336 : }
1337 :
1338 64 : ++i;
1339 71 : }
1340 : }
1341 :
1342 : // Read AirflowNetwork Distribution system component: constant volume fan
1343 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Fan";
1344 25 : DisSysNumOfCVFs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1345 25 : if (DisSysNumOfCVFs > 0 && DisSysNumOfCVFs != m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC")) {
1346 0 : ShowSevereError(m_state, format("The number of entered AirflowNetwork:Distribution:Component:Fan objects is {}", DisSysNumOfCVFs));
1347 0 : ShowSevereError(m_state,
1348 0 : format("The number of entered AirLoopHVAC objects is {}",
1349 0 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC")));
1350 0 : ShowContinueError(m_state, "Both numbers should be equal. Please check your inputs.");
1351 0 : success = false;
1352 : }
1353 :
1354 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1355 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1356 7 : int i = 1; // Temporary workaround
1357 7 : DisSysCompCVFData.allocate(DisSysNumOfCVFs); // Temporary workaround
1358 7 : auto &instancesValue = instances.value();
1359 15 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1360 8 : auto const &fields = instance.value();
1361 8 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1362 8 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1363 :
1364 8 : std::string fan_name = Util::makeUPPER(fields.at("fan_name").get<std::string>());
1365 :
1366 : int fanIndex;
1367 8 : Real64 flowRate = 0.0;
1368 : int inletNode;
1369 : int outletNode;
1370 :
1371 : HVAC::FanType fanType = static_cast<HVAC::FanType>(
1372 8 : getEnumValue(HVAC::fanTypeNamesUC, Util::makeUPPER(fields.at("supply_fan_object_type").get<std::string>())));
1373 :
1374 8 : HVAC::FanType fanType2 = HVAC::FanType::Invalid;
1375 :
1376 8 : if (fanType == HVAC::FanType::SystemModel) {
1377 2 : fanIndex = Fans::GetFanIndex(m_state, fan_name);
1378 2 : if (fanIndex < 0) {
1379 0 : ShowSevereError(m_state, "...occurs in " + CurrentModuleObject + " = " + DisSysCompCVFData(i).name);
1380 0 : success = false;
1381 : } else {
1382 2 : auto *fanSys = dynamic_cast<Fans::FanSystem *>(m_state.dataFans->fans(fanIndex));
1383 2 : assert(fanSys != nullptr);
1384 2 : flowRate = fanSys->maxAirFlowRate * m_state.dataEnvrn->StdRhoAir;
1385 2 : DisSysCompCVFData(i).FanModelFlag = true;
1386 2 : inletNode = fanSys->inletNodeNum;
1387 2 : outletNode = fanSys->outletNodeNum;
1388 2 : if (fanSys->speedControl == Fans::SpeedControl::Continuous) {
1389 0 : fanType2 = HVAC::FanType::VAV;
1390 0 : VAVSystem = true;
1391 : } else {
1392 2 : fanType2 = HVAC::FanType::OnOff;
1393 : }
1394 2 : supplyFanType = fanType2;
1395 : }
1396 :
1397 : } else {
1398 6 : fanIndex = GetFanIndex(m_state, fan_name);
1399 :
1400 6 : if (fanIndex == 0) {
1401 0 : ErrorObjectHeader eoh{RoutineName, CurrentModuleObject, DisSysCompCVFData(i).name};
1402 0 : ShowSevereItemNotFound(m_state, eoh, "Fan Name", fan_name);
1403 0 : success = false;
1404 : }
1405 :
1406 6 : auto *fan = m_state.dataFans->fans(fanIndex);
1407 6 : flowRate = fan->maxAirFlowRate * m_state.dataEnvrn->StdRhoAir;
1408 :
1409 6 : fanType2 = fan->type;
1410 6 : supplyFanType = fanType2;
1411 : }
1412 :
1413 8 : if (!(fanType2 == HVAC::FanType::Constant || fanType2 == HVAC::FanType::OnOff || fanType2 == HVAC::FanType::VAV)) {
1414 0 : ShowSevereError(
1415 : m_state,
1416 0 : format("{}The Supply Fan Object Type in {} = {} is not a valid fan type.", RoutineName, CurrentModuleObject, thisObjectName));
1417 0 : ShowContinueError(m_state, "Valid fan types are Fan:ConstantVolume, Fan:OnOff, Fan:VariableVolume, or Fan:SystemModel.");
1418 0 : success = false;
1419 : } else {
1420 8 : if (fanType == HVAC::FanType::Constant && fanType2 == HVAC::FanType::OnOff) {
1421 0 : ShowSevereError(m_state, "The Supply Fan Object Type defined in " + CurrentModuleObject + " is Fan:ConstantVolume");
1422 0 : ShowContinueError(m_state, "The Supply Fan Object Type defined in an AirLoopHVAC is Fan:OnOff");
1423 0 : success = false;
1424 8 : } else if (fanType == HVAC::FanType::OnOff && fanType2 == HVAC::FanType::Constant) {
1425 0 : ShowSevereError(m_state, "The Supply Fan Object Type defined in " + CurrentModuleObject + " is Fan:SimpleOnOff");
1426 0 : ShowContinueError(m_state, "The Supply Fan Object Type defined in an AirLoopHVAC is Fan:ConstantVolume");
1427 0 : success = false;
1428 : }
1429 : }
1430 8 : bool ErrorsFound{false};
1431 8 : auto *fan = m_state.dataFans->fans(fanIndex);
1432 8 : if (fanType2 == HVAC::FanType::Constant) {
1433 4 : inletNode = fan->inletNodeNum;
1434 4 : outletNode = fan->outletNodeNum;
1435 : }
1436 8 : if (fanType2 == HVAC::FanType::OnOff && !DisSysCompCVFData(i).FanModelFlag) {
1437 2 : inletNode = fan->inletNodeNum;
1438 2 : outletNode = fan->outletNodeNum;
1439 : }
1440 8 : if (fanType2 == HVAC::FanType::VAV && !DisSysCompCVFData(i).FanModelFlag) {
1441 0 : inletNode = fan->inletNodeNum;
1442 0 : outletNode = fan->outletNodeNum;
1443 0 : VAVSystem = true;
1444 : }
1445 :
1446 8 : if (ErrorsFound) {
1447 0 : success = false;
1448 : }
1449 :
1450 8 : DisSysCompCVFData(i).name = fan_name; // Name of duct effective leakage ratio component
1451 8 : DisSysCompCVFData(i).Ctrl = 1.0; // Control ratio
1452 8 : DisSysCompCVFData(i).FanIndex = fanIndex;
1453 8 : DisSysCompCVFData(i).FlowRate = flowRate;
1454 8 : DisSysCompCVFData(i).fanType = fanType2;
1455 8 : DisSysCompCVFData(i).InletNode = inletNode;
1456 8 : DisSysCompCVFData(i).OutletNode = outletNode;
1457 :
1458 : // Add the element to the lookup table, check for name overlaps
1459 8 : if (elements.find(fan_name) == elements.end()) {
1460 8 : elements[fan_name] = &DisSysCompCVFData(i); // Yet another workaround
1461 : } else {
1462 0 : ShowSevereError(
1463 0 : m_state, format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, fan_name));
1464 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1465 0 : success = false;
1466 : }
1467 :
1468 8 : ++i;
1469 15 : }
1470 : }
1471 :
1472 : // Read AirflowNetwork Distribution system component: coil
1473 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Coil";
1474 25 : DisSysNumOfCoils = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1475 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1476 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1477 7 : int i = 1; // Temporary workaround
1478 7 : DisSysCompCoilData.allocate(DisSysNumOfCoils); // Temporary workaround
1479 7 : auto &instancesValue = instances.value();
1480 27 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1481 20 : auto const &fields = instance.value();
1482 : // auto const &thisObjectName = Util::makeUPPER(instance.key());
1483 20 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1484 :
1485 40 : std::string coil_name = fields.at("coil_name").get<std::string>();
1486 40 : std::string coil_type = fields.at("coil_object_type").get<std::string>();
1487 40 : Real64 L{fields.at("air_path_length")};
1488 20 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1489 :
1490 20 : DisSysCompCoilData(i).name = Util::makeUPPER(coil_name); // Name of associated EPlus coil component
1491 20 : DisSysCompCoilData(i).EPlusType = coil_type; // coil type
1492 20 : DisSysCompCoilData(i).L = L; // Air path length
1493 20 : DisSysCompCoilData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1494 :
1495 : // Add the element to the lookup table, check for name overlaps
1496 20 : if (elements.find(DisSysCompCoilData(i).name) == elements.end()) {
1497 20 : elements[DisSysCompCoilData(i).name] = &DisSysCompCoilData(i); // Yet another workaround
1498 : } else {
1499 0 : ShowSevereError(m_state,
1500 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1501 : RoutineName,
1502 : CurrentModuleObject,
1503 0 : DisSysCompCoilData(i).name));
1504 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1505 0 : success = false;
1506 : }
1507 :
1508 20 : ++i;
1509 27 : }
1510 : }
1511 :
1512 : // Read AirflowNetwork Distribution system component: heat exchanger
1513 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:HeatExchanger";
1514 25 : DisSysNumOfHXs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1515 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1516 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1517 0 : int i = 1; // Temporary workaround
1518 0 : DisSysCompHXData.allocate(DisSysNumOfHXs); // Temporary workaround
1519 0 : auto &instancesValue = instances.value();
1520 0 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1521 0 : auto const &fields = instance.value();
1522 : // auto const &thisObjectName = Util::makeUPPER(instance.key());
1523 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1524 :
1525 0 : std::string hx_name = fields.at("heatexchanger_name").get<std::string>();
1526 0 : std::string hx_type = fields.at("heatexchanger_object_type").get<std::string>();
1527 0 : Real64 L{fields.at("air_path_length")};
1528 0 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1529 :
1530 0 : DisSysCompHXData(i).name = Util::makeUPPER(hx_name); // Name of associated EPlus heat exchange component
1531 0 : DisSysCompHXData(i).EPlusType = hx_type; // coil type
1532 0 : DisSysCompHXData(i).L = L; // Air path length
1533 0 : DisSysCompHXData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1534 0 : DisSysCompHXData(i).CoilParentExists = HVACHXAssistedCoolingCoil::VerifyHeatExchangerParent(m_state, hx_type, hx_name);
1535 :
1536 : // Add the element to the lookup table, check for name overlaps
1537 0 : if (elements.find(DisSysCompHXData(i).name) == elements.end()) {
1538 0 : elements[DisSysCompHXData(i).name] = &DisSysCompHXData(i); // Yet another workaround
1539 : } else {
1540 0 : ShowSevereError(m_state,
1541 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1542 : RoutineName,
1543 : CurrentModuleObject,
1544 0 : DisSysCompHXData(i).name));
1545 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1546 0 : success = false;
1547 : }
1548 0 : ++i;
1549 0 : }
1550 : }
1551 :
1552 : // Read AirflowNetwork Distribution system component: terminal unit
1553 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:TerminalUnit";
1554 25 : DisSysNumOfTermUnits = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1555 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1556 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1557 2 : int i = 1; // Temporary workaround
1558 2 : DisSysCompTermUnitData.allocate(DisSysNumOfTermUnits); // Temporary workaround
1559 2 : auto &instancesValue = instances.value();
1560 5 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1561 3 : auto const &fields = instance.value();
1562 : // auto const &thisObjectName = Util::makeUPPER(instance.key());
1563 3 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1564 :
1565 6 : std::string tu_name = fields.at("terminal_unit_name").get<std::string>();
1566 6 : std::string tu_type = fields.at("terminal_unit_object_type").get<std::string>();
1567 6 : Real64 L{fields.at("air_path_length")};
1568 3 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1569 :
1570 3 : DisSysCompTermUnitData(i).name = Util::makeUPPER(tu_name); // Name of associated EPlus coil component
1571 3 : DisSysCompTermUnitData(i).EPlusType = tu_type; // Terminal unit type
1572 3 : DisSysCompTermUnitData(i).L = L; // Air path length
1573 3 : DisSysCompTermUnitData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1574 :
1575 : // Add the element to the lookup table, check for name overlaps
1576 3 : if (elements.find(DisSysCompTermUnitData(i).name) == elements.end()) {
1577 3 : elements[DisSysCompTermUnitData(i).name] = &DisSysCompTermUnitData(i); // Yet another workaround
1578 : } else {
1579 0 : ShowSevereError(m_state,
1580 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1581 : RoutineName,
1582 : CurrentModuleObject,
1583 0 : DisSysCompTermUnitData(i).name));
1584 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1585 0 : success = false;
1586 : }
1587 :
1588 3 : ++i;
1589 5 : }
1590 : }
1591 :
1592 : // Get input data of constant pressure drop component
1593 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ConstantPressureDrop";
1594 25 : DisSysNumOfCPDs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1595 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1596 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1597 2 : int i = 1; // Temporary workaround
1598 2 : DisSysCompCPDData.allocate(DisSysNumOfCPDs); // Temporary workaround
1599 2 : auto &instancesValue = instances.value();
1600 4 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1601 2 : auto const &fields = instance.value();
1602 2 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1603 2 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1604 :
1605 2 : Real64 dp{fields.at("pressure_difference_across_the_component")};
1606 :
1607 2 : DisSysCompCPDData(i).name = thisObjectName; // Name of constant pressure drop component
1608 2 : DisSysCompCPDData(i).A = 1.0; // cross section area
1609 2 : DisSysCompCPDData(i).DP = dp; // Pressure difference across the component
1610 :
1611 : // Add the element to the lookup table, check for name overlaps
1612 2 : if (elements.find(thisObjectName) == elements.end()) {
1613 2 : elements[thisObjectName] = &DisSysCompCPDData(i); // Yet another workaround
1614 : } else {
1615 0 : ShowSevereError(
1616 : m_state,
1617 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1618 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1619 0 : success = false;
1620 : }
1621 :
1622 2 : ++i;
1623 4 : }
1624 : }
1625 :
1626 25 : return success;
1627 25 : }
1628 :
1629 127 : void Solver::get_input()
1630 : {
1631 :
1632 : // SUBROUTINE INFORMATION:
1633 : // AUTHOR Lixing Gu
1634 : // DATE WRITTEN Aug. 2003
1635 : // MODIFIED Aug. 2005
1636 : // RE-ENGINEERED na
1637 :
1638 : // PURPOSE OF THIS SUBROUTINE:
1639 : // This subroutine reads inputs of air distribution system
1640 :
1641 : // Using/Aliasing
1642 : using Curve::GetCurveIndex;
1643 : using DataLoopNode::ObjectIsParent;
1644 : using HVACHXAssistedCoolingCoil::VerifyHeatExchangerParent;
1645 : using MixedAir::GetOAMixerNumber;
1646 : using NodeInputManager::GetOnlySingleNode;
1647 : using OutAirNodeManager::SetOutAirNodes;
1648 : using RoomAir::GetRAFNNodeNum;
1649 :
1650 : // SUBROUTINE PARAMETER DEFINITIONS:
1651 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::get_input: "); // include trailing blank space
1652 :
1653 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1654 : int n;
1655 : int k;
1656 : int count;
1657 : bool NodeFound;
1658 : bool found;
1659 : int NumAPL;
1660 127 : Array1D_string CompName(2);
1661 127 : std::string SimAirNetworkKey;
1662 :
1663 : // Declare variables used in this subroutine for debug purpose
1664 127 : Array1D_int ZoneCheck;
1665 127 : Array1D_int ZoneBCCheck;
1666 :
1667 : int NumAlphas; // Number of Alphas for each GetObjectItem call
1668 : int NumNumbers; // Number of Numbers for each GetObjectItem call
1669 : int IOStatus; // Used in GetObjectItem
1670 127 : std::string CurrentModuleObject;
1671 127 : Array1D_string Alphas; // Alpha input items for object
1672 127 : Array1D_string cAlphaFields; // Alpha field names
1673 127 : Array1D_string cNumericFields; // Numeric field names
1674 127 : Array1D<Real64> Numbers; // Numeric input items for object
1675 127 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
1676 127 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
1677 127 : int MaxNums(0); // Maximum number of numeric input fields
1678 127 : int MaxAlphas(0); // Maximum number of alpha input fields
1679 127 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
1680 : Real64 minHeight;
1681 : Real64 maxHeight;
1682 : Real64 baseratio;
1683 :
1684 127 : auto &Node(m_state.dataLoopNodes->Node);
1685 :
1686 : // Formats
1687 : static constexpr std::string_view Format_110(
1688 : "! <AirflowNetwork Model:Control>, No Multizone or Distribution/Multizone with Distribution/Multizone "
1689 : "without Distribution/Multizone with Distribution only during Fan Operation\n");
1690 : static constexpr std::string_view Format_120("AirflowNetwork Model:Control,{}\n");
1691 :
1692 : // Set the maximum numbers of input fields
1693 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1694 : m_state, "AirflowNetwork:SimulationControl", TotalArgs, NumAlphas, NumNumbers);
1695 127 : MaxNums = max(MaxNums, NumNumbers);
1696 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1697 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(m_state, "AirflowNetwork:MultiZone:Zone", TotalArgs, NumAlphas, NumNumbers);
1698 127 : MaxNums = max(MaxNums, NumNumbers);
1699 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1700 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1701 : m_state, "AirflowNetwork:MultiZone:Surface", TotalArgs, NumAlphas, NumNumbers);
1702 127 : MaxNums = max(MaxNums, NumNumbers);
1703 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1704 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1705 : m_state, "AirflowNetwork:MultiZone:Component:DetailedOpening", TotalArgs, NumAlphas, NumNumbers);
1706 127 : MaxNums = max(MaxNums, NumNumbers);
1707 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1708 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1709 : m_state, "AirflowNetwork:MultiZone:ExternalNode", TotalArgs, NumAlphas, NumNumbers);
1710 127 : MaxNums = max(MaxNums, NumNumbers);
1711 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1712 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1713 : m_state, "AirflowNetwork:MultiZone:WindPressureCoefficientArray", TotalArgs, NumAlphas, NumNumbers);
1714 127 : MaxNums = max(MaxNums, NumNumbers);
1715 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1716 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1717 : m_state, "AirflowNetwork:MultiZone:WindPressureCoefficientValues", TotalArgs, NumAlphas, NumNumbers);
1718 127 : MaxNums = max(MaxNums, NumNumbers);
1719 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1720 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1721 : m_state, "AirflowNetwork:Distribution:Node", TotalArgs, NumAlphas, NumNumbers);
1722 127 : MaxNums = max(MaxNums, NumNumbers);
1723 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1724 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1725 : m_state, "AirflowNetwork:Distribution:DuctViewFactors", TotalArgs, NumAlphas, NumNumbers);
1726 127 : MaxNums = max(MaxNums, NumNumbers);
1727 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1728 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1729 : m_state, "AirflowNetwork:Distribution:Linkage", TotalArgs, NumAlphas, NumNumbers);
1730 127 : MaxNums = max(MaxNums, NumNumbers);
1731 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1732 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1733 : m_state, "AirflowNetwork:OccupantVentilationControl", TotalArgs, NumAlphas, NumNumbers);
1734 127 : MaxNums = max(MaxNums, NumNumbers);
1735 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1736 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(m_state, "AirflowNetwork:IntraZone:Node", TotalArgs, NumAlphas, NumNumbers);
1737 127 : MaxNums = max(MaxNums, NumNumbers);
1738 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1739 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1740 : m_state, "AirflowNetwork:IntraZone:Linkage", TotalArgs, NumAlphas, NumNumbers);
1741 127 : MaxNums = max(MaxNums, NumNumbers);
1742 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1743 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1744 : m_state, "AirflowNetwork:ZoneControl:PressureController", TotalArgs, NumAlphas, NumNumbers);
1745 127 : MaxNums = max(MaxNums, NumNumbers);
1746 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1747 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1748 : m_state, "AirflowNetwork:Distribution:DuctSizing", TotalArgs, NumAlphas, NumNumbers);
1749 127 : MaxNums = max(MaxNums, NumNumbers);
1750 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1751 :
1752 127 : Alphas.allocate(MaxAlphas);
1753 127 : cAlphaFields.allocate(MaxAlphas);
1754 127 : cNumericFields.allocate(MaxNums);
1755 127 : Numbers.dimension(MaxNums, 0.0);
1756 127 : lAlphaBlanks.dimension(MaxAlphas, true);
1757 127 : lNumericBlanks.dimension(MaxNums, true);
1758 :
1759 127 : bool ErrorsFound = false;
1760 :
1761 127 : auto &Zone(m_state.dataHeatBal->Zone);
1762 :
1763 : // Read AirflowNetwork OccupantVentilationControl before reading other AirflowNetwork objects, so that this object can be called by other
1764 : // simple ventilation objects
1765 127 : CurrentModuleObject = "AirflowNetwork:OccupantVentilationControl";
1766 127 : AirflowNetworkNumOfOccuVentCtrls = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1767 127 : if (AirflowNetworkNumOfOccuVentCtrls > 0) {
1768 0 : OccupantVentilationControl.allocate(AirflowNetworkNumOfOccuVentCtrls);
1769 0 : for (int i = 1; i <= AirflowNetworkNumOfOccuVentCtrls; ++i) {
1770 0 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
1771 : CurrentModuleObject,
1772 : i,
1773 : Alphas,
1774 : NumAlphas,
1775 : Numbers,
1776 : NumNumbers,
1777 : IOStatus,
1778 : lNumericBlanks,
1779 : lAlphaBlanks,
1780 : cAlphaFields,
1781 : cNumericFields);
1782 0 : OccupantVentilationControl(i).Name = Alphas(1); // Name of object
1783 0 : OccupantVentilationControl(i).MinOpeningTime = Numbers(1);
1784 0 : if (OccupantVentilationControl(i).MinOpeningTime < 0.0) {
1785 : // Code will never be executed, validation will catch invalid input
1786 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(1) + " < 0.0");
1787 0 : ShowContinueError(m_state,
1788 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", OccupantVentilationControl(i).MinOpeningTime));
1789 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1790 0 : OccupantVentilationControl(i).MinOpeningTime = 0.0;
1791 : }
1792 0 : OccupantVentilationControl(i).MinClosingTime = Numbers(2);
1793 0 : if (OccupantVentilationControl(i).MinClosingTime < 0.0) {
1794 : // Code will never be executed, validation will catch invalid input
1795 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " < 0.0");
1796 0 : ShowContinueError(m_state,
1797 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", OccupantVentilationControl(i).MinClosingTime));
1798 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1799 0 : OccupantVentilationControl(i).MinClosingTime = 0.0;
1800 : }
1801 0 : if (NumAlphas == 1 && NumNumbers == 2) {
1802 0 : OccupantVentilationControl(i).MinTimeControlOnly = true;
1803 : }
1804 0 : if (!lAlphaBlanks(2)) {
1805 0 : OccupantVentilationControl(i).ComfortLowTempCurveName = Alphas(2);
1806 0 : OccupantVentilationControl(i).ComfortLowTempCurveNum = GetCurveIndex(m_state, Alphas(2)); // convert curve name to number
1807 0 : if (OccupantVentilationControl(i).ComfortLowTempCurveNum == 0) {
1808 0 : OccupantVentilationControl(i).MinTimeControlOnly = true;
1809 0 : ShowWarningError(m_state,
1810 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(2) +
1811 0 : " not found = " + OccupantVentilationControl(i).ComfortLowTempCurveName);
1812 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1813 0 : ShowContinueError(
1814 : m_state,
1815 : "Thermal comfort will not be performed and minimum opening and closing times are checked only. Simulation continues.");
1816 : } else {
1817 0 : ErrorsFound |= Curve::CheckCurveDims(m_state,
1818 0 : OccupantVentilationControl(i).ComfortLowTempCurveNum, // Curve index
1819 : {1}, // Valid dimensions
1820 : RoutineName, // Routine name
1821 : CurrentModuleObject, // Object Type
1822 0 : OccupantVentilationControl(i).Name, // Object Name
1823 0 : cAlphaFields(2)); // Field Name
1824 : }
1825 : }
1826 0 : if (!lAlphaBlanks(3)) {
1827 0 : OccupantVentilationControl(i).ComfortHighTempCurveName = Alphas(3);
1828 0 : OccupantVentilationControl(i).ComfortHighTempCurveNum = GetCurveIndex(m_state, Alphas(3)); // convert curve name to number
1829 0 : if (OccupantVentilationControl(i).ComfortHighTempCurveNum > 0) {
1830 0 : ErrorsFound |= Curve::CheckCurveDims(m_state,
1831 0 : OccupantVentilationControl(i).ComfortHighTempCurveNum, // Curve index
1832 : {1}, // Valid dimensions
1833 : RoutineName, // Routine name
1834 : CurrentModuleObject, // Object Type
1835 0 : OccupantVentilationControl(i).Name, // Object Name
1836 0 : cAlphaFields(3)); // Field Name
1837 : } else {
1838 0 : ShowWarningError(m_state,
1839 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) +
1840 0 : " not found = " + OccupantVentilationControl(i).ComfortHighTempCurveName);
1841 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1842 0 : ShowContinueError(m_state, "A single curve of thermal comfort low temperature is used only. Simulation continues.");
1843 : }
1844 : }
1845 0 : if (OccupantVentilationControl(i).ComfortHighTempCurveNum > 0) {
1846 0 : OccupantVentilationControl(i).ComfortBouPoint = Numbers(3);
1847 0 : if (OccupantVentilationControl(i).ComfortBouPoint < 0.0) {
1848 : // Code will never be executed, validation will catch invalid input
1849 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(3) + " < 0.0");
1850 0 : ShowContinueError(
1851 : m_state,
1852 0 : format("..Input value = {:.1R}, Value will be reset to 10.0 as default", OccupantVentilationControl(i).ComfortBouPoint));
1853 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1854 0 : OccupantVentilationControl(i).ComfortBouPoint = 10.0;
1855 : }
1856 : }
1857 : // Check continuity of both curves at boundary point
1858 0 : if (OccupantVentilationControl(i).ComfortLowTempCurveNum > 0 && OccupantVentilationControl(i).ComfortHighTempCurveNum) {
1859 0 : if (std::abs(CurveValue(m_state, OccupantVentilationControl(i).ComfortLowTempCurveNum, Numbers(3)) -
1860 0 : CurveValue(m_state, OccupantVentilationControl(i).ComfortHighTempCurveNum, Numbers(3))) > 0.1) {
1861 0 : ShowSevereError(m_state,
1862 0 : format(RoutineName) + CurrentModuleObject +
1863 : " object: The difference of both curve values at boundary point > 0.1");
1864 0 : ShowContinueError(m_state, "Both curve names are = " + cAlphaFields(2) + " and " + cAlphaFields(3));
1865 0 : ShowContinueError(m_state,
1866 0 : format("The input value of {} = {:.1R}", cNumericFields(3), OccupantVentilationControl(i).ComfortBouPoint));
1867 0 : ErrorsFound = true;
1868 : }
1869 : }
1870 0 : if (!lNumericBlanks(4)) {
1871 0 : OccupantVentilationControl(i).MaxPPD = Numbers(4);
1872 0 : if (OccupantVentilationControl(i).MaxPPD < 0.0 || OccupantVentilationControl(i).MaxPPD > 100.0) {
1873 : // Code will never be executed, validation will catch invalid input
1874 0 : ShowWarningError(m_state,
1875 0 : format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " beyond 0.0 and 100.0");
1876 0 : ShowContinueError(
1877 0 : m_state, format("..Input value = {:.1R}, Value will be reset to 10.0 as default", OccupantVentilationControl(i).MaxPPD));
1878 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1879 0 : OccupantVentilationControl(i).MaxPPD = 10.0;
1880 : }
1881 : }
1882 0 : if (!lAlphaBlanks(4)) {
1883 0 : if (Util::SameString(Alphas(4), "Yes")) {
1884 0 : OccupantVentilationControl(i).OccupancyCheck = true;
1885 0 : } else if (Util::SameString(Alphas(4), "No")) {
1886 0 : OccupantVentilationControl(i).OccupancyCheck = false;
1887 : } else {
1888 : // Code will never be executed, validation will catch invalid input
1889 0 : ShowSevereError(m_state,
1890 0 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" invalid " + cAlphaFields(2) + "=\"" +
1891 0 : Alphas(2) + "\" illegal key.");
1892 0 : ShowContinueError(m_state, "Valid keys are: Yes or No");
1893 0 : ErrorsFound = true;
1894 : }
1895 : }
1896 0 : if (!lAlphaBlanks(5)) {
1897 0 : OccupantVentilationControl(i).OpeningProbSchName = Alphas(5); // a schedule name for opening probability
1898 0 : OccupantVentilationControl(i).openingProbSched = Sched::GetSchedule(m_state, OccupantVentilationControl(i).OpeningProbSchName);
1899 0 : if (OccupantVentilationControl(i).openingProbSched == nullptr) {
1900 0 : ShowSevereError(m_state,
1901 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(5) +
1902 0 : " not found = " + OccupantVentilationControl(i).OpeningProbSchName);
1903 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1904 0 : ErrorsFound = true;
1905 : }
1906 : }
1907 0 : if (!lAlphaBlanks(6)) {
1908 0 : OccupantVentilationControl(i).ClosingProbSchName = Alphas(6); // a schedule name for closing probability
1909 0 : OccupantVentilationControl(i).closingProbSched = Sched::GetSchedule(m_state, OccupantVentilationControl(i).ClosingProbSchName);
1910 0 : if (OccupantVentilationControl(i).closingProbSched == nullptr) {
1911 0 : ShowSevereError(m_state,
1912 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) +
1913 0 : " not found = " + OccupantVentilationControl(i).ClosingProbSchName);
1914 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1915 0 : ErrorsFound = true;
1916 : }
1917 : }
1918 : }
1919 : }
1920 :
1921 127 : if (ErrorsFound) {
1922 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
1923 : }
1924 :
1925 : // *** Read AirflowNetwork simulation parameters
1926 127 : CurrentModuleObject = "AirflowNetwork:SimulationControl";
1927 127 : NumAirflowNetwork = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1928 127 : if (NumAirflowNetwork == 0) {
1929 104 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:Zone") >= 1 &&
1930 104 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:Surface") >= 2) {
1931 1 : control_defaulted = true;
1932 1 : simulation_control.name = "AFNDefaultControl";
1933 1 : simulation_control.type = ControlType::MultizoneWithoutDistribution;
1934 1 : simulation_control.WPCCntr = "SURFACEAVERAGECALCULATION";
1935 1 : simulation_control.HeightOption = "OPENINGHEIGHT";
1936 1 : simulation_control.BldgType = "LOWRISE";
1937 1 : simulation_control.InitType = "ZERONODEPRESSURES";
1938 1 : simulation_control.temperature_height_dependence = false;
1939 1 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
1940 : // Use default values for numerical fields
1941 1 : simulation_control.maximum_iterations = 500;
1942 1 : simulation_control.relative_convergence_tolerance = 1.E-4;
1943 1 : simulation_control.absolute_convergence_tolerance = 1.E-6;
1944 1 : simulation_control.convergence_acceleration_limit = -0.5;
1945 1 : simulation_control.azimuth = 0.0;
1946 1 : simulation_control.aspect_ratio = 1.0;
1947 1 : simulation_control.MaxPressure = 500.0; // Maximum pressure difference by default
1948 1 : SimAirNetworkKey = "MultizoneWithoutDistribution";
1949 1 : simulation_control.InitFlag = 1;
1950 1 : ShowWarningError(m_state, format("{}{} object is not found ", RoutineName, CurrentModuleObject));
1951 3 : ShowContinueError(m_state, "..The default behaviour values are assigned. Please see details in Input Output Reference.");
1952 : } else {
1953 102 : simulation_control.type = ControlType::NoMultizoneOrDistribution;
1954 102 : print(m_state.files.eio, Format_110);
1955 102 : print(m_state.files.eio, Format_120, "NoMultizoneOrDistribution");
1956 102 : return;
1957 : }
1958 : }
1959 25 : if (NumAirflowNetwork > 1) {
1960 0 : ShowFatalError(m_state, format("{}Only one (\"1\") {} object per simulation is allowed.", RoutineName, CurrentModuleObject));
1961 : }
1962 :
1963 25 : if (!control_defaulted) {
1964 24 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
1965 : CurrentModuleObject,
1966 : NumAirflowNetwork,
1967 : Alphas,
1968 : NumAlphas,
1969 : Numbers,
1970 : NumNumbers,
1971 : IOStatus,
1972 : lNumericBlanks,
1973 : lAlphaBlanks,
1974 : cAlphaFields,
1975 : cNumericFields);
1976 :
1977 24 : simulation_control.name = Alphas(1);
1978 24 : simulation_control.WPCCntr = Alphas(3);
1979 24 : simulation_control.HeightOption = Alphas(4);
1980 24 : simulation_control.BldgType = Alphas(5);
1981 :
1982 : // Retrieve flag allowing the support of zone equipment
1983 24 : simulation_control.allow_unsupported_zone_equipment = false;
1984 24 : if (Util::SameString(Alphas(9), "Yes")) {
1985 1 : simulation_control.allow_unsupported_zone_equipment = true;
1986 : }
1987 :
1988 : // Find a flag for possible combination of vent and distribution system
1989 : // This SELECT_CASE_var will go on input refactor, no need to fix
1990 : {
1991 24 : auto const SELECT_CASE_var(Util::makeUPPER(Alphas(2)));
1992 24 : if (SELECT_CASE_var == "NOMULTIZONEORDISTRIBUTION") {
1993 0 : simulation_control.type = ControlType::NoMultizoneOrDistribution;
1994 0 : SimAirNetworkKey = "NoMultizoneOrDistribution";
1995 24 : } else if (SELECT_CASE_var == "MULTIZONEWITHOUTDISTRIBUTION") {
1996 17 : simulation_control.type = ControlType::MultizoneWithoutDistribution;
1997 17 : SimAirNetworkKey = "MultizoneWithoutDistribution";
1998 7 : } else if (SELECT_CASE_var == "MULTIZONEWITHDISTRIBUTIONONLYDURINGFANOPERATION") {
1999 0 : simulation_control.type = ControlType::MultizoneWithDistributionOnlyDuringFanOperation;
2000 0 : SimAirNetworkKey = "MultizoneWithDistributionOnlyDuringFanOperation";
2001 : } else { // if (SELECT_CASE_var == "MULTIZONEWITHDISTRIBUTION") {
2002 7 : simulation_control.type = ControlType::MultizoneWithDistribution;
2003 7 : SimAirNetworkKey = "MultizoneWithDistribution";
2004 : }
2005 24 : }
2006 : }
2007 :
2008 : // Determine a convenience boolean or two to simplify the checking
2009 : // The first one is true if distribution is simulated, replaces some > and >= comparisons
2010 : // SimulateAirflowNetwork > AirflowNetworkControlMultizone -> type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation
2011 : // type == ControlType::MultizoneWithDistribution
2012 : // SimulateAirflowNetwork >= AirflowNetworkControlSimpleADS -> type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation
2013 : // type == ControlType::MultizoneWithDistribution
2014 50 : distribution_simulated = simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation ||
2015 25 : simulation_control.type == ControlType::MultizoneWithDistribution;
2016 : // This one is true if the multizone simulation is ALWAYS done
2017 25 : multizone_always_simulated =
2018 25 : simulation_control.type == ControlType::MultizoneWithDistribution || simulation_control.type == ControlType::MultizoneWithoutDistribution;
2019 :
2020 : // Check the number of primary air loops
2021 25 : if (distribution_simulated) {
2022 7 : NumAPL = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC");
2023 7 : if (NumAPL > 0) {
2024 7 : LoopPartLoadRatio.allocate(NumAPL);
2025 7 : LoopOnOffFanRunTimeFraction.allocate(NumAPL);
2026 7 : LoopOnOffFlag.allocate(NumAPL);
2027 7 : LoopPartLoadRatio = 0.0;
2028 7 : LoopOnOffFanRunTimeFraction = 0.0;
2029 7 : LoopOnOffFlag = false;
2030 : }
2031 : }
2032 25 : print(m_state.files.eio, Format_110);
2033 25 : print(m_state.files.eio, Format_120, SimAirNetworkKey);
2034 :
2035 25 : if (control_defaulted) {
2036 1 : cAlphaFields(2) = "AirflowNetwork Control";
2037 : }
2038 :
2039 : // Check whether there are any objects from infiltration, ventilation, mixing and cross mixing
2040 25 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution ||
2041 25 : simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation) {
2042 0 : if (m_state.dataHeatBal->TotInfiltration + m_state.dataHeatBal->TotVentilation + m_state.dataHeatBal->TotMixing +
2043 0 : m_state.dataHeatBal->TotCrossMixing + m_state.dataHeatBal->TotZoneAirBalance +
2044 0 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneEarthtube") +
2045 0 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneThermalChimney") +
2046 0 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneCoolTower:Shower") ==
2047 : 0) {
2048 0 : ShowWarningError(m_state, format("{}{} = \"{}\"", RoutineName, cAlphaFields(2), SimAirNetworkKey));
2049 0 : ShowContinueError(
2050 : m_state,
2051 : "..but there are no Infiltration, Ventilation, Mixing, Cross Mixing or ZoneAirBalance objects. The simulation continues...");
2052 : }
2053 : }
2054 :
2055 : // Check whether a user wants to perform SIMPLE calculation only or not
2056 25 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) {
2057 0 : return;
2058 : }
2059 :
2060 25 : if (multizone_always_simulated) {
2061 25 : if (m_state.dataHeatBal->TotInfiltration > 0) {
2062 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2063 0 : ShowContinueError(m_state,
2064 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneInfiltration:* objects are present.");
2065 0 : ShowContinueError(m_state, "..ZoneInfiltration objects will not be simulated.");
2066 : }
2067 25 : if (m_state.dataHeatBal->TotVentilation > 0) {
2068 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2069 0 : ShowContinueError(m_state,
2070 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneVentilation:* objects are present.");
2071 0 : ShowContinueError(m_state, "..ZoneVentilation objects will not be simulated.");
2072 : }
2073 25 : if (m_state.dataHeatBal->TotMixing > 0) {
2074 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2075 0 : ShowContinueError(m_state, "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneMixing objects are present.");
2076 0 : ShowContinueError(m_state, "..ZoneMixing objects will not be simulated.");
2077 : }
2078 25 : if (m_state.dataHeatBal->TotCrossMixing > 0) {
2079 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2080 0 : ShowContinueError(m_state,
2081 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneCrossMixing objects are present.");
2082 0 : ShowContinueError(m_state, "..ZoneCrossMixing objects will not be simulated.");
2083 : }
2084 25 : if (m_state.dataHeatBal->TotZoneAirBalance > 0) {
2085 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2086 0 : ShowContinueError(
2087 0 : m_state, "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneAirBalance:OutdoorAir objects are present.");
2088 0 : ShowContinueError(m_state, "..ZoneAirBalance:OutdoorAir objects will not be simulated.");
2089 : }
2090 25 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneEarthtube") > 0) {
2091 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2092 0 : ShowContinueError(m_state,
2093 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneEarthtube objects are present.");
2094 0 : ShowContinueError(m_state, "..ZoneEarthtube objects will not be simulated.");
2095 : }
2096 25 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneThermalChimney") > 0) {
2097 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2098 0 : ShowContinueError(m_state,
2099 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneThermalChimney objects are present.");
2100 0 : ShowContinueError(m_state, "..ZoneThermalChimney objects will not be simulated.");
2101 : }
2102 25 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneCoolTower:Shower") > 0) {
2103 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2104 0 : ShowContinueError(m_state,
2105 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneCoolTower:Shower objects are present.");
2106 0 : ShowContinueError(m_state, "..ZoneCoolTower:Shower objects will not be simulated.");
2107 : }
2108 : }
2109 :
2110 25 : SetOutAirNodes(m_state);
2111 25 : if (!control_defaulted) {
2112 24 : bool SimObjectError = false;
2113 24 : if (Util::SameString(simulation_control.WPCCntr, "Input")) {
2114 10 : simulation_control.iWPCCnt = iWPCCntr::Input;
2115 10 : if (lAlphaBlanks(4)) {
2116 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) + " = INPUT.");
2117 0 : ShowContinueError(m_state, ".." + cAlphaFields(4) + " was not entered.");
2118 0 : ErrorsFound = true;
2119 0 : SimObjectError = true;
2120 : } else {
2121 10 : if (!(Util::SameString(simulation_control.HeightOption, "ExternalNode") ||
2122 10 : Util::SameString(simulation_control.HeightOption, "OpeningHeight"))) {
2123 0 : ShowSevereError(
2124 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(4) + " = " + Alphas(4) + " is invalid.");
2125 0 : ShowContinueError(m_state,
2126 0 : "Valid choices are ExternalNode or OpeningHeight. " + CurrentModuleObject + ": " + cAlphaFields(1) + " = " +
2127 0 : simulation_control.name);
2128 0 : ErrorsFound = true;
2129 0 : SimObjectError = true;
2130 : }
2131 : }
2132 14 : } else if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
2133 14 : simulation_control.iWPCCnt = iWPCCntr::SurfAvg;
2134 14 : if (!(Util::SameString(simulation_control.BldgType, "LowRise") || Util::SameString(simulation_control.BldgType, "HighRise"))) {
2135 0 : ShowSevereError(m_state,
2136 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(5) + " = " + Alphas(5) + " is invalid.");
2137 0 : ShowContinueError(m_state,
2138 0 : "Valid choices are LowRise or HighRise. " + CurrentModuleObject + ": " + cAlphaFields(1) + " = " +
2139 0 : simulation_control.name);
2140 0 : ErrorsFound = true;
2141 0 : SimObjectError = true;
2142 : }
2143 38 : for (k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
2144 24 : if (Node(k).IsLocalNode) {
2145 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(3) + "=" + Alphas(3));
2146 0 : ShowContinueError(m_state,
2147 : "A local air node is defined to INPUT the wind pressure coefficient curve, while Wind Pressure Coefficient "
2148 : "Type is set to SurfaceAverageCalculation.");
2149 0 : ShowContinueError(m_state, "It requires the Wind Pressure Coefficient Type be set to INPUT to use the local air node.");
2150 0 : ErrorsFound = true;
2151 0 : SimObjectError = true;
2152 0 : break;
2153 : }
2154 : }
2155 : } else {
2156 0 : ShowSevereError(m_state,
2157 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) + " = " + simulation_control.WPCCntr +
2158 : " is not valid.");
2159 0 : ShowContinueError(m_state,
2160 0 : "Valid choices are Input or SurfaceAverageCalculation. " + CurrentModuleObject + " = " + simulation_control.name);
2161 0 : ErrorsFound = true;
2162 0 : SimObjectError = true;
2163 : }
2164 :
2165 24 : simulation_control.InitType = Alphas(6);
2166 24 : if (Util::SameString(simulation_control.InitType, "LinearInitializationMethod")) {
2167 5 : simulation_control.InitFlag = 0;
2168 19 : } else if (Util::SameString(simulation_control.InitType, "ZeroNodePressures")) {
2169 19 : simulation_control.InitFlag = 1;
2170 0 : } else if (Util::SameString(simulation_control.InitType, "0")) {
2171 0 : simulation_control.InitFlag = 0;
2172 0 : } else if (Util::SameString(simulation_control.InitType, "1")) {
2173 0 : simulation_control.InitFlag = 1;
2174 : } else {
2175 : // Code will never be executed, validation will catch invalid input
2176 0 : ShowSevereError(m_state,
2177 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) + " = " + Alphas(6) + " is invalid.");
2178 0 : ShowContinueError(m_state,
2179 0 : "Valid choices are LinearInitializationMethod or ZeroNodePressures. " + CurrentModuleObject + " = " +
2180 0 : simulation_control.name);
2181 0 : ErrorsFound = true;
2182 0 : SimObjectError = true;
2183 : }
2184 :
2185 24 : if (!lAlphaBlanks(7) && Util::SameString(Alphas(7), "Yes")) {
2186 0 : simulation_control.temperature_height_dependence = true;
2187 : }
2188 :
2189 24 : if (lAlphaBlanks(8)) {
2190 23 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2191 1 : } else if (Util::SameString(Alphas(8), "SkylineLU")) {
2192 1 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2193 0 : } else if (Util::SameString(Alphas(8), "ConjugateGradient")) {
2194 0 : simulation_control.solver = SimulationControl::Solver::ConjugateGradient;
2195 : } else {
2196 0 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2197 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2198 0 : ShowContinueError(m_state, "..Specified " + cAlphaFields(8) + " = \"" + Alphas(8) + "\" is unrecognized.");
2199 0 : ShowContinueError(m_state, "..Default value \"SkylineLU\" will be used.");
2200 : }
2201 :
2202 : // Get inputs for duct sizing
2203 24 : simulation_control.autosize_ducts = false;
2204 24 : if (NumAlphas == 10) {
2205 24 : if (Util::SameString(Alphas(10), "YES")) {
2206 0 : simulation_control.autosize_ducts = true;
2207 0 : if (simulation_control.type == ControlType::MultizoneWithDistribution) {
2208 0 : if (NumAPL > 1) {
2209 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2210 0 : ShowContinueError(
2211 : m_state,
2212 0 : format("The number of AirLoopHAVC is greater than 1. The current requirement for Duct Sizing requires a "
2213 : "single AirLoopHVAC."));
2214 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2215 0 : simulation_control.autosize_ducts = false;
2216 : }
2217 : }
2218 : }
2219 : }
2220 :
2221 24 : if (SimObjectError) {
2222 0 : ShowFatalError(
2223 : m_state,
2224 0 : format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
2225 : }
2226 :
2227 24 : simulation_control.maximum_iterations = static_cast<int>(Numbers(1));
2228 24 : simulation_control.relative_convergence_tolerance = Numbers(2);
2229 24 : simulation_control.absolute_convergence_tolerance = Numbers(3);
2230 24 : simulation_control.convergence_acceleration_limit = Numbers(4);
2231 24 : simulation_control.azimuth = Numbers(5);
2232 24 : simulation_control.aspect_ratio = Numbers(6);
2233 24 : simulation_control.MaxPressure = 500.0; // Maximum pressure difference by default
2234 : }
2235 :
2236 25 : CurrentModuleObject = "AirflowNetwork:Distribution:DuctSizing";
2237 25 : int NumDuctSizing = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2238 25 : if (NumDuctSizing > 1) {
2239 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2240 0 : ShowContinueError(
2241 : m_state,
2242 0 : format("The number of AirflowNetwork:Distribution:DuctSizing is greater than 1. The current requirement for Duct Sizing requires a "
2243 : "single object."));
2244 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2245 0 : simulation_control.autosize_ducts = false;
2246 25 : } else if (simulation_control.autosize_ducts && NumDuctSizing == 0) {
2247 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2248 0 : ShowContinueError(
2249 : m_state,
2250 0 : format("The number of AirflowNetwork:Distribution:DuctSizing is not avalable. The current requirement for Duct Sizing requires a "
2251 : "single object."));
2252 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2253 0 : simulation_control.autosize_ducts = false;
2254 : }
2255 25 : if (simulation_control.autosize_ducts && NumDuctSizing == 1) {
2256 0 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2257 : CurrentModuleObject,
2258 : NumDuctSizing,
2259 : Alphas,
2260 : NumAlphas,
2261 : Numbers,
2262 : NumNumbers,
2263 : IOStatus,
2264 : lNumericBlanks,
2265 : lAlphaBlanks,
2266 : cAlphaFields,
2267 : cNumericFields);
2268 :
2269 0 : simulation_control.ductSizing.name = Alphas(1);
2270 0 : if (Util::SameString(Alphas(2), Util::makeUPPER("MaximumVelocity"))) {
2271 0 : simulation_control.ductSizing.method = DuctSizingMethod::MaxVelocity;
2272 0 : } else if (Util::SameString(Alphas(2), Util::makeUPPER("PressureLoss"))) {
2273 0 : simulation_control.ductSizing.method = DuctSizingMethod::PressureLoss;
2274 0 : } else if (Util::SameString(Alphas(2), Util::makeUPPER("PressureLossWithMaximumVelocity"))) {
2275 0 : simulation_control.ductSizing.method = DuctSizingMethod::VelocityAndLoss;
2276 : } else {
2277 0 : ShowSevereError(m_state, format("{} {} object, {} = {} is invalid.", RoutineName, CurrentModuleObject, cAlphaFields(2), Alphas(2)));
2278 0 : ShowContinueError(m_state,
2279 0 : format("Valid choices are MaximumVelocity, PressureLoss, and PressureLossWithMaximumVelocity. {}: {} = {}",
2280 : CurrentModuleObject,
2281 : cAlphaFields(1),
2282 : Alphas(1)));
2283 0 : ErrorsFound = true;
2284 : }
2285 0 : if (simulation_control.type != ControlType::MultizoneWithDistribution) {
2286 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2287 0 : ShowContinueError(m_state,
2288 0 : format("Although {} = \"{}\" is entered, but {} is not MultizoneWithoutDistribution.",
2289 : cAlphaFields(10),
2290 : Alphas(10),
2291 : cAlphaFields(2)));
2292 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2293 0 : simulation_control.autosize_ducts = false;
2294 : }
2295 0 : simulation_control.ductSizing.factor = Numbers(1);
2296 0 : simulation_control.ductSizing.max_velocity = Numbers(2);
2297 0 : simulation_control.ductSizing.supply_trunk_pressure_loss = Numbers(3);
2298 0 : simulation_control.ductSizing.supply_branch_pressure_loss = Numbers(4);
2299 0 : simulation_control.ductSizing.return_trunk_pressure_loss = Numbers(5);
2300 0 : simulation_control.ductSizing.return_branch_pressure_loss = Numbers(6);
2301 : }
2302 :
2303 : // *** Read AirflowNetwork simulation zone data
2304 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Zone";
2305 25 : AirflowNetworkNumOfZones = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2306 25 : if (AirflowNetworkNumOfZones > 0) {
2307 25 : MultizoneZoneData.allocate(AirflowNetworkNumOfZones);
2308 25 : AirflowNetworkZoneFlag.dimension(m_state.dataGlobal->NumOfZones, false); // AirflowNetwork zone flag
2309 77 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
2310 52 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2311 : CurrentModuleObject,
2312 : i,
2313 : Alphas,
2314 : NumAlphas,
2315 : Numbers,
2316 : NumNumbers,
2317 : IOStatus,
2318 : lNumericBlanks,
2319 : lAlphaBlanks,
2320 : cAlphaFields,
2321 : cNumericFields);
2322 :
2323 52 : ErrorObjectHeader eoh{RoutineName, CurrentModuleObject, Alphas(1)};
2324 :
2325 52 : MultizoneZoneData(i).ZoneName = Alphas(1); // Name of Associated EnergyPlus Thermal Zone
2326 52 : if (!lAlphaBlanks(2)) {
2327 52 : MultizoneZoneData(i).VentControl = Alphas(2); // Ventilation Control Mode: "Temperature", "Enthalpy",
2328 : }
2329 : // "ASHRAE55ADAPTIVE", "CEN15251AdaptiveComfort,
2330 : // "Constant", or "NoVent"
2331 52 : MultizoneZoneData(i).VentTempControlSchName = Alphas(3); // Name of ventilation temperature control schedule
2332 52 : MultizoneZoneData(i).OpenFactor = Numbers(1); // Limit Value on Multiplier for Modulating Venting Open Factor,
2333 : // Not applicable if Vent Control Mode = CONSTANT or NOVENT
2334 52 : MultizoneZoneData(i).LowValueTemp = Numbers(2); // Lower Value on Inside/Outside Temperature Difference
2335 : // for Modulating the Venting Open Factor with temp control
2336 52 : MultizoneZoneData(i).UpValueTemp = Numbers(3); // Upper Value on Inside/Outside Temperature Difference
2337 : // for Modulating the Venting Open Factor with temp control
2338 52 : MultizoneZoneData(i).LowValueEnth = Numbers(4); // Lower Value on Inside/Outside Temperature Difference
2339 : // for Modulating the Venting Open Factor with Enthalpy control
2340 52 : MultizoneZoneData(i).UpValueEnth = Numbers(5); // Upper Value on Inside/Outside Temperature Difference
2341 : // for Modulating the Venting Open Factor with Enthalpy control
2342 52 : MultizoneZoneData(i).VentCtrNum = VentControlType::None;
2343 52 : MultizoneZoneData(i).SingleSidedCpType = Alphas(5);
2344 52 : MultizoneZoneData(i).BuildWidth = Numbers(6);
2345 :
2346 52 : if (!lAlphaBlanks(6)) {
2347 0 : MultizoneZoneData(i).OccupantVentilationControlName = Alphas(6);
2348 0 : MultizoneZoneData(i).OccupantVentilationControlNum =
2349 0 : Util::FindItemInList(MultizoneZoneData(i).OccupantVentilationControlName, OccupantVentilationControl);
2350 0 : if (MultizoneZoneData(i).OccupantVentilationControlNum == 0) {
2351 0 : ShowSevereError(m_state,
2352 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) +
2353 0 : " not found = " + MultizoneZoneData(i).OccupantVentilationControlName);
2354 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
2355 0 : ErrorsFound = true;
2356 : }
2357 : }
2358 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Temperature")) {
2359 13 : MultizoneZoneData(i).VentCtrNum = VentControlType::Temp;
2360 : }
2361 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Enthalpy")) {
2362 0 : MultizoneZoneData(i).VentCtrNum = VentControlType::Enth;
2363 : }
2364 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Constant")) {
2365 4 : MultizoneZoneData(i).VentCtrNum = VentControlType::Const;
2366 : }
2367 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "ASHRAE55Adaptive")) {
2368 0 : MultizoneZoneData(i).VentCtrNum = VentControlType::ASH55;
2369 : }
2370 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "CEN15251Adaptive")) {
2371 3 : MultizoneZoneData(i).VentCtrNum = VentControlType::CEN15251;
2372 : }
2373 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "NoVent")) {
2374 32 : MultizoneZoneData(i).VentCtrNum = VentControlType::NoVent;
2375 : }
2376 :
2377 52 : if (MultizoneZoneData(i).VentCtrNum < NumOfVentCtrTypes) {
2378 20 : if (NumAlphas >= 4 && (!lAlphaBlanks(4))) {
2379 15 : MultizoneZoneData(i).VentAvailSchName = Alphas(4);
2380 15 : if ((MultizoneZoneData(i).ventAvailSched = Sched::GetSchedule(m_state, MultizoneZoneData(i).VentAvailSchName)) == nullptr) {
2381 0 : ShowSevereItemNotFound(m_state, eoh, cAlphaFields(4), Alphas(4));
2382 0 : ErrorsFound = true;
2383 : }
2384 : }
2385 : } else {
2386 32 : MultizoneZoneData(i).VentAvailSchName = std::string();
2387 32 : MultizoneZoneData(i).ventAvailSched = Sched::GetScheduleAlwaysOn(m_state);
2388 : }
2389 : }
2390 : } else {
2391 0 : ShowSevereError(m_state,
2392 0 : format(RoutineName) + "For an AirflowNetwork Simulation, at least one " + CurrentModuleObject +
2393 : " object is required but none were found.");
2394 0 : ShowFatalError(
2395 0 : m_state, format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
2396 : }
2397 :
2398 : // ==> Zone data validation
2399 77 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
2400 : // Zone name validation
2401 52 : ErrorObjectHeader eoh{RoutineName, CurrentModuleObject, MultizoneZoneData(i).ZoneName};
2402 :
2403 52 : MultizoneZoneData(i).ZoneNum = Util::FindItemInList(MultizoneZoneData(i).ZoneName, Zone);
2404 52 : if (MultizoneZoneData(i).ZoneNum == 0) {
2405 0 : ShowSevereItemNotFound(m_state, eoh, "Zone Name", MultizoneZoneData(i).ZoneName);
2406 0 : ErrorsFound = true;
2407 : } else {
2408 52 : AirflowNetworkZoneFlag(MultizoneZoneData(i).ZoneNum) = true;
2409 52 : MultizoneZoneData(i).Height = Zone(MultizoneZoneData(i).ZoneNum).Centroid.z; // Nodal height
2410 : }
2411 52 : if (MultizoneZoneData(i).VentCtrNum == VentControlType::None) {
2412 0 : ShowSevereError(m_state,
2413 0 : format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(2) + " = " +
2414 0 : MultizoneZoneData(i).VentControl);
2415 0 : ShowContinueError(m_state, "Valid choices are Temperature, Enthalpy, Constant, or NoVent");
2416 0 : ShowContinueError(m_state, ".. in " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\"");
2417 0 : ErrorsFound = true;
2418 : }
2419 :
2420 91 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Temperature") ||
2421 91 : Util::SameString(MultizoneZoneData(i).VentControl, "Enthalpy")) { // Already converted this to an enum, why compare strings?
2422 : // .or. &
2423 : // Util::SameString(MultizoneZoneData(i)%VentControl,'ASHRAE55Adaptive') .or. &
2424 : // Util::SameString(MultizoneZoneData(i)%VentControl,'CEN15251Adaptive')) then
2425 13 : if (MultizoneZoneData(i).VentTempControlSchName.empty()) {
2426 0 : ShowSevereEmptyField(m_state, eoh, cAlphaFields(3), cAlphaFields(2), Alphas(2));
2427 0 : ErrorsFound = true;
2428 13 : } else if ((MultizoneZoneData(i).ventTempControlSched = Sched::GetSchedule(m_state, MultizoneZoneData(i).VentTempControlSchName)) ==
2429 : nullptr) {
2430 0 : ShowSevereItemNotFound(m_state, eoh, cAlphaFields(3), Alphas(3));
2431 0 : ErrorsFound = true;
2432 : }
2433 : } else {
2434 39 : MultizoneZoneData(i).ventTempControlSched = nullptr;
2435 39 : if (!MultizoneZoneData(i).VentTempControlSchName.empty()) {
2436 0 : ShowWarningNonEmptyField(m_state, eoh, cAlphaFields(3), cAlphaFields(2), Alphas(2));
2437 0 : MultizoneZoneData(i).VentTempControlSchName = std::string();
2438 : }
2439 : }
2440 52 : if (MultizoneZoneData(i).OpenFactor > 1.0 || MultizoneZoneData(i).OpenFactor < 0.0) {
2441 : // Code will never be executed, validation will catch invalid input
2442 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(1) + " is out of range [0.0,1.0]");
2443 0 : ShowContinueError(m_state, format("..Input value = {:.2R}, Value will be set to 1.0", MultizoneZoneData(i).OpenFactor));
2444 0 : MultizoneZoneData(i).OpenFactor = 1.0;
2445 : }
2446 :
2447 : {
2448 : // These SELECT_CASE_vars will go on input refactor, no need to fix
2449 52 : auto const SELECT_CASE_var(Util::makeUPPER(MultizoneZoneData(i).VentControl));
2450 52 : if (SELECT_CASE_var == "TEMPERATURE") { // checks on Temperature control
2451 13 : if (MultizoneZoneData(i).LowValueTemp < 0.0) {
2452 : // Code will never be executed, validation will catch invalid input
2453 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " < 0.0");
2454 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be set to 0.0", MultizoneZoneData(i).LowValueTemp));
2455 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2456 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
2457 : }
2458 13 : if (MultizoneZoneData(i).LowValueTemp >= 100.0) {
2459 : // Code will never be executed, validation will catch invalid input
2460 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " >= 100.0");
2461 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneZoneData(i).LowValueTemp));
2462 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2463 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
2464 : }
2465 13 : if (MultizoneZoneData(i).UpValueTemp <= MultizoneZoneData(i).LowValueTemp) {
2466 0 : ShowWarningError(m_state,
2467 0 : format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(3) + " <= " + cNumericFields(2));
2468 0 : ShowContinueError(m_state,
2469 0 : format("..Input value for {} = {:.1R}, Value will be reset to 100.0",
2470 : cNumericFields(3),
2471 0 : MultizoneZoneData(i).UpValueTemp));
2472 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2473 0 : MultizoneZoneData(i).UpValueTemp = 100.0;
2474 : }
2475 :
2476 39 : } else if (SELECT_CASE_var == "ENTHALPY") { // checks for Enthalpy control
2477 0 : if (MultizoneZoneData(i).LowValueEnth < 0.0) {
2478 : // Code will never be executed, validation will catch invalid input
2479 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " < 0.0");
2480 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneZoneData(i).LowValueEnth));
2481 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2482 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
2483 : }
2484 0 : if (MultizoneZoneData(i).LowValueEnth >= 300000.0) {
2485 : // Code will never be executed, validation will catch invalid input
2486 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " >= 300000.0");
2487 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0.", MultizoneZoneData(i).LowValueEnth));
2488 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2489 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
2490 : }
2491 0 : if (MultizoneZoneData(i).UpValueEnth <= MultizoneZoneData(i).LowValueEnth) {
2492 0 : ShowWarningError(m_state,
2493 0 : format("{}{} object, {} <= {}", RoutineName, CurrentModuleObject, cNumericFields(5), cNumericFields(4)));
2494 0 : ShowContinueError(m_state,
2495 0 : format("..Input value for {}= {:.1R}, Value will be reset to 300000.0",
2496 : cNumericFields(5),
2497 0 : MultizoneZoneData(i).UpValueEnth));
2498 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2499 0 : MultizoneZoneData(i).UpValueEnth = 300000.0;
2500 : }
2501 39 : } else if (SELECT_CASE_var == "ASHRAE55ADAPTIVE") {
2502 : // Check that for the given zone, there is a people object for which ASHRAE 55 calculations are carried out
2503 0 : int ZoneNum = MultizoneZoneData(i).ZoneNum;
2504 0 : for (int j = 1; j <= m_state.dataHeatBal->TotPeople; ++j) {
2505 0 : if (ZoneNum == m_state.dataHeatBal->People(j).ZonePtr && m_state.dataHeatBal->People(j).AdaptiveASH55) {
2506 0 : MultizoneZoneData(i).ASH55PeopleInd = j;
2507 : }
2508 : }
2509 0 : if (MultizoneZoneData(i).ASH55PeopleInd == 0) {
2510 0 : ShowFatalError(m_state,
2511 0 : "ASHRAE55 ventilation control for zone " + MultizoneZoneData(i).ZoneName +
2512 : " requires a people object with respective model calculations.");
2513 : }
2514 39 : } else if (SELECT_CASE_var == "CEN15251ADAPTIVE") {
2515 : // Check that for the given zone, there is a people object for which CEN-15251 calculations are carried out
2516 3 : int ZoneNum = MultizoneZoneData(i).ZoneNum;
2517 3 : for (int j = 1; j <= m_state.dataHeatBal->TotPeople; ++j) {
2518 3 : if (ZoneNum == m_state.dataHeatBal->People(j).ZonePtr && m_state.dataHeatBal->People(j).AdaptiveCEN15251) {
2519 3 : MultizoneZoneData(i).CEN15251PeopleInd = j;
2520 3 : break;
2521 : }
2522 : }
2523 3 : if (MultizoneZoneData(i).CEN15251PeopleInd == 0) {
2524 0 : ShowFatalError(m_state,
2525 0 : "CEN15251 ventilation control for zone " + MultizoneZoneData(i).ZoneName +
2526 : " requires a people object with respective model calculations.");
2527 : }
2528 : } else {
2529 : }
2530 52 : }
2531 : }
2532 :
2533 : // *** Read AirflowNetwork external node
2534 25 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
2535 : // Wind coefficient == Surface-Average does not need inputs of external nodes
2536 10 : AirflowNetworkNumOfExtNode =
2537 10 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:ExternalNode");
2538 10 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel) {
2539 1 : AirflowNetworkNumOfOutAirNode = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "OutdoorAir:Node");
2540 1 : AirflowNetworkNumOfExtNode += AirflowNetworkNumOfOutAirNode;
2541 : }
2542 :
2543 10 : if (AirflowNetworkNumOfExtNode > 0) {
2544 10 : MultizoneExternalNodeData.allocate(AirflowNetworkNumOfExtNode);
2545 10 : CurrentModuleObject = "AirflowNetwork:MultiZone:ExternalNode";
2546 41 : for (int i = 1; i <= AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode; ++i) {
2547 31 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2548 : CurrentModuleObject,
2549 : i,
2550 : Alphas,
2551 : NumAlphas,
2552 : Numbers,
2553 : NumNumbers,
2554 : IOStatus,
2555 : lNumericBlanks,
2556 : lAlphaBlanks,
2557 : cAlphaFields,
2558 : cNumericFields);
2559 31 : MultizoneExternalNodeData(i).Name = Alphas(1); // Name of external node
2560 31 : MultizoneExternalNodeData(i).height = Numbers(1); // Nodal height
2561 31 : if (Util::SameString(simulation_control.HeightOption, "ExternalNode") && lNumericBlanks(1)) {
2562 0 : ShowWarningError(m_state,
2563 0 : format(RoutineName) + CurrentModuleObject + " object =" + Alphas(1) + ". The input of " + cNumericFields(1) +
2564 : " is required, but a blank is found.");
2565 0 : ShowContinueError(m_state, format("The default value is assigned as {:.1R}", Numbers(1)));
2566 : }
2567 31 : MultizoneExternalNodeData(i).ExtNum = AirflowNetworkNumOfZones + i; // External node number
2568 31 : MultizoneExternalNodeData(i).curve = Curve::GetCurveIndex(m_state, Alphas(2)); // Wind pressure curve
2569 31 : if (MultizoneExternalNodeData(i).curve == 0) {
2570 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(2) + "=" + Alphas(2));
2571 0 : ShowContinueError(m_state, "Entered in " + CurrentModuleObject + '=' + Alphas(1));
2572 0 : ErrorsFound = true;
2573 : }
2574 31 : if (NumAlphas >= 3 && !lAlphaBlanks(3)) { // Symmetric curve
2575 6 : if (Util::SameString(Alphas(3), "Yes")) {
2576 4 : MultizoneExternalNodeData(i).symmetricCurve = true;
2577 2 : } else if (!Util::SameString(Alphas(3), "No")) {
2578 0 : ShowWarningError(
2579 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(3) + " = " + Alphas(3));
2580 0 : ShowContinueError(m_state, "The default value is assigned as No.");
2581 : }
2582 : }
2583 31 : if (NumAlphas == 4 && !lAlphaBlanks(4)) { // Relative or absolute wind angle
2584 4 : if (Util::SameString(Alphas(4), "Relative")) {
2585 2 : MultizoneExternalNodeData(i).useRelativeAngle = true;
2586 2 : } else if (!Util::SameString(Alphas(4), "Absolute")) {
2587 : // Code will never be executed, validation will catch invalid input
2588 0 : ShowWarningError(
2589 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(4) + " = " + Alphas(4));
2590 0 : ShowContinueError(m_state, "The default value is assigned as Absolute.");
2591 : }
2592 : }
2593 : }
2594 10 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel) {
2595 :
2596 1 : CurrentModuleObject = "OutdoorAir:Node";
2597 3 : for (int i = AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode + 1; i <= AirflowNetworkNumOfExtNode; ++i) {
2598 4 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2599 : CurrentModuleObject,
2600 2 : i - (AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode),
2601 : Alphas,
2602 : NumAlphas,
2603 : Numbers,
2604 : NumNumbers,
2605 : IOStatus,
2606 : lNumericBlanks,
2607 : lAlphaBlanks,
2608 : cAlphaFields,
2609 : cNumericFields);
2610 : // HACK: Need to verify name is unique between "OutdoorAir:Node" and "AirflowNetwork:MultiZone:ExternalNode"
2611 :
2612 2 : if (NumAlphas > 5 && !lAlphaBlanks(6)) { // Wind pressure curve
2613 1 : MultizoneExternalNodeData(i).curve = GetCurveIndex(m_state, Alphas(6));
2614 1 : if (MultizoneExternalNodeData(i).curve == 0) {
2615 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(6) + "=" + Alphas(6));
2616 0 : ShowContinueError(m_state, "Entered in " + CurrentModuleObject + '=' + Alphas(1));
2617 0 : ErrorsFound = true;
2618 : }
2619 : }
2620 :
2621 2 : if (NumAlphas > 6 && !lAlphaBlanks(7)) { // Symmetric curve
2622 1 : if (Util::SameString(Alphas(7), "Yes")) {
2623 0 : MultizoneExternalNodeData(i).symmetricCurve = true;
2624 1 : } else if (!Util::SameString(Alphas(7), "No")) {
2625 0 : ShowWarningError(m_state,
2626 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(7) + " = " +
2627 0 : Alphas(7));
2628 0 : ShowContinueError(m_state, "The default value is assigned as No.");
2629 : }
2630 : }
2631 :
2632 2 : if (NumAlphas > 7 && !lAlphaBlanks(8)) { // Relative or absolute wind angle
2633 1 : if (Util::SameString(Alphas(8), "Relative")) {
2634 0 : MultizoneExternalNodeData(i).useRelativeAngle = true;
2635 1 : } else if (!Util::SameString(Alphas(8), "Absolute")) {
2636 0 : ShowWarningError(m_state,
2637 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(8) + " = " +
2638 0 : Alphas(8));
2639 0 : ShowContinueError(m_state, "The default value is assigned as Absolute.");
2640 : }
2641 : }
2642 :
2643 2 : MultizoneExternalNodeData(i).Name = Alphas(1); // Name of external node
2644 6 : int NodeNum = GetOnlySingleNode(m_state,
2645 2 : Alphas(1),
2646 : ErrorsFound,
2647 : DataLoopNode::ConnectionObjectType::OutdoorAirNode,
2648 : "AirflowNetwork:Multizone:Surface",
2649 : DataLoopNode::NodeFluidType::Air,
2650 : DataLoopNode::ConnectionType::Inlet,
2651 : NodeInputManager::CompFluidStream::Primary,
2652 : ObjectIsParent);
2653 2 : MultizoneExternalNodeData(i).OutAirNodeNum = NodeNum; // Name of outdoor air node
2654 2 : MultizoneExternalNodeData(i).height = Node(NodeNum).Height; // Nodal height
2655 2 : MultizoneExternalNodeData(i).ExtNum = AirflowNetworkNumOfZones + i; // External node number
2656 : }
2657 : }
2658 : } else {
2659 0 : ShowSevereError(m_state,
2660 0 : format(RoutineName) + "An " + CurrentModuleObject +
2661 : " object is required but not found when Wind Pressure Coefficient Type = Input.");
2662 0 : ErrorsFound = true;
2663 : }
2664 : }
2665 :
2666 : // *** Read AirflowNetwork element data
2667 25 : ErrorsFound = ErrorsFound || !get_element_input();
2668 :
2669 : // *** Read AirflowNetwork simulation surface data
2670 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
2671 25 : AirflowNetworkNumOfSurfaces = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2672 25 : if (AirflowNetworkNumOfSurfaces > 0) {
2673 25 : MultizoneSurfaceData.allocate(AirflowNetworkNumOfSurfaces);
2674 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
2675 143 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2676 : CurrentModuleObject,
2677 : i,
2678 : Alphas,
2679 : NumAlphas,
2680 : Numbers,
2681 : NumNumbers,
2682 : IOStatus,
2683 : lNumericBlanks,
2684 : lAlphaBlanks,
2685 : cAlphaFields,
2686 : cNumericFields);
2687 143 : MultizoneSurfaceData(i).SurfName = Alphas(1); // Name of Associated EnergyPlus surface
2688 143 : MultizoneSurfaceData(i).OpeningName = Alphas(2); // Name of crack or opening component,
2689 : // either simple or detailed large opening, or crack
2690 143 : MultizoneSurfaceData(i).ExternalNodeName = Alphas(3); // Name of external node, but not used at WPC="INPUT"
2691 191 : if (Util::FindItemInList(Alphas(3), MultizoneExternalNodeData) &&
2692 48 : m_state.afn->MultizoneExternalNodeData(Util::FindItemInList(Alphas(3), MultizoneExternalNodeData)).curve == 0) {
2693 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(3) + "=" + Alphas(3));
2694 0 : ShowContinueError(m_state,
2695 : "A valid wind pressure coefficient curve name is required but not found when Wind Pressure "
2696 : "Coefficient Type = Input.");
2697 0 : ErrorsFound = true;
2698 : }
2699 143 : MultizoneSurfaceData(i).Factor = Numbers(1); // Crack Actual Value or Window Open Factor for Ventilation
2700 143 : if (MultizoneSurfaceData(i).Factor > 1.0 || MultizoneSurfaceData(i).Factor <= 0.0) {
2701 0 : ShowWarningError(m_state,
2702 0 : format(RoutineName) + CurrentModuleObject + " object=" + MultizoneSurfaceData(i).SurfName + ", " +
2703 0 : cNumericFields(1) + " is out of range (0.0,1.0]");
2704 0 : ShowContinueError(m_state, format("..Input value = {:.2R}, Value will be set to 1.0", MultizoneSurfaceData(i).Factor));
2705 0 : MultizoneSurfaceData(i).Factor = 1.0;
2706 : }
2707 : // Get input of ventilation control and associated data
2708 143 : if (NumAlphas >= 4) {
2709 : // Ventilation Control Mode: "TEMPERATURE", "ENTHALPY",
2710 : // "CONSTANT", "ZONELEVEL", "NOVENT", "ADJACENTTEMPERATURE",
2711 : // or "ADJACENTENTHALPY"
2712 40 : if (!lAlphaBlanks(4)) {
2713 40 : MultizoneSurfaceData(i).VentControl = Alphas(4);
2714 : }
2715 : // Name of ventilation temperature control schedule
2716 40 : if (!lAlphaBlanks(5)) {
2717 6 : MultizoneSurfaceData(i).VentTempControlSchName = Alphas(5);
2718 : }
2719 : {
2720 : // This SELECT_CASE_var will go on input refactor, no need to fix
2721 40 : auto const SELECT_CASE_var(Util::makeUPPER(MultizoneSurfaceData(i).VentControl));
2722 40 : if (SELECT_CASE_var == "TEMPERATURE") {
2723 6 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Temp;
2724 6 : MultizoneSurfaceData(i).IndVentControl = true;
2725 34 : } else if (SELECT_CASE_var == "ENTHALPY") {
2726 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Enth;
2727 0 : MultizoneSurfaceData(i).IndVentControl = true;
2728 34 : } else if (SELECT_CASE_var == "CONSTANT") {
2729 9 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Const;
2730 9 : MultizoneSurfaceData(i).IndVentControl = true;
2731 25 : } else if (SELECT_CASE_var == "ASHRAE55ADAPTIVE") {
2732 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::ASH55;
2733 0 : MultizoneSurfaceData(i).IndVentControl = true;
2734 25 : } else if (SELECT_CASE_var == "CEN15251ADAPTIVE") {
2735 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::CEN15251;
2736 0 : MultizoneSurfaceData(i).IndVentControl = true;
2737 25 : } else if (SELECT_CASE_var == "NOVENT") {
2738 10 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::NoVent;
2739 10 : MultizoneSurfaceData(i).IndVentControl = true;
2740 15 : } else if (SELECT_CASE_var == "ZONELEVEL") {
2741 15 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::ZoneLevel;
2742 15 : MultizoneSurfaceData(i).IndVentControl = false;
2743 0 : } else if (SELECT_CASE_var == "ADJACENTTEMPERATURE") {
2744 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::AdjTemp;
2745 0 : MultizoneSurfaceData(i).IndVentControl = true;
2746 0 : } else if (SELECT_CASE_var == "ADJACENTENTHALPY") {
2747 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::AdjEnth;
2748 0 : MultizoneSurfaceData(i).IndVentControl = true;
2749 : } else {
2750 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(4));
2751 0 : ShowContinueError(m_state,
2752 0 : ".." + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName + ", Specified " + cAlphaFields(4) +
2753 0 : " = " + Alphas(4));
2754 0 : ShowContinueError(m_state,
2755 : "..The valid choices are \"Temperature\", \"Enthalpy\", \"Constant\", \"NoVent\", \"ZoneLevel\", "
2756 : "\"AdjancentTemperature\" or \"AdjacentEnthalpy\"");
2757 0 : ErrorsFound = true;
2758 : }
2759 40 : }
2760 : }
2761 143 : MultizoneSurfaceData(i).ModulateFactor = Numbers(2); // Limit Value on Multiplier for Modulating Venting Open Factor
2762 143 : MultizoneSurfaceData(i).LowValueTemp = Numbers(3); // Lower temperature value for modulation of temperature control
2763 143 : MultizoneSurfaceData(i).UpValueTemp = Numbers(4); // Upper temperature value for modulation of temperature control
2764 143 : MultizoneSurfaceData(i).LowValueEnth = Numbers(5); // Lower Enthalpy value for modulation of Enthalpy control
2765 143 : MultizoneSurfaceData(i).UpValueEnth = Numbers(6); // Lower Enthalpy value for modulation of Enthalpy control
2766 168 : if (MultizoneSurfaceData(i).VentSurfCtrNum < 4 || MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjTemp ||
2767 25 : MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjEnth) {
2768 118 : if (!lAlphaBlanks(6)) {
2769 14 : MultizoneSurfaceData(i).VentAvailSchName = Alphas(6); // Name of ventilation availability schedule
2770 : }
2771 : }
2772 143 : if (!lAlphaBlanks(7)) {
2773 0 : MultizoneSurfaceData(i).OccupantVentilationControlName = Alphas(7);
2774 0 : MultizoneSurfaceData(i).OccupantVentilationControlNum =
2775 0 : Util::FindItemInList(MultizoneSurfaceData(i).OccupantVentilationControlName, OccupantVentilationControl);
2776 0 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) {
2777 0 : ShowSevereError(m_state,
2778 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(7) +
2779 0 : " not found = " + MultizoneSurfaceData(i).OccupantVentilationControlName);
2780 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
2781 0 : ErrorsFound = true;
2782 : }
2783 : }
2784 : // Get data of polygonal surface
2785 143 : if (!lAlphaBlanks(8)) {
2786 5 : if (Alphas(8) == "POLYGONHEIGHT") {
2787 0 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::Height;
2788 5 : } else if (Alphas(8) == "BASESURFACEASPECTRATIO") {
2789 4 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::BaseAspectRatio;
2790 1 : } else if (Alphas(8) == "USERDEFINEDASPECTRATIO") {
2791 1 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::UserAspectRatio;
2792 : } else {
2793 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(8));
2794 0 : ShowContinueError(m_state,
2795 0 : ".." + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName + ", Specified " + cAlphaFields(8) +
2796 0 : " = " + Alphas(8));
2797 0 : ShowContinueError(m_state,
2798 : "..The valid choices are \"PolygonHeight\", \"BaseSurfaceAspectRatio\", or \"UserDefinedAspectRatio\"");
2799 0 : ErrorsFound = true;
2800 : }
2801 : } else {
2802 138 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::Height;
2803 : }
2804 143 : if (!lNumericBlanks(7)) {
2805 1 : MultizoneSurfaceData(i).EquivRecUserAspectRatio = Numbers(7);
2806 : } else {
2807 142 : MultizoneSurfaceData(i).EquivRecUserAspectRatio = 1.0;
2808 : }
2809 : }
2810 : } else {
2811 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
2812 0 : ErrorsFound = true;
2813 : }
2814 :
2815 : // remove extra OutdoorAir:Node, not assigned to External Node Name
2816 25 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel && AirflowNetworkNumOfOutAirNode > 0) {
2817 3 : for (int i = AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode + 1; i <= AirflowNetworkNumOfExtNode; ++i) {
2818 2 : found = false;
2819 10 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
2820 8 : if (Util::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
2821 1 : found = true;
2822 : }
2823 : }
2824 2 : if (!found) {
2825 1 : if (i < AirflowNetworkNumOfExtNode) {
2826 0 : for (k = i; k <= AirflowNetworkNumOfExtNode - 1; ++k) {
2827 0 : MultizoneExternalNodeData(k).Name = MultizoneExternalNodeData(k + 1).Name;
2828 0 : MultizoneExternalNodeData(k).OutAirNodeNum = MultizoneExternalNodeData(k + 1).OutAirNodeNum;
2829 0 : MultizoneExternalNodeData(k).height = MultizoneExternalNodeData(k + 1).height;
2830 0 : MultizoneExternalNodeData(k).ExtNum = MultizoneExternalNodeData(k + 1).ExtNum - 1;
2831 : }
2832 0 : i -= 1;
2833 : }
2834 1 : AirflowNetworkNumOfOutAirNode -= 1;
2835 1 : AirflowNetworkNumOfExtNode -= 1;
2836 1 : MultizoneExternalNodeData.resize(AirflowNetworkNumOfExtNode);
2837 : }
2838 : }
2839 : }
2840 :
2841 : // ==> Validate AirflowNetwork simulation surface data
2842 25 : NumOfExtNodes = 0;
2843 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
2844 : // Check a valid surface defined earlier
2845 143 : MultizoneSurfaceData(i).SurfNum = Util::FindItemInList(MultizoneSurfaceData(i).SurfName, m_state.dataSurface->Surface);
2846 143 : if (MultizoneSurfaceData(i).SurfNum == 0) {
2847 0 : ShowSevereError(m_state,
2848 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(1) +
2849 0 : " given = " + MultizoneSurfaceData(i).SurfName);
2850 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
2851 : }
2852 144 : if (!m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).HeatTransSurf &&
2853 1 : !m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) {
2854 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2855 0 : ShowContinueError(m_state,
2856 0 : "..The surface specified must be a heat transfer surface. Invalid " + cAlphaFields(1) + " = " +
2857 0 : MultizoneSurfaceData(i).SurfName);
2858 0 : ErrorsFound = true;
2859 0 : continue;
2860 : }
2861 : // Ensure an interior surface does not face itself
2862 143 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1) {
2863 : // Check the surface is a subsurface or not
2864 37 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf == MultizoneSurfaceData(i).SurfNum) {
2865 35 : if (MultizoneSurfaceData(i).SurfNum == m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond) {
2866 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2867 0 : ShowContinueError(m_state,
2868 0 : "..The surface facing itself is not allowed. Invalid " + cAlphaFields(1) + " = " +
2869 0 : MultizoneSurfaceData(i).SurfName);
2870 0 : ErrorsFound = true;
2871 : }
2872 : } else {
2873 2 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf ==
2874 2 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).ExtBoundCond) {
2875 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2876 0 : ShowContinueError(m_state,
2877 0 : "..The base surface facing itself is not allowed. Invalid " + cAlphaFields(1) + " = " +
2878 0 : MultizoneSurfaceData(i).SurfName);
2879 0 : ErrorsFound = true;
2880 : }
2881 : }
2882 : }
2883 : // Ensure zones defined in inside and outside environment are used in the object of AIRFLOWNETWORK:MULTIZONE:ZONE
2884 143 : found = false;
2885 143 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone;
2886 : int j;
2887 247 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
2888 247 : if (MultizoneZoneData(j).ZoneNum == n) {
2889 143 : found = true;
2890 143 : break;
2891 : }
2892 : }
2893 : // find a surface geometry
2894 143 : MultizoneSurfaceData(i).Height = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Height;
2895 143 : MultizoneSurfaceData(i).Width = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Width;
2896 143 : MultizoneSurfaceData(i).CHeight = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Centroid.z;
2897 143 : if (found) {
2898 143 : MultizoneSurfaceData(i).NodeNums[0] = j;
2899 : } else {
2900 0 : ShowSevereError(m_state,
2901 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName);
2902 0 : ShowContinueError(m_state,
2903 0 : "..Zone for inside surface must be defined in a AirflowNetwork:MultiZone:Zone object. Could not find Zone = " +
2904 0 : Zone(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone).Name);
2905 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
2906 : }
2907 :
2908 : // Calculate equivalent width and height
2909 143 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides != 4) {
2910 12 : MultizoneSurfaceData(i).NonRectangular = true;
2911 12 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::Height) {
2912 12 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Tilt < 1.0 ||
2913 5 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Tilt > 179.0) { // horizontal surface
2914 : // check base surface shape
2915 2 : if (m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Sides == 4) {
2916 1 : baseratio = m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Width /
2917 1 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Height;
2918 1 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * baseratio);
2919 2 : MultizoneSurfaceData(i).Height =
2920 1 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2921 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2922 0 : ShowWarningError(m_state,
2923 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2924 0 : ShowContinueError(m_state,
2925 : "The entered choice of Equivalent Rectangle Method is PolygonHeight. This choice is not valid for "
2926 : "a horizontal surface.");
2927 0 : ShowContinueError(m_state, "The BaseSurfaceAspectRatio choice is used. Simulation continues.");
2928 : }
2929 : } else {
2930 1 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area *
2931 1 : MultizoneSurfaceData(i).EquivRecUserAspectRatio);
2932 2 : MultizoneSurfaceData(i).Height =
2933 1 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2934 : // add warning
2935 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2936 0 : ShowWarningError(m_state,
2937 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2938 0 : ShowContinueError(m_state,
2939 : "The entered choice of Equivalent Rectangle Method is PolygonHeight. This choice is not valid for "
2940 : "a horizontal surface with a polygonal base surface.");
2941 0 : ShowContinueError(m_state, "The default aspect ratio at 1 is used. Simulation continues.");
2942 : }
2943 : }
2944 : } else {
2945 5 : minHeight = min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2946 5 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2947 5 : maxHeight = max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2948 5 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2949 12 : for (j = 3; j <= m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides; ++j) {
2950 7 : minHeight = min(minHeight,
2951 7 : min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2952 7 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2953 7 : maxHeight = max(maxHeight,
2954 7 : max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2955 7 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2956 : }
2957 5 : if (maxHeight > minHeight) {
2958 5 : MultizoneSurfaceData(i).Height = maxHeight - minHeight;
2959 5 : MultizoneSurfaceData(i).Width =
2960 5 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / (maxHeight - minHeight);
2961 : }
2962 : }
2963 : }
2964 12 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::BaseAspectRatio) {
2965 4 : if (m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Sides == 4) {
2966 2 : baseratio = m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Width /
2967 2 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Height;
2968 2 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * baseratio);
2969 2 : MultizoneSurfaceData(i).Height =
2970 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2971 : } else {
2972 2 : minHeight = min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2973 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2974 2 : maxHeight = max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2975 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2976 4 : for (j = 3; j <= m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides; ++j) {
2977 2 : minHeight = min(minHeight,
2978 2 : min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2979 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2980 2 : maxHeight = max(maxHeight,
2981 2 : max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2982 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2983 : }
2984 2 : if (maxHeight > minHeight) {
2985 1 : MultizoneSurfaceData(i).Height = maxHeight - minHeight;
2986 2 : MultizoneSurfaceData(i).Width =
2987 1 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / (maxHeight - minHeight);
2988 : // add warning
2989 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2990 0 : ShowWarningError(m_state,
2991 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2992 0 : ShowContinueError(m_state,
2993 : "The entered choice of Equivalent Rectangle Method is BaseSurfaceAspectRatio. This choice is not "
2994 : "valid for a polygonal base surface.");
2995 0 : ShowContinueError(m_state, "The PolygonHeight choice is used. Simulation continues.");
2996 : }
2997 : } else {
2998 1 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area *
2999 1 : MultizoneSurfaceData(i).EquivRecUserAspectRatio);
3000 2 : MultizoneSurfaceData(i).Height =
3001 1 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
3002 : // add warning
3003 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3004 0 : ShowWarningError(m_state,
3005 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
3006 0 : ShowContinueError(m_state,
3007 : "The entered choice of Equivalent Rectangle Method is BaseSurfaceAspectRatio. This choice is not "
3008 : "valid for a horizontal surface with a polygonal base surface.");
3009 0 : ShowContinueError(m_state, "The default aspect ratio at 1 is used. Simulation continues.");
3010 : }
3011 : }
3012 : }
3013 : }
3014 12 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::UserAspectRatio) {
3015 2 : MultizoneSurfaceData(i).Width =
3016 1 : sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * MultizoneSurfaceData(i).EquivRecUserAspectRatio);
3017 1 : MultizoneSurfaceData(i).Height =
3018 1 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
3019 : }
3020 : }
3021 :
3022 : // Get the number of external surfaces
3023 180 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == ExternalEnvironment ||
3024 37 : (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3025 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3026 106 : ++AirflowNetworkNumOfExtSurfaces;
3027 : }
3028 :
3029 : // Outside face environment
3030 143 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
3031 80 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond;
3032 112 : if (n == ExternalEnvironment ||
3033 32 : (n == OtherSideCoefNoCalcExt && m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3034 48 : ++NumOfExtNodes;
3035 48 : if (AirflowNetworkNumOfExtNode > 0) {
3036 48 : found = false;
3037 123 : for (j = 1; j <= AirflowNetworkNumOfExtNode; ++j) {
3038 123 : if (Util::SameString(MultizoneSurfaceData(i).ExternalNodeName, MultizoneExternalNodeData(j).Name)) {
3039 48 : MultizoneSurfaceData(i).NodeNums[1] = MultizoneExternalNodeData(j).ExtNum;
3040 48 : found = true;
3041 48 : break;
3042 : }
3043 : }
3044 48 : if (!found) {
3045 0 : ShowSevereError(m_state,
3046 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(3) + " = " +
3047 0 : MultizoneSurfaceData(i).ExternalNodeName);
3048 0 : ShowContinueError(m_state, "A valid " + cAlphaFields(3) + " is required when Wind Pressure Coefficient Type = Input");
3049 0 : ErrorsFound = true;
3050 : }
3051 : } else {
3052 : // MultizoneSurfaceData(i)%NodeNums[1] =
3053 : // AirflowNetworkNumOfZones+NumOfExtNodes
3054 : }
3055 48 : continue;
3056 : } else {
3057 32 : if (n < ExternalEnvironment &&
3058 0 : !(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3059 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3060 0 : ShowSevereError(m_state,
3061 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(1) + " = " +
3062 0 : MultizoneSurfaceData(i).SurfName);
3063 0 : ShowContinueError(m_state, "This type of surface (has ground, etc exposure) cannot be used in the AiflowNetwork model.");
3064 0 : ErrorsFound = true;
3065 : }
3066 : }
3067 32 : found = false;
3068 96 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
3069 96 : if (MultizoneZoneData(j).ZoneNum == m_state.dataSurface->Surface(n).Zone) {
3070 32 : found = true;
3071 32 : break;
3072 : }
3073 : }
3074 32 : if (found) {
3075 32 : MultizoneSurfaceData(i).NodeNums[1] = j;
3076 : } else {
3077 0 : ShowSevereError(m_state,
3078 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3079 0 : MultizoneSurfaceData(i).SurfName);
3080 0 : ShowContinueError(
3081 : m_state,
3082 0 : "..Zone for outside surface must be defined in a AirflowNetwork:MultiZone:Zone object. Could not find Zone = " +
3083 0 : Zone(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone).Name);
3084 0 : ErrorsFound = true;
3085 0 : continue;
3086 : }
3087 : }
3088 95 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
3089 63 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond;
3090 63 : if (n >= 1) { // exterior boundary condition is a surface
3091 5 : found = false;
3092 10 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
3093 10 : if (MultizoneZoneData(j).ZoneNum == m_state.dataSurface->Surface(n).Zone) {
3094 5 : found = true;
3095 5 : break;
3096 : }
3097 : }
3098 5 : if (found) {
3099 5 : MultizoneSurfaceData(i).NodeNums[1] = j;
3100 : } else {
3101 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " = " + MultizoneSurfaceData(i).SurfName);
3102 0 : ShowContinueError(m_state,
3103 0 : "An adjacent zone = " + Zone(m_state.dataSurface->Surface(n).Zone).Name +
3104 : " is not described in AIRFLOWNETWORK:MULTIZONE:ZONE");
3105 0 : ErrorsFound = true;
3106 0 : continue;
3107 : }
3108 : }
3109 : }
3110 95 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == -2 &&
3111 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3112 95 : if (MultizoneSurfaceData(i).NodeNums[1] == 0 && m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond < 0) {
3113 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " = " + MultizoneSurfaceData(i).SurfName);
3114 0 : ShowContinueError(m_state,
3115 0 : "Outside boundary condition and object are " +
3116 0 : cExtBoundCondition(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond) + " and " +
3117 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCondName + ".");
3118 0 : ShowContinueError(m_state, "The outside boundary condition must be exposed to either the outside or an adjacent zone.");
3119 0 : ErrorsFound = true;
3120 0 : continue;
3121 : }
3122 : }
3123 : }
3124 :
3125 : // write outputs in eio file
3126 25 : found = true;
3127 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3128 143 : if (MultizoneSurfaceData(i).NonRectangular) {
3129 12 : if (found) {
3130 3 : print(m_state.files.eio,
3131 : "! <AirflowNetwork Model:Equivalent Rectangle Surface>, Name, Equivalent Height {{m}}, Equivalent Width {{m}} "
3132 : "AirflowNetwork "
3133 : "Model:Equivalent Rectangle\n");
3134 3 : found = false;
3135 : }
3136 12 : print(m_state.files.eio,
3137 : "AirflowNetwork Model:Equivalent Rectangle Surface, {}, {:.2R},{:.2R}\n",
3138 12 : MultizoneSurfaceData(i).SurfName,
3139 12 : MultizoneSurfaceData(i).Height,
3140 12 : MultizoneSurfaceData(i).Width);
3141 : }
3142 : }
3143 :
3144 : // Validate adjacent temperature and Enthalpy control for an interior surface only
3145 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3146 143 : if (MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjTemp) {
3147 0 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1)) {
3148 0 : ShowSevereError(m_state,
3149 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3150 0 : MultizoneSurfaceData(i).SurfName);
3151 0 : ShowContinueError(m_state, "..AdjacentTemperature venting control must be defined for an interzone surface.");
3152 0 : ErrorsFound = true;
3153 : }
3154 : }
3155 143 : if (MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjEnth) {
3156 0 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1)) {
3157 0 : ShowSevereError(m_state,
3158 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3159 0 : MultizoneSurfaceData(i).SurfName);
3160 0 : ShowContinueError(m_state, "..AdjacentEnthalpy venting control must be defined for an interzone surface.");
3161 0 : ErrorsFound = true;
3162 : }
3163 : }
3164 : }
3165 :
3166 : // Ensure the number of external node = the number of external surface with HeightOption choice = OpeningHeight
3167 25 : if (Util::SameString(simulation_control.HeightOption, "OpeningHeight") && simulation_control.iWPCCnt == iWPCCntr::Input) {
3168 0 : if (AirflowNetworkNumOfExtSurfaces != AirflowNetworkNumOfExtNode) {
3169 0 : ShowSevereError(m_state,
3170 0 : format(RoutineName) +
3171 : "When the choice of Height Selection for Local Wind Speed Calculation is OpeningHeight, the number of external "
3172 0 : "surfaces defined in " +
3173 0 : CurrentModuleObject + " objects ");
3174 0 : ShowContinueError(m_state, "has to be equal to the number of AirflowNetwork:MultiZone:ExternalNode objects.");
3175 0 : ShowContinueError(m_state,
3176 0 : format("The entered number of external nodes is {}. The entered number of external surfaces is {}.",
3177 0 : AirflowNetworkNumOfExtNode,
3178 0 : AirflowNetworkNumOfExtSurfaces));
3179 0 : ErrorsFound = true;
3180 : }
3181 : }
3182 :
3183 : // Read AirflowNetwork simulation detailed openings
3184 : // Moved into getAirflowElementInput
3185 :
3186 : // Validate opening component and assign opening dimension
3187 25 : if (AirflowNetworkNumOfDetOpenings > 0) {
3188 9 : for (int i = 1; i <= AirflowNetworkNumOfDetOpenings; ++i) {
3189 5 : found = false;
3190 48 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3191 43 : if (MultizoneCompDetOpeningData(i).name == MultizoneSurfaceData(j).OpeningName) {
3192 : // MultizoneCompDetOpeningData(i)%Width =
3193 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Width
3194 : // MultizoneCompDetOpeningData(i)%Height =
3195 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Height
3196 6 : found = true;
3197 : }
3198 : }
3199 : }
3200 : }
3201 :
3202 : // Read AirflowNetwork simulation simple openings
3203 : // Moved into getAirflowElementInput
3204 :
3205 : // Read AirflowNetwork simulation horizontal openings
3206 : // Moved into getAirflowElementInput
3207 :
3208 : // Check status of control level for each surface with an opening
3209 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
3210 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3211 143 : if (MultizoneSurfaceData(i).SurfNum == 0) {
3212 0 : continue;
3213 : }
3214 143 : bool has_Opening{false}; // Why use array constructor?
3215 :
3216 143 : ErrorObjectHeader eoh{RoutineName, CurrentModuleObject, MultizoneSurfaceData(i).SurfName};
3217 :
3218 : // This is terrible, should not do it this way
3219 143 : auto afe = elements.find(MultizoneSurfaceData(i).OpeningName);
3220 143 : if (afe != elements.end()) {
3221 143 : auto type = afe->second->type();
3222 143 : has_Opening = (type == ComponentType::DOP) || (type == ComponentType::SOP) || (type == ComponentType::HOP);
3223 : }
3224 : // Obtain schedule number and check surface shape
3225 143 : if (has_Opening) {
3226 24 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides == 3) {
3227 5 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName + "\".");
3228 15 : ShowContinueError(m_state,
3229 : "The opening is a Triangular subsurface. A rectangular subsurface will be used with equivalent "
3230 : "width and height.");
3231 : }
3232 : // Venting controls are not allowed for an air boundary surface
3233 25 : if ((m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) &&
3234 1 : (MultizoneSurfaceData(i).VentSurfCtrNum != VentControlType::Const)) {
3235 2 : ShowWarningError(m_state,
3236 2 : format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName +
3237 : "\" is an air boundary surface.");
3238 1 : ShowContinueError(m_state, "Ventilation Control Mode = " + Alphas(4) + " is not valid. Resetting to Constant.");
3239 1 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Const;
3240 1 : MultizoneSurfaceData(i).IndVentControl = true;
3241 : }
3242 :
3243 24 : if (MultizoneSurfaceData(i).VentAvailSchName.empty()) {
3244 18 : MultizoneSurfaceData(i).ventAvailSched = Sched::GetScheduleAlwaysOn(m_state);
3245 6 : } else if ((MultizoneSurfaceData(i).ventAvailSched = Sched::GetSchedule(m_state, MultizoneSurfaceData(i).VentAvailSchName)) ==
3246 : nullptr) {
3247 0 : ShowSevereItemNotFound(m_state, eoh, "Venting Schedule", MultizoneSurfaceData(i).VentAvailSchName);
3248 0 : ErrorsFound = true;
3249 6 : } else if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) {
3250 1 : ShowWarningNonEmptyField(m_state, eoh, "Venting Availbility Schedule");
3251 2 : ShowContinueError(m_state, "Venting is always available for air-boundary surfaces.");
3252 1 : MultizoneSurfaceData(i).ventAvailSched = Sched::GetScheduleAlwaysOn(m_state);
3253 1 : MultizoneSurfaceData(i).VentAvailSchName = "";
3254 : }
3255 :
3256 24 : switch (MultizoneSurfaceData(i).VentSurfCtrNum) {
3257 5 : case VentControlType::Temp:
3258 : case VentControlType::AdjTemp: {
3259 5 : if (MultizoneSurfaceData(i).VentTempControlSchName.empty()) {
3260 0 : ShowSevereEmptyField(m_state, eoh, "Ventilation Schedule", "Ventinlation Control", "Temperature");
3261 0 : ErrorsFound = true;
3262 10 : } else if ((MultizoneSurfaceData(i).ventTempControlSched =
3263 5 : Sched::GetSchedule(m_state, MultizoneSurfaceData(i).VentTempControlSchName)) == nullptr) {
3264 0 : ShowSevereItemNotFound(m_state, eoh, "Ventilation Schedule", MultizoneSurfaceData(i).VentTempControlSchName);
3265 0 : ErrorsFound = true;
3266 : }
3267 5 : if (MultizoneSurfaceData(i).LowValueTemp < 0.0) {
3268 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Temperature difference value < 0.0d0");
3269 0 : ShowContinueError(m_state, format("..Input value={:.1R}, Value will be reset to 0.0.", MultizoneSurfaceData(i).LowValueTemp));
3270 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3271 0 : MultizoneSurfaceData(i).LowValueTemp = 0.0;
3272 : }
3273 5 : if (MultizoneSurfaceData(i).LowValueTemp >= 100.0) {
3274 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Temperature difference value >= 100.0d0");
3275 0 : ShowContinueError(m_state,
3276 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueTemp));
3277 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3278 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
3279 : }
3280 5 : if (MultizoneSurfaceData(i).UpValueTemp <= MultizoneSurfaceData(i).LowValueTemp) {
3281 0 : ShowWarningError(
3282 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Upper Temperature <= Lower Temperature difference value.");
3283 0 : ShowContinueError(m_state,
3284 0 : format("..Input value = {:.1R}, Value will be reset to 100.0", MultizoneSurfaceData(i).UpValueTemp));
3285 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3286 0 : MultizoneSurfaceData(i).UpValueTemp = 100.0;
3287 : }
3288 :
3289 5 : } break;
3290 :
3291 0 : case VentControlType::Enth:
3292 : case VentControlType::AdjEnth: {
3293 0 : if (MultizoneSurfaceData(i).VentTempControlSchName.empty()) {
3294 0 : ShowSevereEmptyField(m_state, eoh, "Ventilation Schedule", "Ventilation Control", "Enthalpy");
3295 0 : ErrorsFound = true;
3296 0 : } else if ((MultizoneSurfaceData(i).ventTempControlSched =
3297 0 : Sched::GetSchedule(m_state, MultizoneSurfaceData(i).VentTempControlSchName)) == nullptr) {
3298 0 : ShowSevereItemNotFound(m_state, eoh, "Ventilation Schedule", MultizoneSurfaceData(i).VentTempControlSchName);
3299 0 : ErrorsFound = true;
3300 : }
3301 0 : if (MultizoneSurfaceData(i).LowValueEnth < 0.0) {
3302 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Enthalpy difference value < 0.0d0");
3303 0 : ShowContinueError(m_state,
3304 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueEnth));
3305 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3306 0 : MultizoneSurfaceData(i).LowValueEnth = 0.0;
3307 : }
3308 0 : if (MultizoneSurfaceData(i).LowValueEnth >= 300000.0) {
3309 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Enthalpy difference value >= 300000.0");
3310 0 : ShowContinueError(m_state,
3311 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueEnth));
3312 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3313 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
3314 : }
3315 0 : if (MultizoneSurfaceData(i).UpValueEnth <= MultizoneSurfaceData(i).LowValueEnth) {
3316 0 : ShowWarningError(m_state,
3317 0 : format(RoutineName) + CurrentModuleObject + " object, Upper Enthalpy <= Lower Enthalpy difference value.");
3318 0 : ShowContinueError(m_state,
3319 0 : format("..Input value = {:.1R}, Value will be set to 300000.0", MultizoneSurfaceData(i).UpValueEnth));
3320 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3321 0 : MultizoneSurfaceData(i).UpValueEnth = 300000.0;
3322 : }
3323 :
3324 0 : } break;
3325 12 : case VentControlType::Const:
3326 : case VentControlType::ASH55:
3327 : case VentControlType::CEN15251:
3328 : case VentControlType::NoVent:
3329 : case VentControlType::ZoneLevel: {
3330 12 : MultizoneSurfaceData(i).ventTempControlSched = nullptr;
3331 12 : MultizoneSurfaceData(i).VentTempControlSchName = "";
3332 12 : } break;
3333 7 : default:
3334 7 : break;
3335 : }
3336 : }
3337 143 : }
3338 :
3339 : // Validate opening component and assign opening dimension
3340 25 : if (AirflowNetworkNumOfSimOpenings > 0) {
3341 18 : for (int i = 1; i <= AirflowNetworkNumOfSimOpenings; ++i) {
3342 9 : found = false;
3343 54 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3344 45 : if (MultizoneCompSimpleOpeningData(i).name == MultizoneSurfaceData(j).OpeningName) {
3345 : // MultizoneCompSimpleOpeningData(i)%Width =
3346 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Width
3347 : // MultizoneCompSimpleOpeningData(i)%Height =
3348 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Height
3349 18 : found = true;
3350 : }
3351 : }
3352 : }
3353 : }
3354 :
3355 : // Calculate CP values
3356 25 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
3357 15 : calculate_Cps();
3358 : // Ensure automatic generation is OK
3359 15 : n = 0;
3360 90 : for (int j = 1; j <= 5; ++j) {
3361 75 : found = false;
3362 216 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3363 177 : if (MultizoneExternalNodeData(i).facadeNum == j) {
3364 36 : found = true;
3365 36 : break;
3366 : }
3367 : }
3368 75 : if (found) {
3369 36 : ++n;
3370 : }
3371 75 : if (j == 5 && (!found)) {
3372 13 : found = true;
3373 13 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3374 0 : ShowWarningError(m_state,
3375 0 : format(RoutineName) +
3376 : "SurfaceAverageCalculation is entered for field = Wind Pressure Coefficient Type, but no roof "
3377 : "surface is defined using an AirflowNetwork:MultiZone:Surface object.");
3378 0 : ShowContinueError(m_state, "Reconsider if this is your modeling intent. Simulation continues.");
3379 : }
3380 : }
3381 : }
3382 15 : if (n < 5 && m_state.dataGlobal->DisplayExtraWarnings) {
3383 0 : ShowWarningError(m_state, format(RoutineName) + "SurfaceAverageCalculation is entered for field = Wind Pressure Coefficient Type.");
3384 0 : ShowContinueError(m_state,
3385 : "The AirflowNetwork model provides wind pressure coefficients for 4 vertical exterior orientations and "
3386 : "1 horizontal roof.");
3387 0 : ShowContinueError(m_state,
3388 0 : format(" There are only {} exterior surface orientations defined in this input file using "
3389 : "AirflowNetwork:MultiZone:Surface objects.",
3390 : n));
3391 0 : ShowContinueError(m_state, "Reconsider if this is your modeling intent. Simulation continues.");
3392 : }
3393 : }
3394 :
3395 : // Assign external node height
3396 35 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation") ||
3397 35 : Util::SameString(simulation_control.HeightOption, "OpeningHeight")) {
3398 73 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3399 278 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3400 298 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == ExternalEnvironment ||
3401 20 : (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3402 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtWind)) {
3403 258 : if (Util::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
3404 58 : MultizoneExternalNodeData(i).height = m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Centroid.z;
3405 58 : break;
3406 : }
3407 : }
3408 : }
3409 : }
3410 : }
3411 :
3412 : // Assign external node azimuth, should consider combining this with the above to avoid the repeated search
3413 115 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3414 435 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3415 506 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == ExternalEnvironment ||
3416 74 : (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3417 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtWind)) {
3418 358 : if (Util::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
3419 87 : MultizoneExternalNodeData(i).azimuth = m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Azimuth;
3420 87 : break;
3421 : }
3422 : }
3423 : }
3424 : }
3425 :
3426 25 : if (ErrorsFound) {
3427 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3428 : }
3429 :
3430 : // Write wind pressure coefficients in the EIO file
3431 25 : print(m_state.files.eio, "! <AirflowNetwork Model:Wind Direction>, Wind Direction #1 to n (degree)\n");
3432 25 : print(m_state.files.eio, "AirflowNetwork Model:Wind Direction, ");
3433 :
3434 25 : int numWinDirs = 11;
3435 25 : Real64 angleDelta = 30.0;
3436 25 : if (AirflowNetworkNumOfSingleSideZones > 0) {
3437 2 : numWinDirs = 35;
3438 2 : angleDelta = 10.0;
3439 : }
3440 :
3441 348 : for (int i = 0; i < numWinDirs; ++i) {
3442 323 : print(m_state.files.eio, "{:.1R},", i * angleDelta);
3443 : }
3444 25 : print(m_state.files.eio, "{:.1R}\n", numWinDirs * angleDelta);
3445 :
3446 25 : print(m_state.files.eio, "! <AirflowNetwork Model:Wind Pressure Coefficients>, Name, Wind Pressure Coefficients #1 to n (dimensionless)\n");
3447 :
3448 : // The old version used to write info with single-sided natural ventilation specific labeling, this version no longer does that.
3449 50 : std::set<int> curves;
3450 115 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3451 90 : curves.insert(MultizoneExternalNodeData(i).curve);
3452 : }
3453 95 : for (auto index : curves) {
3454 70 : print(m_state.files.eio, "AirflowNetwork Model:Wind Pressure Coefficients, {}, ", Curve::GetCurveName(m_state, index));
3455 :
3456 984 : for (int j = 0; j < numWinDirs; ++j) {
3457 914 : print(m_state.files.eio, "{:.2R},", Curve::CurveValue(m_state, index, j * angleDelta));
3458 : }
3459 70 : print(m_state.files.eio, "{:.2R}\n", Curve::CurveValue(m_state, index, numWinDirs * angleDelta));
3460 25 : }
3461 :
3462 25 : if (AirflowNetworkNumOfSingleSideZones > 0) {
3463 4 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3464 2 : if (MultizoneZoneData(i).SingleSidedCpType == "ADVANCED") {
3465 2 : print(m_state.files.eio,
3466 : "AirflowNetwork: Advanced Single-Sided Model: Difference in Opening Wind Pressure Coefficients (DeltaCP), ");
3467 2 : print(m_state.files.eio, "{}, ", MultizoneZoneData(i).ZoneName);
3468 72 : for (unsigned j = 1; j <= EPDeltaCP(i).WindDir.size() - 1; ++j) {
3469 70 : print(m_state.files.eio, "{:.2R},", EPDeltaCP(i).WindDir(j));
3470 : }
3471 2 : print(m_state.files.eio, "{:.2R}\n", EPDeltaCP(i).WindDir(static_cast<int>(EPDeltaCP(i).WindDir.size())));
3472 : }
3473 : }
3474 : }
3475 :
3476 : // If no zone object, exit
3477 25 : if (AirflowNetworkNumOfZones == 0) {
3478 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3479 : }
3480 : // If zone node number =0, exit.
3481 168 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3482 143 : if (MultizoneSurfaceData(j).NodeNums[0] == 0 && ErrorsFound) {
3483 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3484 : }
3485 143 : if (MultizoneSurfaceData(j).NodeNums[1] == 0 && ErrorsFound) {
3486 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3487 : }
3488 : }
3489 :
3490 : // Ensure at least two surfaces are exposed to a zone
3491 25 : ZoneCheck.allocate(AirflowNetworkNumOfZones);
3492 25 : ZoneBCCheck.allocate(AirflowNetworkNumOfZones);
3493 25 : ZoneCheck = 0;
3494 25 : ZoneBCCheck = 0;
3495 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
3496 168 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3497 143 : if (MultizoneSurfaceData(j).NodeNums[0] <= AirflowNetworkNumOfZones) {
3498 143 : ++ZoneCheck(MultizoneSurfaceData(j).NodeNums[0]);
3499 143 : ZoneBCCheck(MultizoneSurfaceData(j).NodeNums[0]) = MultizoneSurfaceData(j).NodeNums[1];
3500 : }
3501 143 : if (MultizoneSurfaceData(j).NodeNums[1] <= AirflowNetworkNumOfZones) {
3502 37 : ++ZoneCheck(MultizoneSurfaceData(j).NodeNums[1]);
3503 37 : ZoneBCCheck(MultizoneSurfaceData(j).NodeNums[1]) = MultizoneSurfaceData(j).NodeNums[0];
3504 : }
3505 : }
3506 77 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3507 52 : if (ZoneCheck(i) == 0) {
3508 0 : ShowSevereError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3509 0 : ShowContinueError(m_state, " does not have any surfaces defined in " + CurrentModuleObject);
3510 0 : ShowContinueError(m_state, "Each zone should have at least two surfaces defined in " + CurrentModuleObject);
3511 0 : ErrorsFound = true;
3512 : }
3513 52 : if (ZoneCheck(i) == 1) {
3514 0 : ShowSevereError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3515 0 : ShowContinueError(m_state, " has only one surface defined in " + CurrentModuleObject);
3516 0 : ShowContinueError(m_state, " Each zone should have at least two surfaces defined in " + CurrentModuleObject);
3517 0 : ErrorsFound = true;
3518 : }
3519 52 : if (ZoneCheck(i) > 1) {
3520 52 : bool SurfaceFound = false;
3521 137 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3522 137 : if (MultizoneSurfaceData(j).NodeNums[0] == i) {
3523 31 : if (ZoneBCCheck(i) != MultizoneSurfaceData(j).NodeNums[1]) {
3524 31 : SurfaceFound = true;
3525 31 : break;
3526 : }
3527 : }
3528 106 : if (MultizoneSurfaceData(j).NodeNums[1] == i) {
3529 21 : if (ZoneBCCheck(i) != MultizoneSurfaceData(j).NodeNums[0]) {
3530 21 : SurfaceFound = true;
3531 21 : break;
3532 : }
3533 : }
3534 : }
3535 52 : if (!SurfaceFound) {
3536 0 : ShowWarningError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3537 0 : ShowContinueError(m_state,
3538 0 : "has more than one surface defined in " + CurrentModuleObject + ", but has the same boundary conditions");
3539 0 : ShowContinueError(m_state, "Please check inputs of " + CurrentModuleObject);
3540 : }
3541 : }
3542 : }
3543 25 : ZoneCheck.deallocate();
3544 25 : ZoneBCCheck.deallocate();
3545 :
3546 : // Validate CP Value number
3547 25 : if (simulation_control.iWPCCnt == iWPCCntr::Input) { // Surface-Average does not need inputs of external nodes
3548 : // Ensure different curve is used to avoid a single side boundary condition
3549 10 : found = false;
3550 10 : bool differentAngle = false;
3551 12 : for (int j = 2; j <= AirflowNetworkNumOfExtNode; ++j) {
3552 10 : if (MultizoneExternalNodeData(j - 1).curve != MultizoneExternalNodeData(j).curve) {
3553 8 : found = true;
3554 8 : break;
3555 : } else {
3556 : // If the curves are the same, then check to see if the azimuths are different
3557 2 : if (MultizoneExternalNodeData(j - 1).azimuth != MultizoneExternalNodeData(j).azimuth) {
3558 2 : differentAngle = MultizoneExternalNodeData(j - 1).symmetricCurve || MultizoneExternalNodeData(j).symmetricCurve;
3559 : }
3560 : }
3561 : }
3562 10 : if (!found && !differentAngle) {
3563 0 : ShowSevereError(m_state,
3564 : "The same Wind Pressure Coefficient Curve name is used in all AirflowNetwork:MultiZone:ExternalNode objects.");
3565 0 : ShowContinueError(
3566 : m_state, "Please input at least two different Wind Pressure Coefficient Curve names to avoid single side boundary condition.");
3567 0 : ErrorsFound = true;
3568 : }
3569 : }
3570 :
3571 : // Assign occupant ventilation control number from zone to surface
3572 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3573 143 : int j = MultizoneSurfaceData(i).SurfNum;
3574 143 : auto const &surf = m_state.dataSurface->Surface(j);
3575 143 : if (surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
3576 107 : surf.OriginalClass == SurfaceClass::GlassDoor) {
3577 93 : for (n = 1; n <= AirflowNetworkNumOfZones; ++n) {
3578 57 : if (MultizoneZoneData(n).ZoneNum == m_state.dataSurface->Surface(j).Zone) {
3579 36 : if (MultizoneZoneData(n).OccupantVentilationControlNum > 0 && MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) {
3580 0 : MultizoneSurfaceData(i).OccupantVentilationControlNum = MultizoneZoneData(n).OccupantVentilationControlNum;
3581 : }
3582 : }
3583 : }
3584 : }
3585 : }
3586 :
3587 : // Read AirflowNetwork Intra zone node
3588 25 : CurrentModuleObject = "AirflowNetwork:IntraZone:Node";
3589 25 : IntraZoneNumOfNodes = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3590 25 : if (IntraZoneNumOfNodes > 0) {
3591 1 : IntraZoneNodeData.allocate(IntraZoneNumOfNodes);
3592 6 : for (int i = 1; i <= IntraZoneNumOfNodes; ++i) {
3593 5 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3594 : CurrentModuleObject,
3595 : i,
3596 : Alphas,
3597 : NumAlphas,
3598 : Numbers,
3599 : NumNumbers,
3600 : IOStatus,
3601 : lNumericBlanks,
3602 : lAlphaBlanks,
3603 : cAlphaFields,
3604 : cNumericFields);
3605 5 : IntraZoneNodeData(i).Name = Alphas(1); // Name of node
3606 5 : IntraZoneNodeData(i).RAFNNodeName = Alphas(2); // Name of RoomAir node
3607 5 : IntraZoneNodeData(i).Height = Numbers(1); // Nodal height
3608 : // verify RoomAir model node names(May be too early to check and move to another subroutine)
3609 : bool Errorfound1;
3610 5 : GetRAFNNodeNum(
3611 5 : m_state, IntraZoneNodeData(i).RAFNNodeName, IntraZoneNodeData(i).ZoneNum, IntraZoneNodeData(i).RAFNNodeNum, Errorfound1);
3612 5 : if (Errorfound1) {
3613 0 : ErrorsFound = true;
3614 : }
3615 5 : if (IntraZoneNodeData(i).RAFNNodeNum == 0) {
3616 0 : ShowSevereError(m_state,
3617 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "' invalid name " + cAlphaFields(2) + "='" +
3618 0 : Alphas(2));
3619 0 : ErrorsFound = true;
3620 : }
3621 10 : IntraZoneNodeData(i).AFNZoneNum =
3622 5 : Util::FindItemInList(Alphas(3), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3623 5 : if (MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).RAFNNodeNum == 0) {
3624 1 : GetRAFNNodeNum(m_state,
3625 1 : MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).ZoneName,
3626 1 : IntraZoneNodeData(i).ZoneNum,
3627 1 : MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).RAFNNodeNum,
3628 : Errorfound1);
3629 : }
3630 5 : if (IntraZoneNodeData(i).ZoneNum == 0) {
3631 0 : ShowSevereError(m_state,
3632 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "' the Zone is not defined for " +
3633 0 : cAlphaFields(3) + "='" + Alphas(3));
3634 0 : ErrorsFound = true;
3635 : }
3636 : }
3637 : }
3638 :
3639 : // check model compatibility
3640 25 : if (IntraZoneNumOfNodes > 0) {
3641 1 : if (!Util::SameString(SimAirNetworkKey, "MultizoneWithoutDistribution")) {
3642 0 : ShowSevereError(m_state,
3643 0 : format(RoutineName) + CurrentModuleObject +
3644 0 : " model requires Simulation Control = MultizoneWithoutDistribution, while the input choice is " +
3645 0 : SimAirNetworkKey + ".");
3646 0 : ErrorsFound = true;
3647 0 : ShowFatalError(
3648 : m_state,
3649 0 : format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
3650 : }
3651 : }
3652 :
3653 25 : NumOfNodesIntraZone = IntraZoneNumOfNodes;
3654 : // check zone node
3655 25 : IntraZoneNumOfZones = 0;
3656 77 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3657 52 : if (MultizoneZoneData(i).RAFNNodeNum > 0) {
3658 1 : IntraZoneNumOfZones += 1;
3659 : }
3660 : }
3661 :
3662 : // Override error check due to RoomAirNode for the time being
3663 :
3664 : // Read AirflowNetwork Intra linkage
3665 25 : CurrentModuleObject = "AirflowNetwork:IntraZone:Linkage";
3666 25 : IntraZoneNumOfLinks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3667 25 : if (IntraZoneNumOfLinks > 0) {
3668 1 : IntraZoneLinkageData.allocate(IntraZoneNumOfLinks);
3669 1 : UniqueAirflowNetworkSurfaceName.reserve(IntraZoneNumOfLinks);
3670 7 : for (int i = 1; i <= IntraZoneNumOfLinks; ++i) {
3671 6 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3672 : CurrentModuleObject,
3673 : i,
3674 : Alphas,
3675 : NumAlphas,
3676 : Numbers,
3677 : NumNumbers,
3678 : IOStatus,
3679 : lNumericBlanks,
3680 : lAlphaBlanks,
3681 : cAlphaFields,
3682 : cNumericFields);
3683 6 : IntraZoneLinkageData(i).Name = Alphas(1); // Name of linkage
3684 6 : IntraZoneLinkageData(i).NodeNames[0] = Alphas(2);
3685 6 : IntraZoneLinkageData(i).NodeHeights[0] = 0.0;
3686 6 : IntraZoneLinkageData(i).NodeNames[1] = Alphas(3);
3687 6 : IntraZoneLinkageData(i).NodeHeights[1] = 0.0;
3688 6 : IntraZoneLinkageData(i).CompName = Alphas(4);
3689 6 : if (!lAlphaBlanks(5)) {
3690 : // Perform simple test first.The comprehensive input validation will occur later
3691 : // Check valid surface name
3692 0 : IntraZoneLinkageData(i).SurfaceName = Alphas(5);
3693 0 : IntraZoneLinkageData(i).LinkNum =
3694 0 : Util::FindItemInList(Alphas(5), MultizoneSurfaceData, &MultizoneSurfaceProp::SurfName, AirflowNetworkNumOfSurfaces);
3695 0 : if (IntraZoneLinkageData(i).LinkNum == 0) {
3696 0 : ShowSevereError(m_state,
3697 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(5) +
3698 0 : " given = " + Alphas(5) + " in AirflowNetwork:MultiZone:Surface objects");
3699 0 : ErrorsFound = true;
3700 : }
3701 0 : GlobalNames::VerifyUniqueInterObjectName(
3702 0 : m_state, UniqueAirflowNetworkSurfaceName, Alphas(5), CurrentModuleObject, cAlphaFields(5), ErrorsFound);
3703 : }
3704 6 : if (Util::SameString(Alphas(2), Alphas(3))) {
3705 0 : ShowSevereError(m_state,
3706 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid inputs of both node name with " +
3707 0 : Alphas(2) + " = " + Alphas(3));
3708 0 : ErrorsFound = true;
3709 : }
3710 : // Check valid node names
3711 6 : IntraZoneLinkageData(i).NodeNums[0] = Util::FindItemInList(Alphas(2), IntraZoneNodeData, IntraZoneNumOfNodes);
3712 6 : if (IntraZoneLinkageData(i).NodeNums[0] == 0) {
3713 0 : IntraZoneLinkageData(i).NodeNums[0] =
3714 0 : Util::FindItemInList(Alphas(2), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3715 0 : IntraZoneLinkageData(i).NodeHeights[0] = Zone(MultizoneZoneData(IntraZoneLinkageData(i).NodeNums[0]).ZoneNum).Centroid.z;
3716 0 : if (IntraZoneLinkageData(i).NodeNums[0] == 0) {
3717 0 : ShowSevereError(m_state,
3718 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(2) +
3719 0 : " given = " + Alphas(2) + " in AirflowNetwork:IntraZone:Node and AirflowNetwork:MultiZone:Zone objects");
3720 0 : ErrorsFound = true;
3721 : }
3722 : } else {
3723 6 : IntraZoneLinkageData(i).NodeHeights[0] = IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0]).Height;
3724 6 : IntraZoneLinkageData(i).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0] + AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
3725 : }
3726 6 : IntraZoneLinkageData(i).NodeNums[1] = Util::FindItemInList(Alphas(3), IntraZoneNodeData, IntraZoneNumOfNodes);
3727 6 : if (IntraZoneLinkageData(i).NodeNums[1] == 0) {
3728 2 : IntraZoneLinkageData(i).NodeNums[1] =
3729 2 : Util::FindItemInList(Alphas(3), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3730 2 : if (IntraZoneLinkageData(i).NodeNums[1] > 0) {
3731 2 : IntraZoneLinkageData(i).NodeHeights[1] = Zone(MultizoneZoneData(IntraZoneLinkageData(i).NodeNums[1]).ZoneNum).Centroid.z;
3732 : } else {
3733 0 : if (simulation_control.iWPCCnt == iWPCCntr::Input) { // Surface-Average does not need inputs of external nodes
3734 0 : IntraZoneLinkageData(i).NodeNums[1] = MultizoneSurfaceData(IntraZoneLinkageData(i).LinkNum).NodeNums[1];
3735 0 : if (IntraZoneLinkageData(i).NodeNums[1] == 0) {
3736 0 : ShowSevereError(m_state,
3737 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(3) +
3738 0 : " given = " + Alphas(3) +
3739 : " in AirflowNetwork:IntraZone:Node or AirflowNetwork:MultiZone:Zone or "
3740 : "AirflowNetwork:MultiZone:ExternalNode objects");
3741 0 : ErrorsFound = true;
3742 : }
3743 : }
3744 0 : if (simulation_control.iWPCCnt == iWPCCntr::SurfAvg) {
3745 0 : if (!lAlphaBlanks(3)) {
3746 0 : ShowWarningError(m_state,
3747 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + " The input of " + cAlphaFields(3) +
3748 : " is not needed, ");
3749 0 : ShowContinueError(m_state,
3750 : " since AirflowNetwork Wind Pressure Coefficient Type = SURFACE-AVERAGE CALCULATION. The "
3751 : "simulation continues...");
3752 : }
3753 0 : IntraZoneLinkageData(i).NodeNums[1] = MultizoneSurfaceData(IntraZoneLinkageData(i).LinkNum).NodeNums[1];
3754 : }
3755 : }
3756 : } else {
3757 4 : IntraZoneLinkageData(i).NodeHeights[1] = IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1]).Height;
3758 4 : IntraZoneLinkageData(i).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1] + AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
3759 : }
3760 : // Ensure the both linked nodes for a surface are not zone nodes.One of nodes has to be an intrazone node
3761 8 : if (IntraZoneLinkageData(i).NodeNums[1] <= AirflowNetworkNumOfZones &&
3762 2 : IntraZoneLinkageData(i).NodeNums[0] <= AirflowNetworkNumOfZones) {
3763 0 : ShowSevereError(m_state,
3764 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid node inputs " + Alphas(2) + " and " +
3765 0 : Alphas(3) + " are zone nodes");
3766 0 : ErrorsFound = true;
3767 : }
3768 6 : if (IntraZoneLinkageData(i).NodeNums[0] <= AirflowNetworkNumOfZones &&
3769 6 : IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode && lAlphaBlanks(5)) {
3770 0 : if (IntraZoneLinkageData(i).NodeNums[0] !=
3771 0 : m_state.afn->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3772 0 : .AFNZoneNum) {
3773 0 : ShowSevereError(
3774 : m_state,
3775 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + ": Invalid zone inputs between Node and Link " +
3776 0 : Alphas(2) + " and " +
3777 0 : m_state.afn->MultizoneZoneData(IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0]).AFNZoneNum).ZoneName);
3778 0 : ErrorsFound = true;
3779 : }
3780 : }
3781 6 : if (IntraZoneLinkageData(i).NodeNums[1] <= AirflowNetworkNumOfZones &&
3782 6 : IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode && lAlphaBlanks(5)) {
3783 2 : if (IntraZoneLinkageData(i).NodeNums[1] !=
3784 2 : m_state.afn->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3785 2 : .AFNZoneNum) {
3786 0 : ShowSevereError(
3787 : m_state,
3788 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + ": Invalid zone inputs between Node and Link " +
3789 0 : Alphas(3) + " and " +
3790 0 : m_state.afn->MultizoneZoneData(IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1]).AFNZoneNum).ZoneName);
3791 0 : ErrorsFound = true;
3792 : }
3793 : }
3794 : }
3795 :
3796 : // Reset the number of intrazone links for a given surface
3797 1 : NumOfLinksIntraZone = IntraZoneNumOfLinks;
3798 7 : for (int i = 1; i <= IntraZoneNumOfLinks; ++i) {
3799 6 : int j = IntraZoneLinkageData(i).LinkNum;
3800 6 : if (j > 0) {
3801 : // Revise data in multizone object
3802 0 : NumOfLinksIntraZone = NumOfLinksIntraZone - 1;
3803 0 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == 0) {
3804 : // Exterior surface NodeNums[1] should be equal
3805 0 : if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3806 0 : MultizoneSurfaceData(j).RAFNflag = true;
3807 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3808 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3809 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3810 0 : MultizoneSurfaceData(j).RAFNflag = true;
3811 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3812 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3813 : } else {
3814 0 : ShowSevereError(m_state,
3815 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3816 0 : IntraZoneLinkageData(i).Name +
3817 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3818 0 : ErrorsFound = true;
3819 : }
3820 : } else {
3821 : // Interior surface
3822 0 : if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode &&
3823 0 : IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3824 0 : MultizoneSurfaceData(j).RAFNflag = true;
3825 0 : if (MultizoneZoneData(MultizoneSurfaceData(j).NodeNums[0]).ZoneNum ==
3826 0 : m_state.afn
3827 0 : ->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3828 0 : .ZoneNum) {
3829 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3830 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3831 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1];
3832 : } else {
3833 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3834 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3835 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[0];
3836 : }
3837 0 : } else if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3838 0 : MultizoneSurfaceData(j).RAFNflag = true;
3839 0 : if (IntraZoneLinkageData(i).NodeNums[1] == MultizoneSurfaceData(j).NodeNums[0]) {
3840 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[0];
3841 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] == MultizoneSurfaceData(j).NodeNums[1]) {
3842 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3843 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3844 : } else {
3845 0 : ShowSevereError(m_state,
3846 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3847 0 : IntraZoneLinkageData(i).Name +
3848 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3849 0 : ErrorsFound = true;
3850 : }
3851 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3852 0 : MultizoneSurfaceData(j).RAFNflag = true;
3853 0 : if (IntraZoneLinkageData(i).NodeNums[0] == MultizoneSurfaceData(j).NodeNums[0]) {
3854 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1];
3855 0 : } else if (IntraZoneLinkageData(i).NodeNums[0] == MultizoneSurfaceData(j).NodeNums[1]) {
3856 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3857 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3858 : } else {
3859 0 : ShowSevereError(m_state,
3860 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3861 0 : IntraZoneLinkageData(i).Name +
3862 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3863 0 : ErrorsFound = true;
3864 : }
3865 : }
3866 : }
3867 : }
3868 : }
3869 : // Remove links with surface defined in Multizone : Surface objects
3870 1 : if (NumOfLinksIntraZone < IntraZoneNumOfLinks) {
3871 0 : int link = 1;
3872 0 : while (link <= NumOfLinksIntraZone) {
3873 0 : if (IntraZoneLinkageData(link).LinkNum > 0) {
3874 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3875 0 : ShowWarningError(m_state,
3876 0 : format(RoutineName) + CurrentModuleObject + "='" + IntraZoneLinkageData(link).Name +
3877 : " is reomoved from the list due to the surface conncetion from Intrazone to Interzone.");
3878 : }
3879 0 : for (int j = link; j <= IntraZoneNumOfLinks - 1; ++j) {
3880 0 : IntraZoneLinkageData(j) = IntraZoneLinkageData(j + 1);
3881 : }
3882 : }
3883 0 : if (IntraZoneLinkageData(link).LinkNum == 0) {
3884 0 : link = link + 1;
3885 : }
3886 : }
3887 0 : if (IntraZoneLinkageData(link).LinkNum > 0) {
3888 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3889 0 : ShowWarningError(m_state,
3890 0 : format(RoutineName) + CurrentModuleObject + "='" + IntraZoneLinkageData(link).Name +
3891 : " is removed from the list due to the surface connection from Intrazone to Interzone.");
3892 : }
3893 : }
3894 : }
3895 : }
3896 :
3897 : // Read AirflowNetwork Distribution system node
3898 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Node";
3899 25 : DisSysNumOfNodes = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3900 25 : if (DisSysNumOfNodes > 0) {
3901 7 : DisSysNodeData.allocate(DisSysNumOfNodes);
3902 142 : for (int i = 1; i <= DisSysNumOfNodes; ++i) {
3903 135 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3904 : CurrentModuleObject,
3905 : i,
3906 : Alphas,
3907 : NumAlphas,
3908 : Numbers,
3909 : NumNumbers,
3910 : IOStatus,
3911 : lNumericBlanks,
3912 : lAlphaBlanks,
3913 : cAlphaFields,
3914 : cNumericFields);
3915 135 : DisSysNodeData(i).Name = Alphas(1); // Name of node
3916 135 : DisSysNodeData(i).EPlusName = Alphas(2); // Name of associated EnergyPlus node
3917 135 : DisSysNodeData(i).EPlusType = Alphas(3); // Name of associated EnergyPlus type
3918 135 : DisSysNodeData(i).Height = Numbers(1); // Nodal height
3919 135 : DisSysNodeData(i).EPlusNodeNum = 0; // EPlus node number
3920 : // verify EnergyPlus object type
3921 381 : if (Util::SameString(Alphas(3), "AirLoopHVAC:ZoneMixer") || Util::SameString(Alphas(3), "AirLoopHVAC:ZoneSplitter") ||
3922 348 : Util::SameString(Alphas(3), "AirLoopHVAC:OutdoorAirSystem") || Util::SameString(Alphas(3), "OAMixerOutdoorAirStreamNode") ||
3923 339 : Util::SameString(Alphas(3), "OutdoorAir:NodeList") || Util::SameString(Alphas(3), "OutdoorAir:Node") ||
3924 375 : Util::SameString(Alphas(3), "Other") || lAlphaBlanks(3)) {
3925 : } else {
3926 0 : ShowSevereError(m_state,
3927 0 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" invalid " + cAlphaFields(3) + "=\"" +
3928 0 : Alphas(3) + "\" illegal key.");
3929 0 : ShowContinueError(m_state,
3930 : "Valid keys are: AirLoopHVAC:ZoneMixer, AirLoopHVAC:ZoneSplitter, AirLoopHVAC:OutdoorAirSystem, "
3931 : "OAMixerOutdoorAirStreamNode, OutdoorAir:NodeList, OutdoorAir:Node or Other.");
3932 0 : ErrorsFound = true;
3933 : }
3934 : // Avoid duplication of EPlusName
3935 1695 : for (int j = 1; j < i; ++j) {
3936 1560 : if (!Util::SameString(Alphas(2), "")) {
3937 1088 : if (Util::SameString(DisSysNodeData(j).EPlusName, Alphas(2))) {
3938 2 : ShowSevereError(m_state,
3939 2 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" Duplicated " + cAlphaFields(2) +
3940 3 : "=\"" + Alphas(2) + "\". Please make a correction.");
3941 1 : ErrorsFound = true;
3942 : }
3943 : }
3944 : }
3945 : }
3946 : } else {
3947 18 : if (distribution_simulated) {
3948 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
3949 0 : ErrorsFound = true;
3950 : }
3951 : }
3952 :
3953 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Duct";
3954 25 : if (DisSysNumOfDucts == 0) {
3955 18 : if (distribution_simulated) {
3956 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
3957 0 : ErrorsFound = true;
3958 : }
3959 : }
3960 :
3961 : // Read AirflowNetwork distribution system component: DuctViewFactors
3962 25 : CurrentModuleObject = "AirflowNetwork:Distribution:DuctViewFactors";
3963 25 : DisSysNumOfDuctViewFactors = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3964 25 : if (DisSysNumOfDuctViewFactors > 0) {
3965 2 : AirflowNetworkLinkageViewFactorData.allocate(DisSysNumOfDuctViewFactors);
3966 4 : for (int i = 1; i <= DisSysNumOfDuctViewFactors; ++i) {
3967 2 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3968 : CurrentModuleObject,
3969 : i,
3970 : Alphas,
3971 : NumAlphas,
3972 : Numbers,
3973 : NumNumbers,
3974 : IOStatus,
3975 : lNumericBlanks,
3976 : lAlphaBlanks,
3977 : cAlphaFields,
3978 : cNumericFields);
3979 :
3980 2 : auto &this_VF_object(AirflowNetworkLinkageViewFactorData(i));
3981 :
3982 2 : this_VF_object.LinkageName = Alphas(1); // Name of linkage
3983 :
3984 : // Surface exposure fraction
3985 2 : if (Numbers(2) > 1) {
3986 0 : ShowWarningError(m_state,
3987 0 : "Duct surface exposure fraction greater than 1. Check input in: " + CurrentModuleObject + " " +
3988 0 : this_VF_object.LinkageName);
3989 0 : ShowContinueError(m_state, "Using value of 1 for surface exposure fraction");
3990 0 : this_VF_object.DuctExposureFraction = 1;
3991 2 : } else if (Numbers(2) < 0) {
3992 0 : ShowWarningError(
3993 0 : m_state, "Surface exposure fraction less than 0. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
3994 0 : ShowContinueError(m_state, "Using value of 0 for surface exposure fraction");
3995 0 : this_VF_object.DuctExposureFraction = 0;
3996 : } else {
3997 2 : this_VF_object.DuctExposureFraction = Numbers(1);
3998 : }
3999 :
4000 : // Duct surface emittance
4001 2 : if (Numbers(2) > 1) {
4002 0 : ShowWarningError(
4003 0 : m_state, "Duct surface emittance greater than 1. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4004 0 : ShowContinueError(m_state, "Using value of 1 for surface emittance");
4005 0 : this_VF_object.DuctEmittance = 1;
4006 2 : } else if (Numbers(2) < 0) {
4007 0 : ShowWarningError(
4008 0 : m_state, "Surface exposure fraction less than 0. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4009 0 : ShowContinueError(m_state, "Using value of 0 for surface exposure fraction");
4010 0 : this_VF_object.DuctEmittance = 0;
4011 : } else {
4012 2 : this_VF_object.DuctEmittance = Numbers(2);
4013 : }
4014 :
4015 2 : this_VF_object.ObjectNum = i;
4016 :
4017 2 : int numSurfaces = NumAlphas - 1;
4018 :
4019 2 : this_VF_object.LinkageSurfaceData.allocate(numSurfaces);
4020 :
4021 12 : for (int surfNum = 1; surfNum < NumAlphas; ++surfNum) {
4022 10 : this_VF_object.LinkageSurfaceData(surfNum).SurfaceName = Alphas(surfNum + 1); // Surface name
4023 10 : this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum = Util::FindItemInList(Alphas(surfNum + 1), m_state.dataSurface->Surface);
4024 :
4025 10 : if (this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum == 0) {
4026 0 : ShowFatalError(
4027 0 : m_state, "Surface " + Alphas(surfNum + 1) + " not found. See: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4028 : }
4029 :
4030 : // Surface view factor
4031 10 : if (!m_state.dataSurface->Surface(this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum).HeatTransSurf) {
4032 0 : ShowWarningError(m_state,
4033 0 : "Surface=" + Alphas(surfNum + 1) + " is not a heat transfer surface. Check input in: " +
4034 0 : CurrentModuleObject + " " + this_VF_object.LinkageName);
4035 0 : ShowContinueError(m_state, "Using value of 0 for view factor");
4036 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 0;
4037 10 : } else if (Numbers(surfNum + 2) > 1) {
4038 0 : ShowWarningError(m_state,
4039 0 : "View factor for surface " + Alphas(surfNum + 1) +
4040 0 : " greater than 1. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4041 0 : ShowContinueError(m_state, "Using value of 1 for view factor");
4042 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 1;
4043 10 : } else if (Numbers(surfNum + 2) < 0) {
4044 0 : ShowWarningError(m_state,
4045 0 : "View factor for surface " + Alphas(surfNum + 1) + " less than 0. Check input in: " + CurrentModuleObject +
4046 0 : " " + this_VF_object.LinkageName);
4047 0 : ShowContinueError(m_state, "Using value of 0 for view factor");
4048 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 0;
4049 : } else {
4050 10 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = Numbers(surfNum + 2);
4051 : }
4052 : }
4053 : }
4054 : }
4055 :
4056 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Fan";
4057 25 : if (DisSysNumOfCVFs == 0) {
4058 18 : if (distribution_simulated) {
4059 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
4060 0 : ErrorsFound = true;
4061 : }
4062 : }
4063 :
4064 : // Read PressureController
4065 25 : CurrentModuleObject = "AirflowNetwork:ZoneControl:PressureController";
4066 25 : NumOfPressureControllers = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
4067 25 : if (NumOfPressureControllers > 1) {
4068 0 : ShowSevereError(m_state,
4069 0 : format(RoutineName) + "More " + CurrentModuleObject + " are found. Currently only one( \"1\") " + CurrentModuleObject +
4070 : " object per simulation is allowed when using AirflowNetwork Distribution Systems.");
4071 0 : ShowFatalError(
4072 0 : m_state, format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
4073 : }
4074 :
4075 25 : if (NumOfPressureControllers > 0) {
4076 1 : PressureControllerData.allocate(NumOfPressureControllers);
4077 2 : for (int i = 1; i <= NumOfPressureControllers; ++i) {
4078 1 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
4079 : CurrentModuleObject,
4080 : i,
4081 : Alphas,
4082 : NumAlphas,
4083 : Numbers,
4084 : NumNumbers,
4085 : IOStatus,
4086 : lNumericBlanks,
4087 : lAlphaBlanks,
4088 : cAlphaFields,
4089 : cNumericFields);
4090 :
4091 1 : ErrorObjectHeader eoh{RoutineName, CurrentModuleObject, Alphas(1)};
4092 :
4093 1 : PressureControllerData(i).Name = Alphas(1); // Object Name
4094 1 : PressureControllerData(i).ZoneName = Alphas(2); // Zone name
4095 1 : PressureControllerData(i).ZoneNum = Util::FindItemInList(Alphas(2), Zone);
4096 2 : PressureControllerData(i).AFNNodeNum =
4097 1 : Util::FindItemInList(Alphas(2), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
4098 1 : if (PressureControllerData(i).ZoneNum == 0) {
4099 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(2) + " given.");
4100 0 : ShowContinueError(m_state, "..invalid " + cAlphaFields(2) + " = \"" + PressureControllerData(i).ZoneName + "\"");
4101 0 : ErrorsFound = true;
4102 : }
4103 :
4104 1 : PressureControllerData(i).ControlObjectType = Alphas(3); // Control Object Type
4105 1 : PressureControllerData(i).ControlObjectName = Alphas(4); // Control Object Name
4106 :
4107 : {
4108 : // This SELECT_CASE_var will go on input refactor, no need to fix
4109 1 : auto const SELECT_CASE_var(Util::makeUPPER(Alphas(3)));
4110 1 : if (SELECT_CASE_var == "AIRFLOWNETWORK:MULTIZONE:COMPONENT:ZONEEXHAUSTFAN") {
4111 0 : PressureControllerData(i).ControlTypeSet = PressureCtrlExhaust;
4112 1 : } else if (SELECT_CASE_var == "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT:RELIEFAIRFLOW") {
4113 1 : PressureControllerData(i).ControlTypeSet = PressureCtrlRelief;
4114 : } else { // Error
4115 0 : ShowSevereError(m_state,
4116 0 : format(RoutineName) + CurrentModuleObject + " object, The entered choice for " + cAlphaFields(3) +
4117 0 : " is not valid = \"" + PressureControllerData(i).Name + "\"");
4118 0 : ShowContinueError(m_state,
4119 : "Valid choices are "
4120 : "\"AirflowNetwork:MultiZone:Component:ZoneExhaustFan\",\"AirflowNetwork:Distribution:Component:"
4121 : "ReliefAirFlow\"");
4122 0 : ShowContinueError(m_state, "The input choice is " + Alphas(3));
4123 0 : ErrorsFound = true;
4124 : }
4125 1 : }
4126 :
4127 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlExhaust) {
4128 : // This is not great
4129 0 : bool is_EXF{false};
4130 0 : auto afe = elements.find(Alphas(4));
4131 0 : if (afe != elements.end()) {
4132 0 : is_EXF = afe->second->type() == ComponentType::EXF;
4133 : }
4134 0 : if (!is_EXF) {
4135 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, an invalid name is given:");
4136 0 : ShowContinueError(m_state, ".. invalid " + cAlphaFields(4) + " = \"" + Alphas(4) + "\".");
4137 0 : ErrorsFound = true;
4138 : }
4139 0 : }
4140 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlRelief) {
4141 : // This is not great
4142 1 : bool is_REL{false};
4143 1 : auto afe = elements.find(Alphas(4));
4144 1 : if (afe != elements.end()) {
4145 1 : is_REL = afe->second->type() == ComponentType::REL;
4146 : }
4147 1 : if (!is_REL) {
4148 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, an invalid name is given:");
4149 0 : ShowContinueError(m_state, ".. invalid " + cAlphaFields(4) + " = \"" + Alphas(4) + "\".");
4150 0 : ErrorsFound = true;
4151 : }
4152 1 : }
4153 :
4154 1 : if (lAlphaBlanks(5)) {
4155 1 : PressureControllerData(i).availSched = Sched::GetScheduleAlwaysOn(m_state);
4156 0 : } else if ((PressureControllerData(i).availSched = Sched::GetSchedule(m_state, Alphas(5))) == nullptr) {
4157 0 : ShowSevereItemNotFound(m_state, eoh, cAlphaFields(5), Alphas(5));
4158 0 : ErrorsFound = true;
4159 : }
4160 :
4161 1 : if ((PressureControllerData(i).presSetpointSched = Sched::GetSchedule(m_state, Alphas(6))) == nullptr) {
4162 0 : ShowSevereItemNotFound(m_state, eoh, cAlphaFields(6), Alphas(6));
4163 0 : ErrorsFound = true;
4164 : }
4165 : }
4166 : }
4167 :
4168 : // Assign numbers of nodes and linkages
4169 25 : if (simulation_control.type != ControlType::NoMultizoneOrDistribution) {
4170 25 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
4171 10 : NumOfNodesMultiZone = AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
4172 : } else {
4173 15 : NumOfNodesMultiZone = AirflowNetworkNumOfZones + NumOfExtNodes;
4174 : }
4175 25 : NumOfLinksMultiZone = AirflowNetworkNumOfSurfaces;
4176 25 : AirflowNetworkNumOfNodes = NumOfNodesMultiZone;
4177 25 : if (NumOfNodesIntraZone > 0) {
4178 1 : AirflowNetworkNumOfNodes = AirflowNetworkNumOfNodes + NumOfNodesIntraZone;
4179 : }
4180 25 : AirflowNetworkNumOfLinks = NumOfLinksMultiZone;
4181 25 : if (NumOfLinksIntraZone > 0) {
4182 1 : AirflowNetworkNumOfLinks = AirflowNetworkNumOfLinks + NumOfLinksIntraZone;
4183 : }
4184 : }
4185 25 : if (distribution_simulated) {
4186 7 : AirflowNetworkNumOfNodes = NumOfNodesMultiZone + DisSysNumOfNodes + NumOfNodesIntraZone;
4187 : }
4188 :
4189 : // Assign node data
4190 25 : AirflowNetworkNodeData.allocate(AirflowNetworkNumOfNodes);
4191 : // Zone node
4192 77 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
4193 52 : AirflowNetworkNodeData(i).Name = MultizoneZoneData(i).ZoneName;
4194 52 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4195 52 : AirflowNetworkNodeData(i).EPlusZoneNum = MultizoneZoneData(i).ZoneNum;
4196 52 : AirflowNetworkNodeData(i).NodeHeight = MultizoneZoneData(i).Height;
4197 : }
4198 : // External node
4199 25 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
4200 42 : for (int i = AirflowNetworkNumOfZones + 1; i <= NumOfNodesMultiZone; ++i) {
4201 32 : AirflowNetworkNodeData(i).Name = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).Name;
4202 32 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4203 32 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4204 32 : AirflowNetworkNodeData(i).NodeHeight = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).height;
4205 32 : AirflowNetworkNodeData(i).ExtNodeNum = i - AirflowNetworkNumOfZones;
4206 32 : AirflowNetworkNodeData(i).OutAirNodeNum = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).OutAirNodeNum;
4207 : }
4208 : } else { // Surface-Average input
4209 73 : for (int i = AirflowNetworkNumOfZones + 1; i <= NumOfNodesMultiZone; ++i) {
4210 58 : n = i - AirflowNetworkNumOfZones;
4211 58 : AirflowNetworkNodeData(i).Name = MultizoneExternalNodeData(n).Name;
4212 58 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4213 58 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4214 58 : AirflowNetworkNodeData(i).ExtNodeNum = n;
4215 : }
4216 : }
4217 :
4218 : // Intrazone node
4219 25 : if (NumOfNodesIntraZone > 0) {
4220 6 : for (int i = NumOfNodesMultiZone + 1; i <= NumOfNodesMultiZone + NumOfNodesIntraZone; ++i) {
4221 5 : n = i - NumOfNodesMultiZone;
4222 5 : AirflowNetworkNodeData(i).Name = IntraZoneNodeData(n).Name;
4223 5 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4224 5 : AirflowNetworkNodeData(i).EPlusZoneNum = IntraZoneNodeData(n).ZoneNum;
4225 5 : AirflowNetworkNodeData(i).NodeHeight = IntraZoneNodeData(n).Height;
4226 5 : AirflowNetworkNodeData(i).RAFNNodeNum = IntraZoneNodeData(n).RAFNNodeNum;
4227 : }
4228 2 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
4229 1 : if (MultizoneZoneData(i).RAFNNodeNum > 0) {
4230 1 : AirflowNetworkNodeData(i).RAFNNodeNum = MultizoneZoneData(i).RAFNNodeNum;
4231 : }
4232 : }
4233 : }
4234 25 : NumOfNodesMultiZone = NumOfNodesMultiZone + NumOfNodesIntraZone;
4235 :
4236 : // Check whether Distribution system is simulated
4237 25 : if (AirflowNetworkNumOfNodes > NumOfNodesMultiZone) {
4238 : // Search node types: OAMixerOutdoorAirStreamNode, OutdoorAir:NodeList, and OutdoorAir:Node
4239 7 : int j = 0;
4240 142 : for (int i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
4241 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
4242 3 : ++j;
4243 : }
4244 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:NodeList")) {
4245 0 : ++j;
4246 : }
4247 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:Node")) {
4248 0 : ++j;
4249 : }
4250 : }
4251 :
4252 142 : for (int i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
4253 135 : AirflowNetworkNodeData(i).Name = DisSysNodeData(i - NumOfNodesMultiZone).Name;
4254 135 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4255 135 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4256 135 : AirflowNetworkNodeData(i).NodeHeight = DisSysNodeData(i - NumOfNodesMultiZone).Height;
4257 135 : AirflowNetworkNodeData(i).EPlusNodeNum = DisSysNodeData(i - NumOfNodesMultiZone).EPlusNodeNum;
4258 : // Get mixer information
4259 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:ZoneMixer")) {
4260 8 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::MIX;
4261 : }
4262 : // Get splitter information
4263 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:ZoneSplitter")) {
4264 8 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPL;
4265 : }
4266 : // Get outside air system information
4267 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
4268 3 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::OAN;
4269 : }
4270 : // Get OA system inlet information 'OAMixerOutdoorAirStreamNode' was specified as an outdoor air node implicitly
4271 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
4272 3 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::EXT;
4273 3 : AirflowNetworkNodeData(i).ExtNodeNum = AirflowNetworkNumOfExtNode + 1;
4274 3 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4275 : }
4276 270 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:NodeList") ||
4277 270 : Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:Node")) {
4278 0 : if (j > 1) {
4279 0 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::EXT;
4280 0 : AirflowNetworkNodeData(i).ExtNodeNum = AirflowNetworkNumOfExtNode + 1;
4281 0 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4282 : } else {
4283 0 : ShowSevereError(m_state,
4284 0 : format(RoutineName) + "AirflowNetwork:Distribution:Node: The outdoor air node is found at " +
4285 0 : AirflowNetworkNodeData(i).Name);
4286 0 : ShowContinueError(m_state,
4287 : "The node with Component Object Type = OAMixerOutdoorAirStreamNode is not found. Please check inputs.");
4288 0 : ErrorsFound = true;
4289 : }
4290 : }
4291 : }
4292 : }
4293 :
4294 : // Start to assembly AirflowNetwork Components
4295 25 : AirflowNetworkNumOfComps = AirflowNetworkNumOfDetOpenings + AirflowNetworkNumOfSimOpenings + AirflowNetworkNumOfSurCracks +
4296 25 : AirflowNetworkNumOfSurELA + DisSysNumOfLeaks + DisSysNumOfELRs + DisSysNumOfDucts + DisSysNumOfDampers +
4297 25 : DisSysNumOfCVFs + DisSysNumOfDetFans + DisSysNumOfCPDs + DisSysNumOfCoils + DisSysNumOfTermUnits +
4298 25 : AirflowNetworkNumOfExhFan + DisSysNumOfHXs + AirflowNetworkNumOfHorOpenings + NumOfOAFans + NumOfReliefFans +
4299 25 : AirflowNetworkNumOfSFR;
4300 25 : AirflowNetworkCompData.allocate(AirflowNetworkNumOfComps);
4301 :
4302 30 : for (int i = 1; i <= AirflowNetworkNumOfDetOpenings; ++i) { // Detailed opening component
4303 5 : AirflowNetworkCompData(i).Name = MultizoneCompDetOpeningData(i).name;
4304 5 : compnum[AirflowNetworkCompData(i).Name] = i;
4305 5 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DOP;
4306 5 : AirflowNetworkCompData(i).TypeNum = i;
4307 5 : AirflowNetworkCompData(i).EPlusName = "";
4308 5 : AirflowNetworkCompData(i).EPlusCompName = "";
4309 5 : AirflowNetworkCompData(i).EPlusType = "";
4310 5 : AirflowNetworkCompData(i).CompNum = i;
4311 : }
4312 :
4313 25 : int j = AirflowNetworkNumOfDetOpenings;
4314 34 : for (int i = 1 + j; i <= AirflowNetworkNumOfSimOpenings + j; ++i) { // Simple opening component
4315 9 : n = i - j;
4316 9 : AirflowNetworkCompData(i).Name = MultizoneCompSimpleOpeningData(n).name;
4317 9 : compnum[AirflowNetworkCompData(i).Name] = i;
4318 9 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SOP;
4319 9 : AirflowNetworkCompData(i).TypeNum = n;
4320 9 : AirflowNetworkCompData(i).EPlusName = "";
4321 9 : AirflowNetworkCompData(i).EPlusCompName = "";
4322 9 : AirflowNetworkCompData(i).EPlusType = "";
4323 9 : AirflowNetworkCompData(i).CompNum = i;
4324 : }
4325 :
4326 25 : j += AirflowNetworkNumOfSimOpenings;
4327 61 : for (int i = 1 + j; i <= AirflowNetworkNumOfSurCracks + j; ++i) { // Surface crack component
4328 36 : n = i - j;
4329 36 : AirflowNetworkCompData(i).Name = MultizoneSurfaceCrackData(n).name;
4330 36 : compnum[AirflowNetworkCompData(i).Name] = i;
4331 36 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SCR;
4332 36 : AirflowNetworkCompData(i).TypeNum = n;
4333 36 : AirflowNetworkCompData(i).EPlusName = "";
4334 36 : AirflowNetworkCompData(i).EPlusCompName = "";
4335 36 : AirflowNetworkCompData(i).EPlusType = "";
4336 36 : AirflowNetworkCompData(i).CompNum = i;
4337 : }
4338 :
4339 25 : j += AirflowNetworkNumOfSurCracks;
4340 33 : for (int i = 1 + j; i <= AirflowNetworkNumOfSurELA + j; ++i) { // Surface crack component
4341 8 : n = i - j;
4342 8 : AirflowNetworkCompData(i).Name = MultizoneSurfaceELAData(n).name;
4343 8 : compnum[AirflowNetworkCompData(i).Name] = i;
4344 8 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SEL;
4345 8 : AirflowNetworkCompData(i).TypeNum = n;
4346 8 : AirflowNetworkCompData(i).EPlusName = "";
4347 8 : AirflowNetworkCompData(i).EPlusCompName = "";
4348 8 : AirflowNetworkCompData(i).EPlusType = "";
4349 8 : AirflowNetworkCompData(i).CompNum = i;
4350 : }
4351 :
4352 25 : j += AirflowNetworkNumOfSurELA;
4353 28 : for (int i = 1 + j; i <= AirflowNetworkNumOfExhFan + j; ++i) { // Zone exhaust fan component
4354 3 : n = i - j;
4355 3 : AirflowNetworkCompData(i).Name = MultizoneCompExhaustFanData(n).name;
4356 3 : compnum[AirflowNetworkCompData(i).Name] = i;
4357 3 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::EXF;
4358 3 : AirflowNetworkCompData(i).TypeNum = n;
4359 3 : AirflowNetworkCompData(i).EPlusName = "";
4360 3 : AirflowNetworkCompData(i).EPlusCompName = "";
4361 3 : AirflowNetworkCompData(i).EPlusType = "";
4362 3 : AirflowNetworkCompData(i).CompNum = i;
4363 : }
4364 :
4365 25 : j += AirflowNetworkNumOfExhFan;
4366 26 : for (int i = 1 + j; i <= AirflowNetworkNumOfHorOpenings + j; ++i) { // Distribution system crack component
4367 1 : n = i - j;
4368 1 : AirflowNetworkCompData(i).Name = MultizoneCompHorOpeningData(n).name;
4369 1 : compnum[AirflowNetworkCompData(i).Name] = i;
4370 1 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::HOP;
4371 1 : AirflowNetworkCompData(i).TypeNum = n;
4372 1 : AirflowNetworkCompData(i).EPlusName = "";
4373 1 : AirflowNetworkCompData(i).EPlusCompName = "";
4374 1 : AirflowNetworkCompData(i).EPlusType = "";
4375 1 : AirflowNetworkCompData(i).CompNum = i;
4376 : }
4377 :
4378 25 : j += AirflowNetworkNumOfHorOpenings;
4379 30 : for (int i = 1 + j; i <= DisSysNumOfLeaks + j; ++i) { // Distribution system crack component
4380 5 : n = i - j;
4381 5 : AirflowNetworkCompData(i).Name = DisSysCompLeakData(n).name;
4382 5 : compnum[AirflowNetworkCompData(i).Name] = i;
4383 5 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::PLR;
4384 5 : AirflowNetworkCompData(i).TypeNum = n;
4385 5 : AirflowNetworkCompData(i).EPlusName = "";
4386 5 : AirflowNetworkCompData(i).EPlusCompName = "";
4387 5 : AirflowNetworkCompData(i).EPlusType = "";
4388 5 : AirflowNetworkCompData(i).CompNum = i;
4389 : }
4390 :
4391 25 : j += DisSysNumOfLeaks;
4392 45 : for (int i = 1 + j; i <= DisSysNumOfELRs + j; ++i) { // Distribution system effective leakage ratio component
4393 20 : n = i - j;
4394 20 : AirflowNetworkCompData(i).Name = DisSysCompELRData(n).name;
4395 20 : compnum[AirflowNetworkCompData(i).Name] = i;
4396 20 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::ELR;
4397 20 : AirflowNetworkCompData(i).TypeNum = n;
4398 20 : AirflowNetworkCompData(i).EPlusName = "";
4399 20 : AirflowNetworkCompData(i).EPlusCompName = "";
4400 20 : AirflowNetworkCompData(i).EPlusType = "";
4401 20 : AirflowNetworkCompData(i).CompNum = i;
4402 : }
4403 :
4404 25 : j += DisSysNumOfELRs;
4405 89 : for (int i = 1 + j; i <= DisSysNumOfDucts + j; ++i) { // Distribution system effective leakage ratio component
4406 64 : n = i - j;
4407 64 : AirflowNetworkCompData(i).Name = DisSysCompDuctData(n).name;
4408 64 : compnum[AirflowNetworkCompData(i).Name] = i;
4409 64 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DWC;
4410 64 : AirflowNetworkCompData(i).TypeNum = n;
4411 64 : AirflowNetworkCompData(i).EPlusName = "";
4412 64 : AirflowNetworkCompData(i).EPlusCompName = "";
4413 64 : AirflowNetworkCompData(i).EPlusType = "";
4414 64 : AirflowNetworkCompData(i).CompNum = i;
4415 : }
4416 :
4417 25 : j += DisSysNumOfDucts;
4418 25 : for (int i = 1 + j; i <= DisSysNumOfDampers + j; ++i) { // Distribution system effective leakage ratio component
4419 0 : n = i - j;
4420 0 : AirflowNetworkCompData(i).Name = DisSysCompDamperData(n).name;
4421 0 : compnum[AirflowNetworkCompData(i).Name] = i;
4422 0 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DMP;
4423 0 : AirflowNetworkCompData(i).TypeNum = n;
4424 0 : AirflowNetworkCompData(i).EPlusName = "";
4425 0 : AirflowNetworkCompData(i).EPlusCompName = "";
4426 0 : AirflowNetworkCompData(i).EPlusType = "";
4427 0 : AirflowNetworkCompData(i).CompNum = i;
4428 : }
4429 :
4430 25 : j += DisSysNumOfDampers;
4431 33 : for (int i = 1 + j; i <= DisSysNumOfCVFs + j; ++i) { // Distribution system constant volume fan component
4432 8 : n = i - j;
4433 8 : AirflowNetworkCompData(i).Name = DisSysCompCVFData(n).name;
4434 8 : compnum[AirflowNetworkCompData(i).Name] = i;
4435 8 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::CVF;
4436 8 : AirflowNetworkCompData(i).TypeNum = n;
4437 8 : AirflowNetworkCompData(i).EPlusName = "";
4438 8 : AirflowNetworkCompData(i).EPlusCompName = "";
4439 8 : AirflowNetworkCompData(i).EPlusType = "";
4440 8 : AirflowNetworkCompData(i).CompNum = i;
4441 8 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::FAN;
4442 : }
4443 :
4444 25 : j += DisSysNumOfCVFs;
4445 25 : for (int i = 1 + j; i <= DisSysNumOfDetFans + j; ++i) { // Distribution system fan component
4446 0 : n = i - j;
4447 0 : AirflowNetworkCompData(i).Name = DisSysCompDetFanData(n).name;
4448 0 : compnum[AirflowNetworkCompData(i).Name] = i;
4449 0 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::FAN;
4450 0 : AirflowNetworkCompData(i).TypeNum = n;
4451 0 : AirflowNetworkCompData(i).EPlusName = "";
4452 0 : AirflowNetworkCompData(i).EPlusCompName = "";
4453 0 : AirflowNetworkCompData(i).EPlusType = "";
4454 0 : AirflowNetworkCompData(i).CompNum = i;
4455 0 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::FAN;
4456 : }
4457 :
4458 25 : j += DisSysNumOfDetFans;
4459 27 : for (int i = 1 + j; i <= DisSysNumOfCPDs + j; ++i) { // Distribution system constant pressure drop component
4460 2 : n = i - j;
4461 2 : AirflowNetworkCompData(i).Name = DisSysCompCPDData(n).name;
4462 2 : compnum[AirflowNetworkCompData(i).Name] = i;
4463 2 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::CPD;
4464 2 : AirflowNetworkCompData(i).TypeNum = n;
4465 2 : AirflowNetworkCompData(i).EPlusName = "";
4466 2 : AirflowNetworkCompData(i).EPlusCompName = "";
4467 2 : AirflowNetworkCompData(i).EPlusType = "";
4468 2 : AirflowNetworkCompData(i).CompNum = i;
4469 : }
4470 :
4471 25 : j += DisSysNumOfCPDs;
4472 45 : for (int i = 1 + j; i <= DisSysNumOfCoils + j; ++i) { // Distribution system coil component
4473 20 : n = i - j;
4474 20 : AirflowNetworkCompData(i).Name = DisSysCompCoilData(n).name;
4475 20 : compnum[AirflowNetworkCompData(i).Name] = i;
4476 20 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::COI;
4477 20 : AirflowNetworkCompData(i).TypeNum = n;
4478 20 : AirflowNetworkCompData(i).EPlusName = "";
4479 20 : AirflowNetworkCompData(i).EPlusCompName = "";
4480 20 : AirflowNetworkCompData(i).EPlusType = "";
4481 20 : AirflowNetworkCompData(i).CompNum = i;
4482 20 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::COI;
4483 : }
4484 :
4485 25 : j += DisSysNumOfCoils;
4486 28 : for (int i = 1 + j; i <= DisSysNumOfTermUnits + j; ++i) { // Terminal unit component
4487 3 : n = i - j;
4488 3 : AirflowNetworkCompData(i).Name = DisSysCompTermUnitData(n).name;
4489 3 : compnum[AirflowNetworkCompData(i).Name] = i;
4490 3 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::TMU;
4491 3 : AirflowNetworkCompData(i).TypeNum = n;
4492 3 : AirflowNetworkCompData(i).EPlusName = "";
4493 3 : AirflowNetworkCompData(i).EPlusCompName = "";
4494 3 : AirflowNetworkCompData(i).EPlusType = "";
4495 3 : AirflowNetworkCompData(i).CompNum = i;
4496 3 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::RHT;
4497 : }
4498 :
4499 25 : j += DisSysNumOfTermUnits;
4500 25 : for (int i = 1 + j; i <= DisSysNumOfHXs + j; ++i) { // Distribution system heat exchanger component
4501 0 : n = i - j;
4502 0 : AirflowNetworkCompData(i).Name = DisSysCompHXData(n).name;
4503 0 : compnum[AirflowNetworkCompData(i).Name] = i;
4504 0 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::HEX;
4505 0 : AirflowNetworkCompData(i).TypeNum = n;
4506 0 : AirflowNetworkCompData(i).EPlusName = "";
4507 0 : AirflowNetworkCompData(i).EPlusCompName = "";
4508 0 : AirflowNetworkCompData(i).EPlusType = "";
4509 0 : AirflowNetworkCompData(i).CompNum = i;
4510 0 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::HEX;
4511 : }
4512 :
4513 25 : j += DisSysNumOfHXs;
4514 28 : for (int i = 1 + j; i <= NumOfOAFans + j; ++i) { // OA fan component
4515 3 : n = i - j;
4516 3 : AirflowNetworkCompData(i).Name = DisSysCompOutdoorAirData(n).name;
4517 3 : compnum[AirflowNetworkCompData(i).Name] = i;
4518 3 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::OAF;
4519 3 : AirflowNetworkCompData(i).TypeNum = n;
4520 3 : AirflowNetworkCompData(i).EPlusName = "";
4521 3 : AirflowNetworkCompData(i).EPlusCompName = "";
4522 3 : AirflowNetworkCompData(i).EPlusType = "";
4523 3 : AirflowNetworkCompData(i).CompNum = i;
4524 : }
4525 :
4526 25 : j += NumOfOAFans;
4527 27 : for (int i = 1 + j; i <= NumOfReliefFans + j; ++i) { // OA fan component
4528 2 : n = i - j;
4529 2 : AirflowNetworkCompData(i).Name = DisSysCompReliefAirData(n).name;
4530 2 : compnum[AirflowNetworkCompData(i).Name] = i;
4531 2 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::REL;
4532 2 : AirflowNetworkCompData(i).TypeNum = n;
4533 2 : AirflowNetworkCompData(i).EPlusName = "";
4534 2 : AirflowNetworkCompData(i).EPlusCompName = "";
4535 2 : AirflowNetworkCompData(i).EPlusType = "";
4536 2 : AirflowNetworkCompData(i).CompNum = i;
4537 : }
4538 :
4539 : // This is also a bit of a hack to keep things working, this needs to be removed ASAP
4540 25 : j += NumOfReliefFans;
4541 25 : int ii = 1 + j;
4542 25 : int type_i = 1;
4543 25 : for (auto const &el : SpecifiedMassFlowData) {
4544 0 : AirflowNetworkCompData(ii).Name = el.name;
4545 0 : compnum[el.name] = ii;
4546 0 : AirflowNetworkCompData(ii).CompTypeNum = iComponentTypeNum::SMF;
4547 0 : AirflowNetworkCompData(ii).TypeNum = type_i;
4548 0 : AirflowNetworkCompData(ii).EPlusName = "";
4549 0 : AirflowNetworkCompData(ii).EPlusCompName = "";
4550 0 : AirflowNetworkCompData(ii).EPlusType = "";
4551 0 : AirflowNetworkCompData(ii).CompNum = ii;
4552 0 : ++ii;
4553 0 : ++type_i;
4554 : }
4555 :
4556 25 : type_i = 1;
4557 25 : for (auto const &el : SpecifiedVolumeFlowData) {
4558 0 : AirflowNetworkCompData(ii).Name = el.name;
4559 0 : compnum[el.name] = ii;
4560 0 : AirflowNetworkCompData(ii).CompTypeNum = iComponentTypeNum::SVF;
4561 0 : AirflowNetworkCompData(ii).TypeNum = type_i;
4562 0 : AirflowNetworkCompData(ii).EPlusName = "";
4563 0 : AirflowNetworkCompData(ii).EPlusCompName = "";
4564 0 : AirflowNetworkCompData(ii).EPlusType = "";
4565 0 : AirflowNetworkCompData(ii).CompNum = ii;
4566 0 : ++ii;
4567 0 : ++type_i;
4568 : }
4569 :
4570 : // Assign linkage data
4571 :
4572 : // Read AirflowNetwork linkage data
4573 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Linkage";
4574 25 : DisSysNumOfLinks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
4575 25 : if (DisSysNumOfLinks > 0 && distribution_simulated) { // Multizone + Distribution
4576 7 : AirflowNetworkNumOfLinks = NumOfLinksMultiZone + DisSysNumOfLinks;
4577 7 : AirflowNetworkLinkageData.allocate(DisSysNumOfLinks + AirflowNetworkNumOfSurfaces);
4578 : } else { // Multizone + IntraZone only
4579 : // AirflowNetworkLinkageData.allocate( AirflowNetworkNumOfSurfaces );
4580 18 : AirflowNetworkLinkageData.allocate(AirflowNetworkNumOfLinks);
4581 : }
4582 :
4583 : // Assign Multizone linkage based on surfaces, by assuming every surface has a crack or opening
4584 25 : j = 0;
4585 168 : for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
4586 143 : if (MultizoneSurfaceData(count).SurfNum == 0) {
4587 0 : continue;
4588 : }
4589 143 : AirflowNetworkLinkageData(count).Name = MultizoneSurfaceData(count).SurfName;
4590 143 : AirflowNetworkLinkageData(count).NodeNums[0] = MultizoneSurfaceData(count).NodeNums[0];
4591 143 : AirflowNetworkLinkageData(count).NodeNums[1] = MultizoneSurfaceData(count).NodeNums[1];
4592 143 : AirflowNetworkLinkageData(count).CompName = MultizoneSurfaceData(count).OpeningName;
4593 143 : AirflowNetworkLinkageData(count).ZoneNum = 0;
4594 143 : AirflowNetworkLinkageData(count).LinkNum = count;
4595 143 : AirflowNetworkLinkageData(count).NodeHeights[0] = MultizoneSurfaceData(count).CHeight;
4596 143 : AirflowNetworkLinkageData(count).NodeHeights[1] = MultizoneSurfaceData(count).CHeight;
4597 143 : if (!m_state.dataSurface->WorldCoordSystem) {
4598 45 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum > 0) {
4599 45 : AirflowNetworkLinkageData(count).NodeHeights[0] -=
4600 45 : Zone(AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum).OriginZ;
4601 : }
4602 45 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum > 0) {
4603 3 : AirflowNetworkLinkageData(count).NodeHeights[1] -=
4604 3 : Zone(AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum).OriginZ;
4605 : }
4606 : }
4607 : // Find component number
4608 143 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4609 143 : if (afe != elements.end()) {
4610 : // found = false;
4611 : // for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
4612 143 : AirflowNetworkLinkageData(count).element = afe->second;
4613 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4614 143 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4615 143 : assert(compnum_iter != compnum.end());
4616 143 : int compnum = compnum_iter->second;
4617 143 : AirflowNetworkLinkageData(count).CompNum = compnum;
4618 :
4619 143 : auto const &surf = m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum);
4620 :
4621 143 : switch (AirflowNetworkLinkageData(count).element->type()) {
4622 6 : case ComponentType::DOP: {
4623 : // if (AirflowNetworkLinkageData(count).CompName ==
4624 : // AirflowNetworkCompData(i).Name) {
4625 : // AirflowNetworkLinkageData(count).CompNum = i;
4626 : // found = true;
4627 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::DOP) {
4628 6 : ++j;
4629 6 : AirflowNetworkLinkageData(count).DetOpenNum = j;
4630 6 : MultizoneSurfaceData(count).Multiplier = surf.Multiplier;
4631 6 : if (surf.Tilt < 10.0 || surf.Tilt > 170.0) {
4632 0 : ShowWarningError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4633 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is within ");
4634 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through large horizontal openings are poorly");
4635 0 : ShowContinueError(m_state, "modeled in the AirflowNetwork model resulting in only one-way airflow.");
4636 : }
4637 6 : if (!(surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::GlassDoor ||
4638 0 : surf.OriginalClass == SurfaceClass::Door || surf.IsAirBoundarySurf)) {
4639 0 : ShowSevereError(m_state,
4640 0 : format(RoutineName) +
4641 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4642 0 : AirflowNetworkLinkageData(count).Name);
4643 0 : ErrorsFound = true;
4644 : }
4645 :
4646 6 : if (surf.OriginalClass == SurfaceClass::Door || surf.OriginalClass == SurfaceClass::GlassDoor) {
4647 0 : if (MultizoneCompDetOpeningData(AirflowNetworkCompData(compnum).TypeNum).LVOType == 2) {
4648 0 : ShowSevereError(m_state,
4649 0 : format(RoutineName) +
4650 : "AirflowNetworkComponent: The opening with horizontally pivoted type must be assigned to a "
4651 0 : "window surface at " +
4652 0 : AirflowNetworkLinkageData(count).Name);
4653 0 : ErrorsFound = true;
4654 : }
4655 : }
4656 6 : } break;
4657 18 : case ComponentType::SOP: {
4658 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SOP) {
4659 18 : MultizoneSurfaceData(count).Multiplier = surf.Multiplier;
4660 18 : if (surf.Tilt < 10.0 || surf.Tilt > 170.0) {
4661 0 : ShowSevereError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4662 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is within");
4663 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through horizontal openings are not allowed.");
4664 0 : ShowContinueError(m_state, "AirflowNetwork:Multizone:Component:SimpleOpening = " + AirflowNetworkCompData(compnum).Name);
4665 0 : ErrorsFound = true;
4666 : }
4667 :
4668 18 : if (!(surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::GlassDoor ||
4669 0 : surf.OriginalClass == SurfaceClass::Door || surf.IsAirBoundarySurf)) {
4670 0 : ShowSevereError(m_state,
4671 0 : format(RoutineName) +
4672 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4673 0 : AirflowNetworkLinkageData(count).Name);
4674 0 : ErrorsFound = true;
4675 : }
4676 18 : } break;
4677 0 : case ComponentType::HOP: {
4678 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::HOP) {
4679 0 : MultizoneSurfaceData(count).Multiplier = surf.Multiplier;
4680 : // Get linkage height from upper and lower zones
4681 0 : if (MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum > 0) {
4682 0 : AirflowNetworkLinkageData(count).NodeHeights[0] =
4683 0 : Zone(MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum).Centroid.z;
4684 : }
4685 0 : if (AirflowNetworkLinkageData(count).NodeNums[1] <= AirflowNetworkNumOfZones) {
4686 0 : if (MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum > 0) {
4687 0 : AirflowNetworkLinkageData(count).NodeHeights[1] =
4688 0 : Zone(m_state.afn->MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum).Centroid.z;
4689 : }
4690 : }
4691 0 : if (AirflowNetworkLinkageData(count).NodeNums[1] > AirflowNetworkNumOfZones) {
4692 0 : ShowSevereError(m_state,
4693 0 : format(RoutineName) +
4694 0 : "AirflowNetworkComponent: The horizontal opening must be located between two thermal zones at " +
4695 0 : AirflowNetworkLinkageData(count).Name);
4696 0 : ShowContinueError(m_state, "This component is exposed to outdoors.");
4697 0 : ErrorsFound = true;
4698 : } else {
4699 0 : if (!(MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum > 0 &&
4700 0 : MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum > 0)) {
4701 0 : ShowSevereError(m_state,
4702 0 : format(RoutineName) +
4703 0 : "AirflowNetworkComponent: The horizontal opening must be located between two thermal zones at " +
4704 0 : AirflowNetworkLinkageData(count).Name);
4705 0 : ErrorsFound = true;
4706 : }
4707 : }
4708 0 : if (!(surf.Tilt > 170.0 && surf.Tilt < 190.0) && !(surf.Tilt > -10.0 && surf.Tilt < 10.0)) {
4709 0 : ShowWarningError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4710 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is above");
4711 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through non-horizontal openings are not modeled");
4712 0 : ShowContinueError(m_state,
4713 0 : "with the object of AirflowNetwork:Multizone:Component:HorizontalOpening = " +
4714 0 : AirflowNetworkCompData(compnum).Name);
4715 : }
4716 0 : if (!(surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::GlassDoor ||
4717 0 : surf.OriginalClass == SurfaceClass::Door || surf.IsAirBoundarySurf)) {
4718 0 : ShowSevereError(m_state,
4719 0 : format(RoutineName) +
4720 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4721 0 : AirflowNetworkLinkageData(count).Name);
4722 0 : ErrorsFound = true;
4723 : }
4724 0 : } break;
4725 119 : default:
4726 : // Nothing to do here
4727 119 : break;
4728 : }
4729 143 : } else {
4730 0 : ShowSevereError(m_state,
4731 0 : format(RoutineName) + CurrentModuleObject + ": The component is not defined in " +
4732 0 : AirflowNetworkLinkageData(count).Name);
4733 0 : ErrorsFound = true;
4734 : }
4735 143 : }
4736 :
4737 : // Assign intrazone links
4738 31 : for (count = 1 + AirflowNetworkNumOfSurfaces; count <= NumOfLinksIntraZone + AirflowNetworkNumOfSurfaces; ++count) {
4739 6 : AirflowNetworkLinkageData(count).Name = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).Name;
4740 6 : AirflowNetworkLinkageData(count).NodeNums[0] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeNums[0];
4741 6 : AirflowNetworkLinkageData(count).NodeNums[1] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeNums[1];
4742 6 : AirflowNetworkLinkageData(count).CompName = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).CompName;
4743 6 : AirflowNetworkLinkageData(count).ZoneNum = 0;
4744 6 : AirflowNetworkLinkageData(count).LinkNum = count;
4745 6 : AirflowNetworkLinkageData(count).NodeHeights[0] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeHeights[0];
4746 6 : AirflowNetworkLinkageData(count).NodeHeights[1] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeHeights[1];
4747 : // Find component number
4748 6 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4749 6 : if (afe != elements.end()) {
4750 6 : AirflowNetworkLinkageData(count).element = afe->second;
4751 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4752 6 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4753 6 : assert(compnum_iter != compnum.end());
4754 6 : int compnum = compnum_iter->second;
4755 6 : AirflowNetworkLinkageData(count).CompNum = compnum;
4756 6 : if (AirflowNetworkLinkageData(count).element->type() != ComponentType::SCR &&
4757 0 : AirflowNetworkLinkageData(count).element->type() != ComponentType::SEL) {
4758 :
4759 0 : ShowSevereError(m_state,
4760 0 : format(RoutineName) + AirflowNetworkLinkageData(count).CompName + ": The component is not allowed in " +
4761 0 : AirflowNetworkLinkageData(count).Name);
4762 0 : ShowContinueError(m_state,
4763 : "The allowed component type is either AirflowNetwork:MultiZone:Surface:Crack or "
4764 : "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea.");
4765 0 : ErrorsFound = true;
4766 : }
4767 6 : } else {
4768 0 : ShowSevereError(m_state,
4769 0 : format(RoutineName) + AirflowNetworkLinkageData(count).CompName + ": The component is not defined in " +
4770 0 : AirflowNetworkLinkageData(count).Name);
4771 0 : ErrorsFound = true;
4772 : }
4773 6 : }
4774 :
4775 : // Reset AirflowNetworkNumOfSurfaces by including NumOfLinksIntraZone
4776 25 : AirflowNetworkNumOfSurfaces = AirflowNetworkNumOfSurfaces + NumOfLinksIntraZone;
4777 25 : if (NumOfLinksIntraZone > 0) {
4778 1 : NumOfLinksMultiZone = AirflowNetworkNumOfSurfaces;
4779 : }
4780 :
4781 : // Assign AirflowNetwork info in RoomAirflowNetworkZoneInfo
4782 25 : if (NumOfNodesIntraZone > 0) {
4783 11 : for (int i = 1; i <= NumOfNodesMultiZone; ++i) {
4784 10 : n = AirflowNetworkNodeData(i).EPlusZoneNum;
4785 10 : AirflowNetworkNodeData(i).NumOfLinks = 0;
4786 10 : if (n > 0 && AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
4787 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID = i;
4788 90 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
4789 84 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i) {
4790 14 : AirflowNetworkNodeData(i).NumOfLinks = AirflowNetworkNodeData(i).NumOfLinks + 1;
4791 70 : } else if (AirflowNetworkLinkageData(j).NodeNums[1] == i) {
4792 6 : AirflowNetworkNodeData(i).NumOfLinks = AirflowNetworkNodeData(i).NumOfLinks + 1;
4793 : } else {
4794 : }
4795 : }
4796 : }
4797 10 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
4798 42 : for (j = 1; j <= m_state.dataRoomAir->AFNZoneInfo(n).NumOfAirNodes; ++j) {
4799 36 : if (m_state.dataRoomAir->AFNZoneInfo(n).Node(j).AFNNodeID == i) {
4800 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).NumOfAirflowLinks = AirflowNetworkNodeData(i).NumOfLinks;
4801 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link.allocate(AirflowNetworkNodeData(i).NumOfLinks);
4802 6 : k = 1;
4803 74 : for (int m = 1; m <= AirflowNetworkNumOfSurfaces; ++m) {
4804 74 : if (AirflowNetworkLinkageData(m).NodeNums[0] == i) {
4805 14 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNSimuID = m;
4806 14 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNDataID = m;
4807 14 : k = k + 1;
4808 14 : if (k > AirflowNetworkNodeData(i).NumOfLinks) {
4809 4 : break;
4810 : }
4811 : }
4812 70 : if (AirflowNetworkLinkageData(m).NodeNums[1] == i) {
4813 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNSimuID = m;
4814 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNDataID = m;
4815 6 : k = k + 1;
4816 6 : if (k > AirflowNetworkNodeData(i).NumOfLinks) {
4817 2 : break;
4818 : }
4819 : }
4820 : }
4821 : }
4822 : }
4823 : }
4824 : }
4825 : }
4826 :
4827 25 : if (DisSysNumOfLinks > 0 && distribution_simulated) { // Distribution
4828 :
4829 259 : for (auto &e : AirflowNetworkLinkageData) {
4830 252 : e.ZoneNum = 0;
4831 : }
4832 :
4833 180 : for (count = AirflowNetworkNumOfSurfaces + 1; count <= AirflowNetworkNumOfLinks; ++count) {
4834 :
4835 346 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
4836 : CurrentModuleObject,
4837 173 : count - AirflowNetworkNumOfSurfaces,
4838 : Alphas,
4839 : NumAlphas,
4840 : Numbers,
4841 : NumNumbers,
4842 : IOStatus,
4843 : lNumericBlanks,
4844 : lAlphaBlanks,
4845 : cAlphaFields,
4846 : cNumericFields);
4847 173 : AirflowNetworkLinkageData(count).Name = Alphas(1);
4848 173 : AirflowNetworkLinkageData(count).NodeNames[0] = Alphas(2);
4849 173 : AirflowNetworkLinkageData(count).NodeHeights[0] = 0.0;
4850 173 : AirflowNetworkLinkageData(count).NodeNames[1] = Alphas(3);
4851 173 : AirflowNetworkLinkageData(count).NodeHeights[1] = 0.0;
4852 173 : AirflowNetworkLinkageData(count).CompName = Alphas(4);
4853 173 : AirflowNetworkLinkageData(count).ZoneName = Alphas(5);
4854 173 : AirflowNetworkLinkageData(count).LinkNum = count;
4855 :
4856 199 : for (int i = 1; i <= DisSysNumOfDuctViewFactors; ++i) {
4857 28 : if (AirflowNetworkLinkageData(count).Name == AirflowNetworkLinkageViewFactorData(i).LinkageName) {
4858 2 : AirflowNetworkLinkageData(count).LinkageViewFactorObjectNum = AirflowNetworkLinkageViewFactorData(i).ObjectNum;
4859 2 : break;
4860 : }
4861 : }
4862 :
4863 173 : if (!lAlphaBlanks(5)) {
4864 69 : AirflowNetworkLinkageData(count).ZoneNum = Util::FindItemInList(AirflowNetworkLinkageData(count).ZoneName, Zone);
4865 69 : if (AirflowNetworkLinkageData(count).ZoneNum == 0) {
4866 0 : ShowSevereError(m_state,
4867 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(5) +
4868 0 : " given = " + AirflowNetworkLinkageData(count).ZoneName);
4869 0 : ErrorsFound = true;
4870 : }
4871 : }
4872 173 : if (Alphas(2) == Alphas(3)) {
4873 0 : ShowSevereError(m_state,
4874 0 : format(RoutineName) + CurrentModuleObject + ", " + cAlphaFields(2) + " = " + cAlphaFields(3) + " in " +
4875 0 : AirflowNetworkLinkageData(count).Name);
4876 0 : ErrorsFound = true;
4877 : }
4878 : // Find component number
4879 173 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4880 173 : if (afe != elements.end()) {
4881 173 : AirflowNetworkLinkageData(count).element = afe->second;
4882 :
4883 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4884 173 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4885 173 : assert(compnum_iter != compnum.end());
4886 173 : int compnum = compnum_iter->second;
4887 173 : AirflowNetworkLinkageData(count).CompNum = compnum;
4888 173 : } else {
4889 0 : ShowSevereError(m_state,
4890 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(4) + " is not defined in " +
4891 0 : AirflowNetworkLinkageData(count).Name);
4892 0 : ErrorsFound = true;
4893 : }
4894 : // Find Node number
4895 173 : found = false;
4896 3470 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4897 3470 : if (AirflowNetworkLinkageData(count).NodeNames[0] == AirflowNetworkNodeData(i).Name) {
4898 173 : AirflowNetworkLinkageData(count).NodeNums[0] = i;
4899 173 : AirflowNetworkLinkageData(count).NodeHeights[0] += AirflowNetworkNodeData(i).NodeHeight;
4900 173 : found = true;
4901 173 : break;
4902 : }
4903 : }
4904 173 : if (!found) {
4905 0 : ShowSevereError(m_state,
4906 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(2) + " is not found in the node data " +
4907 0 : AirflowNetworkLinkageData(count).Name);
4908 0 : ErrorsFound = true;
4909 : }
4910 3444 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4911 3444 : if (AirflowNetworkLinkageData(count).NodeNames[1] == AirflowNetworkNodeData(i).Name) {
4912 173 : AirflowNetworkLinkageData(count).NodeNums[1] = i;
4913 173 : AirflowNetworkLinkageData(count).NodeHeights[1] += AirflowNetworkNodeData(i).NodeHeight;
4914 173 : found = true;
4915 173 : break;
4916 : }
4917 : }
4918 173 : if (!found) {
4919 0 : ShowSevereError(m_state,
4920 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(3) + " is not found in the node data " +
4921 0 : AirflowNetworkLinkageData(count).Name);
4922 0 : ErrorsFound = true;
4923 : }
4924 173 : }
4925 7 : } else {
4926 :
4927 18 : if (distribution_simulated) {
4928 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
4929 0 : ErrorsFound = true;
4930 : }
4931 : }
4932 :
4933 : // Ensure no duplicated names in AirflowNetwork component objects
4934 : // for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
4935 : // for (j = i + 1; j <= AirflowNetworkNumOfComps; ++j) {
4936 : // if (Util::SameString(AirflowNetworkCompData(i).Name,
4937 : // AirflowNetworkCompData(j).Name)) {
4938 : // // SurfaceAirflowLeakageNames
4939 : // if (i <= 4 && j <= 4) {
4940 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::DOP)
4941 : // CompName(1) = "AirflowNetwork:MultiZone:Component:DetailedOpening";
4942 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SOP)
4943 : // CompName(1) = "AirflowNetwork:MultiZone:Component:SimpleOpening";
4944 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SCR) CompName(1) =
4945 : // "AirflowNetwork:MultiZone:Surface:Crack"; if (AirflowNetworkCompData(i).CompTypeNum ==
4946 : // iComponentTypeNum::SEL) CompName(1) = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea"; if
4947 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DOP) CompName(2) =
4948 : // "AirflowNetwork:MultiZone:Component:DetailedOpening"; if (AirflowNetworkCompData(j).CompTypeNum ==
4949 : // iComponentTypeNum::SOP) CompName(2) = "AirflowNetwork:MultiZone:Component:SimpleOpening"; if
4950 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::SCR) CompName(2) =
4951 : // "AirflowNetwork:MultiZone:Surface:Crack"; if (AirflowNetworkCompData(j).CompTypeNum ==
4952 : // iComponentTypeNum::SEL) CompName(2) = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea"; ShowSevereError(m_state, RoutineName
4953 : // + "Duplicated component names are found = " + AirflowNetworkCompData(i).Name); ShowContinueError(m_state,
4954 : // "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2)); ErrorsFound = true;
4955 : // }
4956 : // // Distribution component
4957 : // if (i > 4 && j > 4) {
4958 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::PLR) CompName(1) =
4959 : // "AirflowNetwork:Distribution:Component:Leak"; if (AirflowNetworkCompData(i).CompTypeNum ==
4960 : // iComponentTypeNum::DWC) CompName(1) = "AirflowNetwork:Distribution:Component:Duct"; if
4961 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::ELR) CompName(1) =
4962 : // "AirflowNetwork:Distribution:Component:LeakageRatio"; if (AirflowNetworkCompData(i).CompTypeNum ==
4963 : // iComponentTypeNum::DMP) CompName(1) = "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT DAMPER"; if
4964 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::CVF) CompName(1) =
4965 : // "AirflowNetwork:Distribution:Component:Fan"; if (AirflowNetworkCompData(i).CompTypeNum ==
4966 : // iComponentTypeNum::CPD) CompName(1) = "AirflowNetwork:Distribution:Component:ConstantPressureDrop"; if
4967 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::COI) CompName(1) =
4968 : // "AirflowNetwork:Distribution:Component:Coil"; if (AirflowNetworkCompData(i).CompTypeNum ==
4969 : // iComponentTypeNum::TMU) CompName(1) = "AirflowNetwork:Distribution:Component:TerminalUnit"; if
4970 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::HEX) CompName(1) =
4971 : // "AirflowNetwork:Distribution:Component:HeatExchanger"; if (AirflowNetworkCompData(j).CompTypeNum ==
4972 : // iComponentTypeNum::PLR) CompName(2) = "AirflowNetwork:Distribution:Component:Leak"; if
4973 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DWC) CompName(2) =
4974 : // "AirflowNetwork:Distribution:Component:Duct"; if (AirflowNetworkCompData(j).CompTypeNum ==
4975 : // iComponentTypeNum::ELR) CompName(2) = "AirflowNetwork:Distribution:Component:LeakageRatio"; if
4976 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DMP) CompName(2) =
4977 : // "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT DAMPER"; if (AirflowNetworkCompData(j).CompTypeNum ==
4978 : // iComponentTypeNum::CVF) CompName(2) = "AirflowNetwork:Distribution:Component:Fan"; if
4979 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::CPD) CompName(2) =
4980 : // "AirflowNetwork:Distribution:Component:ConstantPressureDrop"; if (AirflowNetworkCompData(j).CompTypeNum
4981 : // == iComponentTypeNum::COI) CompName(2) = "AirflowNetwork:Distribution:Component:Coil"; if
4982 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::TMU) CompName(2) =
4983 : // "AirflowNetwork:Distribution:Component:TerminalUnit"; if (AirflowNetworkCompData(j).CompTypeNum ==
4984 : // iComponentTypeNum::HEX) CompName(2) = "AirflowNetwork:Distribution:Component:HeatExchanger"; ShowSevereError(m_state,
4985 : // format(RoutineName) + "Duplicated component names are found = " + AirflowNetworkCompData(i).Name);
4986 : // ShowContinueError(m_state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
4987 : // ErrorsFound = true;
4988 : // }
4989 : // }
4990 : // }
4991 : // }
4992 :
4993 : // Node and component validation
4994 347 : for (count = 1; count <= AirflowNetworkNumOfLinks; ++count) {
4995 322 : NodeFound = false;
4996 3764 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4997 3764 : if (i == AirflowNetworkLinkageData(count).NodeNums[0]) {
4998 322 : NodeFound = true;
4999 322 : break;
5000 : }
5001 : }
5002 322 : if (!NodeFound) {
5003 0 : if (count <= AirflowNetworkNumOfSurfaces) {
5004 0 : ShowSevereError(m_state,
5005 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
5006 0 : " in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name + " is not found");
5007 : } else {
5008 0 : ShowSevereError(m_state,
5009 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
5010 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
5011 : " is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE objects.");
5012 : }
5013 0 : ErrorsFound = true;
5014 : }
5015 322 : NodeFound = false;
5016 4234 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5017 4234 : if (i == AirflowNetworkLinkageData(count).NodeNums[1]) {
5018 322 : NodeFound = true;
5019 322 : break;
5020 : }
5021 : }
5022 322 : if (!NodeFound) {
5023 0 : if (count <= AirflowNetworkNumOfSurfaces) {
5024 0 : ShowSevereError(m_state,
5025 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
5026 0 : " in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name + " is not found");
5027 : } else {
5028 0 : ShowSevereError(m_state,
5029 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[1] +
5030 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
5031 : " is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE objects.");
5032 : }
5033 0 : ErrorsFound = true;
5034 : }
5035 322 : bool CompFound = false;
5036 7617 : for (int i = 1; i <= AirflowNetworkNumOfComps; ++i) {
5037 7295 : if (i == AirflowNetworkLinkageData(count).CompNum) {
5038 322 : CompFound = true;
5039 : }
5040 : }
5041 322 : if (!CompFound) {
5042 0 : ShowSevereError(m_state,
5043 0 : format(RoutineName) + "Component = " + AirflowNetworkLinkageData(count).CompName +
5044 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
5045 : " is not found in AirflowNetwork Component Data objects.");
5046 0 : ErrorsFound = true;
5047 : }
5048 : }
5049 :
5050 : // Ensure every AirflowNetworkNode is used in AirflowNetworkLinkage
5051 307 : for (count = 1; count <= AirflowNetworkNumOfNodes; ++count) {
5052 282 : bool NodeFound1 = false;
5053 282 : bool NodeFound2 = false;
5054 9424 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
5055 9142 : if (count == AirflowNetworkLinkageData(i).NodeNums[0]) {
5056 322 : NodeFound1 = true;
5057 : }
5058 9142 : if (count == AirflowNetworkLinkageData(i).NodeNums[1]) {
5059 322 : NodeFound2 = true;
5060 : }
5061 : }
5062 282 : if ((!NodeFound1) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum == 0) {
5063 0 : ShowSevereError(m_state,
5064 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5065 : " is not found as Node 1 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5066 0 : ShowContinueError(m_state,
5067 : "Each non-external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined as Node 1 once in "
5068 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5069 0 : ErrorsFound = true;
5070 : }
5071 282 : if ((!NodeFound2) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum == 0) {
5072 0 : ShowSevereError(m_state,
5073 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5074 : " is not found as Node 2 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5075 0 : ShowContinueError(m_state,
5076 : "Each non-external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined as Node 2 once in "
5077 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5078 0 : ErrorsFound = true;
5079 : }
5080 282 : if ((!NodeFound1) && (!NodeFound2) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum > 0) {
5081 0 : ShowSevereError(m_state,
5082 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5083 : " is not found as Node 1 Name or Node 2 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5084 0 : ShowContinueError(m_state, "This external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5085 0 : ErrorsFound = true;
5086 : }
5087 : }
5088 :
5089 : // Ensure there is at least one node defined as EXTERNAL node
5090 25 : NodeFound = false;
5091 307 : for (count = 1; count <= AirflowNetworkNumOfNodes; ++count) {
5092 282 : if (AirflowNetworkNodeData(count).ExtNodeNum > 0) {
5093 93 : NodeFound = true;
5094 : }
5095 : }
5096 25 : if (!NodeFound) {
5097 0 : ShowSevereError(m_state,
5098 0 : format(RoutineName) +
5099 : "No External Nodes found in AirflowNetwork:Multizone:ExternalNode. There must be at least 1 external node defined.");
5100 0 : ErrorsFound = true;
5101 : }
5102 :
5103 25 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
5104 96 : for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
5105 86 : if (AirflowNetworkLinkageData(count).NodeNums[0] == 0) {
5106 0 : ShowSevereError(m_state,
5107 0 : "The surface is not found in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name);
5108 0 : ErrorsFound = true;
5109 : }
5110 86 : if (AirflowNetworkLinkageData(count).NodeNums[1] == 0) {
5111 0 : ShowSevereError(m_state,
5112 0 : "The external node is not found in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name);
5113 0 : ErrorsFound = true;
5114 : }
5115 : }
5116 : }
5117 :
5118 : // Provide a warning when a door component is assigned as envelope leakage
5119 : // if (!ErrorsFound) {
5120 : // for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
5121 : // if
5122 : // (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).ExtNodeNum
5123 : // > 0 &&
5124 : // AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum
5125 : // > 0 && AirflowNetworkLinkageData(count).CompNum > 0) { if
5126 : // (AirflowNetworkCompData(AirflowNetworkLinkageData(count).CompNum).CompTypeNum
5127 : // == iComponentTypeNum::SOP) {
5128 : // }
5129 : // }
5130 : // if
5131 : // (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).ExtNodeNum
5132 : // > 0 &&
5133 : // AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum
5134 : // > 0 && AirflowNetworkLinkageData(count).CompNum > 0) { if
5135 : // (AirflowNetworkCompData(AirflowNetworkLinkageData(count).CompNum).CompTypeNum
5136 : // == iComponentTypeNum::SOP) {
5137 : // }
5138 : // }
5139 : // }
5140 : // }
5141 :
5142 : // Ensure the name of each heat exchanger is shown either once or twice in the field of
5143 25 : if (distribution_simulated) {
5144 7 : for (int i = 1; i <= DisSysNumOfHXs; ++i) {
5145 0 : count = 0;
5146 0 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
5147 0 : if (Util::SameString(AirflowNetworkLinkageData(j).CompName, DisSysCompHXData(i).name)) {
5148 0 : ++count;
5149 : }
5150 : }
5151 :
5152 0 : if (DisSysCompHXData(i).CoilParentExists && count != 2) {
5153 0 : ShowSevereError(m_state,
5154 0 : format(RoutineName) + "The inputs of component name field as a heat exchanger in "
5155 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE is not correct");
5156 0 : ShowContinueError(m_state,
5157 0 : "The entered name of heat exchanger is " + DisSysCompHXData(i).name +
5158 : " in AirflowNetwork:Distribution:Component:HeatExchanger objects");
5159 0 : ShowContinueError(m_state, format("The correct appearance number is 2. The entered appearance number is {}", count));
5160 0 : ErrorsFound = true;
5161 : }
5162 0 : if ((!DisSysCompHXData(i).CoilParentExists) && count != 1) {
5163 0 : ShowSevereError(m_state,
5164 0 : format(RoutineName) + "The inputs of component name field as a heat exchanger in "
5165 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE is not correct");
5166 0 : ShowContinueError(m_state,
5167 0 : "The entered name of heat exchanger is " + DisSysCompHXData(i).name +
5168 : " in AirflowNetwork:Distribution:Component:HeatExchanger objects");
5169 0 : ShowContinueError(m_state, format("The correct appearance number is 1. The entered appearance number is {}", count));
5170 0 : ErrorsFound = true;
5171 : }
5172 : }
5173 : }
5174 :
5175 : // Check node assignments using AirflowNetwork:Distribution:Component:OutdoorAirFlow or
5176 : // AirflowNetwork:Distribution:Component:ReliefAirFlow
5177 198 : for (count = AirflowNetworkNumOfSurfaces + 1; count <= AirflowNetworkNumOfLinks; ++count) {
5178 173 : int i = AirflowNetworkLinkageData(count).CompNum;
5179 173 : j = AirflowNetworkLinkageData(count).NodeNums[0];
5180 173 : k = AirflowNetworkLinkageData(count).NodeNums[1];
5181 :
5182 173 : if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::OAF) {
5183 3 : if (!Util::SameString(DisSysNodeData(j - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
5184 0 : ShowSevereError(m_state,
5185 0 : format(RoutineName) +
5186 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5187 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5188 0 : AirflowNetworkNodeData(j).Name + ",");
5189 0 : ShowContinueError(
5190 0 : m_state, "the component type in the first node should be OAMixerOutdoorAirStreamNode at " + AirflowNetworkNodeData(j).Name);
5191 0 : ErrorsFound = true;
5192 : }
5193 3 : if (!Util::SameString(DisSysNodeData(k - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
5194 0 : ShowSevereError(m_state,
5195 0 : format(RoutineName) +
5196 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5197 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5198 0 : AirflowNetworkNodeData(k).Name + ",");
5199 0 : ShowContinueError(m_state,
5200 0 : "the component object type in the second node should be AirLoopHVAC:OutdoorAirSystem at " +
5201 0 : AirflowNetworkNodeData(k).Name);
5202 0 : ErrorsFound = true;
5203 : }
5204 : }
5205 :
5206 173 : if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::REL) {
5207 2 : if (!Util::SameString(DisSysNodeData(j - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
5208 0 : ShowSevereError(m_state,
5209 0 : format(RoutineName) +
5210 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5211 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5212 0 : AirflowNetworkNodeData(j).Name + ",");
5213 0 : ShowContinueError(m_state,
5214 0 : "the component object type in the first node should be AirLoopHVAC:OutdoorAirSystem at " +
5215 0 : AirflowNetworkNodeData(j).Name);
5216 0 : ErrorsFound = true;
5217 : }
5218 2 : if (!Util::SameString(DisSysNodeData(k - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
5219 0 : ShowSevereError(m_state,
5220 0 : format(RoutineName) +
5221 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5222 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5223 0 : AirflowNetworkNodeData(k).Name + ",");
5224 0 : ShowContinueError(
5225 0 : m_state, "the component type in the second node should be OAMixerOutdoorAirStreamNode at " + AirflowNetworkNodeData(k).Name);
5226 0 : ErrorsFound = true;
5227 : }
5228 : }
5229 : }
5230 :
5231 25 : if (ErrorsFound) {
5232 2 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
5233 : }
5234 :
5235 24 : Alphas.deallocate();
5236 24 : cAlphaFields.deallocate();
5237 24 : cNumericFields.deallocate();
5238 24 : Numbers.deallocate();
5239 24 : lAlphaBlanks.deallocate();
5240 24 : lNumericBlanks.deallocate();
5241 :
5242 24 : if (!ErrorsFound) {
5243 24 : allocate_and_initialize();
5244 : }
5245 1157 : }
5246 :
5247 16855 : void Solver::initialize()
5248 : {
5249 : // SUBROUTINE INFORMATION:
5250 : // AUTHOR Lixing Gu
5251 : // DATE WRITTEN Aug. 2003
5252 : // MODIFIED na
5253 : // RE-ENGINEERED na
5254 :
5255 : // PURPOSE OF THIS SUBROUTINE:
5256 : // This subroutine initializes variables of additional zone loads caused by ADS.
5257 :
5258 : // USE STATEMENTS:
5259 16855 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
5260 :
5261 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5262 : int i;
5263 : int ZoneNum;
5264 16855 : auto &Zone(m_state.dataHeatBal->Zone);
5265 :
5266 16855 : if (initializeOneTimeFlag) {
5267 4 : exchangeData.allocate(m_state.dataGlobal->NumOfZones); // AirflowNetwork exchange data due to air-forced system
5268 5 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5269 2 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
5270 1 : multiExchangeData.allocate(m_state.dataGlobal->NumOfZones);
5271 1 : break;
5272 : }
5273 : }
5274 :
5275 4 : initializeOneTimeFlag = false;
5276 4 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5277 0 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5278 0 : SetupOutputVariable(m_state,
5279 : "AFN Zone Outdoor Air Mass Flow Rate",
5280 : Constant::Units::kg_s,
5281 0 : exchangeData(i).SumMHr,
5282 : OutputProcessor::TimeStepType::System,
5283 : OutputProcessor::StoreType::Average,
5284 0 : Zone(i).Name);
5285 0 : SetupOutputVariable(m_state,
5286 : "AFN Zone Mixing Mass Flow Rate",
5287 : Constant::Units::kg_s,
5288 0 : exchangeData(i).SumMMHr,
5289 : OutputProcessor::TimeStepType::System,
5290 : OutputProcessor::StoreType::Average,
5291 0 : Zone(i).Name);
5292 0 : SetupOutputVariable(m_state,
5293 : "AFN Zone Outdoor Air CO2 Mass Flow Rate",
5294 : Constant::Units::kg_s,
5295 0 : exchangeData(i).SumMHrCO,
5296 : OutputProcessor::TimeStepType::System,
5297 : OutputProcessor::StoreType::Average,
5298 0 : Zone(i).Name);
5299 0 : SetupOutputVariable(m_state,
5300 : "AFN Zone Mixing CO2 Mass Flow Rate",
5301 : Constant::Units::kg_s,
5302 0 : exchangeData(i).SumMMHrCO,
5303 : OutputProcessor::TimeStepType::System,
5304 : OutputProcessor::StoreType::Average,
5305 0 : Zone(i).Name);
5306 0 : SetupOutputVariable(m_state,
5307 : "AFN Zone Total CO2 Mass Flow Rate",
5308 : Constant::Units::kg_s,
5309 0 : exchangeData(i).TotalCO2,
5310 : OutputProcessor::TimeStepType::System,
5311 : OutputProcessor::StoreType::Average,
5312 0 : Zone(i).Name);
5313 : }
5314 : }
5315 4 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5316 0 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5317 0 : if (!m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5318 0 : SetupOutputVariable(m_state,
5319 : "AFN Zone Outdoor Air Mass Flow Rate",
5320 : Constant::Units::kg_s,
5321 0 : exchangeData(i).SumMHr,
5322 : OutputProcessor::TimeStepType::System,
5323 : OutputProcessor::StoreType::Average,
5324 0 : Zone(i).Name);
5325 0 : SetupOutputVariable(m_state,
5326 : "AFN Zone Mixing Mass Flow Rate",
5327 : Constant::Units::kg_s,
5328 0 : exchangeData(i).SumMMHr,
5329 : OutputProcessor::TimeStepType::System,
5330 : OutputProcessor::StoreType::Average,
5331 0 : Zone(i).Name);
5332 : }
5333 0 : SetupOutputVariable(m_state,
5334 : "AFN Zone Outdoor Air Generic Air Contaminant Mass Flow Rate",
5335 : Constant::Units::kg_s,
5336 0 : exchangeData(i).SumMHrGC,
5337 : OutputProcessor::TimeStepType::System,
5338 : OutputProcessor::StoreType::Average,
5339 0 : Zone(i).Name);
5340 0 : SetupOutputVariable(m_state,
5341 : "AFN Zone Mixing Generic Air Contaminant Mass Flow Rate",
5342 : Constant::Units::kg_s,
5343 0 : exchangeData(i).SumMMHrGC,
5344 : OutputProcessor::TimeStepType::System,
5345 : OutputProcessor::StoreType::Average,
5346 0 : Zone(i).Name);
5347 0 : SetupOutputVariable(m_state,
5348 : "AFN Zone Total Generic Air Contaminant Mass Flow Rate",
5349 : Constant::Units::kg_s,
5350 0 : exchangeData(i).TotalGC,
5351 : OutputProcessor::TimeStepType::System,
5352 : OutputProcessor::StoreType::Average,
5353 0 : Zone(i).Name);
5354 : }
5355 : }
5356 : }
5357 :
5358 16855 : if (m_state.dataGlobal->BeginEnvrnFlag && initializeMyEnvrnFlag) {
5359 : // Assign node values
5360 280 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5361 272 : AirflowNetworkNodeSimu(i).TZ = 23.0;
5362 272 : AirflowNetworkNodeSimu(i).WZ = 0.00084;
5363 272 : AirflowNetworkNodeSimu(i).PZ = 0.0;
5364 272 : AirflowNetworkNodeSimu(i).TZlast = AirflowNetworkNodeSimu(i).TZ;
5365 272 : AirflowNetworkNodeSimu(i).WZlast = AirflowNetworkNodeSimu(i).WZ;
5366 272 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5367 0 : AirflowNetworkNodeSimu(i).CO2Z = m_state.dataContaminantBalance->OutdoorCO2;
5368 0 : AirflowNetworkNodeSimu(i).CO2Zlast = AirflowNetworkNodeSimu(i).CO2Z;
5369 : }
5370 272 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5371 0 : AirflowNetworkNodeSimu(i).GCZ = m_state.dataContaminantBalance->OutdoorGC;
5372 0 : AirflowNetworkNodeSimu(i).GCZlast = AirflowNetworkNodeSimu(i).GCZ;
5373 : }
5374 272 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
5375 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
5376 0 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp = 23.0;
5377 0 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat = 0.0;
5378 : }
5379 : }
5380 :
5381 312 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
5382 304 : AirflowNetworkLinkSimu(i).FLOW = 0.0;
5383 304 : AirflowNetworkLinkSimu(i).FLOW2 = 0.0;
5384 : }
5385 :
5386 32 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5387 24 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT;
5388 24 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).airHumRat;
5389 24 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5390 0 : ANCO(i) = m_state.dataContaminantBalance->ZoneAirCO2(i);
5391 : }
5392 24 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5393 0 : ANGC(i) = m_state.dataContaminantBalance->ZoneAirGC(i);
5394 : }
5395 : }
5396 8 : if (AirflowNetworkNumOfOccuVentCtrls > 0) {
5397 0 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5398 0 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5399 0 : MultizoneSurfaceData(i).PrevOpeningstatus = AirflowNetwork::OpenStatus::FreeOperation;
5400 0 : MultizoneSurfaceData(i).CloseElapsedTime = 0.0;
5401 0 : MultizoneSurfaceData(i).OpenElapsedTime = 0.0;
5402 0 : MultizoneSurfaceData(i).OpeningStatus = AirflowNetwork::OpenStatus::FreeOperation;
5403 0 : MultizoneSurfaceData(i).OpeningProbStatus = AirflowNetwork::ProbabilityCheck::NoAction;
5404 0 : MultizoneSurfaceData(i).ClosingProbStatus = 0;
5405 : }
5406 : }
5407 : }
5408 :
5409 8 : initializeMyEnvrnFlag = false;
5410 : }
5411 16855 : if (!m_state.dataGlobal->BeginEnvrnFlag) {
5412 16717 : initializeMyEnvrnFlag = true;
5413 16717 : if (simulation_control.type != ControlType::NoMultizoneOrDistribution) {
5414 16717 : if (RollBackFlag) {
5415 0 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5416 0 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).XMAT[0];
5417 0 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).WPrevZoneTS[0];
5418 0 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5419 0 : ANCO(i) = m_state.dataContaminantBalance->CO2ZoneTimeMinus1(i);
5420 : }
5421 0 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5422 0 : ANGC(i) = m_state.dataContaminantBalance->GCZoneTimeMinus1(i);
5423 : }
5424 : }
5425 : } else {
5426 66865 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5427 50148 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT;
5428 50148 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).airHumRat;
5429 50148 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5430 0 : ANCO(i) = m_state.dataContaminantBalance->ZoneAirCO2(i);
5431 : }
5432 50148 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5433 0 : ANGC(i) = m_state.dataContaminantBalance->ZoneAirGC(i);
5434 : }
5435 : }
5436 : }
5437 :
5438 585021 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5439 568304 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0) {
5440 50148 : AirflowNetworkNodeSimu(i).TZ = ANZT(AirflowNetworkNodeData(i).EPlusZoneNum);
5441 50148 : AirflowNetworkNodeSimu(i).WZ = ANZW(AirflowNetworkNodeData(i).EPlusZoneNum);
5442 50148 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5443 0 : AirflowNetworkNodeSimu(i).CO2Z = ANCO(AirflowNetworkNodeData(i).EPlusZoneNum);
5444 : }
5445 50148 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5446 0 : AirflowNetworkNodeSimu(i).GCZ = ANGC(AirflowNetworkNodeData(i).EPlusZoneNum);
5447 : }
5448 : }
5449 568304 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
5450 284148 : if (AirflowNetworkNodeData(i).OutAirNodeNum > 0 &&
5451 1 : m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).IsLocalNode) {
5452 0 : AirflowNetworkNodeSimu(i).TZ = m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).OutAirDryBulb;
5453 0 : AirflowNetworkNodeSimu(i).WZ = m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).HumRat;
5454 : } else {
5455 284147 : AirflowNetworkNodeSimu(i).TZ = AirflowNetwork::OutDryBulbTempAt(m_state, AirflowNetworkNodeData(i).NodeHeight);
5456 284147 : AirflowNetworkNodeSimu(i).WZ = m_state.dataEnvrn->OutHumRat;
5457 : }
5458 :
5459 284147 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5460 0 : AirflowNetworkNodeSimu(i).CO2Z = m_state.dataContaminantBalance->OutdoorCO2;
5461 : }
5462 284147 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5463 0 : AirflowNetworkNodeSimu(i).GCZ = m_state.dataContaminantBalance->OutdoorGC;
5464 : }
5465 : }
5466 :
5467 568304 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
5468 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
5469 0 : if (m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID == i) {
5470 0 : AirflowNetworkNodeSimu(i).TZ =
5471 0 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp;
5472 0 : AirflowNetworkNodeSimu(i).WZ =
5473 0 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat;
5474 : }
5475 : }
5476 : }
5477 : }
5478 : }
5479 :
5480 67417 : for (auto &e : exchangeData) {
5481 50562 : e.TotalSen = 0.0;
5482 50562 : e.TotalLat = 0.0;
5483 50562 : e.MultiZoneSen = 0.0;
5484 50562 : e.MultiZoneLat = 0.0;
5485 50562 : e.LeakSen = 0.0;
5486 50562 : e.LeakLat = 0.0;
5487 50562 : e.CondSen = 0.0;
5488 50562 : e.DiffLat = 0.0;
5489 50562 : e.RadGain = 0.0;
5490 16855 : }
5491 16855 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5492 0 : for (auto &e : exchangeData) {
5493 0 : e.TotalCO2 = 0.0;
5494 0 : }
5495 : }
5496 16855 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5497 0 : for (auto &e : exchangeData) {
5498 0 : e.TotalGC = 0.0;
5499 0 : }
5500 : }
5501 :
5502 : // Occupant ventilation control
5503 16855 : Real64 CurrentEndTime = m_state.dataGlobal->CurrentTime + m_state.dataHVACGlobal->SysTimeElapsed;
5504 16855 : if (CurrentEndTime > CurrentEndTimeLast && TimeStepSys >= TimeStepSysLast) {
5505 97820 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5506 92929 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) {
5507 0 : continue;
5508 : }
5509 92929 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5510 0 : MultizoneSurfaceData(i).PrevOpeningstatus = MultizoneSurfaceData(i).OpeningStatus;
5511 0 : MultizoneSurfaceData(i).OpenFactorLast = MultizoneSurfaceData(i).OpenFactor;
5512 0 : if (MultizoneSurfaceData(i).OpenFactor > 0.0) {
5513 0 : MultizoneSurfaceData(i).OpenElapsedTime += (CurrentEndTime - CurrentEndTimeLast) * 60.0;
5514 0 : MultizoneSurfaceData(i).CloseElapsedTime = 0.0;
5515 : } else {
5516 0 : MultizoneSurfaceData(i).OpenElapsedTime = 0.0;
5517 0 : MultizoneSurfaceData(i).CloseElapsedTime += (CurrentEndTime - CurrentEndTimeLast) * 60.0;
5518 : }
5519 0 : int j = MultizoneSurfaceData(i).SurfNum;
5520 0 : OccupantVentilationControl(MultizoneSurfaceData(i).OccupantVentilationControlNum)
5521 0 : .calc(m_state,
5522 0 : m_state.dataSurface->Surface(j).Zone,
5523 0 : MultizoneSurfaceData(i).OpenElapsedTime,
5524 0 : MultizoneSurfaceData(i).CloseElapsedTime,
5525 0 : MultizoneSurfaceData(i).OpeningStatus,
5526 0 : MultizoneSurfaceData(i).OpeningProbStatus,
5527 0 : MultizoneSurfaceData(i).ClosingProbStatus);
5528 0 : if (MultizoneSurfaceData(i).OpeningStatus == AirflowNetwork::OpenStatus::MinCheckForceOpen) {
5529 0 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).OpenFactorLast;
5530 : }
5531 0 : if (MultizoneSurfaceData(i).OpeningStatus == AirflowNetwork::OpenStatus::MinCheckForceClose) {
5532 0 : MultizoneSurfaceData(i).OpenFactor = 0.0;
5533 : }
5534 : }
5535 : }
5536 : }
5537 16855 : TimeStepSysLast = TimeStepSys;
5538 16855 : CurrentEndTimeLast = CurrentEndTime;
5539 16855 : }
5540 :
5541 24 : void Solver::allocate_and_initialize()
5542 : {
5543 :
5544 : // SUBROUTINE INFORMATION:
5545 : // AUTHOR Lixing Gu
5546 : // DATE WRITTEN Aug. 2003
5547 : // MODIFIED na
5548 : // RE-ENGINEERED na
5549 :
5550 : // PURPOSE OF THIS SUBROUTINE:
5551 : // This subroutine initializes variables and allocates dynamic arrays.
5552 :
5553 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5554 : int i;
5555 : int SurfNum;
5556 24 : auto &Zone(m_state.dataHeatBal->Zone);
5557 :
5558 24 : AirflowNetworkNodeSimu.allocate(AirflowNetworkNumOfNodes); // Node simulation variable in air distribution system
5559 24 : AirflowNetworkLinkSimu.allocate(AirflowNetworkNumOfLinks); // Link simulation variable in air distribution system
5560 24 : linkReport.allocate(AirflowNetworkNumOfLinks); // Report link simulation variable in air distribution system
5561 :
5562 27 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5563 7 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
5564 4 : nodeReport.allocate(AirflowNetworkNumOfZones);
5565 4 : linkReport1.allocate(AirflowNetworkNumOfSurfaces);
5566 4 : break;
5567 : }
5568 : }
5569 :
5570 24 : MA.allocate(AirflowNetworkNumOfNodes * AirflowNetworkNumOfNodes);
5571 24 : MV.allocate(AirflowNetworkNumOfNodes);
5572 24 : IVEC.allocate(AirflowNetworkNumOfNodes + 20);
5573 :
5574 24 : AirflowNetworkReportData.allocate(m_state.dataGlobal->NumOfZones); // Report variables
5575 24 : AirflowNetworkZnRpt.allocate(m_state.dataGlobal->NumOfZones); // Report variables
5576 :
5577 24 : ANZT.allocate(m_state.dataGlobal->NumOfZones); // Local zone air temperature for rollback use
5578 24 : ANZW.allocate(m_state.dataGlobal->NumOfZones); // Local zone humidity ratio for rollback use
5579 24 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5580 0 : ANCO.allocate(m_state.dataGlobal->NumOfZones); // Local zone CO2 for rollback use
5581 : }
5582 24 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5583 0 : ANGC.allocate(m_state.dataGlobal->NumOfZones); // Local zone generic contaminant for rollback use
5584 : }
5585 24 : allocate();
5586 :
5587 24 : bool OnOffFanFlag = false;
5588 31 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5589 7 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
5590 4 : OnOffFanFlag = true;
5591 : }
5592 : }
5593 :
5594 : // CurrentModuleObject='AirflowNetwork Simulations'
5595 287 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5596 526 : SetupOutputVariable(m_state,
5597 : "AFN Node Temperature",
5598 : Constant::Units::C,
5599 263 : AirflowNetworkNodeSimu(i).TZ,
5600 : OutputProcessor::TimeStepType::System,
5601 : OutputProcessor::StoreType::Average,
5602 263 : AirflowNetworkNodeData(i).Name);
5603 526 : SetupOutputVariable(m_state,
5604 : "AFN Node Humidity Ratio",
5605 : Constant::Units::kgWater_kgDryAir,
5606 263 : AirflowNetworkNodeSimu(i).WZ,
5607 : OutputProcessor::TimeStepType::System,
5608 : OutputProcessor::StoreType::Average,
5609 263 : AirflowNetworkNodeData(i).Name);
5610 263 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5611 0 : SetupOutputVariable(m_state,
5612 : "AFN Node CO2 Concentration",
5613 : Constant::Units::ppm,
5614 0 : AirflowNetworkNodeSimu(i).CO2Z,
5615 : OutputProcessor::TimeStepType::System,
5616 : OutputProcessor::StoreType::Average,
5617 0 : AirflowNetworkNodeData(i).Name);
5618 : }
5619 263 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5620 0 : SetupOutputVariable(m_state,
5621 : "AFN Node Generic Air Contaminant Concentration",
5622 : Constant::Units::ppm,
5623 0 : AirflowNetworkNodeSimu(i).GCZ,
5624 : OutputProcessor::TimeStepType::System,
5625 : OutputProcessor::StoreType::Average,
5626 0 : AirflowNetworkNodeData(i).Name);
5627 : }
5628 263 : if (!(supplyFanType == HVAC::FanType::OnOff && i <= AirflowNetworkNumOfZones)) {
5629 498 : SetupOutputVariable(m_state,
5630 : "AFN Node Total Pressure",
5631 : Constant::Units::Pa,
5632 249 : AirflowNetworkNodeSimu(i).PZ,
5633 : OutputProcessor::TimeStepType::System,
5634 : OutputProcessor::StoreType::Average,
5635 249 : AirflowNetworkNodeData(i).Name);
5636 : }
5637 263 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
5638 178 : SetupOutputVariable(m_state,
5639 : "AFN Node Wind Pressure",
5640 : Constant::Units::Pa,
5641 89 : AirflowNetworkNodeSimu(i).PZ,
5642 : OutputProcessor::TimeStepType::System,
5643 : OutputProcessor::StoreType::Average,
5644 89 : AirflowNetworkNodeData(i).Name);
5645 : }
5646 : }
5647 :
5648 328 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
5649 304 : if (!(supplyFanType == HVAC::FanType::OnOff && i <= AirflowNetworkNumOfSurfaces)) {
5650 504 : SetupOutputVariable(m_state,
5651 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
5652 : Constant::Units::kg_s,
5653 252 : linkReport(i).FLOW,
5654 : OutputProcessor::TimeStepType::System,
5655 : OutputProcessor::StoreType::Average,
5656 252 : AirflowNetworkLinkageData(i).Name);
5657 504 : SetupOutputVariable(m_state,
5658 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
5659 : Constant::Units::kg_s,
5660 252 : linkReport(i).FLOW2,
5661 : OutputProcessor::TimeStepType::System,
5662 : OutputProcessor::StoreType::Average,
5663 252 : AirflowNetworkLinkageData(i).Name);
5664 504 : SetupOutputVariable(m_state,
5665 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
5666 : Constant::Units::m3_s,
5667 252 : linkReport(i).VolFLOW,
5668 : OutputProcessor::TimeStepType::System,
5669 : OutputProcessor::StoreType::Average,
5670 252 : AirflowNetworkLinkageData(i).Name);
5671 504 : SetupOutputVariable(m_state,
5672 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
5673 : Constant::Units::m3_s,
5674 252 : linkReport(i).VolFLOW2,
5675 : OutputProcessor::TimeStepType::System,
5676 : OutputProcessor::StoreType::Average,
5677 252 : AirflowNetworkLinkageData(i).Name);
5678 504 : SetupOutputVariable(m_state,
5679 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
5680 : Constant::Units::Pa,
5681 252 : AirflowNetworkLinkSimu(i).DP,
5682 : OutputProcessor::TimeStepType::System,
5683 : OutputProcessor::StoreType::Average,
5684 252 : AirflowNetworkLinkageData(i).Name);
5685 : }
5686 : }
5687 :
5688 169 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5689 145 : if (AirflowNetworkLinkageData(i).element == nullptr) {
5690 : // This is not great
5691 0 : continue;
5692 : }
5693 145 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::DOP ||
5694 266 : AirflowNetworkLinkageData(i).element->type() == ComponentType::SOP ||
5695 121 : AirflowNetworkLinkageData(i).element->type() == ComponentType::HOP) {
5696 24 : SurfNum = MultizoneSurfaceData(i).SurfNum;
5697 48 : SetupOutputVariable(m_state,
5698 : "AFN Surface Venting Window or Door Opening Factor",
5699 : Constant::Units::None,
5700 24 : MultizoneSurfaceData(i).OpenFactor,
5701 : OutputProcessor::TimeStepType::System,
5702 : OutputProcessor::StoreType::Average,
5703 24 : MultizoneSurfaceData(i).SurfName);
5704 24 : if (m_state.dataGlobal->AnyEnergyManagementSystemInModel) {
5705 0 : SetupEMSActuator(m_state,
5706 : "AirFlow Network Window/Door Opening",
5707 0 : MultizoneSurfaceData(i).SurfName,
5708 : "Venting Opening Factor",
5709 : "[Fraction]",
5710 0 : MultizoneSurfaceData(i).EMSOpenFactorActuated,
5711 0 : MultizoneSurfaceData(i).EMSOpenFactor);
5712 : }
5713 48 : SetupOutputVariable(m_state,
5714 : "AFN Surface Venting Window or Door Opening Modulation Multiplier",
5715 : Constant::Units::None,
5716 24 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum),
5717 : OutputProcessor::TimeStepType::System,
5718 : OutputProcessor::StoreType::Average,
5719 24 : m_state.dataSurface->Surface(SurfNum).Name);
5720 48 : SetupOutputVariable(m_state,
5721 : "AFN Surface Venting Inside Setpoint Temperature",
5722 : Constant::Units::C,
5723 24 : m_state.dataSurface->SurfWinInsideTempForVentingRep(SurfNum),
5724 : OutputProcessor::TimeStepType::System,
5725 : OutputProcessor::StoreType::Average,
5726 24 : m_state.dataSurface->Surface(SurfNum).Name);
5727 48 : SetupOutputVariable(m_state,
5728 : "AFN Surface Venting Availability Status",
5729 : Constant::Units::None,
5730 24 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum),
5731 : OutputProcessor::TimeStepType::System,
5732 : OutputProcessor::StoreType::Average,
5733 24 : m_state.dataSurface->Surface(SurfNum).Name);
5734 24 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5735 0 : SetupOutputVariable(m_state,
5736 : "AFN Surface Venting Window or Door Opening Factor at Previous Time Step",
5737 : Constant::Units::None,
5738 0 : MultizoneSurfaceData(i).OpenFactorLast,
5739 : OutputProcessor::TimeStepType::System,
5740 : OutputProcessor::StoreType::Average,
5741 0 : MultizoneSurfaceData(i).SurfName);
5742 0 : SetupOutputVariable(m_state,
5743 : "AFN Surface Opening Elapsed Time",
5744 : Constant::Units::min,
5745 0 : MultizoneSurfaceData(i).OpenElapsedTime,
5746 : OutputProcessor::TimeStepType::System,
5747 : OutputProcessor::StoreType::Average,
5748 0 : MultizoneSurfaceData(i).SurfName);
5749 0 : SetupOutputVariable(m_state,
5750 : "AFN Surface Closing Elapsed Time",
5751 : Constant::Units::min,
5752 0 : MultizoneSurfaceData(i).CloseElapsedTime,
5753 : OutputProcessor::TimeStepType::System,
5754 : OutputProcessor::StoreType::Average,
5755 0 : MultizoneSurfaceData(i).SurfName);
5756 0 : SetupOutputVariable(m_state,
5757 : "AFN Surface Opening Status at Previous Time Step",
5758 : Constant::Units::None,
5759 0 : MultizoneSurfaceData(i).PrevOpeningstatus,
5760 : OutputProcessor::TimeStepType::System,
5761 : OutputProcessor::StoreType::Average,
5762 0 : MultizoneSurfaceData(i).SurfName);
5763 0 : SetupOutputVariable(m_state,
5764 : "AFN Surface Opening Status",
5765 : Constant::Units::None,
5766 0 : MultizoneSurfaceData(i).OpeningStatus,
5767 : OutputProcessor::TimeStepType::System,
5768 : OutputProcessor::StoreType::Average,
5769 0 : MultizoneSurfaceData(i).SurfName);
5770 0 : SetupOutputVariable(m_state,
5771 : "AFN Surface Opening Probability Status",
5772 : Constant::Units::None,
5773 0 : MultizoneSurfaceData(i).OpeningProbStatus,
5774 : OutputProcessor::TimeStepType::System,
5775 : OutputProcessor::StoreType::Average,
5776 0 : MultizoneSurfaceData(i).SurfName);
5777 0 : SetupOutputVariable(m_state,
5778 : "AFN Surface Closing Probability Status",
5779 : Constant::Units::None,
5780 0 : MultizoneSurfaceData(i).ClosingProbStatus,
5781 : OutputProcessor::TimeStepType::System,
5782 : OutputProcessor::StoreType::Average,
5783 0 : MultizoneSurfaceData(i).SurfName);
5784 : }
5785 : }
5786 : }
5787 :
5788 78 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5789 : // Multizone losses due to force air systems
5790 108 : SetupOutputVariable(m_state,
5791 : "AFN Zone Infiltration Sensible Heat Gain Rate",
5792 : Constant::Units::W,
5793 54 : AirflowNetworkReportData(i).MultiZoneInfiSenGainW,
5794 : OutputProcessor::TimeStepType::System,
5795 : OutputProcessor::StoreType::Average,
5796 54 : Zone(i).Name);
5797 108 : SetupOutputVariable(m_state,
5798 : "AFN Zone Infiltration Sensible Heat Gain Energy",
5799 : Constant::Units::J,
5800 54 : AirflowNetworkReportData(i).MultiZoneInfiSenGainJ,
5801 : OutputProcessor::TimeStepType::System,
5802 : OutputProcessor::StoreType::Sum,
5803 54 : Zone(i).Name);
5804 108 : SetupOutputVariable(m_state,
5805 : "AFN Zone Ventilation Sensible Heat Gain Rate",
5806 : Constant::Units::W,
5807 54 : AirflowNetworkReportData(i).MultiZoneVentSenGainW,
5808 : OutputProcessor::TimeStepType::System,
5809 : OutputProcessor::StoreType::Average,
5810 54 : Zone(i).Name);
5811 108 : SetupOutputVariable(m_state,
5812 : "AFN Zone Ventilation Sensible Heat Gain Energy",
5813 : Constant::Units::J,
5814 54 : AirflowNetworkReportData(i).MultiZoneVentSenGainJ,
5815 : OutputProcessor::TimeStepType::System,
5816 : OutputProcessor::StoreType::Sum,
5817 54 : Zone(i).Name);
5818 108 : SetupOutputVariable(m_state,
5819 : "AFN Zone Mixing Sensible Heat Gain Rate",
5820 : Constant::Units::W,
5821 54 : AirflowNetworkReportData(i).MultiZoneMixSenGainW,
5822 : OutputProcessor::TimeStepType::System,
5823 : OutputProcessor::StoreType::Average,
5824 54 : Zone(i).Name);
5825 108 : SetupOutputVariable(m_state,
5826 : "AFN Zone Mixing Sensible Heat Gain Energy",
5827 : Constant::Units::J,
5828 54 : AirflowNetworkReportData(i).MultiZoneMixSenGainJ,
5829 : OutputProcessor::TimeStepType::System,
5830 : OutputProcessor::StoreType::Sum,
5831 54 : Zone(i).Name);
5832 108 : SetupOutputVariable(m_state,
5833 : "AFN Zone Infiltration Sensible Heat Loss Rate",
5834 : Constant::Units::W,
5835 54 : AirflowNetworkReportData(i).MultiZoneInfiSenLossW,
5836 : OutputProcessor::TimeStepType::System,
5837 : OutputProcessor::StoreType::Average,
5838 54 : Zone(i).Name);
5839 108 : SetupOutputVariable(m_state,
5840 : "AFN Zone Infiltration Sensible Heat Loss Energy",
5841 : Constant::Units::J,
5842 54 : AirflowNetworkReportData(i).MultiZoneInfiSenLossJ,
5843 : OutputProcessor::TimeStepType::System,
5844 : OutputProcessor::StoreType::Sum,
5845 54 : Zone(i).Name);
5846 108 : SetupOutputVariable(m_state,
5847 : "AFN Zone Ventilation Sensible Heat Loss Rate",
5848 : Constant::Units::W,
5849 54 : AirflowNetworkReportData(i).MultiZoneVentSenLossW,
5850 : OutputProcessor::TimeStepType::System,
5851 : OutputProcessor::StoreType::Average,
5852 54 : Zone(i).Name);
5853 108 : SetupOutputVariable(m_state,
5854 : "AFN Zone Ventilation Sensible Heat Loss Energy",
5855 : Constant::Units::J,
5856 54 : AirflowNetworkReportData(i).MultiZoneVentSenLossJ,
5857 : OutputProcessor::TimeStepType::System,
5858 : OutputProcessor::StoreType::Sum,
5859 54 : Zone(i).Name);
5860 108 : SetupOutputVariable(m_state,
5861 : "AFN Zone Mixing Sensible Heat Loss Rate",
5862 : Constant::Units::W,
5863 54 : AirflowNetworkReportData(i).MultiZoneMixSenLossW,
5864 : OutputProcessor::TimeStepType::System,
5865 : OutputProcessor::StoreType::Average,
5866 54 : Zone(i).Name);
5867 108 : SetupOutputVariable(m_state,
5868 : "AFN Zone Mixing Sensible Heat Loss Energy",
5869 : Constant::Units::J,
5870 54 : AirflowNetworkReportData(i).MultiZoneMixSenLossJ,
5871 : OutputProcessor::TimeStepType::System,
5872 : OutputProcessor::StoreType::Sum,
5873 54 : Zone(i).Name);
5874 108 : SetupOutputVariable(m_state,
5875 : "AFN Zone Infiltration Latent Heat Gain Rate",
5876 : Constant::Units::W,
5877 54 : AirflowNetworkReportData(i).MultiZoneInfiLatGainW,
5878 : OutputProcessor::TimeStepType::System,
5879 : OutputProcessor::StoreType::Average,
5880 54 : Zone(i).Name);
5881 108 : SetupOutputVariable(m_state,
5882 : "AFN Zone Infiltration Latent Heat Gain Energy",
5883 : Constant::Units::J,
5884 54 : AirflowNetworkReportData(i).MultiZoneInfiLatGainJ,
5885 : OutputProcessor::TimeStepType::System,
5886 : OutputProcessor::StoreType::Sum,
5887 54 : Zone(i).Name);
5888 108 : SetupOutputVariable(m_state,
5889 : "AFN Zone Infiltration Latent Heat Loss Rate",
5890 : Constant::Units::W,
5891 54 : AirflowNetworkReportData(i).MultiZoneInfiLatLossW,
5892 : OutputProcessor::TimeStepType::System,
5893 : OutputProcessor::StoreType::Average,
5894 54 : Zone(i).Name);
5895 108 : SetupOutputVariable(m_state,
5896 : "AFN Zone Infiltration Latent Heat Loss Energy",
5897 : Constant::Units::J,
5898 54 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ,
5899 : OutputProcessor::TimeStepType::System,
5900 : OutputProcessor::StoreType::Sum,
5901 54 : Zone(i).Name);
5902 108 : SetupOutputVariable(m_state,
5903 : "AFN Zone Ventilation Latent Heat Gain Rate",
5904 : Constant::Units::W,
5905 54 : AirflowNetworkReportData(i).MultiZoneVentLatGainW,
5906 : OutputProcessor::TimeStepType::System,
5907 : OutputProcessor::StoreType::Average,
5908 54 : Zone(i).Name);
5909 108 : SetupOutputVariable(m_state,
5910 : "AFN Zone Ventilation Latent Heat Gain Energy",
5911 : Constant::Units::J,
5912 54 : AirflowNetworkReportData(i).MultiZoneVentLatGainJ,
5913 : OutputProcessor::TimeStepType::System,
5914 : OutputProcessor::StoreType::Sum,
5915 54 : Zone(i).Name);
5916 108 : SetupOutputVariable(m_state,
5917 : "AFN Zone Ventilation Latent Heat Loss Rate",
5918 : Constant::Units::W,
5919 54 : AirflowNetworkReportData(i).MultiZoneVentLatLossW,
5920 : OutputProcessor::TimeStepType::System,
5921 : OutputProcessor::StoreType::Average,
5922 54 : Zone(i).Name);
5923 108 : SetupOutputVariable(m_state,
5924 : "AFN Zone Ventilation Latent Heat Loss Energy",
5925 : Constant::Units::J,
5926 54 : AirflowNetworkReportData(i).MultiZoneVentLatLossJ,
5927 : OutputProcessor::TimeStepType::System,
5928 : OutputProcessor::StoreType::Sum,
5929 54 : Zone(i).Name);
5930 108 : SetupOutputVariable(m_state,
5931 : "AFN Zone Mixing Latent Heat Gain Rate",
5932 : Constant::Units::W,
5933 54 : AirflowNetworkReportData(i).MultiZoneMixLatGainW,
5934 : OutputProcessor::TimeStepType::System,
5935 : OutputProcessor::StoreType::Average,
5936 54 : Zone(i).Name);
5937 108 : SetupOutputVariable(m_state,
5938 : "AFN Zone Mixing Latent Heat Gain Energy",
5939 : Constant::Units::J,
5940 54 : AirflowNetworkReportData(i).MultiZoneMixLatGainJ,
5941 : OutputProcessor::TimeStepType::System,
5942 : OutputProcessor::StoreType::Sum,
5943 54 : Zone(i).Name);
5944 108 : SetupOutputVariable(m_state,
5945 : "AFN Zone Mixing Latent Heat Loss Rate",
5946 : Constant::Units::W,
5947 54 : AirflowNetworkReportData(i).MultiZoneMixLatLossW,
5948 : OutputProcessor::TimeStepType::System,
5949 : OutputProcessor::StoreType::Average,
5950 54 : Zone(i).Name);
5951 108 : SetupOutputVariable(m_state,
5952 : "AFN Zone Mixing Latent Heat Loss Energy",
5953 : Constant::Units::J,
5954 54 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ,
5955 : OutputProcessor::TimeStepType::System,
5956 : OutputProcessor::StoreType::Sum,
5957 54 : Zone(i).Name);
5958 : // Supply leak losses due to force air systems
5959 108 : SetupOutputVariable(m_state,
5960 : "AFN Zone Duct Leaked Air Sensible Heat Gain Rate",
5961 : Constant::Units::W,
5962 54 : AirflowNetworkReportData(i).LeakSenGainW,
5963 : OutputProcessor::TimeStepType::System,
5964 : OutputProcessor::StoreType::Average,
5965 54 : Zone(i).Name);
5966 108 : SetupOutputVariable(m_state,
5967 : "AFN Zone Duct Leaked Air Sensible Heat Gain Energy",
5968 : Constant::Units::J,
5969 54 : AirflowNetworkReportData(i).LeakSenGainJ,
5970 : OutputProcessor::TimeStepType::System,
5971 : OutputProcessor::StoreType::Sum,
5972 54 : Zone(i).Name);
5973 108 : SetupOutputVariable(m_state,
5974 : "AFN Zone Duct Leaked Air Sensible Heat Loss Rate",
5975 : Constant::Units::W,
5976 54 : AirflowNetworkReportData(i).LeakSenLossW,
5977 : OutputProcessor::TimeStepType::System,
5978 : OutputProcessor::StoreType::Average,
5979 54 : Zone(i).Name);
5980 108 : SetupOutputVariable(m_state,
5981 : "AFN Zone Duct Leaked Air Sensible Heat Loss Energy",
5982 : Constant::Units::J,
5983 54 : AirflowNetworkReportData(i).LeakSenLossJ,
5984 : OutputProcessor::TimeStepType::System,
5985 : OutputProcessor::StoreType::Sum,
5986 54 : Zone(i).Name);
5987 108 : SetupOutputVariable(m_state,
5988 : "AFN Zone Duct Leaked Air Latent Heat Gain Rate",
5989 : Constant::Units::W,
5990 54 : AirflowNetworkReportData(i).LeakLatGainW,
5991 : OutputProcessor::TimeStepType::System,
5992 : OutputProcessor::StoreType::Average,
5993 54 : Zone(i).Name);
5994 108 : SetupOutputVariable(m_state,
5995 : "AFN Zone Duct Leaked Air Latent Heat Gain Energy",
5996 : Constant::Units::J,
5997 54 : AirflowNetworkReportData(i).LeakLatGainJ,
5998 : OutputProcessor::TimeStepType::System,
5999 : OutputProcessor::StoreType::Sum,
6000 54 : Zone(i).Name);
6001 108 : SetupOutputVariable(m_state,
6002 : "AFN Zone Duct Leaked Air Latent Heat Loss Rate",
6003 : Constant::Units::W,
6004 54 : AirflowNetworkReportData(i).LeakLatLossW,
6005 : OutputProcessor::TimeStepType::System,
6006 : OutputProcessor::StoreType::Average,
6007 54 : Zone(i).Name);
6008 108 : SetupOutputVariable(m_state,
6009 : "AFN Zone Duct Leaked Air Latent Heat Loss Energy",
6010 : Constant::Units::J,
6011 54 : AirflowNetworkReportData(i).LeakLatLossJ,
6012 : OutputProcessor::TimeStepType::System,
6013 : OutputProcessor::StoreType::Sum,
6014 54 : Zone(i).Name);
6015 : // Conduction losses due to force air systems
6016 108 : SetupOutputVariable(m_state,
6017 : "AFN Zone Duct Conduction Sensible Heat Gain Rate",
6018 : Constant::Units::W,
6019 54 : AirflowNetworkReportData(i).CondSenGainW,
6020 : OutputProcessor::TimeStepType::System,
6021 : OutputProcessor::StoreType::Average,
6022 54 : Zone(i).Name);
6023 108 : SetupOutputVariable(m_state,
6024 : "AFN Zone Duct Conduction Sensible Heat Gain Energy",
6025 : Constant::Units::J,
6026 54 : AirflowNetworkReportData(i).CondSenGainJ,
6027 : OutputProcessor::TimeStepType::System,
6028 : OutputProcessor::StoreType::Sum,
6029 54 : Zone(i).Name);
6030 108 : SetupOutputVariable(m_state,
6031 : "AFN Zone Duct Conduction Sensible Heat Loss Rate",
6032 : Constant::Units::W,
6033 54 : AirflowNetworkReportData(i).CondSenLossW,
6034 : OutputProcessor::TimeStepType::System,
6035 : OutputProcessor::StoreType::Average,
6036 54 : Zone(i).Name);
6037 108 : SetupOutputVariable(m_state,
6038 : "AFN Zone Duct Conduction Sensible Heat Loss Energy",
6039 : Constant::Units::J,
6040 54 : AirflowNetworkReportData(i).CondSenLossJ,
6041 : OutputProcessor::TimeStepType::System,
6042 : OutputProcessor::StoreType::Sum,
6043 54 : Zone(i).Name);
6044 108 : SetupOutputVariable(m_state,
6045 : "AFN Zone Duct Diffusion Latent Heat Gain Rate",
6046 : Constant::Units::W,
6047 54 : AirflowNetworkReportData(i).DiffLatGainW,
6048 : OutputProcessor::TimeStepType::System,
6049 : OutputProcessor::StoreType::Average,
6050 54 : Zone(i).Name);
6051 108 : SetupOutputVariable(m_state,
6052 : "AFN Zone Duct Diffusion Latent Heat Gain Energy",
6053 : Constant::Units::J,
6054 54 : AirflowNetworkReportData(i).DiffLatGainJ,
6055 : OutputProcessor::TimeStepType::System,
6056 : OutputProcessor::StoreType::Sum,
6057 54 : Zone(i).Name);
6058 108 : SetupOutputVariable(m_state,
6059 : "AFN Zone Duct Diffusion Latent Heat Loss Rate",
6060 : Constant::Units::W,
6061 54 : AirflowNetworkReportData(i).DiffLatLossW,
6062 : OutputProcessor::TimeStepType::System,
6063 : OutputProcessor::StoreType::Average,
6064 54 : Zone(i).Name);
6065 108 : SetupOutputVariable(m_state,
6066 : "AFN Zone Duct Diffusion Latent Heat Loss Energy",
6067 : Constant::Units::J,
6068 54 : AirflowNetworkReportData(i).DiffLatLossJ,
6069 : OutputProcessor::TimeStepType::System,
6070 : OutputProcessor::StoreType::Sum,
6071 54 : Zone(i).Name);
6072 : // Radiation losses due to forced air systems
6073 108 : SetupOutputVariable(m_state,
6074 : "AFN Zone Duct Radiation Heat Gain Rate",
6075 : Constant::Units::W,
6076 54 : AirflowNetworkReportData(i).RadGainW,
6077 : OutputProcessor::TimeStepType::System,
6078 : OutputProcessor::StoreType::Average,
6079 54 : Zone(i).Name);
6080 108 : SetupOutputVariable(m_state,
6081 : "AFN Zone Duct Radiation Sensible Heat Gain Energy",
6082 : Constant::Units::J,
6083 54 : AirflowNetworkReportData(i).RadGainJ,
6084 : OutputProcessor::TimeStepType::System,
6085 : OutputProcessor::StoreType::Sum,
6086 54 : Zone(i).Name);
6087 108 : SetupOutputVariable(m_state,
6088 : "AFN Zone Duct Radiation Heat Loss Rate",
6089 : Constant::Units::W,
6090 54 : AirflowNetworkReportData(i).RadLossW,
6091 : OutputProcessor::TimeStepType::System,
6092 : OutputProcessor::StoreType::Average,
6093 54 : Zone(i).Name);
6094 108 : SetupOutputVariable(m_state,
6095 : "AFN Zone Duct Radiation Sensible Heat Loss Energy",
6096 : Constant::Units::J,
6097 54 : AirflowNetworkReportData(i).RadLossJ,
6098 : OutputProcessor::TimeStepType::System,
6099 : OutputProcessor::StoreType::Sum,
6100 54 : Zone(i).Name);
6101 : // Total losses due to force air systems
6102 108 : SetupOutputVariable(m_state,
6103 : "AFN Distribution Sensible Heat Gain Rate",
6104 : Constant::Units::W,
6105 54 : AirflowNetworkReportData(i).TotalSenGainW,
6106 : OutputProcessor::TimeStepType::System,
6107 : OutputProcessor::StoreType::Average,
6108 54 : Zone(i).Name);
6109 108 : SetupOutputVariable(m_state,
6110 : "AFN Distribution Sensible Heat Gain Energy",
6111 : Constant::Units::J,
6112 54 : AirflowNetworkReportData(i).TotalSenGainJ,
6113 : OutputProcessor::TimeStepType::System,
6114 : OutputProcessor::StoreType::Sum,
6115 54 : Zone(i).Name);
6116 108 : SetupOutputVariable(m_state,
6117 : "AFN Distribution Sensible Heat Loss Rate",
6118 : Constant::Units::W,
6119 54 : AirflowNetworkReportData(i).TotalSenLossW,
6120 : OutputProcessor::TimeStepType::System,
6121 : OutputProcessor::StoreType::Average,
6122 54 : Zone(i).Name);
6123 108 : SetupOutputVariable(m_state,
6124 : "AFN Distribution Sensible Heat Loss Energy",
6125 : Constant::Units::J,
6126 54 : AirflowNetworkReportData(i).TotalSenLossJ,
6127 : OutputProcessor::TimeStepType::System,
6128 : OutputProcessor::StoreType::Sum,
6129 54 : Zone(i).Name);
6130 108 : SetupOutputVariable(m_state,
6131 : "AFN Distribution Latent Heat Gain Rate",
6132 : Constant::Units::W,
6133 54 : AirflowNetworkReportData(i).TotalLatGainW,
6134 : OutputProcessor::TimeStepType::System,
6135 : OutputProcessor::StoreType::Average,
6136 54 : Zone(i).Name);
6137 108 : SetupOutputVariable(m_state,
6138 : "AFN Distribution Latent Heat Gain Energy",
6139 : Constant::Units::J,
6140 54 : AirflowNetworkReportData(i).TotalLatGainJ,
6141 : OutputProcessor::TimeStepType::System,
6142 : OutputProcessor::StoreType::Sum,
6143 54 : Zone(i).Name);
6144 108 : SetupOutputVariable(m_state,
6145 : "AFN Distribution Latent Heat Loss Rate",
6146 : Constant::Units::W,
6147 54 : AirflowNetworkReportData(i).TotalLatLossW,
6148 : OutputProcessor::TimeStepType::System,
6149 : OutputProcessor::StoreType::Average,
6150 54 : Zone(i).Name);
6151 108 : SetupOutputVariable(m_state,
6152 : "AFN Distribution Latent Heat Loss Energy",
6153 : Constant::Units::J,
6154 54 : AirflowNetworkReportData(i).TotalLatLossJ,
6155 : OutputProcessor::TimeStepType::System,
6156 : OutputProcessor::StoreType::Sum,
6157 54 : Zone(i).Name);
6158 : }
6159 :
6160 78 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
6161 108 : SetupOutputVariable(m_state,
6162 : "AFN Zone Infiltration Volume",
6163 : Constant::Units::m3,
6164 54 : AirflowNetworkZnRpt(i).InfilVolume,
6165 : OutputProcessor::TimeStepType::System,
6166 : OutputProcessor::StoreType::Sum,
6167 54 : Zone(i).Name);
6168 108 : SetupOutputVariable(m_state,
6169 : "AFN Zone Infiltration Mass",
6170 : Constant::Units::kg,
6171 54 : AirflowNetworkZnRpt(i).InfilMass,
6172 : OutputProcessor::TimeStepType::System,
6173 : OutputProcessor::StoreType::Sum,
6174 54 : Zone(i).Name);
6175 108 : SetupOutputVariable(m_state,
6176 : "AFN Zone Infiltration Air Change Rate",
6177 : Constant::Units::ach,
6178 54 : AirflowNetworkZnRpt(i).InfilAirChangeRate,
6179 : OutputProcessor::TimeStepType::System,
6180 : OutputProcessor::StoreType::Average,
6181 54 : Zone(i).Name);
6182 108 : SetupOutputVariable(m_state,
6183 : "AFN Zone Ventilation Volume",
6184 : Constant::Units::m3,
6185 54 : AirflowNetworkZnRpt(i).VentilVolume,
6186 : OutputProcessor::TimeStepType::System,
6187 : OutputProcessor::StoreType::Sum,
6188 54 : Zone(i).Name);
6189 108 : SetupOutputVariable(m_state,
6190 : "AFN Zone Ventilation Mass",
6191 : Constant::Units::kg,
6192 54 : AirflowNetworkZnRpt(i).VentilMass,
6193 : OutputProcessor::TimeStepType::System,
6194 : OutputProcessor::StoreType::Sum,
6195 54 : Zone(i).Name);
6196 108 : SetupOutputVariable(m_state,
6197 : "AFN Zone Ventilation Air Change Rate",
6198 : Constant::Units::ach,
6199 54 : AirflowNetworkZnRpt(i).VentilAirChangeRate,
6200 : OutputProcessor::TimeStepType::System,
6201 : OutputProcessor::StoreType::Average,
6202 54 : Zone(i).Name);
6203 108 : SetupOutputVariable(m_state,
6204 : "AFN Zone Mixing Volume",
6205 : Constant::Units::m3,
6206 54 : AirflowNetworkZnRpt(i).MixVolume,
6207 : OutputProcessor::TimeStepType::System,
6208 : OutputProcessor::StoreType::Sum,
6209 54 : Zone(i).Name);
6210 108 : SetupOutputVariable(m_state,
6211 : "AFN Zone Mixing Mass",
6212 : Constant::Units::kg,
6213 54 : AirflowNetworkZnRpt(i).MixMass,
6214 : OutputProcessor::TimeStepType::System,
6215 : OutputProcessor::StoreType::Sum,
6216 54 : Zone(i).Name);
6217 :
6218 108 : SetupOutputVariable(m_state,
6219 : "AFN Zone Exfiltration Heat Transfer Rate",
6220 : Constant::Units::W,
6221 54 : AirflowNetworkZnRpt(i).ExfilTotalLoss,
6222 : OutputProcessor::TimeStepType::System,
6223 : OutputProcessor::StoreType::Average,
6224 54 : Zone(i).Name);
6225 108 : SetupOutputVariable(m_state,
6226 : "AFN Zone Exfiltration Sensible Heat Transfer Rate",
6227 : Constant::Units::W,
6228 54 : AirflowNetworkZnRpt(i).ExfilSensiLoss,
6229 : OutputProcessor::TimeStepType::System,
6230 : OutputProcessor::StoreType::Average,
6231 54 : Zone(i).Name);
6232 108 : SetupOutputVariable(m_state,
6233 : "AFN Zone Exfiltration Latent Heat Transfer Rate",
6234 : Constant::Units::W,
6235 54 : AirflowNetworkZnRpt(i).ExfilLatentLoss,
6236 : OutputProcessor::TimeStepType::System,
6237 : OutputProcessor::StoreType::Average,
6238 54 : Zone(i).Name);
6239 : }
6240 :
6241 24 : if (OnOffFanFlag) {
6242 18 : for (i = 1; i <= AirflowNetworkNumOfZones; ++i) {
6243 28 : SetupOutputVariable(m_state,
6244 : "AFN Zone Average Pressure",
6245 : Constant::Units::Pa,
6246 14 : nodeReport(i).PZ,
6247 : OutputProcessor::TimeStepType::System,
6248 : OutputProcessor::StoreType::Average,
6249 14 : Zone(i).Name);
6250 28 : SetupOutputVariable(m_state,
6251 : "AFN Zone On Cycle Pressure",
6252 : Constant::Units::Pa,
6253 14 : nodeReport(i).PZON,
6254 : OutputProcessor::TimeStepType::System,
6255 : OutputProcessor::StoreType::Average,
6256 14 : Zone(i).Name);
6257 28 : SetupOutputVariable(m_state,
6258 : "AFN Zone Off Cycle Pressure",
6259 : Constant::Units::Pa,
6260 14 : nodeReport(i).PZOFF,
6261 : OutputProcessor::TimeStepType::System,
6262 : OutputProcessor::StoreType::Average,
6263 14 : Zone(i).Name);
6264 : }
6265 56 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6266 104 : SetupOutputVariable(m_state,
6267 : "AFN Linkage Node 1 to 2 Average Mass Flow Rate",
6268 : Constant::Units::kg_s,
6269 52 : linkReport1(i).FLOW,
6270 : OutputProcessor::TimeStepType::System,
6271 : OutputProcessor::StoreType::Average,
6272 52 : MultizoneSurfaceData(i).SurfName);
6273 104 : SetupOutputVariable(m_state,
6274 : "AFN Linkage Node 2 to 1 Average Mass Flow Rate",
6275 : Constant::Units::kg_s,
6276 52 : linkReport1(i).FLOW2,
6277 : OutputProcessor::TimeStepType::System,
6278 : OutputProcessor::StoreType::Average,
6279 52 : MultizoneSurfaceData(i).SurfName);
6280 104 : SetupOutputVariable(m_state,
6281 : "AFN Linkage Node 1 to 2 Average Volume Flow Rate",
6282 : Constant::Units::m3_s,
6283 52 : linkReport1(i).VolFLOW,
6284 : OutputProcessor::TimeStepType::System,
6285 : OutputProcessor::StoreType::Average,
6286 52 : MultizoneSurfaceData(i).SurfName);
6287 104 : SetupOutputVariable(m_state,
6288 : "AFN Linkage Node 2 to 1 Average Volume Flow Rate",
6289 : Constant::Units::m3_s,
6290 52 : linkReport1(i).VolFLOW2,
6291 : OutputProcessor::TimeStepType::System,
6292 : OutputProcessor::StoreType::Average,
6293 52 : MultizoneSurfaceData(i).SurfName);
6294 104 : SetupOutputVariable(m_state,
6295 : "AFN Surface Average Pressure Difference",
6296 : Constant::Units::Pa,
6297 52 : linkReport1(i).DP,
6298 : OutputProcessor::TimeStepType::System,
6299 : OutputProcessor::StoreType::Average,
6300 52 : MultizoneSurfaceData(i).SurfName);
6301 104 : SetupOutputVariable(m_state,
6302 : "AFN Surface On Cycle Pressure Difference",
6303 : Constant::Units::Pa,
6304 52 : linkReport1(i).DPON,
6305 : OutputProcessor::TimeStepType::System,
6306 : OutputProcessor::StoreType::Average,
6307 52 : MultizoneSurfaceData(i).SurfName);
6308 104 : SetupOutputVariable(m_state,
6309 : "AFN Surface Off Cycle Pressure Difference",
6310 : Constant::Units::Pa,
6311 52 : linkReport1(i).DPOFF,
6312 : OutputProcessor::TimeStepType::System,
6313 : OutputProcessor::StoreType::Average,
6314 52 : MultizoneSurfaceData(i).SurfName);
6315 : }
6316 : }
6317 :
6318 : // Assign node reference height
6319 287 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
6320 263 : if (!simulation_control.temperature_height_dependence) {
6321 263 : AirflowNetworkNodeData(i).NodeHeight = 0.0;
6322 : }
6323 263 : int ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
6324 263 : if (ZoneNum > 0) {
6325 55 : if (m_state.dataSurface->WorldCoordSystem) {
6326 43 : AirflowNetworkNodeData(i).NodeHeight = 0.0;
6327 : } else {
6328 12 : AirflowNetworkNodeData(i).NodeHeight = Zone(ZoneNum).OriginZ;
6329 : }
6330 : }
6331 : }
6332 24 : }
6333 :
6334 16865 : void Solver::calculate_balance()
6335 : {
6336 : // SUBROUTINE INFORMATION:
6337 : // AUTHOR Lixing Gu
6338 : // DATE WRITTEN Oct. 2005
6339 : // MODIFIED na
6340 : // RE-ENGINEERED na
6341 :
6342 : // PURPOSE OF THIS SUBROUTINE:
6343 : // This subroutine performs simulations of nodal pressures and linkage airflows.
6344 :
6345 : // Using/Aliasing
6346 : using General::SolveRoot;
6347 : using HVAC::VerySmallMassFlow;
6348 :
6349 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6350 : int i;
6351 : int j;
6352 : int n;
6353 : int NodeNum;
6354 : Real64 GlobalOpenFactor;
6355 : Real64 ZonePressure1;
6356 : Real64 ZonePressure2;
6357 : Real64 PressureSet;
6358 : Real64 LocalAzimuth;
6359 : Real64 LocalWindSpeed;
6360 : Real64 LocalWindDir;
6361 : Real64 LocalHumRat;
6362 : Real64 LocalDryBulb;
6363 16865 : Array1D<Real64> Par; // Pressure setpoint
6364 16865 : Real64 constexpr ErrorToler(0.00001);
6365 16865 : int constexpr MaxIte(20);
6366 : int SolFla;
6367 : Real64 MinExhaustMassFlowrate;
6368 : Real64 MaxExhaustMassFlowrate;
6369 : Real64 MinReliefMassFlowrate;
6370 : Real64 MaxReliefMassFlowrate;
6371 : int AirLoopNum;
6372 :
6373 16865 : auto &Node(m_state.dataLoopNodes->Node);
6374 :
6375 : // Validate supply and return connections
6376 16865 : if (CalcAirflowNetworkAirBalanceOneTimeFlag) {
6377 11 : CalcAirflowNetworkAirBalanceOneTimeFlag = false;
6378 11 : if (CalcAirflowNetworkAirBalanceErrorsFound) {
6379 0 : ShowFatalError(m_state, "GetAirflowNetworkInput: Program terminates for preceding reason(s).");
6380 : }
6381 : }
6382 :
6383 508909 : for (n = 1; n <= ActualNumOfNodes; ++n) {
6384 492044 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
6385 205511 : AirflowNetworkNodeSimu(n).PZ = 0.0;
6386 : } else {
6387 : // Assigning ambient conditions to external nodes
6388 286533 : i = AirflowNetworkNodeData(n).ExtNodeNum;
6389 286533 : if (i > 0) {
6390 286533 : AirflowNetworkNodeSimu(n).TZ = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(n).NodeHeight);
6391 286533 : AirflowNetworkNodeSimu(n).WZ = m_state.dataEnvrn->OutHumRat;
6392 286533 : if (i <= AirflowNetworkNumOfExtNode) {
6393 286527 : if (MultizoneExternalNodeData(i).OutAirNodeNum == 0) {
6394 286526 : LocalWindSpeed = DataEnvironment::WindSpeedAt(m_state, MultizoneExternalNodeData(i).height);
6395 286526 : LocalDryBulb = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(n).NodeHeight);
6396 286526 : LocalAzimuth = MultizoneExternalNodeData(i).azimuth;
6397 286526 : AirflowNetworkNodeSimu(n).PZ = calculate_wind_pressure(MultizoneExternalNodeData(i).curve,
6398 286526 : MultizoneExternalNodeData(i).symmetricCurve,
6399 286526 : MultizoneExternalNodeData(i).useRelativeAngle,
6400 : LocalAzimuth,
6401 : LocalWindSpeed,
6402 286526 : m_state.dataEnvrn->WindDir,
6403 : LocalDryBulb,
6404 286526 : m_state.dataEnvrn->OutHumRat);
6405 : } else {
6406 : // If and outdoor air node object is defined as the External Node Name in AirflowNetwork:MultiZone:Surface,
6407 : // the node object requires to define the Wind Pressure Coefficient Curve Name.
6408 1 : NodeNum = MultizoneExternalNodeData(i).OutAirNodeNum;
6409 1 : LocalWindSpeed = Node((NodeNum)).OutAirWindSpeed;
6410 1 : LocalWindDir = Node((NodeNum)).OutAirWindDir;
6411 1 : LocalHumRat = Node((NodeNum)).HumRat;
6412 1 : LocalDryBulb = Node((NodeNum)).OutAirDryBulb;
6413 1 : LocalAzimuth = MultizoneExternalNodeData(i).azimuth;
6414 1 : AirflowNetworkNodeSimu(n).PZ = calculate_wind_pressure(MultizoneExternalNodeData(i).curve,
6415 1 : MultizoneExternalNodeData(i).symmetricCurve,
6416 1 : MultizoneExternalNodeData(i).useRelativeAngle,
6417 : LocalAzimuth,
6418 : LocalWindSpeed,
6419 : LocalWindDir,
6420 : LocalDryBulb,
6421 : LocalHumRat);
6422 1 : AirflowNetworkNodeSimu(n).TZ = LocalDryBulb;
6423 1 : AirflowNetworkNodeSimu(n).WZ = LocalHumRat;
6424 : }
6425 : }
6426 :
6427 : } else {
6428 0 : ShowSevereError(m_state,
6429 0 : "GetAirflowNetworkInput: AIRFLOWNETWORK:DISTRIBUTION:NODE: Invalid external node = " +
6430 0 : AirflowNetworkNodeData(n).Name);
6431 0 : CalcAirflowNetworkAirBalanceErrorsFound = true;
6432 : }
6433 : }
6434 : }
6435 :
6436 337172 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6437 320307 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) {
6438 0 : continue;
6439 : }
6440 320307 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::SCR) {
6441 109 : AirflowNetworkLinkageData(i).control = MultizoneSurfaceData(i).Factor;
6442 : }
6443 320307 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) {
6444 320307 : MultizoneSurfaceData(i).OpenFactor = 0.0;
6445 : }
6446 320307 : j = MultizoneSurfaceData(i).SurfNum;
6447 320307 : auto const &surf = m_state.dataSurface->Surface(j);
6448 320307 : if (surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
6449 320293 : surf.OriginalClass == SurfaceClass::GlassDoor || surf.IsAirBoundarySurf) {
6450 14 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
6451 0 : if (MultizoneSurfaceData(i).OpeningStatus == OpenStatus::FreeOperation) {
6452 0 : if (MultizoneSurfaceData(i).OpeningProbStatus == ProbabilityCheck::ForceChange) {
6453 0 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).Factor;
6454 0 : } else if (MultizoneSurfaceData(i).ClosingProbStatus == ProbabilityCheck::ForceChange) {
6455 0 : MultizoneSurfaceData(i).OpenFactor = 0.0;
6456 0 : } else if (MultizoneSurfaceData(i).ClosingProbStatus == ProbabilityCheck::KeepStatus ||
6457 0 : MultizoneSurfaceData(i).OpeningProbStatus == ProbabilityCheck::KeepStatus) {
6458 0 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).OpenFactorLast;
6459 : } else {
6460 0 : venting_control(i, MultizoneSurfaceData(i).OpenFactor);
6461 : }
6462 : }
6463 : } else {
6464 14 : venting_control(i, MultizoneSurfaceData(i).OpenFactor);
6465 : }
6466 14 : MultizoneSurfaceData(i).OpenFactor *= MultizoneSurfaceData(i).WindModifier;
6467 14 : if (MultizoneSurfaceData(i).HybridVentClose) {
6468 3 : MultizoneSurfaceData(i).OpenFactor = 0.0;
6469 3 : if (m_state.dataSurface->SurfWinVentingOpenFactorMultRep(j) > 0.0) {
6470 3 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(j) = 0.0;
6471 : }
6472 : }
6473 14 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DOP ||
6474 26 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SOP ||
6475 12 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
6476 0 : if (AirflowNetworkFanActivated && distribution_simulated && MultizoneSurfaceData(i).OpenFactor > 0.0 &&
6477 0 : (m_state.dataSurface->Surface(j).ExtBoundCond == ExternalEnvironment ||
6478 0 : (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
6479 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) &&
6480 0 : !m_state.dataGlobal->WarmupFlag) {
6481 : // Exterior Large opening only
6482 0 : ++MultizoneSurfaceData(i).ExtLargeOpeningErrCount;
6483 0 : if (MultizoneSurfaceData(i).ExtLargeOpeningErrCount < 2) {
6484 0 : ShowWarningError(m_state,
6485 0 : "AirflowNetwork: The window or door is open during HVAC system operation " +
6486 0 : MultizoneSurfaceData(i).SurfName);
6487 0 : ShowContinueError(m_state, format("The window or door opening factor is {:.2R}", MultizoneSurfaceData(i).OpenFactor));
6488 0 : ShowContinueErrorTimeStamp(m_state, "");
6489 : } else {
6490 0 : ShowRecurringWarningErrorAtEnd(m_state,
6491 0 : "AirFlowNetwork: " + MultizoneSurfaceData(i).SurfName +
6492 : " The window or door is open during HVAC system operation error continues...",
6493 0 : MultizoneSurfaceData(i).ExtLargeOpeningErrIndex,
6494 0 : MultizoneSurfaceData(i).OpenFactor,
6495 0 : MultizoneSurfaceData(i).OpenFactor);
6496 : }
6497 : }
6498 : }
6499 14 : if (MultizoneSurfaceData(i).OpenFactor > 1.0) {
6500 0 : ++MultizoneSurfaceData(i).OpenFactorErrCount;
6501 0 : if (MultizoneSurfaceData(i).OpenFactorErrCount < 2) {
6502 0 : ShowWarningError(m_state,
6503 0 : "AirflowNetwork: The window or door opening factor is greater than 1.0 " + MultizoneSurfaceData(i).SurfName);
6504 0 : ShowContinueErrorTimeStamp(m_state, "");
6505 : } else {
6506 0 : ShowRecurringWarningErrorAtEnd(m_state,
6507 0 : "AirFlowNetwork: " + MultizoneSurfaceData(i).SurfName +
6508 : " The window or door opening factor is greater than 1.0 error continues...",
6509 0 : MultizoneSurfaceData(i).OpenFactorErrIndex,
6510 0 : MultizoneSurfaceData(i).OpenFactor,
6511 0 : MultizoneSurfaceData(i).OpenFactor);
6512 : }
6513 : }
6514 : }
6515 : }
6516 :
6517 : // Check if the global ventilation control is applied or not
6518 16865 : GlobalOpenFactor = -1.0;
6519 337172 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6520 320307 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) {
6521 0 : continue;
6522 : }
6523 320307 : if (MultizoneSurfaceData(i).HybridCtrlMaster) {
6524 0 : GlobalOpenFactor = MultizoneSurfaceData(i).OpenFactor;
6525 0 : break;
6526 : }
6527 : }
6528 16865 : if (GlobalOpenFactor >= 0.0) {
6529 0 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6530 0 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) {
6531 0 : continue;
6532 : }
6533 0 : j = MultizoneSurfaceData(i).SurfNum;
6534 0 : auto const &surf = m_state.dataSurface->Surface(j);
6535 0 : if (surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
6536 0 : surf.OriginalClass == SurfaceClass::GlassDoor) {
6537 0 : if (MultizoneSurfaceData(i).HybridCtrlGlobal) {
6538 0 : MultizoneSurfaceData(i).OpenFactor = GlobalOpenFactor;
6539 : }
6540 : }
6541 : }
6542 : }
6543 :
6544 16865 : if (!Par.allocated()) {
6545 16865 : Par.allocate(1);
6546 16865 : Par = 0.0;
6547 : }
6548 :
6549 16865 : PressureSetFlag = 0;
6550 :
6551 16865 : if (NumOfPressureControllers == 1) {
6552 2 : if (PressureControllerData(1).availSched == nullptr) {
6553 0 : PressureSetFlag = PressureControllerData(1).ControlTypeSet;
6554 2 : } else if (PressureControllerData(1).availSched->getCurrentVal() > 0.0) {
6555 2 : PressureSetFlag = PressureControllerData(1).ControlTypeSet;
6556 : }
6557 2 : if (PressureSetFlag > 0) {
6558 2 : PressureSet = PressureControllerData(1).presSetpointSched->getCurrentVal();
6559 : }
6560 : }
6561 :
6562 16865 : initialize_calculation();
6563 :
6564 16865 : if (!(PressureSetFlag > 0 && AirflowNetworkFanActivated)) {
6565 16864 : airmov();
6566 1 : } else if (PressureSetFlag == PressureCtrlExhaust) {
6567 0 : AirLoopNum = AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).AirLoopNum;
6568 0 : MinExhaustMassFlowrate = 2.0 * VerySmallMassFlow;
6569 0 : MaxExhaustMassFlowrate = Node(PressureControllerData(1).OANodeNum).MassFlowRate;
6570 0 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling &&
6571 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio > 0.0) {
6572 0 : MaxExhaustMassFlowrate = MaxExhaustMassFlowrate / m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
6573 : }
6574 0 : ExhaustFanMassFlowRate = MinExhaustMassFlowrate;
6575 0 : airmov();
6576 0 : ZonePressure1 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6577 0 : if (ZonePressure1 <= PressureSet) {
6578 : // The highest pressure due to minimum flow rate could not reach Pressure set, bypass pressure set calculation
6579 0 : if (!m_state.dataGlobal->WarmupFlag) {
6580 0 : if (ErrCountLowPre == 0) {
6581 0 : ++ErrCountLowPre;
6582 0 : ShowWarningError(m_state,
6583 : "The calculated pressure with minimum exhaust fan rate is lower than the pressure setpoint. The pressure "
6584 : "control is unable to perform.");
6585 0 : ShowContinueErrorTimeStamp(m_state,
6586 0 : format("Calculated pressure = {:.2R}[Pa], Pressure setpoint ={:.2R}", ZonePressure1, PressureSet));
6587 : } else {
6588 0 : ++ErrCountLowPre;
6589 0 : ShowRecurringWarningErrorAtEnd(m_state,
6590 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6591 : ": The AFN model continues not to perform pressure control due to lower zone pressure...",
6592 0 : ErrIndexLowPre,
6593 : ZonePressure1,
6594 : ZonePressure1);
6595 : }
6596 : }
6597 : } else {
6598 0 : ExhaustFanMassFlowRate = MaxExhaustMassFlowrate;
6599 0 : airmov();
6600 0 : ZonePressure2 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6601 0 : if (ZonePressure2 >= PressureSet) {
6602 : // The lowest pressure due to maximum flow rate is still higher than Pressure set, bypass pressure set calculation
6603 0 : if (!m_state.dataGlobal->WarmupFlag) {
6604 0 : if (ErrCountHighPre == 0) {
6605 0 : ++ErrCountHighPre;
6606 0 : ShowWarningError(m_state,
6607 : "The calculated pressure with maximum exhaust fan rate is higher than the pressure setpoint. The "
6608 : "pressure control is unable to perform.");
6609 0 : ShowContinueErrorTimeStamp(
6610 0 : m_state, format("Calculated pressure = {:.2R}[Pa], Pressure setpoint = {:.2R}", ZonePressure2, PressureSet));
6611 : } else {
6612 0 : ++ErrCountHighPre;
6613 0 : ShowRecurringWarningErrorAtEnd(
6614 : m_state,
6615 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6616 : ": The AFN model continues not to perform pressure control due to higher zone pressure...",
6617 0 : ErrIndexHighPre,
6618 : ZonePressure2,
6619 : ZonePressure2);
6620 : }
6621 : }
6622 : } else {
6623 : // if ( ZonePressure1 > PressureSet && ZonePressure2 < PressureSet ) {
6624 0 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
6625 0 : auto f = [&thisState, PressureSet](Real64 const ControllerMassFlowRate) {
6626 0 : return AFNPressureResidual(thisState, ControllerMassFlowRate, PressureSet);
6627 0 : };
6628 0 : General::SolveRoot(
6629 0 : m_state, ErrorToler, MaxIte, SolFla, ExhaustFanMassFlowRate, f, MinExhaustMassFlowrate, MaxExhaustMassFlowrate);
6630 0 : if (SolFla == -1) {
6631 0 : if (!m_state.dataGlobal->WarmupFlag) {
6632 0 : if (ErrCountVar == 0) {
6633 0 : ++ErrCountVar;
6634 0 : ShowWarningError(m_state, "Iteration limit exceeded pressure setpoint using an exhaust fan. Simulation continues.");
6635 0 : ShowContinueErrorTimeStamp(m_state, format("Exhaust fan flow rate = {:.4R}", ExhaustFanMassFlowRate));
6636 : } else {
6637 0 : ++ErrCountVar;
6638 0 : ShowRecurringWarningErrorAtEnd(m_state,
6639 0 : PressureControllerData(1).Name +
6640 : "\": Iteration limit warning exceeding pressure setpoint continues...",
6641 0 : ErrIndexVar,
6642 0 : ExhaustFanMassFlowRate,
6643 0 : ExhaustFanMassFlowRate);
6644 : }
6645 : }
6646 0 : } else if (SolFla == -2) {
6647 0 : ShowFatalError(m_state,
6648 0 : "Zone pressure control failed using an exhaust fan: no solution is reached, for " +
6649 0 : PressureControllerData(1).Name);
6650 : }
6651 : }
6652 : }
6653 : } else { // PressureCtrlRelief - Pressure control type is Relief Flow
6654 1 : AirLoopNum = AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).AirLoopNum;
6655 1 : MinReliefMassFlowrate = 2.0 * VerySmallMassFlow;
6656 1 : MaxReliefMassFlowrate = Node(PressureControllerData(1).OANodeNum).MassFlowRate;
6657 1 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling &&
6658 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio > 0.0) {
6659 0 : MaxReliefMassFlowrate = MaxReliefMassFlowrate / m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
6660 : }
6661 1 : ReliefMassFlowRate = MinReliefMassFlowrate;
6662 1 : initialize_calculation();
6663 1 : airmov();
6664 1 : ZonePressure1 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6665 :
6666 1 : if (ZonePressure1 <= PressureSet) {
6667 : // The highest pressure due to minimum flow rate could not reach Pressure set, bypass pressure set calculation
6668 0 : if (!m_state.dataGlobal->WarmupFlag) {
6669 0 : if (ErrCountLowPre == 0) {
6670 0 : ++ErrCountLowPre;
6671 0 : ShowWarningError(m_state,
6672 : "The calculated pressure with minimum relief air rate is lower than the pressure setpoint. The pressure "
6673 : "control is unable to perform.");
6674 0 : ShowContinueErrorTimeStamp(m_state,
6675 0 : format("Calculated pressure = {:.2R}[Pa], Pressure setpoint ={:.2R}", ZonePressure1, PressureSet));
6676 : } else {
6677 0 : ++ErrCountLowPre;
6678 0 : ShowRecurringWarningErrorAtEnd(m_state,
6679 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6680 : ": The AFN model continues not to perform pressure control due to lower zone pressure...",
6681 0 : ErrIndexLowPre,
6682 : ZonePressure1,
6683 : ZonePressure1);
6684 : }
6685 : }
6686 : } else {
6687 1 : ReliefMassFlowRate = MaxReliefMassFlowrate;
6688 1 : initialize_calculation();
6689 1 : airmov();
6690 1 : ZonePressure2 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6691 1 : if (ZonePressure2 >= PressureSet) {
6692 : // The lowest pressure due to maximum flow rate is still higher than Pressure set, bypass pressure set calculation
6693 0 : if (!m_state.dataGlobal->WarmupFlag) {
6694 0 : if (ErrCountHighPre == 0) {
6695 0 : ++ErrCountHighPre;
6696 0 : ShowWarningError(m_state,
6697 : "The calculated pressure with maximum relief air rate is higher than the pressure setpoint. The "
6698 : "pressure control is unable to perform.");
6699 0 : ShowContinueErrorTimeStamp(
6700 0 : m_state, format("Calculated pressure = {:.2R}[Pa], Pressure setpoint = {:.2R}", ZonePressure2, PressureSet));
6701 : } else {
6702 0 : ++ErrCountHighPre;
6703 0 : ShowRecurringWarningErrorAtEnd(
6704 : m_state,
6705 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6706 : ": The AFN model continues not to perform pressure control due to higher zone pressure...",
6707 0 : ErrIndexHighPre,
6708 : ZonePressure2,
6709 : ZonePressure2);
6710 : }
6711 : }
6712 : } else {
6713 : // if ( ZonePressure1 > PressureSet && ZonePressure2 < PressureSet ) {
6714 1 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
6715 7 : auto f = [&thisState, PressureSet](Real64 const ControllerMassFlowRate) {
6716 7 : return AFNPressureResidual(thisState, ControllerMassFlowRate, PressureSet);
6717 1 : };
6718 1 : General::SolveRoot(m_state, ErrorToler, MaxIte, SolFla, ReliefMassFlowRate, f, MinReliefMassFlowrate, MaxReliefMassFlowrate);
6719 1 : if (SolFla == -1) {
6720 0 : if (!m_state.dataGlobal->WarmupFlag) {
6721 0 : if (ErrCountVar == 0) {
6722 0 : ++ErrCountVar;
6723 0 : ShowWarningError(m_state, "Iteration limit exceeded pressure setpoint using relief air. Simulation continues.");
6724 0 : ShowContinueErrorTimeStamp(m_state, format("Relief air flow rate = {:.4R}", ReliefMassFlowRate));
6725 : } else {
6726 0 : ++ErrCountVar;
6727 0 : ShowRecurringWarningErrorAtEnd(m_state,
6728 0 : PressureControllerData(1).Name +
6729 : "\": Iteration limit warning exceeding pressure setpoint continues...",
6730 0 : ErrIndexVar,
6731 0 : ReliefMassFlowRate,
6732 0 : ReliefMassFlowRate);
6733 : }
6734 : }
6735 1 : } else if (SolFla == -2) {
6736 0 : ShowFatalError(
6737 0 : m_state, "Zone pressure control failed using relief air: no solution is reached, for " + PressureControllerData(1).Name);
6738 : }
6739 : }
6740 : }
6741 : }
6742 16865 : }
6743 :
6744 7 : Real64 AFNPressureResidual(EnergyPlusData &state,
6745 : Real64 const ControllerMassFlowRate, // Pressure setpoint
6746 : Real64 PressureSet)
6747 : {
6748 : // FUNCTION INFORMATION:
6749 : // AUTHOR Lixing Gu
6750 : // DATE WRITTEN April 2016
6751 : // MODIFIED NA
6752 : // RE-ENGINEERED NA
6753 :
6754 : // PURPOSE OF THIS FUNCTION:
6755 : // Calculates residual function ((ZonePressure - PressureSet)/PressureSet)
6756 :
6757 : // METHODOLOGY EMPLOYED:
6758 : // Calls AIRMOV to get the pressure in the controlled zone and calculates the residual as defined above
6759 :
6760 : // Return value
6761 : Real64 AFNPressureResidual;
6762 :
6763 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
6764 : Real64 ZonePressure;
6765 :
6766 7 : if (state.afn->PressureSetFlag == PressureCtrlExhaust) {
6767 0 : state.afn->ExhaustFanMassFlowRate = ControllerMassFlowRate;
6768 : }
6769 :
6770 7 : if (state.afn->PressureSetFlag == PressureCtrlRelief) {
6771 7 : state.afn->ReliefMassFlowRate = ControllerMassFlowRate;
6772 : }
6773 7 : auto &solver = state.afn;
6774 7 : solver->initialize_calculation();
6775 7 : solver->airmov();
6776 :
6777 7 : ZonePressure = state.afn->AirflowNetworkNodeSimu(state.afn->PressureControllerData(1).AFNNodeNum).PZ;
6778 :
6779 7 : if (PressureSet != 0.0) {
6780 7 : AFNPressureResidual = (ZonePressure - PressureSet) / PressureSet;
6781 : } else {
6782 0 : AFNPressureResidual = (ZonePressure - PressureSet);
6783 : }
6784 7 : return AFNPressureResidual;
6785 : }
6786 :
6787 84 : static int makeTable(EnergyPlusData &state, const std::string &name, const int gridIndex, const std::vector<Real64> &y)
6788 : {
6789 : // Add a new table and performance curve
6790 84 : std::string contextString = "CalcWindPressureCoeffs: Creating table \"" + name + "\"";
6791 84 : std::pair<EnergyPlusData *, std::string> callbackPair{&state, contextString};
6792 84 : state.dataCurveManager->btwxtManager.setLoggingContext(&callbackPair);
6793 :
6794 84 : Curve::Curve *curve = Curve::AddCurve(state, name);
6795 :
6796 84 : curve->numDims = 1;
6797 :
6798 84 : curve->curveType = Curve::CurveType::BtwxtTableLookup;
6799 :
6800 84 : curve->inputLimits[0].min = 0.0;
6801 84 : curve->inputLimits[0].minPresent = true;
6802 84 : curve->inputLimits[0].max = 360.0;
6803 84 : curve->inputLimits[0].maxPresent = true;
6804 :
6805 84 : curve->TableIndex = gridIndex;
6806 84 : curve->GridValueIndex = state.dataCurveManager->btwxtManager.addOutputValues(gridIndex, y);
6807 :
6808 84 : return curve->Num;
6809 84 : }
6810 :
6811 16 : void Solver::calculate_Cps()
6812 : {
6813 :
6814 : // SUBROUTINE INFORMATION:
6815 : // AUTHOR Fred Winkelmann
6816 : // DATE WRITTEN May 2003
6817 : // MODIFIED Revised by L. Gu, Nov. 2005, to meet requirements of AirflowNetwork
6818 : // MODIFIED Revised by L. Gu, Dec. 2008, to set the number of external nodes based on
6819 : // the number of external surfaces
6820 : // MODIFIED Revised by J. DeGraw, Feb. 2017, to use tables
6821 : // RE-ENGINEERED na
6822 :
6823 : // PURPOSE OF THIS SUBROUTINE:
6824 : // Calculates surface-average wind pressure coefficients for
6825 : // the walls and roof of a rectangular building.
6826 :
6827 : // METHODOLOGY EMPLOYED:
6828 : // Interpolates correlations between surface-average wind pressure coefficient and wind direction based on
6829 : // measurements (see REFERENCES). Applicable only to rectangular buildings.
6830 :
6831 : // REFERENCES:
6832 : // For low-rise buildings: M.V. Swami and S. Chandra, Correlations for Pressure Distribution
6833 : // on Buildings and Calculation of Natural-Ventilation Airflow. ASHRAE Transactions 94 (1): 243-266.
6834 : // For high-rise buildings: 2001 ASHRAE Fundamentals Handbook, p. 16.5, Fig. 7, "Surface Averaged
6835 : // Wall Pressure Coefficients for Tall Buildings" and p.16.6, Fig. 9, "Surface Averaged Roof Pressure
6836 : // Coefficients for Tall Buildings; from R.E. Akins, J.A. Peterka, and J.E. Cermak. 1979.
6837 : // Averaged Pressure Coefficients for Rectangular Buildings. Wind Engineering. Proc. Fifth
6838 : // International Conference 7:369-80, Fort Collins, CO. Pergamon Press, NY.
6839 :
6840 : // Using/Aliasing
6841 : using namespace DataSurfaces;
6842 :
6843 : // index 1 is wind incidence angle (0,30,60,...,300,330 deg)
6844 : // index 2 is side ratio (0.25,1.0,4.0)
6845 : // Surface-averaged wind-pressure coefficient array for walls
6846 : static constexpr std::array<std::array<Real64, 12>, 3> CPHighRiseWall = {{
6847 : {0.60, 0.54, 0.23, -0.25, -0.61, -0.55, -0.51, -0.55, -0.61, -0.25, 0.23, 0.54},
6848 : {0.60, 0.48, 0.04, -0.56, -0.56, -0.42, -0.37, -0.42, -0.56, -0.56, 0.04, 0.48},
6849 : {0.60, 0.44, -0.26, -0.70, -0.53, -0.32, -0.22, -0.32, -0.53, -0.70, -0.26, 0.44},
6850 : }};
6851 :
6852 : // index 1 is wind incidence angle (0,30,60,...,300,330 deg)
6853 : // index 2 is side ratio (0.25,0.5,1.0)
6854 : // Surface-averaged wind-pressure coefficient array for roof
6855 : static constexpr std::array<std::array<Real64, 12>, 3> CPHighRiseRoof = {{
6856 : {-0.28, -0.69, -0.72, -0.76, -0.72, -0.69, -0.28, -0.69, -0.72, -0.76, -0.72, -0.69},
6857 : {-0.47, -0.52, -0.70, -0.76, -0.70, -0.52, -0.47, -0.52, -0.70, -0.76, -0.70, -0.52},
6858 : {-0.70, -0.55, -0.55, -0.70, -0.55, -0.55, -0.70, -0.55, -0.55, -0.70, -0.55, -0.55},
6859 : }};
6860 :
6861 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6862 : int FacadeNum; // Facade number
6863 : int ExtNum; // External number
6864 : int AFNZnNum; // Zone number
6865 : Real64 SideRatio; // For vertical facades, width of facade / width of adjacent facade
6866 : Real64 SR; // SideRatio restricted to 0.25 to 4.0 range
6867 : Real64 SideRatioFac; // LOG(SideRatio)
6868 : Real64 IncRad; // IncAng in radians
6869 : int IAng; // Incidence angle index; used in interpolation
6870 : Real64 DelAng; // Incidence angle difference; used in interpolation
6871 : Real64 WtAng; // Incidence angle weighting factor; used in interpolation
6872 : int ISR; // Side ratio index, for interpolation
6873 : Real64 WtSR; // Side ratio weighting factor; used in interpolation
6874 : int SurfNum; // Surface number
6875 : int SurfDatNum; // Surface data number
6876 : Real64 SurfAng; // Azimuth angle of surface normal (degrees clockwise from North)
6877 : int FacadeNumThisSurf; // Facade number for a particular surface
6878 : Real64 AngDiff; // Angle difference between wind and surface direction (deg)
6879 : Real64 AngDiffMin; // Minimum angle difference between wind and surface direction (deg)
6880 32 : std::vector<int> curveIndex = {0, 0, 0, 0, 0};
6881 :
6882 : // Facade azimuth angle
6883 80 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
6884 64 : FacadeAng(FacadeNum) = m_state.afn->simulation_control.azimuth + (FacadeNum - 1) * 90.0;
6885 64 : if (FacadeAng(FacadeNum) >= 360.0) {
6886 10 : FacadeAng(FacadeNum) -= 360.0;
6887 : }
6888 : }
6889 :
6890 16 : FacadeAng(5) = simulation_control.azimuth + 90.0;
6891 :
6892 : // Create AirflowNetwork external node objects -- one for each of the external surfaces
6893 :
6894 16 : MultizoneExternalNodeData.allocate(AirflowNetworkNumOfExtSurfaces);
6895 16 : AirflowNetworkNumOfExtNode = AirflowNetworkNumOfExtSurfaces;
6896 16 : NumOfExtNodes = AirflowNetworkNumOfExtSurfaces;
6897 76 : for (ExtNum = 1; ExtNum <= NumOfExtNodes; ++ExtNum) {
6898 60 : MultizoneExternalNodeData(ExtNum).ExtNum = AirflowNetworkNumOfZones + ExtNum;
6899 60 : MultizoneExternalNodeData(ExtNum).Name = format("ExtNode{:4}", ExtNum);
6900 : }
6901 :
6902 : // Associate each external node with SurfaceData
6903 :
6904 16 : ExtNum = 0;
6905 81 : for (SurfDatNum = 1; SurfDatNum <= AirflowNetworkNumOfSurfaces; ++SurfDatNum) {
6906 65 : if (SurfDatNum > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) {
6907 0 : continue;
6908 : }
6909 65 : SurfNum = MultizoneSurfaceData(SurfDatNum).SurfNum;
6910 65 : if (SurfNum == 0) {
6911 0 : continue; // Error caught earlier
6912 : }
6913 72 : if (m_state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment ||
6914 7 : (m_state.dataSurface->Surface(SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt && m_state.dataSurface->Surface(SurfNum).ExtWind)) {
6915 60 : ++ExtNum;
6916 60 : if (m_state.dataSurface->Surface(SurfNum).Tilt >= 45.0) { // "Vertical" surface
6917 54 : SurfAng = m_state.dataSurface->Surface(SurfNum).Azimuth;
6918 54 : FacadeNumThisSurf = 1;
6919 54 : AngDiffMin = std::abs(SurfAng - FacadeAng(1));
6920 54 : if (AngDiffMin > 359.0) {
6921 0 : AngDiffMin = std::abs(AngDiffMin - 360.0);
6922 : }
6923 216 : for (FacadeNum = 2; FacadeNum <= 4; ++FacadeNum) {
6924 162 : AngDiff = std::abs(SurfAng - FacadeAng(FacadeNum));
6925 162 : if (AngDiff > 359.0) {
6926 0 : AngDiff = std::abs(AngDiff - 360.0);
6927 : }
6928 162 : if (AngDiff < AngDiffMin) {
6929 71 : AngDiffMin = AngDiff;
6930 71 : FacadeNumThisSurf = FacadeNum;
6931 : }
6932 : }
6933 54 : MultizoneExternalNodeData(ExtNum).facadeNum = FacadeNumThisSurf;
6934 : } else { // "Roof" surface
6935 6 : MultizoneExternalNodeData(ExtNum).facadeNum = 5;
6936 : }
6937 60 : MultizoneSurfaceData(SurfDatNum).NodeNums[1] = MultizoneExternalNodeData(ExtNum).ExtNum;
6938 60 : MultizoneSurfaceData(SurfDatNum).ExternalNodeName = MultizoneExternalNodeData(ExtNum).Name;
6939 : }
6940 : }
6941 :
6942 : // Check if using the advanced single sided model
6943 37 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
6944 21 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
6945 2 : ++AirflowNetworkNumOfSingleSideZones;
6946 : }
6947 : }
6948 :
6949 32 : std::vector<Real64> dirs30 = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360};
6950 16 : std::vector<Btwxt::GridAxis> dirs30Axes;
6951 16 : dirs30Axes.emplace_back(dirs30,
6952 : "30 Degree Increment",
6953 0 : Btwxt::InterpolationMethod::linear,
6954 16 : Btwxt::ExtrapolationMethod::linear,
6955 16 : std::pair<double, double>{0.0, 360.0});
6956 :
6957 48 : auto dirs30GridIndex = m_state.dataCurveManager->btwxtManager.addGrid("30 Degree Increments", dirs30Axes);
6958 :
6959 16 : if (AirflowNetworkNumOfSingleSideZones == 0) { // do the standard surface average coefficient calculation
6960 : // Create the array of wind directions
6961 :
6962 : // Create a curve for each facade
6963 84 : for (FacadeNum = 1; FacadeNum <= 5; ++FacadeNum) {
6964 70 : if (FacadeNum == 1 || FacadeNum == 3 || FacadeNum == 5) {
6965 42 : SideRatio = simulation_control.aspect_ratio;
6966 : } else { // FacadeNum = 2 or 4
6967 28 : SideRatio = 1.0 / simulation_control.aspect_ratio;
6968 : }
6969 70 : if (Util::SameString(simulation_control.BldgType, "HighRise") && FacadeNum != 5) {
6970 0 : SideRatio = 1.0 / SideRatio;
6971 : }
6972 70 : SideRatioFac = std::log(SideRatio);
6973 70 : std::vector<Real64> vals(13);
6974 910 : for (int windDirNum = 1; windDirNum <= 12; ++windDirNum) {
6975 840 : Real64 WindAng = (windDirNum - 1) * 30.0;
6976 840 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
6977 840 : if (IncAng > 180.0) {
6978 152 : IncAng = 360.0 - IncAng;
6979 : }
6980 840 : IAng = int(IncAng / 30.0) + 1;
6981 840 : DelAng = mod(IncAng, 30.0);
6982 840 : WtAng = 1.0 - DelAng / 30.0;
6983 :
6984 : // Wind-pressure coefficients for vertical facades, low-rise building
6985 :
6986 840 : if (Util::SameString(simulation_control.BldgType, "LowRise") && FacadeNum <= 4) {
6987 672 : IncRad = IncAng * Constant::DegToRad;
6988 672 : Real64 const cos_IncRad_over_2(std::cos(IncRad / 2.0));
6989 1344 : vals[windDirNum - 1] = 0.6 * std::log(1.248 - 0.703 * std::sin(IncRad / 2.0) - 1.175 * pow_2(std::sin(IncRad)) +
6990 672 : 0.131 * pow_3(std::sin(2.0 * IncRad * SideRatioFac)) + 0.769 * cos_IncRad_over_2 +
6991 672 : 0.07 * pow_2(SideRatioFac * std::sin(IncRad / 2.0)) + 0.717 * pow_2(cos_IncRad_over_2));
6992 : }
6993 :
6994 : // Wind-pressure coefficients for vertical facades, high-rise building
6995 :
6996 168 : else if (Util::SameString(simulation_control.BldgType, "HighRise") && FacadeNum <= 4) {
6997 0 : SR = min(max(SideRatio, 0.25), 4.0);
6998 0 : if (SR >= 0.25 && SR < 1.0) {
6999 0 : ISR = 1;
7000 0 : WtSR = (1.0 - SR) / 0.75;
7001 : } else { // 1.0 <= SR <= 4.0
7002 0 : ISR = 2;
7003 0 : WtSR = (4.0 - SR) / 3.0;
7004 : }
7005 0 : vals[windDirNum - 1] = WtSR * (WtAng * CPHighRiseWall[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseWall[ISR - 1][IAng]) +
7006 0 : (1.0 - WtSR) * (WtAng * CPHighRiseWall[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseWall[ISR][IAng]);
7007 : }
7008 :
7009 : // Wind-pressure coefficients for roof (assumed same for low-rise and high-rise buildings)
7010 :
7011 336 : else if ((Util::SameString(simulation_control.BldgType, "HighRise") ||
7012 336 : Util::SameString(simulation_control.BldgType, "LowRise")) &&
7013 168 : FacadeNum == 5) {
7014 168 : SR = min(max(SideRatio, 0.25), 1.0);
7015 168 : if (SR >= 0.25 && SR < 0.5) {
7016 84 : ISR = 1;
7017 84 : WtSR = (0.5 - SR) / 0.25;
7018 : } else { // 0.5 <= SR <= 1.0
7019 84 : ISR = 2;
7020 84 : WtSR = (1.0 - SR) / 0.5;
7021 : }
7022 336 : vals[windDirNum - 1] = WtSR * (WtAng * CPHighRiseRoof[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR - 1][IAng]) +
7023 168 : (1.0 - WtSR) * (WtAng * CPHighRiseRoof[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR][IAng]);
7024 : }
7025 :
7026 : } // End of wind direction loop
7027 : // Add new table
7028 70 : vals[12] = vals[0]; // Enforce periodicity
7029 70 : curveIndex[FacadeNum - 1] = AirflowNetwork::makeTable(m_state, format("!WPCTABLE{}", FacadeNum), dirs30GridIndex, vals);
7030 70 : } // End of facade number loop
7031 :
7032 : } else { //-calculate the advanced single sided wind pressure coefficients
7033 :
7034 : // Calculate the wind pressure coefficients vs. wind direction for each external node
7035 : // The wind pressure coeffients are stored temporarily in the "valsByFacade" vector and then
7036 : // converted into a table near the end of this else. There will be at least seven profiles
7037 : // (four sides plus one roof plus two for each pair of windows). The name is thus a little
7038 : // misleading, as it isn't really the values by facade once you get beyond the first five.
7039 2 : std::vector<std::vector<Real64>> valsByFacade(5);
7040 10 : for (FacadeNum = 0; FacadeNum < 4; ++FacadeNum) {
7041 16 : valsByFacade[FacadeNum] = std::vector<Real64>(36);
7042 : }
7043 2 : FacadeNum = 4;
7044 2 : valsByFacade[FacadeNum] = std::vector<Real64>(12);
7045 10 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
7046 8 : if (FacadeNum == 1 || FacadeNum == 3) {
7047 4 : SideRatio = simulation_control.aspect_ratio;
7048 : } else { // FacadeNum = 2 or 4
7049 4 : SideRatio = 1.0 / simulation_control.aspect_ratio;
7050 : }
7051 8 : if (Util::SameString(simulation_control.BldgType, "HighRise")) {
7052 0 : SideRatio = 1.0 / SideRatio;
7053 : }
7054 8 : SideRatioFac = std::log(SideRatio);
7055 296 : for (int windDirNum = 1; windDirNum <= 36; ++windDirNum) {
7056 288 : Real64 WindAng = (windDirNum - 1) * 10.0;
7057 288 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
7058 288 : if (IncAng > 180.0) {
7059 68 : IncAng = 360.0 - IncAng;
7060 : }
7061 : // IAng = int(IncAng / 10.0) + 1;
7062 288 : DelAng = mod(IncAng, 10.0);
7063 288 : WtAng = 1.0 - DelAng / 10.0;
7064 : // Wind-pressure coefficients for vertical facades, low-rise building
7065 288 : IncRad = IncAng * Constant::DegToRad;
7066 288 : valsByFacade[FacadeNum - 1][windDirNum - 1] =
7067 288 : 0.6 * std::log(1.248 - 0.703 * std::sin(IncRad / 2.0) - 1.175 * pow_2(std::sin(IncRad)) +
7068 288 : 0.131 * pow_3(std::sin(2.0 * IncRad * SideRatioFac)) + 0.769 * std::cos(IncRad / 2.0) +
7069 288 : 0.07 * pow_2(SideRatioFac * std::sin(IncRad / 2.0)) + 0.717 * pow_2(std::cos(IncRad / 2.0)));
7070 : } // End of wind direction loop
7071 : } // End of facade number loop
7072 : // Add a roof
7073 2 : FacadeNum = 5;
7074 2 : SR = min(max(SideRatio, 0.25), 1.0);
7075 2 : if (SR >= 0.25 && SR < 0.5) {
7076 0 : ISR = 1;
7077 0 : WtSR = (0.5 - SR) / 0.25;
7078 : } else { // 0.5 <= SR <= 1.0
7079 2 : ISR = 2;
7080 2 : WtSR = (1.0 - SR) / 0.5;
7081 : }
7082 26 : for (int windDirNum = 1; windDirNum <= 12; ++windDirNum) {
7083 24 : Real64 WindAng = (windDirNum - 1) * 30.0;
7084 24 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
7085 24 : if (IncAng > 180.0) {
7086 0 : IncAng = 360.0 - IncAng;
7087 : }
7088 24 : IAng = int(IncAng / 30.0) + 1;
7089 24 : DelAng = mod(IncAng, 30.0);
7090 24 : WtAng = 1.0 - DelAng / 30.0;
7091 : // Wind-pressure coefficients for roof (assumed same for low-rise and high-rise buildings)
7092 24 : valsByFacade[FacadeNum - 1][windDirNum - 1] =
7093 24 : WtSR * (WtAng * CPHighRiseRoof[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR - 1][IAng]) +
7094 24 : (1.0 - WtSR) * (WtAng * CPHighRiseRoof[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR][IAng]);
7095 : }
7096 2 : single_sided_Cps(valsByFacade); // run the advanced single sided subroutine if at least one zone calls for it
7097 : // Resize the curve index array
7098 2 : curveIndex.resize(valsByFacade.size());
7099 : // Create the curves
7100 :
7101 : std::vector<Real64> dirs10 = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180,
7102 4 : 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360};
7103 :
7104 2 : std::vector<Btwxt::GridAxis> dirs10Axes;
7105 2 : dirs10Axes.emplace_back(dirs10,
7106 : "10 Degree Increments",
7107 0 : Btwxt::InterpolationMethod::linear,
7108 2 : Btwxt::ExtrapolationMethod::linear,
7109 2 : std::pair<double, double>{0.0, 360.0});
7110 :
7111 6 : auto dirs10GridIndex = m_state.dataCurveManager->btwxtManager.addGrid("10 Degree Increments", dirs10Axes);
7112 :
7113 10 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
7114 8 : valsByFacade[FacadeNum - 1].push_back(valsByFacade[FacadeNum - 1][0]); // Enforce periodicity
7115 16 : curveIndex[FacadeNum - 1] =
7116 8 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLEFACADE{}", FacadeNum), dirs10GridIndex, valsByFacade[FacadeNum - 1]);
7117 : }
7118 2 : FacadeNum = 5;
7119 2 : valsByFacade[FacadeNum - 1].push_back(valsByFacade[FacadeNum - 1][0]); // Enforce periodicity
7120 4 : curveIndex[FacadeNum - 1] =
7121 2 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLEFACADE{}", FacadeNum), dirs30GridIndex, valsByFacade[FacadeNum - 1]);
7122 6 : for (unsigned facadeNum = 6; facadeNum <= valsByFacade.size(); ++facadeNum) {
7123 4 : valsByFacade[facadeNum - 1].push_back(valsByFacade[facadeNum - 1][0]); // Enforce periodicity
7124 8 : curveIndex[facadeNum - 1] =
7125 4 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLE{}", facadeNum), dirs10GridIndex, valsByFacade[facadeNum - 1]);
7126 : }
7127 2 : }
7128 : // Connect the external nodes to the new curves
7129 76 : for (ExtNum = 1; ExtNum <= NumOfExtNodes; ++ExtNum) {
7130 60 : MultizoneExternalNodeData(ExtNum).curve = curveIndex[MultizoneExternalNodeData(ExtNum).facadeNum - 1];
7131 : }
7132 16 : }
7133 :
7134 286540 : Real64 Solver::calculate_wind_pressure(int const curve, // Curve index, change this to pointer after curve refactor
7135 : bool const symmetricCurve, // True if the curve is symmetric (0 to 180)
7136 : bool const relativeAngle, // True if the Cp curve angle is measured relative to the surface
7137 : Real64 const azimuth, // Azimuthal angle of surface
7138 : Real64 const windSpeed, // Wind velocity
7139 : Real64 const windDir, // Wind direction
7140 : Real64 const dryBulbTemp, // Air node dry bulb temperature
7141 : Real64 const humRat // Air node humidity ratio
7142 : )
7143 : {
7144 :
7145 : // SUBROUTINE INFORMATION:
7146 : // AUTHOR Lixing Gu
7147 : // DATE WRITTEN Oct. 2005
7148 : // MODIFIED Jason DeGraw, Feb. 2017, modify to use curves
7149 : // MODIFIED Xuan Luo, Aug. 2017, modify to use local air condition
7150 : // RE-ENGINEERED na
7151 :
7152 : // PURPOSE OF THIS SUBROUTINE:
7153 : // Calculates surface wind pressure based on given CP values
7154 :
7155 : // REFERENCES:
7156 : // COMIS Fundamentals
7157 :
7158 : // Return value is wind pressure[Pa]
7159 :
7160 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
7161 286540 : Real64 angle(windDir);
7162 : Real64 rho; // Outdoor air density
7163 : Real64 Cp; // Cp value at given wind direction
7164 :
7165 : // Calculate outdoor density
7166 286540 : rho = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, dryBulbTemp, humRat);
7167 :
7168 : // Calculate pressure coefficient
7169 286540 : if (relativeAngle) {
7170 6 : angle = angle - azimuth;
7171 6 : if (angle < 0.0) {
7172 2 : angle += 360.0;
7173 : }
7174 : }
7175 286540 : if (symmetricCurve) {
7176 4 : if (angle > 180.0) {
7177 2 : angle = 360.0 - angle;
7178 : }
7179 : }
7180 286540 : Cp = Curve::CurveValue(m_state, curve, angle);
7181 :
7182 286540 : return Cp * 0.5 * rho * windSpeed * windSpeed;
7183 : }
7184 :
7185 399344 : Real64 Solver::duct_inside_convection_resistance(Real64 const Tair, // Average air temperature
7186 : Real64 const mdot, // Mass flow rate
7187 : Real64 const Dh, // Hydraulic diameter
7188 : Real64 const hIn // User defined convection coefficient
7189 : )
7190 : {
7191 : // SUBROUTINE INFORMATION:
7192 : // AUTHOR Matt Mitchell, Tony Fontanini
7193 : // DATE WRITTEN Feb. 2017
7194 : // MODIFIED na
7195 : // RE-ENGINEERED na
7196 :
7197 : // PURPOSE OF THIS SUBROUTINE:
7198 : // Calculates duct inside convection coefficients
7199 :
7200 : // REFERENCES:
7201 : // ASTM C1340
7202 : // Jakob, F.E., Fischer, R.D., Flanigan, L.J. 1987. "Experimental Validation of the Duct Submodel for the SP43 Simulation Model."
7203 : // ASHRAE Trans. pp 1499-1514.
7204 :
7205 399344 : Real64 hIn_final = 0;
7206 :
7207 399344 : if (hIn == 0) {
7208 :
7209 399341 : Real64 Tair_IP = Tair * 1.8 + 32.0; // Convert C to F
7210 399341 : Real64 mdot_IP = mdot * 2.20462 * 3600; // Convert kg/s to lb/hr
7211 399341 : Real64 Dh_IP = Dh * 3.28084; // Convert m to ft
7212 399341 : Real64 Ai_IP = pow_2(Dh_IP) * Constant::Pi / 4;
7213 :
7214 399341 : Real64 CorrelationCoeff = 0.00368 + 1.5e-6 * (Tair_IP - 80);
7215 399341 : Real64 MassFlux = mdot_IP / Ai_IP; // lb/hr-ft2
7216 :
7217 399341 : Real64 DuctInsideConvCoeff_IP = CorrelationCoeff * pow(MassFlux, 0.8) / pow(Dh_IP, 0.2); // BTU/hr-ft2-F
7218 :
7219 399341 : hIn_final = DuctInsideConvCoeff_IP * pow_2(3.28084) * 1.8 * 1055.06 / 3600; // Convert BTU/hr-ft2-F to W/m2-K
7220 :
7221 : } else {
7222 3 : hIn_final = hIn;
7223 : }
7224 :
7225 399344 : if (hIn_final == 0) {
7226 0 : return 0;
7227 : } else {
7228 399344 : return 1 / hIn_final;
7229 : }
7230 : }
7231 :
7232 399346 : Real64 Solver::duct_outside_convection_resistance(Real64 const Ts, // Surface temperature
7233 : Real64 const Tamb, // Free air temperature
7234 : Real64 const Wamb, // Free air humidity ratio
7235 : Real64 const Pamb, // Free air barometric pressure
7236 : Real64 const Dh, // Hydraulic diameter
7237 : int const ZoneNum, // Zone number
7238 : Real64 const hOut // User defined convection coefficient
7239 : )
7240 : {
7241 : // SUBROUTINE INFORMATION:
7242 : // AUTHOR Matt Mitchell, Tony Fontanini
7243 : // DATE WRITTEN Feb. 2017
7244 : // MODIFIED na
7245 : // RE-ENGINEERED na
7246 :
7247 : // PURPOSE OF THIS SUBROUTINE:
7248 : // Calculates duct outside convection coefficients
7249 :
7250 : // REFERENCES:
7251 : // ASTM C1340
7252 :
7253 399346 : Real64 k = properties.thermal_conductivity(Ts);
7254 399346 : auto &Zone(m_state.dataHeatBal->Zone);
7255 :
7256 399346 : Real64 hOut_final = 0;
7257 :
7258 399346 : if (hOut == 0) {
7259 :
7260 : // Free convection
7261 399343 : Real64 Pr = properties.prandtl_number(Pamb, (Ts + Tamb) / 2, Wamb);
7262 399343 : Real64 KinVisc = properties.kinematic_viscosity(Pamb, (Ts + Tamb) / 2, Wamb);
7263 399343 : Real64 Beta = 2.0 / ((Tamb + Constant::Kelvin) + (Ts + Constant::Kelvin));
7264 399343 : Real64 Gr = Constant::Gravity * Beta * std::abs(Ts - Tamb) * pow_3(Dh) / pow_2(KinVisc);
7265 399343 : Real64 Ra = Gr * Pr;
7266 399343 : Real64 Nu_free(0);
7267 :
7268 399343 : if (Ra < 10e9) {
7269 399343 : Nu_free = 0.53 * pow(Ra, 0.25);
7270 : } else {
7271 0 : Nu_free = 0.13 * pow(Ra, 0.333);
7272 : }
7273 :
7274 399343 : Real64 V = 0;
7275 : // Forced convection
7276 399343 : if (ZoneNum > 0) {
7277 306607 : Real64 ACH = zone_OA_change_rate(ZoneNum); // Zone air change rate [1/hr]
7278 306607 : Real64 Vol = Zone(ZoneNum).Volume; // Zone volume [m3]
7279 306607 : V = pow(Vol, 0.333) * ACH / 3600; // Average air speed in zone [m/s]
7280 : } else {
7281 92736 : V = m_state.dataEnvrn->WindSpeed;
7282 : }
7283 :
7284 399343 : Real64 Re = V * Dh / KinVisc; // Reynolds number
7285 399343 : Real64 c = 0;
7286 399343 : Real64 n = 0;
7287 :
7288 399343 : if (Re <= 4) {
7289 6 : c = 0.989;
7290 6 : n = 0.33;
7291 399337 : } else if (4 < Re && Re <= 40) {
7292 169307 : c = 0.911;
7293 169307 : n = 0.385;
7294 230030 : } else if (40 < Re && Re <= 4000) {
7295 137294 : c = 0.683;
7296 137294 : n = 0.466;
7297 92736 : } else if (4000 < Re && Re <= 40000) {
7298 38752 : c = 0.193;
7299 38752 : n = 0.618;
7300 53984 : } else if (40000 < Re) {
7301 53984 : c = 0.0266;
7302 53984 : n = 0.805;
7303 : }
7304 :
7305 399343 : Real64 Nu_forced = c * pow(Re, n) * pow(Pr, 0.333);
7306 :
7307 399343 : Real64 Nu_combined = pow(pow_3(Nu_free) + pow_3(Nu_forced), 0.333);
7308 399343 : hOut_final = Nu_combined * k / Dh;
7309 :
7310 : } else {
7311 3 : hOut_final = hOut;
7312 : }
7313 :
7314 399346 : if (hOut_final == 0) {
7315 0 : return 0;
7316 : } else {
7317 399346 : return 1 / hOut_final;
7318 : }
7319 : }
7320 :
7321 11054 : void Solver::calculate_heat_balance()
7322 : {
7323 : // SUBROUTINE INFORMATION:
7324 : // AUTHOR Lixing Gu
7325 : // DATE WRITTEN Oct. 2005
7326 : // MODIFIED na
7327 : // RE-ENGINEERED Revised based on Subroutine CalcADSHeatBalance
7328 :
7329 : // PURPOSE OF THIS SUBROUTINE:
7330 : // This subroutine performs AirflowNetwork thermal simulations.
7331 :
7332 : // USE STATEMENTS:
7333 11054 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
7334 :
7335 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7336 : int i;
7337 : int LF;
7338 : int LT;
7339 : int CompNum;
7340 : int NF;
7341 : int NT;
7342 : iComponentTypeNum CompTypeNum;
7343 : int ExtNodeNum;
7344 : Real64 Ei;
7345 : Real64 DirSign;
7346 : Real64 Tamb;
7347 : Real64 Wamb;
7348 : Real64 Pamb;
7349 : Real64 CpAir;
7350 : Real64 TZON;
7351 : Real64 load;
7352 : int ZoneNum;
7353 :
7354 11054 : auto &Node(m_state.dataLoopNodes->Node);
7355 :
7356 11054 : MA = 0.0;
7357 11054 : MV = 0.0;
7358 :
7359 431106 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
7360 420052 : CompNum = AirflowNetworkLinkageData(i).CompNum;
7361 420052 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
7362 420052 : std::string CompName = AirflowNetworkCompData(CompNum).EPlusName;
7363 420052 : CpAir = PsyCpAirFnW((AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i).NodeNums[0]).WZ +
7364 420052 : AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i).NodeNums[1]).WZ) /
7365 : 2.0);
7366 : // Calculate duct conduction loss
7367 420052 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct element only
7368 121594 : int TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7369 121594 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7370 121594 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7371 121594 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7372 121594 : DirSign = 1.0;
7373 : } else { // flow direction is the opposite as input from node 2 to node 1
7374 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7375 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7376 0 : DirSign = -1.0;
7377 : }
7378 : // Fatal error when return flow is opposite to the desired direction
7379 121594 : if (AirflowNetworkLinkSimu(i).FLOW == 0.0 && AirflowNetworkLinkSimu(i).FLOW2 > 0.0) {
7380 0 : if (LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
7381 0 : ShowSevereError(m_state,
7382 : "AirflowNetwork: The airflow direction is opposite to the intended direction (from node 1 to node 2) in "
7383 0 : "AirflowNetwork:Distribution:Linkage = " +
7384 0 : AirflowNetworkLinkageData(i).Name);
7385 0 : ShowContinueErrorTimeStamp(m_state, "");
7386 0 : ShowContinueError(m_state,
7387 : "The sum of the airflows entering the zone is greater than the airflows leaving the zone (e.g., wind "
7388 : "and stack effect).");
7389 0 : ShowContinueError(m_state,
7390 : "Please check wind speed or reduce values of \"Window/Door Opening Factor, or Crack Factor\" defined in "
7391 : "AirflowNetwork:MultiZone:Surface objects.");
7392 : // ShowFatalError(state, "AirflowNetwork: The previous error causes termination." );
7393 : }
7394 : }
7395 :
7396 121594 : if (AirflowNetworkLinkageData(i).ZoneNum < 0) {
7397 0 : ExtNodeNum = AirflowNetworkLinkageData(i).NodeNums[1];
7398 0 : if (AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum > 0 && Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).IsLocalNode) {
7399 0 : Tamb = Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).OutAirDryBulb;
7400 0 : Wamb = Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).HumRat;
7401 : } else {
7402 0 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(ExtNodeNum).NodeHeight);
7403 0 : Wamb = m_state.dataEnvrn->OutHumRat;
7404 : }
7405 121594 : } else if (AirflowNetworkLinkageData(i).ZoneNum == 0) {
7406 44216 : Tamb = AirflowNetworkNodeSimu(LT).TZ;
7407 44216 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7408 : } else {
7409 77378 : Tamb = ANZT(AirflowNetworkLinkageData(i).ZoneNum);
7410 77378 : Wamb = ANZW(AirflowNetworkLinkageData(i).ZoneNum);
7411 : }
7412 :
7413 121594 : Pamb = m_state.dataEnvrn->OutBaroPress;
7414 :
7415 121594 : Real64 constexpr tolerance = 0.001;
7416 121594 : Real64 UThermal(10); // Initialize. This will get updated.
7417 121594 : Real64 UThermal_iter = 0;
7418 121594 : Real64 Tsurr = Tamb;
7419 121594 : Real64 Tsurr_K = Tsurr + Constant::Kelvin;
7420 121594 : Real64 Tin = AirflowNetworkNodeSimu(LF).TZ;
7421 121594 : Real64 TDuctSurf = (Tamb + Tin) / 2.0;
7422 121594 : Real64 TDuctSurf_K = TDuctSurf + Constant::Kelvin;
7423 121594 : Real64 DuctSurfArea = DisSysCompDuctData(TypeNum).L * DisSysCompDuctData(TypeNum).hydraulicDiameter * Constant::Pi;
7424 :
7425 : // If user defined view factors not present, calculate air-to-air heat transfer
7426 121594 : if (AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum == 0) {
7427 :
7428 : // Calculate convection coefficient if one or both not present
7429 121594 : if (DisSysCompDuctData(TypeNum).InsideConvCoeff == 0 && DisSysCompDuctData(TypeNum).OutsideConvCoeff == 0) {
7430 520931 : while (std::abs(UThermal - UThermal_iter) > tolerance) {
7431 399337 : UThermal_iter = UThermal;
7432 :
7433 1597348 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin,
7434 399337 : AirflowNetworkLinkSimu(i).FLOW,
7435 399337 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7436 399337 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7437 1597348 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7438 : Tamb,
7439 : Wamb,
7440 : Pamb,
7441 399337 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7442 399337 : AirflowNetworkLinkageData(i).ZoneNum,
7443 399337 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7444 399337 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7445 399337 : Real64 RThermTotal = RThermConvIn + RThermConvOut + RThermConduct;
7446 399337 : UThermal = pow(RThermTotal, -1);
7447 :
7448 : // Duct conduction, assuming effectiveness = 1 - exp(-NTU)
7449 399337 : Ei = General::epexp(-UThermal * DuctSurfArea, (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7450 399337 : Real64 QCondDuct = std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * (Tamb - Tin) * (1 - Ei);
7451 :
7452 399337 : TDuctSurf = Tamb - QCondDuct * RThermConvOut / DuctSurfArea;
7453 : }
7454 : } else { // Air-to-air only. U and h values are all known
7455 0 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin,
7456 0 : AirflowNetworkLinkSimu(i).FLOW,
7457 0 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7458 0 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7459 0 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7460 : Tamb,
7461 : Wamb,
7462 : Pamb,
7463 0 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7464 0 : AirflowNetworkLinkageData(i).ZoneNum,
7465 0 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7466 0 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7467 0 : Real64 RThermTotal = RThermConvIn + RThermConvOut + RThermConduct;
7468 0 : UThermal = pow(RThermTotal, -1);
7469 : }
7470 :
7471 121594 : Tsurr = Tamb;
7472 :
7473 : } else { // Air-to-air + radiation heat transfer
7474 :
7475 0 : auto &VFObj(AirflowNetworkLinkageViewFactorData(AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum));
7476 0 : VFObj.QRad = 0;
7477 0 : VFObj.QConv = 0;
7478 :
7479 0 : Real64 Tin_ave = Tin;
7480 0 : Real64 hOut = 0;
7481 :
7482 0 : while (std::abs(UThermal - UThermal_iter) > tolerance) {
7483 0 : UThermal_iter = UThermal;
7484 :
7485 0 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin_ave,
7486 0 : AirflowNetworkLinkSimu(i).FLOW,
7487 0 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7488 0 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7489 0 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7490 : Tamb,
7491 : Wamb,
7492 : Pamb,
7493 0 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7494 0 : AirflowNetworkLinkageData(i).ZoneNum,
7495 0 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7496 :
7497 0 : if (RThermConvOut > 0.0) {
7498 0 : hOut = 1 / RThermConvOut;
7499 : }
7500 :
7501 0 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7502 :
7503 0 : Real64 hrjTj_sum = 0;
7504 0 : Real64 hrj_sum = 0;
7505 :
7506 0 : for (int j = 1; j <= VFObj.LinkageSurfaceData.u(); ++j) {
7507 :
7508 0 : int ZoneSurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7509 :
7510 0 : Real64 TSurfj = m_state.dataHeatBalSurf->SurfOutsideTempHist(1)(ZoneSurfNum);
7511 0 : Real64 TSurfj_K = TSurfj + Constant::Kelvin;
7512 :
7513 : Real64 ZoneSurfEmissivity =
7514 0 : m_state.dataConstruction->Construct(m_state.dataSurface->Surface(ZoneSurfNum).Construction).InsideAbsorpThermal;
7515 0 : Real64 ZoneSurfArea = m_state.dataSurface->Surface(ZoneSurfNum).Area;
7516 :
7517 0 : Real64 DuctEmissivity = VFObj.DuctEmittance;
7518 0 : Real64 DuctExposureFrac = VFObj.DuctExposureFraction;
7519 0 : Real64 DuctToZoneSurfViewFactor = VFObj.LinkageSurfaceData(j).ViewFactor;
7520 :
7521 0 : Real64 DuctSurfResistance = (1 - DuctEmissivity) / (DuctExposureFrac * DuctSurfArea * DuctEmissivity);
7522 0 : Real64 SpaceResistance = 1 / (DuctExposureFrac * DuctSurfArea * DuctToZoneSurfViewFactor);
7523 0 : Real64 ZoneSurfResistance = (1 - ZoneSurfEmissivity) / (ZoneSurfArea * ZoneSurfEmissivity);
7524 :
7525 0 : VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor =
7526 0 : Constant::StefanBoltzmann / (DuctSurfResistance + SpaceResistance + ZoneSurfResistance);
7527 :
7528 0 : Real64 hrj = VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor * (TDuctSurf_K + TSurfj_K) *
7529 0 : (pow_2(TDuctSurf_K) + pow_2(TSurfj_K)) / DuctSurfArea;
7530 :
7531 0 : hrjTj_sum += hrj * TSurfj;
7532 0 : hrj_sum += hrj;
7533 : }
7534 :
7535 0 : Tsurr = (hOut * Tamb + hrjTj_sum) / (hOut + hrj_sum); // Surroundings temperature [C]
7536 0 : Tsurr_K = Tsurr + Constant::Kelvin;
7537 :
7538 0 : Real64 RThermTotal = RThermConvIn + RThermConduct + 1 / (hOut + hrj_sum);
7539 0 : UThermal = pow(RThermTotal, -1);
7540 :
7541 0 : Real64 NTU = UThermal * DuctSurfArea / (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir);
7542 0 : Tin_ave = Tsurr + (Tin - Tsurr) * (1 / NTU) * (1 - exp(-NTU));
7543 :
7544 0 : TDuctSurf = Tin_ave - UThermal * (RThermConvIn + RThermConduct) * (Tin_ave - Tsurr);
7545 0 : TDuctSurf_K = TDuctSurf + Constant::Kelvin;
7546 : }
7547 :
7548 0 : for (int j = 1; j <= VFObj.LinkageSurfaceData.u(); ++j) {
7549 0 : int ZoneSurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7550 0 : Real64 TSurfj = m_state.dataHeatBalSurf->SurfOutsideTempHist(1)(ZoneSurfNum);
7551 0 : Real64 TSurfj_K = TSurfj + Constant::Kelvin;
7552 0 : VFObj.LinkageSurfaceData(j).SurfaceRadLoad = VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor *
7553 0 : (pow_4(TDuctSurf_K) - pow_4(TSurfj_K)); // Radiant load for this surface [W]
7554 0 : int SurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7555 0 : Real64 ZoneSurfaceArea = m_state.dataSurface->Surface(SurfNum).Area;
7556 0 : m_state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) += VFObj.LinkageSurfaceData(j).SurfaceRadLoad * TimeStepSys *
7557 0 : Constant::rSecsInHour /
7558 : ZoneSurfaceArea; // Energy to each surface per unit area [J/m2]
7559 0 : VFObj.QRad += VFObj.LinkageSurfaceData(j).SurfaceRadLoad; // Total radiant load from all surfaces for this system timestep [W]
7560 : }
7561 :
7562 0 : VFObj.QConv = hOut * DuctSurfArea * (TDuctSurf - Tamb);
7563 0 : UThermal = (VFObj.QRad + VFObj.QConv) / (DuctSurfArea * std::abs(Tsurr - Tin));
7564 : }
7565 :
7566 121594 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7567 0 : Ei = General::epexp(-UThermal * DuctSurfArea, (AirflowNetworkLinkSimu(i).FLOW2 * CpAir));
7568 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7569 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * Ei;
7570 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Tsurr * (1.0 - Ei) * CpAir;
7571 : } else {
7572 121594 : Ei = General::epexp(-UThermal * DuctSurfArea, (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7573 121594 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7574 121594 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * Ei;
7575 121594 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Tsurr * (1.0 - Ei) * CpAir;
7576 : }
7577 : }
7578 420052 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
7579 0 : int TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7580 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7581 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7582 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7583 0 : DirSign = 1.0;
7584 : } else { // flow direction is the opposite as input from node 2 to node 1
7585 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7586 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7587 0 : DirSign = -1.0;
7588 : }
7589 0 : Ei = General::epexp(-0.001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7590 0 : (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7591 0 : Tamb = AirflowNetworkNodeSimu(LT).TZ;
7592 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7593 0 : Ei = General::epexp(-0.001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7594 0 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir));
7595 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7596 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * Ei;
7597 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Tamb * (1.0 - Ei) * CpAir;
7598 : } else {
7599 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7600 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * Ei;
7601 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Tamb * (1.0 - Ei) * CpAir;
7602 : }
7603 : }
7604 420052 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
7605 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7606 33162 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7607 33162 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7608 33162 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7609 33162 : DirSign = 1.0;
7610 : } else { // flow direction is the opposite as input from node 2 to node 1
7611 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7612 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7613 0 : DirSign = -1.0;
7614 : }
7615 : }
7616 : // Calculate temp in a constant pressure drop element
7617 420052 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
7618 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7619 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7620 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7621 : } else { // flow direction is the opposite as input from node 2 to node 1
7622 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7623 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7624 : }
7625 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7626 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7627 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7628 : } else {
7629 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7630 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7631 : }
7632 0 : MV(LT) = 0.0;
7633 : }
7634 : // Calculate return leak
7635 420052 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
7636 : // Return leak element only
7637 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
7638 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7639 22108 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7640 22108 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7641 22108 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7642 22108 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7643 : }
7644 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
7645 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7646 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7647 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7648 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7649 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7650 : }
7651 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
7652 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7653 4308 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7654 4308 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7655 4308 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7656 4308 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7657 : }
7658 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
7659 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7660 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7661 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7662 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7663 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7664 : }
7665 : }
7666 : // Check reheat unit or coil
7667 420052 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(i).VAVTermDamper)) {
7668 0 : NF = 0;
7669 0 : NT = 0;
7670 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
7671 0 : NF = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum;
7672 : }
7673 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
7674 0 : NT = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum;
7675 : }
7676 0 : if ((NF == 0) || (NT == 0)) {
7677 0 : ShowFatalError(m_state,
7678 0 : "Node number in the primary air loop is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " +
7679 0 : AirflowNetworkLinkageData(i).Name);
7680 : }
7681 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) {
7682 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7683 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7684 0 : load = Node(NT).Temp - Node(NF).Temp;
7685 : } else {
7686 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7687 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7688 0 : load = Node(NF).Temp - Node(NT).Temp;
7689 : }
7690 0 : CpAir = PsyCpAirFnW(Node(NT).HumRat);
7691 0 : MV(LT) += AirflowNetworkLinkSimu(i).FLOW * CpAir * load;
7692 : }
7693 420052 : }
7694 :
7695 : // Prescribe temperature for EPlus nodes
7696 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7697 375836 : bool found = false;
7698 375836 : bool OANode = false;
7699 14259660 : for (int j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
7700 13928040 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7701 817996 : CompNum = AirflowNetworkLinkageData(j).CompNum;
7702 817996 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
7703 0 : found = true;
7704 0 : break;
7705 : }
7706 : // Overwrite fan outlet node
7707 817996 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7708 11054 : found = false;
7709 11054 : break;
7710 : }
7711 : // Overwrite return connection outlet
7712 806942 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
7713 22108 : found = true;
7714 22108 : break;
7715 : }
7716 806942 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
7717 22108 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
7718 11054 : found = true;
7719 11054 : break;
7720 : }
7721 : }
7722 14270714 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
7723 386890 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
7724 0 : OANode = true;
7725 0 : break;
7726 : }
7727 : }
7728 375836 : if (found) {
7729 33162 : continue;
7730 : }
7731 342674 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) {
7732 11054 : continue;
7733 : }
7734 331620 : int j = AirflowNetworkNodeData(i).EPlusNodeNum;
7735 :
7736 408998 : if (j > 0 &&
7737 77378 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
7738 55270 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
7739 55270 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7740 55270 : MV(i) = Node(j).Temp * 1.0e10;
7741 : }
7742 331620 : if (j > 0 && OANode) {
7743 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7744 0 : MV(i) = Node(j).Temp * 1.0e10;
7745 : }
7746 331620 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7747 22108 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
7748 22108 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7749 22108 : MV(i) = ANZT(ZoneNum) * 1.0e10;
7750 : }
7751 331620 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7752 187918 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7753 187918 : if (AirflowNetworkNodeData(i).OutAirNodeNum > 0) {
7754 0 : MV(i) = Node(AirflowNetworkNodeData(i).OutAirNodeNum).OutAirDryBulb * 1.0e10;
7755 : } else {
7756 187918 : MV(i) = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(i).NodeHeight) * 1.0e10;
7757 : }
7758 : }
7759 331620 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7760 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7761 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
7762 0 : if (m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID == i) {
7763 0 : MV(i) = m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp * 1.0e10;
7764 : }
7765 : }
7766 : }
7767 :
7768 : // Assign node value to distribution nodes with fan off
7769 165810 : for (i = 1 + NumOfNodesMultiZone; i <= AirflowNetworkNumOfNodes; ++i) {
7770 154756 : int j = AirflowNetworkNodeData(i).EPlusNodeNum;
7771 154756 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
7772 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7773 0 : MV(i) = Node(j).Temp * 1.0e10;
7774 : }
7775 154756 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
7776 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7777 0 : MV(i) = AirflowNetworkNodeSimu(i).TZlast * 1.0e10;
7778 : }
7779 : }
7780 :
7781 : // Check singularity
7782 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7783 375836 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
7784 0 : if (i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
7785 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7786 0 : MV(i) = AirflowNetworkNodeSimu(i).TZlast * 1.0e10;
7787 : } else {
7788 0 : ShowFatalError(m_state,
7789 0 : "CalcAirflowNetworkHeatBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
7790 0 : AirflowNetworkNodeData(i).Name);
7791 : }
7792 : }
7793 : }
7794 :
7795 : // Get an inverse matrix
7796 11054 : mrxinv(AirflowNetworkNumOfNodes);
7797 :
7798 : // Calculate node temperatures
7799 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7800 375836 : TZON = 0.0;
7801 13154260 : for (int j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
7802 12778424 : TZON += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
7803 : }
7804 375836 : AirflowNetworkNodeSimu(i).TZ = TZON;
7805 : }
7806 11054 : }
7807 :
7808 11054 : void Solver::calculate_moisture_balance()
7809 : {
7810 : // SUBROUTINE INFORMATION:
7811 : // AUTHOR Lixing Gu
7812 : // DATE WRITTEN Oct. 2005
7813 : // MODIFIED na
7814 : // RE-ENGINEERED Revised based on Subroutine CalcADSMoistureBalance
7815 :
7816 : // PURPOSE OF THIS SUBROUTINE:
7817 : // This subroutine performs AirflowNetwork moisture simulations.
7818 :
7819 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7820 : int i;
7821 : int j;
7822 : int LF;
7823 : int LT;
7824 : int CompNum;
7825 : int NF;
7826 : int NT;
7827 : iComponentTypeNum CompTypeNum;
7828 : int TypeNum;
7829 : Real64 Ei;
7830 : Real64 DirSign;
7831 : Real64 Wamb;
7832 : Real64 WZON;
7833 : Real64 load;
7834 : int ZoneNum;
7835 :
7836 11054 : auto &Node(m_state.dataLoopNodes->Node);
7837 :
7838 11054 : MA = 0.0;
7839 11054 : MV = 0.0;
7840 431106 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
7841 420052 : CompNum = AirflowNetworkLinkageData(i).CompNum;
7842 420052 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
7843 420052 : std::string CompName = AirflowNetworkCompData(CompNum).EPlusName;
7844 : // Calculate duct moisture diffusion loss
7845 420052 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct component only
7846 121594 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7847 121594 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7848 121594 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7849 121594 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7850 121594 : DirSign = 1.0;
7851 : } else { // flow direction is the opposite as input from node 2 to node 1
7852 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7853 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7854 0 : DirSign = -1.0;
7855 : }
7856 121594 : Ei = General::epexp(-DisSysCompDuctData(TypeNum).UMoisture * DisSysCompDuctData(TypeNum).L *
7857 121594 : DisSysCompDuctData(TypeNum).hydraulicDiameter * Constant::Pi,
7858 121594 : (DirSign * AirflowNetworkLinkSimu(i).FLOW));
7859 121594 : if (AirflowNetworkLinkageData(i).ZoneNum < 0) {
7860 0 : Wamb = m_state.dataEnvrn->OutHumRat;
7861 121594 : } else if (AirflowNetworkLinkageData(i).ZoneNum == 0) {
7862 44216 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7863 : } else {
7864 77378 : Wamb = ANZW(AirflowNetworkLinkageData(i).ZoneNum);
7865 : }
7866 121594 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7867 0 : Ei = General::epexp(-DisSysCompDuctData(TypeNum).UMoisture * DisSysCompDuctData(TypeNum).L *
7868 0 : DisSysCompDuctData(TypeNum).hydraulicDiameter * Constant::Pi,
7869 0 : (AirflowNetworkLinkSimu(i).FLOW2));
7870 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7871 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Ei;
7872 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Wamb * (1.0 - Ei);
7873 : } else {
7874 121594 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7875 121594 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * Ei;
7876 121594 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Wamb * (1.0 - Ei);
7877 : }
7878 : }
7879 420052 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
7880 0 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7881 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7882 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7883 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7884 0 : DirSign = 1.0;
7885 : } else { // flow direction is the opposite as input from node 2 to node 1
7886 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7887 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7888 0 : DirSign = -1.0;
7889 : }
7890 0 : Ei = General::epexp(-0.0001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7891 0 : (DirSign * AirflowNetworkLinkSimu(i).FLOW));
7892 0 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7893 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7894 :
7895 : Ei =
7896 0 : General::epexp(-0.0001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7897 0 : (AirflowNetworkLinkSimu(i).FLOW2));
7898 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7899 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Ei;
7900 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Wamb * (1.0 - Ei);
7901 : } else {
7902 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7903 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * Ei;
7904 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Wamb * (1.0 - Ei);
7905 : }
7906 : }
7907 420052 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
7908 33162 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7909 33162 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7910 33162 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7911 33162 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7912 33162 : DirSign = 1.0;
7913 : } else { // flow direction is the opposite as input from node 2 to node 1
7914 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7915 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7916 0 : DirSign = -1.0;
7917 : }
7918 : }
7919 : // Calculate temp in a constant pressure drop component
7920 420052 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
7921 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7922 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7923 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7924 : } else { // flow direction is the opposite as input from node 2 to node 1
7925 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7926 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7927 : }
7928 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7929 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7930 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7931 : } else {
7932 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7933 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7934 : }
7935 0 : MV(LT) = 0.0;
7936 : }
7937 : // Calculate return leak
7938 420052 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
7939 : // Return leak component only
7940 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
7941 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7942 22108 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7943 22108 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7944 22108 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7945 22108 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7946 : }
7947 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
7948 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7949 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7950 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7951 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7952 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7953 : }
7954 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
7955 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7956 4308 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7957 4308 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7958 4308 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7959 4308 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7960 : }
7961 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
7962 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7963 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7964 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7965 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7966 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7967 : }
7968 : }
7969 : // Check reheat unit
7970 420052 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(i).VAVTermDamper)) {
7971 0 : NF = 0;
7972 0 : NT = 0;
7973 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
7974 0 : NF = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum;
7975 : }
7976 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
7977 0 : NT = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum;
7978 : }
7979 0 : if ((NF == 0) || (NT == 0)) {
7980 0 : ShowFatalError(m_state,
7981 0 : "Node number in the primary air loop is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " +
7982 0 : AirflowNetworkLinkageData(i).Name);
7983 : }
7984 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) {
7985 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7986 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7987 0 : load = Node(NT).HumRat - Node(NF).HumRat;
7988 : } else {
7989 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7990 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7991 0 : load = Node(NF).HumRat - Node(NT).HumRat;
7992 : }
7993 0 : MV(LT) += AirflowNetworkLinkSimu(i).FLOW * load;
7994 : }
7995 420052 : }
7996 :
7997 : // Prescribe temperature for EPlus nodes
7998 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7999 375836 : bool found = false;
8000 375836 : bool OANode = false;
8001 14259660 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
8002 13928040 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8003 817996 : CompNum = AirflowNetworkLinkageData(j).CompNum;
8004 817996 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
8005 0 : found = true;
8006 0 : break;
8007 : }
8008 : // Overwrite fan outlet node
8009 817996 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8010 11054 : found = false;
8011 11054 : break;
8012 : }
8013 : // Overwrite return connection outlet
8014 806942 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
8015 22108 : found = true;
8016 22108 : break;
8017 : }
8018 806942 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
8019 22108 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
8020 11054 : found = true;
8021 11054 : break;
8022 : }
8023 : }
8024 14270714 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
8025 386890 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
8026 0 : OANode = true;
8027 0 : break;
8028 : }
8029 : }
8030 375836 : if (found) {
8031 33162 : continue;
8032 : }
8033 342674 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) {
8034 11054 : continue;
8035 : }
8036 331620 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8037 408998 : if (j > 0 &&
8038 77378 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
8039 55270 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
8040 55270 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8041 55270 : MV(i) = Node(j).HumRat * 1.0e10;
8042 : }
8043 331620 : if (j > 0 && OANode) {
8044 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8045 0 : MV(i) = Node(j).HumRat * 1.0e10;
8046 : }
8047 331620 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8048 22108 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8049 22108 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8050 22108 : MV(i) = ANZW(ZoneNum) * 1.0e10;
8051 : }
8052 331620 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
8053 187918 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8054 187918 : MV(i) = m_state.dataEnvrn->OutHumRat * 1.0e10;
8055 : }
8056 331620 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8057 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8058 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8059 0 : if (m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID == i) {
8060 0 : MV(i) = m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat * 1.0e10;
8061 : }
8062 : }
8063 : }
8064 :
8065 : // Assign node value to distribution nodes with fan off
8066 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8067 375836 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8068 375836 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
8069 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8070 0 : MV(i) = Node(j).HumRat * 1.0e10;
8071 : }
8072 375836 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
8073 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8074 0 : MV(i) = AirflowNetworkNodeSimu(i).WZlast * 1.0e10;
8075 : }
8076 : }
8077 :
8078 : // Check singularity
8079 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8080 375836 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-8) {
8081 0 : ShowFatalError(m_state,
8082 0 : "CalcAirflowNetworkMoisBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
8083 0 : AirflowNetworkNodeData(i).Name);
8084 : }
8085 : }
8086 :
8087 : // Get an inverse matrix
8088 11054 : mrxinv(AirflowNetworkNumOfNodes);
8089 :
8090 : // Calculate node temperatures
8091 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8092 375836 : WZON = 0.0;
8093 13154260 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
8094 12778424 : WZON += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
8095 : }
8096 375836 : AirflowNetworkNodeSimu(i).WZ = WZON;
8097 : }
8098 11054 : }
8099 :
8100 0 : void Solver::calculate_CO2_balance()
8101 : {
8102 : // SUBROUTINE INFORMATION:
8103 : // AUTHOR Lixing Gu
8104 : // DATE WRITTEN June. 2010
8105 : // MODIFIED na
8106 : // RE-ENGINEERED Revised based on Subroutine CalcAirflowNetworkMoisBalance
8107 :
8108 : // PURPOSE OF THIS SUBROUTINE:
8109 : // This subroutine performs AirflowNetwork CO2 simulations.
8110 :
8111 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8112 : int i;
8113 : int j;
8114 : int LF;
8115 : int LT;
8116 : int CompNum;
8117 : iComponentTypeNum CompTypeNum;
8118 : Real64 DirSign;
8119 : Real64 COZN;
8120 : int ZoneNum;
8121 :
8122 0 : MA = 0.0;
8123 0 : MV = 0.0;
8124 0 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
8125 0 : CompNum = AirflowNetworkLinkageData(i).CompNum;
8126 0 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
8127 0 : std::string CompName = AirflowNetworkCompData(CompNum).EPlusName;
8128 : // Calculate duct moisture diffusion loss
8129 0 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct component only
8130 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8131 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8132 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8133 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8134 0 : DirSign = 1.0;
8135 : } else { // flow direction is the opposite as input from node 2 to node 1
8136 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8137 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8138 0 : DirSign = -1.0;
8139 : }
8140 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8141 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8142 : }
8143 0 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
8144 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8145 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8146 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8147 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8148 0 : DirSign = 1.0;
8149 : } else { // flow direction is the opposite as input from node 2 to node 1
8150 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8151 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8152 0 : DirSign = -1.0;
8153 : }
8154 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8155 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8156 : }
8157 0 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
8158 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8159 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8160 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8161 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8162 0 : DirSign = 1.0;
8163 : } else { // flow direction is the opposite as input from node 2 to node 1
8164 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8165 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8166 0 : DirSign = -1.0;
8167 : }
8168 : }
8169 : // Calculate temp in a constant pressure drop component
8170 0 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
8171 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8172 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8173 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8174 : } else { // flow direction is the opposite as input from node 2 to node 1
8175 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8176 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8177 : }
8178 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8179 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8180 0 : MV(LT) = 0.0;
8181 : }
8182 : // Calculate return leak
8183 0 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
8184 : // Return leak component only
8185 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
8186 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8187 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8188 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8189 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8190 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8191 : }
8192 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
8193 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8194 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8195 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8196 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8197 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8198 : }
8199 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
8200 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8201 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8202 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8203 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8204 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8205 : }
8206 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
8207 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8208 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8209 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8210 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8211 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8212 : }
8213 : }
8214 0 : }
8215 :
8216 : // Prescribe temperature for EPlus nodes
8217 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8218 0 : bool found = false;
8219 0 : bool OANode = false;
8220 0 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
8221 0 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8222 0 : CompNum = AirflowNetworkLinkageData(j).CompNum;
8223 0 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
8224 0 : found = true;
8225 0 : break;
8226 : }
8227 : // Overwrite fan outlet node
8228 0 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8229 0 : found = false;
8230 0 : break;
8231 : }
8232 : // Overwrite return connection outlet
8233 0 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
8234 0 : found = true;
8235 0 : break;
8236 : }
8237 0 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
8238 0 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
8239 0 : found = true;
8240 0 : break;
8241 : }
8242 : }
8243 0 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
8244 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
8245 0 : OANode = true;
8246 0 : break;
8247 : }
8248 : }
8249 0 : if (found) {
8250 0 : continue;
8251 : }
8252 0 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) {
8253 0 : continue;
8254 : }
8255 0 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8256 0 : if (j > 0 &&
8257 0 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
8258 0 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
8259 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8260 0 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8261 : }
8262 0 : if (j > 0 && OANode) {
8263 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8264 0 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8265 : }
8266 0 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8267 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8268 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8269 0 : MV(i) = ANCO(ZoneNum) * 1.0e10;
8270 : }
8271 0 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
8272 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8273 0 : MV(i) = m_state.dataContaminantBalance->OutdoorCO2 * 1.0e10;
8274 : }
8275 : }
8276 :
8277 : // Assign node value to distribution nodes with fan off
8278 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8279 0 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8280 0 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
8281 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8282 0 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8283 : }
8284 0 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
8285 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8286 0 : MV(i) = AirflowNetworkNodeSimu(i).CO2Zlast * 1.0e10;
8287 : }
8288 : }
8289 :
8290 : // Check singularity
8291 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8292 0 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
8293 0 : ShowFatalError(m_state,
8294 0 : "CalcAirflowNetworkCO2Balance: A diagonal entity is zero in AirflowNetwork matrix at node " +
8295 0 : AirflowNetworkNodeData(i).Name);
8296 : }
8297 : }
8298 :
8299 : // Get an inverse matrix
8300 0 : mrxinv(AirflowNetworkNumOfNodes);
8301 :
8302 : // Calculate node temperatures
8303 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8304 0 : COZN = 0.0;
8305 0 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
8306 0 : COZN += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
8307 : }
8308 0 : AirflowNetworkNodeSimu(i).CO2Z = COZN;
8309 : }
8310 0 : }
8311 :
8312 0 : void Solver::calculate_GC_balance()
8313 : {
8314 : // SUBROUTINE INFORMATION:
8315 : // AUTHOR Lixing Gu
8316 : // DATE WRITTEN Jan. 2012
8317 : // MODIFIED na
8318 : // RE-ENGINEERED Revised based on Subroutine CalcAirflowNetworkCO2Balance
8319 :
8320 : // PURPOSE OF THIS SUBROUTINE:
8321 : // This subroutine performs AirflowNetwork generic contaminant simulations.
8322 :
8323 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8324 : int i;
8325 : int j;
8326 : int LF;
8327 : int LT;
8328 : int CompNum;
8329 : iComponentTypeNum CompTypeNum;
8330 : Real64 DirSign;
8331 : Real64 COZN;
8332 : int ZoneNum;
8333 :
8334 0 : MA = 0.0;
8335 0 : MV = 0.0;
8336 0 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
8337 0 : CompNum = AirflowNetworkLinkageData(i).CompNum;
8338 0 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
8339 0 : std::string_view CompName = AirflowNetworkCompData(CompNum).EPlusName;
8340 : // Calculate duct moisture diffusion loss
8341 0 : if (CompTypeNum == iComponentTypeNum::DWC && CompName.empty()) { // Duct component only
8342 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8343 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8344 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8345 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8346 0 : DirSign = 1.0;
8347 : } else { // flow direction is the opposite as input from node 2 to node 1
8348 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8349 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8350 0 : DirSign = -1.0;
8351 : }
8352 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8353 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8354 : }
8355 0 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
8356 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8357 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8358 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8359 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8360 0 : DirSign = 1.0;
8361 : } else { // flow direction is the opposite as input from node 2 to node 1
8362 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8363 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8364 0 : DirSign = -1.0;
8365 : }
8366 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8367 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8368 : }
8369 0 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
8370 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8371 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8372 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8373 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8374 0 : DirSign = 1.0;
8375 : } else { // flow direction is the opposite as input from node 2 to node 1
8376 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8377 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8378 0 : DirSign = -1.0;
8379 : }
8380 : }
8381 : // Calculate temp in a constant pressure drop component
8382 0 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
8383 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8384 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8385 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8386 : } else { // flow direction is the opposite as input from node 2 to node 1
8387 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8388 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8389 : }
8390 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8391 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8392 0 : MV(LT) = 0.0;
8393 : }
8394 : // Calculate return leak
8395 0 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
8396 : // Return leak component only
8397 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
8398 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8399 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8400 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8401 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8402 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8403 : }
8404 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
8405 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8406 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8407 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8408 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8409 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8410 : }
8411 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
8412 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8413 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8414 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8415 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8416 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8417 : }
8418 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
8419 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8420 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8421 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8422 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8423 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8424 : }
8425 : }
8426 : }
8427 :
8428 : // Prescribe temperature for EPlus nodes
8429 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8430 0 : bool found = false;
8431 0 : bool OANode = false;
8432 0 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
8433 0 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8434 0 : CompNum = AirflowNetworkLinkageData(j).CompNum;
8435 0 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
8436 0 : found = true;
8437 0 : break;
8438 : }
8439 : // Overwrite fan outlet node
8440 0 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8441 0 : found = false;
8442 0 : break;
8443 : }
8444 : // Overwrite return connection outlet
8445 0 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
8446 0 : found = true;
8447 0 : break;
8448 : }
8449 0 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
8450 0 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
8451 0 : found = true;
8452 0 : break;
8453 : }
8454 : }
8455 0 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
8456 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
8457 0 : OANode = true;
8458 0 : break;
8459 : }
8460 : }
8461 0 : if (found) {
8462 0 : continue;
8463 : }
8464 0 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) {
8465 0 : continue;
8466 : }
8467 0 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8468 0 : if (j > 0 &&
8469 0 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
8470 0 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
8471 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8472 0 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8473 : }
8474 0 : if (j > 0 && OANode) {
8475 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8476 0 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8477 : }
8478 0 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8479 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8480 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8481 0 : MV(i) = ANGC(ZoneNum) * 1.0e10;
8482 : }
8483 0 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
8484 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8485 0 : MV(i) = m_state.dataContaminantBalance->OutdoorGC * 1.0e10;
8486 : }
8487 : }
8488 :
8489 : // Assign node value to distribution nodes with fan off
8490 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8491 0 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8492 0 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
8493 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8494 0 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8495 : }
8496 0 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
8497 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8498 0 : MV(i) = AirflowNetworkNodeSimu(i).GCZlast * 1.0e10;
8499 : }
8500 : }
8501 :
8502 : // Check singularity
8503 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8504 0 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
8505 0 : ShowFatalError(m_state,
8506 0 : "CalcAirflowNetworkGCBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
8507 0 : AirflowNetworkNodeData(i).Name);
8508 : }
8509 : }
8510 :
8511 : // Get an inverse matrix
8512 0 : mrxinv(AirflowNetworkNumOfNodes);
8513 :
8514 : // Calculate node temperatures
8515 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8516 0 : COZN = 0.0;
8517 0 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
8518 0 : COZN += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
8519 : }
8520 0 : AirflowNetworkNodeSimu(i).GCZ = COZN;
8521 : }
8522 0 : }
8523 :
8524 22108 : void Solver::mrxinv(int const NORDER)
8525 : {
8526 :
8527 : // SUBROUTINE INFORMATION:
8528 : // AUTHOR Lixing Gu
8529 : // DATE WRITTEN Oct. 2005
8530 : // MODIFIED na
8531 : // RE-ENGINEERED Revised based on Subroutine ADSINV
8532 :
8533 : // PURPOSE OF THIS SUBROUTINE:
8534 : // This subroutine inverses a matrix
8535 :
8536 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8537 : int i;
8538 : int j;
8539 : int K;
8540 : int M;
8541 : Real64 R1;
8542 : Real64 S;
8543 :
8544 22108 : IVEC = 0;
8545 773780 : for (i = 1; i <= NORDER; ++i) {
8546 751672 : IVEC(i + 20) = i;
8547 : }
8548 773780 : for (i = 1; i <= NORDER; ++i) {
8549 751672 : R1 = 0.0;
8550 751672 : M = i;
8551 13905932 : for (j = i; j <= NORDER; ++j) {
8552 13154260 : if (std::abs(R1) < std::abs(MA((i - 1) * NORDER + j))) {
8553 751672 : M = j;
8554 751672 : R1 = MA((i - 1) * NORDER + j);
8555 : }
8556 : }
8557 751672 : if (i != M) {
8558 0 : K = IVEC(M + 20);
8559 0 : IVEC(M + 20) = IVEC(i + 20);
8560 0 : IVEC(i + 20) = K;
8561 0 : for (j = 1; j <= NORDER; ++j) {
8562 0 : S = MA((j - 1) * NORDER + i);
8563 0 : MA((j - 1) * NORDER + i) = MA((j - 1) * NORDER + M);
8564 0 : MA((j - 1) * NORDER + M) = S;
8565 : }
8566 : }
8567 751672 : MA((i - 1) * NORDER + i) = 1.0;
8568 26308520 : for (j = 1; j <= NORDER; ++j) {
8569 25556848 : MA((i - 1) * NORDER + j) /= R1;
8570 : }
8571 26308520 : for (j = 1; j <= NORDER; ++j) {
8572 25556848 : if (i == j) {
8573 751672 : continue;
8574 : }
8575 24805176 : R1 = MA((j - 1) * NORDER + i);
8576 24805176 : if (std::abs(R1) <= 1.0E-20) {
8577 24243860 : continue;
8578 : }
8579 561316 : MA((j - 1) * NORDER + i) = 0.0;
8580 19646060 : for (K = 1; K <= NORDER; ++K) {
8581 19084744 : MA((j - 1) * NORDER + K) -= R1 * MA((i - 1) * NORDER + K);
8582 : }
8583 : }
8584 : }
8585 773780 : for (i = 1; i <= NORDER; ++i) {
8586 751672 : if (IVEC(i + 20) == i) {
8587 751672 : continue;
8588 : }
8589 0 : M = i;
8590 0 : while (NORDER > M) {
8591 0 : ++M;
8592 0 : if (IVEC(M + 20) == i) {
8593 0 : break;
8594 : }
8595 : }
8596 0 : IVEC(M + 20) = IVEC(i + 20);
8597 0 : for (j = 1; j <= NORDER; ++j) {
8598 0 : R1 = MA((i - 1) * NORDER + j);
8599 0 : MA((i - 1) * NORDER + j) = MA((M - 1) * NORDER + j);
8600 0 : MA((M - 1) * NORDER + j) = R1;
8601 : }
8602 0 : IVEC(i + 20) = i;
8603 : }
8604 22108 : }
8605 :
8606 344 : void Solver::report()
8607 : {
8608 :
8609 : // SUBROUTINE INFORMATION:
8610 : // AUTHOR Lixing Gu
8611 : // DATE WRITTEN 2/1/04
8612 : // MODIFIED na
8613 : // RE-ENGINEERED na
8614 :
8615 : // PURPOSE OF THIS SUBROUTINE:
8616 : // This subroutine reports outputs of air distribution systems
8617 :
8618 : // Using/Aliasing
8619 344 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
8620 344 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
8621 :
8622 344 : auto &Zone(m_state.dataHeatBal->Zone);
8623 :
8624 : // SUBROUTINE PARAMETER DEFINITIONS:
8625 344 : constexpr Real64 Lam(2.5e6); // Heat of vaporization (J/kg)
8626 :
8627 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8628 : int i;
8629 : int n;
8630 : int M;
8631 : int ZN1;
8632 : int ZN2;
8633 : Real64 AirDensity;
8634 : Real64 CpAir;
8635 : Real64 Tamb;
8636 : Real64 hg; // latent heat of vaporization
8637 : Real64 ReportingConstant;
8638 : Real64 ReportingFraction;
8639 : int AirLoopNum;
8640 : int FanNum;
8641 : Real64 RepOnOffFanRunTimeFraction;
8642 :
8643 344 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) {
8644 0 : return;
8645 : }
8646 :
8647 344 : if (!onetime) {
8648 3 : onceZoneFlag.dimension(m_state.dataGlobal->NumOfZones, false);
8649 3 : onceSurfFlag.dimension(AirflowNetworkNumOfLinks, false);
8650 3 : onetime = true;
8651 : }
8652 344 : ReportingConstant = TimeStepSys * Constant::rSecsInHour;
8653 :
8654 344 : m_state.dataHeatBal->ZoneTotalExfiltrationHeatLoss = 0.0;
8655 :
8656 1385 : for (auto &e : AirflowNetworkReportData) {
8657 1041 : e.MultiZoneInfiSenGainW = 0.0;
8658 1041 : e.MultiZoneInfiSenGainJ = 0.0;
8659 1041 : e.MultiZoneInfiSenLossW = 0.0;
8660 1041 : e.MultiZoneInfiSenLossJ = 0.0;
8661 1041 : e.MultiZoneInfiLatGainW = 0.0;
8662 1041 : e.MultiZoneInfiLatGainJ = 0.0;
8663 1041 : e.MultiZoneInfiLatLossW = 0.0;
8664 1041 : e.MultiZoneInfiLatLossJ = 0.0;
8665 1041 : e.MultiZoneVentSenGainW = 0.0;
8666 1041 : e.MultiZoneVentSenGainJ = 0.0;
8667 1041 : e.MultiZoneVentSenLossW = 0.0;
8668 1041 : e.MultiZoneVentSenLossJ = 0.0;
8669 1041 : e.MultiZoneVentLatGainW = 0.0;
8670 1041 : e.MultiZoneVentLatGainJ = 0.0;
8671 1041 : e.MultiZoneVentLatLossW = 0.0;
8672 1041 : e.MultiZoneVentLatLossJ = 0.0;
8673 1041 : e.MultiZoneMixSenGainW = 0.0;
8674 1041 : e.MultiZoneMixSenGainJ = 0.0;
8675 1041 : e.MultiZoneMixSenLossW = 0.0;
8676 1041 : e.MultiZoneMixSenLossJ = 0.0;
8677 1041 : e.MultiZoneMixLatGainW = 0.0;
8678 1041 : e.MultiZoneMixLatGainJ = 0.0;
8679 1041 : e.MultiZoneMixLatLossW = 0.0;
8680 1041 : e.MultiZoneMixLatLossJ = 0.0;
8681 1041 : e.LeakSenGainW = 0.0;
8682 1041 : e.LeakSenGainJ = 0.0;
8683 1041 : e.LeakSenLossW = 0.0;
8684 1041 : e.LeakSenLossJ = 0.0;
8685 1041 : e.LeakLatGainW = 0.0;
8686 1041 : e.LeakLatGainJ = 0.0;
8687 1041 : e.LeakLatLossW = 0.0;
8688 1041 : e.LeakLatLossJ = 0.0;
8689 1041 : e.CondSenGainW = 0.0;
8690 1041 : e.CondSenGainJ = 0.0;
8691 1041 : e.CondSenLossW = 0.0;
8692 1041 : e.CondSenLossJ = 0.0;
8693 1041 : e.DiffLatGainW = 0.0;
8694 1041 : e.DiffLatGainJ = 0.0;
8695 1041 : e.DiffLatLossW = 0.0;
8696 1041 : e.DiffLatLossJ = 0.0;
8697 1041 : e.RadGainW = 0.0;
8698 1041 : e.RadGainJ = 0.0;
8699 1041 : e.RadLossW = 0.0;
8700 1041 : e.RadLossJ = 0.0;
8701 1041 : e.TotalSenGainW = 0.0;
8702 1041 : e.TotalSenGainJ = 0.0;
8703 1041 : e.TotalSenLossW = 0.0;
8704 1041 : e.TotalSenLossJ = 0.0;
8705 1041 : e.TotalLatGainW = 0.0;
8706 1041 : e.TotalLatGainJ = 0.0;
8707 1041 : e.TotalLatLossW = 0.0;
8708 1041 : e.TotalLatLossJ = 0.0;
8709 : }
8710 :
8711 : // Calculate sensible and latent loads in each zone from multizone airflows
8712 344 : if (multizone_always_simulated ||
8713 0 : (simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation && AirflowNetworkFanActivated)) {
8714 6888 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
8715 6544 : n = AirflowNetworkLinkageData(i).NodeNums[0];
8716 6544 : M = AirflowNetworkLinkageData(i).NodeNums[1];
8717 6544 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
8718 6544 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
8719 : // Find a linkage from a zone to outdoors
8720 6544 : if (ZN1 > 0 && ZN2 == 0) {
8721 5823 : auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
8722 5823 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfLinkedOutAirNode > 0) {
8723 0 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(MultizoneSurfaceData(i).SurfNum);
8724 0 : CpAir = PsyCpAirFnW(Psychrometrics::PsyWFnTdbTwbPb(m_state,
8725 : Tamb,
8726 0 : m_state.dataSurface->SurfOutWetBulbTemp(MultizoneSurfaceData(i).SurfNum),
8727 0 : m_state.dataEnvrn->OutBaroPress));
8728 : } else {
8729 5823 : Tamb = Zone(ZN1).OutDryBulbTemp;
8730 5823 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
8731 : }
8732 5823 : hg = Psychrometrics::PsyHgAirFnWTdb(zn1HB.airHumRat, zn1HB.MAT);
8733 :
8734 11616 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
8735 5793 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
8736 5459 : if (Tamb > zn1HB.MAT) {
8737 1256 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT));
8738 1256 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainJ +=
8739 1256 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant;
8740 : } else {
8741 4203 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb));
8742 4203 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossJ +=
8743 4203 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant;
8744 : }
8745 5459 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
8746 12 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainW +=
8747 6 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg;
8748 6 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainJ +=
8749 6 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8750 : } else {
8751 10906 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossW +=
8752 5453 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8753 5453 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossJ +=
8754 5453 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8755 : }
8756 : } else {
8757 364 : if (Tamb > zn1HB.MAT) {
8758 69 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT));
8759 69 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainJ +=
8760 69 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant;
8761 : } else {
8762 295 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb));
8763 295 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossJ +=
8764 295 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant;
8765 : }
8766 364 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
8767 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainW +=
8768 0 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg;
8769 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainJ +=
8770 0 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8771 : } else {
8772 728 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossW +=
8773 364 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8774 364 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossJ +=
8775 364 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8776 : }
8777 : }
8778 : }
8779 6544 : if (ZN1 == 0 && ZN2 > 0) {
8780 0 : auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
8781 0 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfLinkedOutAirNode > 0) {
8782 0 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(MultizoneSurfaceData(i).SurfNum);
8783 0 : CpAir = PsyCpAirFnW(Psychrometrics::PsyWFnTdbTwbPb(m_state,
8784 : Tamb,
8785 0 : m_state.dataSurface->SurfOutWetBulbTemp(MultizoneSurfaceData(i).SurfNum),
8786 0 : m_state.dataEnvrn->OutBaroPress));
8787 : } else {
8788 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
8789 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
8790 : }
8791 0 : hg = Psychrometrics::PsyHgAirFnWTdb(zn2HB.airHumRat, zn2HB.MAT);
8792 :
8793 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
8794 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
8795 0 : if (Tamb > zn2HB.MAT) {
8796 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT));
8797 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainJ +=
8798 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant;
8799 : } else {
8800 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb));
8801 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossJ +=
8802 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant;
8803 : }
8804 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
8805 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainW +=
8806 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg;
8807 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainJ +=
8808 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8809 : } else {
8810 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossW +=
8811 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8812 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossJ +=
8813 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8814 : }
8815 : } else {
8816 0 : if (Tamb > zn2HB.MAT) {
8817 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT));
8818 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainJ +=
8819 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant;
8820 : } else {
8821 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb));
8822 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossJ +=
8823 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant;
8824 : }
8825 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
8826 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainW +=
8827 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg;
8828 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainJ +=
8829 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8830 : } else {
8831 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossW +=
8832 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8833 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossJ +=
8834 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8835 : }
8836 : }
8837 : }
8838 :
8839 6544 : if (ZN1 > 0 && ZN2 > 0) {
8840 721 : auto const &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
8841 721 : auto const &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
8842 721 : CpAir = PsyCpAirFnW((zn1HB.airHumRat + zn2HB.airHumRat) / 2.0);
8843 721 : hg = Psychrometrics::PsyHgAirFnWTdb((zn1HB.airHumRat + zn2HB.airHumRat) / 2.0, (zn1HB.MAT + zn2HB.MAT) / 2.0);
8844 721 : if (zn1HB.MAT > zn2HB.MAT) {
8845 545 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn1HB.MAT - zn2HB.MAT));
8846 545 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainJ +=
8847 545 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant;
8848 : } else {
8849 176 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - zn1HB.MAT));
8850 176 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossJ +=
8851 176 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant;
8852 : }
8853 721 : if (zn1HB.airHumRat > zn2HB.airHumRat) {
8854 1360 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainW +=
8855 680 : (AirflowNetworkLinkSimu(i).FLOW * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg;
8856 680 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainJ +=
8857 680 : (AirflowNetworkLinkSimu(i).FLOW * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8858 : } else {
8859 82 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossW +=
8860 41 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg;
8861 41 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossJ +=
8862 41 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8863 : }
8864 721 : if (zn2HB.MAT > zn1HB.MAT) {
8865 136 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn2HB.MAT - zn1HB.MAT));
8866 136 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainJ +=
8867 136 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant;
8868 : } else {
8869 585 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - zn2HB.MAT));
8870 585 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossJ +=
8871 585 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant;
8872 : }
8873 721 : if (zn2HB.airHumRat > zn1HB.airHumRat) {
8874 10 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainW +=
8875 5 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg;
8876 5 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainJ +=
8877 5 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8878 : } else {
8879 1432 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossW +=
8880 716 : std::abs(AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg;
8881 716 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossJ +=
8882 716 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8883 : }
8884 : }
8885 : }
8886 : }
8887 :
8888 : // Assign data for report
8889 344 : if (distribution_simulated) {
8890 1385 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
8891 1041 : if (exchangeData(i).LeakSen > 0.0) {
8892 144 : AirflowNetworkReportData(i).LeakSenGainW = exchangeData(i).LeakSen;
8893 144 : AirflowNetworkReportData(i).LeakSenGainJ = exchangeData(i).LeakSen * ReportingConstant;
8894 : } else {
8895 897 : AirflowNetworkReportData(i).LeakSenLossW = -exchangeData(i).LeakSen;
8896 897 : AirflowNetworkReportData(i).LeakSenLossJ = -exchangeData(i).LeakSen * ReportingConstant;
8897 : }
8898 1041 : if (exchangeData(i).LeakLat > 0.0) {
8899 0 : AirflowNetworkReportData(i).LeakLatGainW = exchangeData(i).LeakLat * Lam;
8900 0 : AirflowNetworkReportData(i).LeakLatGainJ = exchangeData(i).LeakLat * Lam * ReportingConstant;
8901 : } else {
8902 1041 : AirflowNetworkReportData(i).LeakLatLossW = -exchangeData(i).LeakLat * Lam;
8903 1041 : AirflowNetworkReportData(i).LeakLatLossJ = -exchangeData(i).LeakLat * Lam * ReportingConstant;
8904 : }
8905 1041 : if (exchangeData(i).CondSen > 0.0) {
8906 380 : AirflowNetworkReportData(i).CondSenGainW = exchangeData(i).CondSen;
8907 380 : AirflowNetworkReportData(i).CondSenGainJ = exchangeData(i).CondSen * ReportingConstant;
8908 : } else {
8909 661 : AirflowNetworkReportData(i).CondSenLossW = -exchangeData(i).CondSen;
8910 661 : AirflowNetworkReportData(i).CondSenLossJ = -exchangeData(i).CondSen * ReportingConstant;
8911 : }
8912 1041 : if (exchangeData(i).DiffLat > 0.0) {
8913 339 : AirflowNetworkReportData(i).DiffLatGainW = exchangeData(i).DiffLat * Lam;
8914 339 : AirflowNetworkReportData(i).DiffLatGainJ = exchangeData(i).DiffLat * Lam * ReportingConstant;
8915 : } else {
8916 702 : AirflowNetworkReportData(i).DiffLatLossW = -exchangeData(i).DiffLat * Lam;
8917 702 : AirflowNetworkReportData(i).DiffLatLossJ = -exchangeData(i).DiffLat * Lam * ReportingConstant;
8918 : }
8919 1041 : if (exchangeData(i).RadGain < 0.0) {
8920 0 : AirflowNetworkReportData(i).RadGainW = -exchangeData(i).RadGain;
8921 0 : AirflowNetworkReportData(i).RadGainJ = -exchangeData(i).RadGain * ReportingConstant;
8922 : } else {
8923 1041 : AirflowNetworkReportData(i).RadLossW = exchangeData(i).RadGain;
8924 1041 : AirflowNetworkReportData(i).RadLossJ = exchangeData(i).RadGain * ReportingConstant;
8925 : }
8926 1041 : if (exchangeData(i).TotalSen > 0.0) {
8927 380 : AirflowNetworkReportData(i).TotalSenGainW = exchangeData(i).TotalSen;
8928 380 : AirflowNetworkReportData(i).TotalSenGainJ = exchangeData(i).TotalSen * ReportingConstant;
8929 : } else {
8930 661 : AirflowNetworkReportData(i).TotalSenLossW = -exchangeData(i).TotalSen;
8931 661 : AirflowNetworkReportData(i).TotalSenLossJ = -exchangeData(i).TotalSen * ReportingConstant;
8932 : }
8933 1041 : if (exchangeData(i).TotalLat > 0.0) {
8934 339 : AirflowNetworkReportData(i).TotalLatGainW = exchangeData(i).TotalLat * Lam;
8935 339 : AirflowNetworkReportData(i).TotalLatGainJ = exchangeData(i).TotalLat * Lam * ReportingConstant;
8936 : } else {
8937 702 : AirflowNetworkReportData(i).TotalLatLossW = -exchangeData(i).TotalLat * Lam;
8938 702 : AirflowNetworkReportData(i).TotalLatLossJ = -exchangeData(i).TotalLat * Lam * ReportingConstant;
8939 : }
8940 : }
8941 : }
8942 :
8943 : // Zone report
8944 :
8945 1385 : for (auto &e : AirflowNetworkZnRpt) {
8946 1041 : e.InfilVolume = 0.0;
8947 1041 : e.InfilMass = 0.0;
8948 1041 : e.InfilAirChangeRate = 0.0;
8949 1041 : e.VentilVolume = 0.0;
8950 1041 : e.VentilMass = 0.0;
8951 1041 : e.VentilAirChangeRate = 0.0;
8952 1041 : e.MixVolume = 0.0;
8953 1041 : e.MixMass = 0.0;
8954 344 : }
8955 :
8956 683 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
8957 339 : if (DisSysNumOfCVFs == 0) {
8958 0 : continue;
8959 : }
8960 339 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
8961 339 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
8962 339 : break;
8963 : }
8964 : }
8965 534 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
8966 195 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
8967 : // ON Cycle calculation
8968 195 : onceZoneFlag = false;
8969 780 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
8970 585 : if (AirflowNetworkNodeData(i).AirLoopNum > 0 && AirflowNetworkNodeData(i).AirLoopNum != AirLoopNum) {
8971 0 : continue;
8972 : }
8973 585 : if (AirflowNetworkNodeData(i).AirLoopNum == AirLoopNum) {
8974 390 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
8975 : }
8976 585 : if (AirflowNetworkNodeData(i).AirLoopNum == 0) {
8977 195 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
8978 : }
8979 585 : if (AirflowNetworkNodeData(i).AirLoopNum == 0 && onceZoneFlag(i)) {
8980 0 : continue;
8981 : }
8982 585 : AirflowNetworkReportData(i).MultiZoneInfiSenGainW *= RepOnOffFanRunTimeFraction;
8983 585 : AirflowNetworkReportData(i).MultiZoneInfiSenGainJ *= RepOnOffFanRunTimeFraction;
8984 585 : AirflowNetworkReportData(i).MultiZoneInfiSenLossW *= RepOnOffFanRunTimeFraction;
8985 585 : AirflowNetworkReportData(i).MultiZoneInfiSenLossJ *= RepOnOffFanRunTimeFraction;
8986 585 : AirflowNetworkReportData(i).MultiZoneInfiLatGainW *= RepOnOffFanRunTimeFraction;
8987 585 : AirflowNetworkReportData(i).MultiZoneInfiLatGainJ *= RepOnOffFanRunTimeFraction;
8988 585 : AirflowNetworkReportData(i).MultiZoneInfiLatLossW *= RepOnOffFanRunTimeFraction;
8989 585 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ *= RepOnOffFanRunTimeFraction;
8990 585 : AirflowNetworkReportData(i).MultiZoneVentSenGainW *= RepOnOffFanRunTimeFraction;
8991 585 : AirflowNetworkReportData(i).MultiZoneVentSenGainJ *= RepOnOffFanRunTimeFraction;
8992 585 : AirflowNetworkReportData(i).MultiZoneVentSenLossW *= RepOnOffFanRunTimeFraction;
8993 585 : AirflowNetworkReportData(i).MultiZoneVentSenLossJ *= RepOnOffFanRunTimeFraction;
8994 585 : AirflowNetworkReportData(i).MultiZoneVentLatGainW *= RepOnOffFanRunTimeFraction;
8995 585 : AirflowNetworkReportData(i).MultiZoneVentLatGainJ *= RepOnOffFanRunTimeFraction;
8996 585 : AirflowNetworkReportData(i).MultiZoneVentLatLossW *= RepOnOffFanRunTimeFraction;
8997 585 : AirflowNetworkReportData(i).MultiZoneVentLatLossJ *= RepOnOffFanRunTimeFraction;
8998 585 : AirflowNetworkReportData(i).MultiZoneMixSenGainW *= RepOnOffFanRunTimeFraction;
8999 585 : AirflowNetworkReportData(i).MultiZoneMixSenGainJ *= RepOnOffFanRunTimeFraction;
9000 585 : AirflowNetworkReportData(i).MultiZoneMixSenLossW *= RepOnOffFanRunTimeFraction;
9001 585 : AirflowNetworkReportData(i).MultiZoneMixSenLossJ *= RepOnOffFanRunTimeFraction;
9002 585 : AirflowNetworkReportData(i).MultiZoneMixLatGainW *= RepOnOffFanRunTimeFraction;
9003 585 : AirflowNetworkReportData(i).MultiZoneMixLatGainJ *= RepOnOffFanRunTimeFraction;
9004 585 : AirflowNetworkReportData(i).MultiZoneMixLatLossW *= RepOnOffFanRunTimeFraction;
9005 585 : AirflowNetworkReportData(i).MultiZoneMixLatLossJ *= RepOnOffFanRunTimeFraction;
9006 585 : if (AirflowNetworkNodeData(i).AirLoopNum == 0) {
9007 195 : onceZoneFlag(i) = true;
9008 : }
9009 : }
9010 : // Off Cycle addon
9011 195 : onceSurfFlag = false;
9012 3900 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
9013 3705 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9014 3705 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9015 3705 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
9016 3705 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
9017 : // Find a linkage from a zone to outdoors
9018 3705 : if (ZN1 > 0 && ZN2 == 0) {
9019 3315 : auto const &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
9020 3315 : if (AirflowNetworkNodeData(n).AirLoopNum > 0 && AirflowNetworkNodeData(n).AirLoopNum != AirLoopNum) {
9021 0 : continue;
9022 : }
9023 3315 : if (AirflowNetworkNodeData(n).AirLoopNum == AirLoopNum) {
9024 2535 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
9025 : }
9026 3315 : if (AirflowNetworkNodeData(n).AirLoopNum == 0) {
9027 780 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
9028 : }
9029 3315 : if (AirflowNetworkNodeData(n).AirLoopNum == 0 && onceSurfFlag(i)) {
9030 0 : continue;
9031 : }
9032 3315 : ReportingFraction = (1.0 - RepOnOffFanRunTimeFraction);
9033 3315 : Tamb = Zone(ZN1).OutDryBulbTemp;
9034 3315 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9035 6630 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9036 3315 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9037 3120 : if (Tamb > zn1HB.MAT) {
9038 2512 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainW +=
9039 1256 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * (1.0 - RepOnOffFanRunTimeFraction);
9040 1256 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainJ +=
9041 1256 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9042 : } else {
9043 3728 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossW +=
9044 1864 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * (1.0 - RepOnOffFanRunTimeFraction);
9045 1864 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossJ +=
9046 1864 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
9047 : }
9048 3120 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
9049 0 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainW +=
9050 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingFraction;
9051 0 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainJ +=
9052 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingConstant *
9053 : ReportingFraction;
9054 : } else {
9055 6240 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossW +=
9056 3120 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
9057 3120 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossJ +=
9058 3120 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9059 : ReportingFraction;
9060 : }
9061 : } else {
9062 195 : if (Tamb > zn1HB.MAT) {
9063 138 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainW +=
9064 69 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * (1.0 - RepOnOffFanRunTimeFraction);
9065 69 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainJ +=
9066 69 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9067 : } else {
9068 252 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossW +=
9069 126 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * (1.0 - RepOnOffFanRunTimeFraction);
9070 126 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossJ +=
9071 126 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
9072 : }
9073 195 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
9074 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainW +=
9075 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingFraction;
9076 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainJ +=
9077 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingConstant *
9078 : ReportingFraction;
9079 : } else {
9080 390 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossW +=
9081 195 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
9082 195 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossJ +=
9083 195 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9084 : ReportingFraction;
9085 : }
9086 : }
9087 3315 : if (AirflowNetworkNodeData(n).AirLoopNum == 0) {
9088 780 : onceSurfFlag(i) = true;
9089 : }
9090 : }
9091 3705 : if (ZN1 == 0 && ZN2 > 0) {
9092 0 : auto const &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
9093 0 : if (AirflowNetworkNodeData(M).AirLoopNum > 0 && AirflowNetworkNodeData(M).AirLoopNum != AirLoopNum) {
9094 0 : continue;
9095 : }
9096 0 : if (AirflowNetworkNodeData(M).AirLoopNum == AirLoopNum) {
9097 0 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
9098 : }
9099 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0) {
9100 0 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
9101 : }
9102 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0 && onceSurfFlag(i)) {
9103 0 : continue;
9104 : }
9105 0 : ReportingFraction = (1.0 - RepOnOffFanRunTimeFraction);
9106 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
9107 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9108 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9109 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9110 0 : if (Tamb > zn2HB.MAT) {
9111 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainW +=
9112 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingFraction;
9113 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainJ +=
9114 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9115 : } else {
9116 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossW +=
9117 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingFraction;
9118 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossJ +=
9119 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
9120 : }
9121 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
9122 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainW +=
9123 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingFraction;
9124 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainJ +=
9125 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingConstant *
9126 : ReportingFraction;
9127 : } else {
9128 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossW +=
9129 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
9130 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossJ +=
9131 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9132 : ReportingFraction;
9133 : }
9134 : } else {
9135 0 : if (Tamb > zn2HB.MAT) {
9136 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainW +=
9137 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingFraction;
9138 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainJ +=
9139 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9140 : } else {
9141 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossW +=
9142 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingFraction;
9143 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossJ +=
9144 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
9145 : }
9146 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
9147 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainW +=
9148 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingFraction;
9149 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainJ +=
9150 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingConstant *
9151 : ReportingFraction;
9152 : } else {
9153 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossW +=
9154 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
9155 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossJ +=
9156 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9157 : ReportingFraction;
9158 : }
9159 : }
9160 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0) {
9161 0 : onceSurfFlag(i) = true;
9162 : }
9163 : }
9164 :
9165 3705 : if (ZN1 > 0 && ZN2 > 0) {
9166 390 : auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
9167 390 : auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
9168 390 : ReportingFraction = (1.0 - MaxOnOffFanRunTimeFraction);
9169 390 : CpAir = PsyCpAirFnW(zn1HB.airHumRat);
9170 390 : if (zn1HB.MAT > zn2HB.MAT) {
9171 508 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainW +=
9172 254 : (linkReport1(i).FLOWOFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingFraction;
9173 254 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainJ +=
9174 254 : (linkReport1(i).FLOWOFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9175 : } else {
9176 272 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossW +=
9177 136 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingFraction;
9178 136 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossJ +=
9179 136 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9180 : }
9181 390 : if (zn1HB.airHumRat > zn2HB.airHumRat) {
9182 780 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainW +=
9183 390 : (linkReport1(i).FLOWOFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingFraction;
9184 390 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainJ +=
9185 390 : (linkReport1(i).FLOWOFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingConstant * ReportingFraction;
9186 : } else {
9187 0 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossW +=
9188 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingFraction;
9189 0 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossJ +=
9190 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingConstant * ReportingFraction;
9191 : }
9192 390 : CpAir = PsyCpAirFnW(zn2HB.airHumRat);
9193 390 : if (zn2HB.MAT > zn1HB.MAT) {
9194 272 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainW +=
9195 136 : (linkReport1(i).FLOW2OFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingFraction;
9196 136 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainJ +=
9197 136 : (linkReport1(i).FLOW2OFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9198 : } else {
9199 508 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossW +=
9200 254 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingFraction;
9201 254 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossJ +=
9202 254 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9203 : }
9204 :
9205 390 : if (zn2HB.airHumRat > zn1HB.airHumRat) {
9206 0 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainW +=
9207 0 : (linkReport1(i).FLOW2OFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingFraction;
9208 0 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainJ +=
9209 0 : (linkReport1(i).FLOW2OFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingConstant * ReportingFraction;
9210 : } else {
9211 780 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossW +=
9212 390 : std::abs(linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingFraction;
9213 390 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossJ +=
9214 390 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingConstant * ReportingFraction;
9215 : }
9216 : }
9217 : }
9218 : }
9219 : }
9220 :
9221 344 : if (!multizone_always_simulated) {
9222 0 : return;
9223 : }
9224 :
9225 1385 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) { // Start of zone loads report variable update loop ...
9226 1041 : auto &thisZoneHB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i);
9227 1041 : Tamb = Zone(i).OutDryBulbTemp;
9228 1041 : CpAir = PsyCpAirFnW(thisZoneHB.airHumRatAvg);
9229 1041 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.airHumRatAvg);
9230 :
9231 1041 : AirflowNetworkZnRpt(i).InfilMass = (exchangeData(i).SumMCp / CpAir) * ReportingConstant;
9232 1041 : AirflowNetworkZnRpt(i).InfilVolume = AirflowNetworkZnRpt(i).InfilMass / AirDensity;
9233 1041 : AirflowNetworkZnRpt(i).InfilAirChangeRate = AirflowNetworkZnRpt(i).InfilVolume / (TimeStepSys * Zone(i).Volume);
9234 1041 : AirflowNetworkZnRpt(i).VentilMass = (exchangeData(i).SumMVCp / CpAir) * ReportingConstant;
9235 1041 : AirflowNetworkZnRpt(i).VentilVolume = AirflowNetworkZnRpt(i).VentilMass / AirDensity;
9236 1041 : AirflowNetworkZnRpt(i).VentilAirChangeRate = AirflowNetworkZnRpt(i).VentilVolume / (TimeStepSys * Zone(i).Volume);
9237 1041 : AirflowNetworkZnRpt(i).MixMass = (exchangeData(i).SumMMCp / CpAir) * ReportingConstant;
9238 1041 : AirflowNetworkZnRpt(i).MixVolume = AirflowNetworkZnRpt(i).MixMass / AirDensity;
9239 : // save values for predefined report
9240 1041 : Real64 stdDensAFNInfilVolume = AirflowNetworkZnRpt(i).InfilMass / m_state.dataEnvrn->StdRhoAir;
9241 1041 : Real64 stdDensAFNNatVentVolume = AirflowNetworkZnRpt(i).VentilMass / m_state.dataEnvrn->StdRhoAir;
9242 1041 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolStdDen = stdDensAFNNatVentVolume;
9243 1041 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolTotalStdDen += stdDensAFNNatVentVolume;
9244 1041 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalStdDen += stdDensAFNInfilVolume;
9245 1041 : if (m_state.dataHeatBal->ZonePreDefRep(i).isOccupied) {
9246 339 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolTotalOccStdDen += stdDensAFNNatVentVolume;
9247 339 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalOccStdDen += stdDensAFNInfilVolume;
9248 339 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalOcc +=
9249 339 : (AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) * Zone(i).Multiplier * Zone(i).ListMultiplier;
9250 339 : if ((AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) <
9251 339 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolMin) {
9252 64 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolMin =
9253 64 : (AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) * Zone(i).Multiplier * Zone(i).ListMultiplier;
9254 : }
9255 : }
9256 :
9257 1041 : Real64 H2OHtOfVap = Psychrometrics::PsyHgAirFnWTdb(m_state.dataEnvrn->OutHumRat, Zone(i).OutDryBulbTemp);
9258 1041 : AirflowNetworkZnRpt(i).InletMass = 0;
9259 1041 : AirflowNetworkZnRpt(i).OutletMass = 0;
9260 1041 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).IsControlled) {
9261 1017 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumInletNodes; ++j) {
9262 678 : AirflowNetworkZnRpt(i).InletMass +=
9263 678 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).InletNode(j)).MassFlowRate * ReportingConstant;
9264 : }
9265 1017 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumExhaustNodes; ++j) {
9266 678 : AirflowNetworkZnRpt(i).OutletMass +=
9267 678 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).ExhaustNode(j)).MassFlowRate * ReportingConstant;
9268 : }
9269 678 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumReturnNodes; ++j) {
9270 339 : AirflowNetworkZnRpt(i).OutletMass +=
9271 339 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).ReturnNode(j)).MassFlowRate * ReportingConstant;
9272 : }
9273 : }
9274 1041 : AirflowNetworkZnRpt(i).ExfilMass = AirflowNetworkZnRpt(i).InfilMass + AirflowNetworkZnRpt(i).VentilMass + AirflowNetworkZnRpt(i).MixMass +
9275 1041 : AirflowNetworkZnRpt(i).InletMass - AirflowNetworkZnRpt(i).OutletMass;
9276 1041 : AirflowNetworkZnRpt(i).ExfilSensiLoss = AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * (thisZoneHB.MAT - Tamb) * CpAir;
9277 2082 : AirflowNetworkZnRpt(i).ExfilLatentLoss =
9278 1041 : AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * (thisZoneHB.airHumRat - m_state.dataEnvrn->OutHumRat) * H2OHtOfVap;
9279 1041 : AirflowNetworkZnRpt(i).ExfilTotalLoss = AirflowNetworkZnRpt(i).ExfilSensiLoss + AirflowNetworkZnRpt(i).ExfilLatentLoss;
9280 :
9281 1041 : m_state.dataHeatBal->ZoneTotalExfiltrationHeatLoss += AirflowNetworkZnRpt(i).ExfilTotalLoss * ReportingConstant;
9282 : } // ... end of zone loads report variable update loop.
9283 :
9284 : // Rewrite AirflowNetwork airflow rate
9285 683 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9286 339 : if (DisSysNumOfCVFs == 0) {
9287 0 : continue;
9288 : }
9289 339 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9290 339 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9291 339 : break;
9292 : }
9293 : }
9294 339 : onceSurfFlag = false;
9295 :
9296 6780 : for (i = 1; i <= NumOfLinksMultiZone; ++i) {
9297 6441 : if (onceSurfFlag(i)) {
9298 0 : continue;
9299 : }
9300 6441 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9301 6441 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkLinkageData(i).NodeHeights[0]);
9302 6441 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, Tamb, m_state.dataEnvrn->OutHumRat);
9303 10146 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
9304 3705 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
9305 3705 : linkReport(i).VolFLOW = linkReport1(i).FLOW / AirDensity;
9306 3705 : linkReport(i).VolFLOW2 = linkReport1(i).FLOW2 / AirDensity;
9307 : } else {
9308 2736 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity;
9309 2736 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity;
9310 : }
9311 6441 : onceSurfFlag(i) = true;
9312 : }
9313 : }
9314 :
9315 339 : if (AirflowNetworkNumOfLinks > NumOfLinksMultiZone) {
9316 6780 : for (i = NumOfLinksMultiZone + 1; i <= AirflowNetworkNumOfLinks; ++i) {
9317 6441 : if (onceSurfFlag(i)) {
9318 0 : continue;
9319 : }
9320 6441 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9321 6441 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9322 6441 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9323 : AirDensity =
9324 6441 : PsyRhoAirFnPbTdbW(m_state,
9325 6441 : (AirflowNetworkNodeSimu(n).PZ + AirflowNetworkNodeSimu(M).PZ) / 2.0 + m_state.dataEnvrn->OutBaroPress,
9326 6441 : (AirflowNetworkNodeSimu(n).TZ + AirflowNetworkNodeSimu(M).TZ) / 2.0,
9327 6441 : (AirflowNetworkNodeSimu(n).WZ + AirflowNetworkNodeSimu(M).WZ) / 2.0);
9328 10146 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
9329 3705 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
9330 3705 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity * (1.0 - LoopOnOffFanRunTimeFraction(AirLoopNum));
9331 3705 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity * (1.0 - LoopOnOffFanRunTimeFraction(AirLoopNum));
9332 3705 : onceSurfFlag(i) = true;
9333 : } else {
9334 2736 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity;
9335 2736 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity;
9336 : }
9337 : }
9338 : }
9339 : }
9340 : }
9341 : }
9342 :
9343 16856 : void Solver::update(ObjexxFCL::Optional_bool_const FirstHVACIteration) // True when solution technique on first iteration
9344 : {
9345 :
9346 : // SUBROUTINE INFORMATION:
9347 : // AUTHOR Lixing Gu
9348 : // DATE WRITTEN 12/10/05
9349 : // MODIFIED na
9350 : // RE-ENGINEERED na
9351 :
9352 : // PURPOSE OF THIS SUBROUTINE:
9353 : // This subroutine update variables used in the AirflowNetwork model.
9354 :
9355 : // Using/Aliasing
9356 16856 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
9357 : using HVAC::VerySmallMassFlow;
9358 :
9359 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9360 : int n;
9361 : int M;
9362 : int ZN1;
9363 : int ZN2;
9364 : int Node1;
9365 : int Node2;
9366 : Real64 CpAir;
9367 : Real64 Qsen;
9368 : Real64 Qlat;
9369 : Real64 AirDensity;
9370 : Real64 Tamb;
9371 : Real64 PartLoadRatio;
9372 : Real64 OnOffRatio;
9373 : Real64 NodeMass;
9374 : Real64 AFNMass;
9375 :
9376 16856 : auto &Zone(m_state.dataHeatBal->Zone);
9377 16856 : auto &Node(m_state.dataLoopNodes->Node);
9378 :
9379 67427 : for (auto &e : exchangeData) {
9380 50571 : e.SumMCp = 0.0;
9381 50571 : e.SumMCpT = 0.0;
9382 50571 : e.SumMVCp = 0.0;
9383 50571 : e.SumMVCpT = 0.0;
9384 50571 : e.SumMHr = 0.0;
9385 50571 : e.SumMHrW = 0.0;
9386 50571 : e.SumMMCp = 0.0;
9387 50571 : e.SumMMCpT = 0.0;
9388 50571 : e.SumMMHr = 0.0;
9389 50571 : e.SumMMHrW = 0.0;
9390 16856 : }
9391 16856 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9392 0 : for (auto &e : exchangeData) {
9393 0 : e.SumMHrCO = 0.0;
9394 0 : e.SumMMHrCO = 0.0;
9395 0 : }
9396 : }
9397 16856 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9398 0 : for (auto &e : exchangeData) {
9399 0 : e.SumMHrGC = 0.0;
9400 0 : e.SumMMHrGC = 0.0;
9401 0 : }
9402 : }
9403 :
9404 : // Calculate sensible and latent loads in each zone from multizone airflows
9405 16856 : if (multizone_always_simulated ||
9406 0 : (simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation && AirflowNetworkFanActivated)) {
9407 337108 : for (int i = 1; i <= NumOfLinksMultiZone; ++i) { // Multizone airflow energy
9408 320252 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9409 320252 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9410 320252 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
9411 320252 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
9412 320252 : if (ZN1 > 0 && ZN2 == 0) {
9413 : // Find a linkage from outdoors to this zone
9414 286523 : Tamb = Zone(ZN1).OutDryBulbTemp;
9415 286523 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9416 573025 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9417 286502 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9418 269656 : exchangeData(ZN1).SumMCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9419 269656 : exchangeData(ZN1).SumMCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * Tamb;
9420 : } else {
9421 16867 : exchangeData(ZN1).SumMVCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9422 16867 : exchangeData(ZN1).SumMVCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * Tamb;
9423 : }
9424 286523 : exchangeData(ZN1).SumMHr += AirflowNetworkLinkSimu(i).FLOW2;
9425 286523 : exchangeData(ZN1).SumMHrW += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataEnvrn->OutHumRat;
9426 286523 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9427 0 : exchangeData(ZN1).SumMHrCO += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataContaminantBalance->OutdoorCO2;
9428 : }
9429 286523 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9430 0 : exchangeData(ZN1).SumMHrGC += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataContaminantBalance->OutdoorGC;
9431 : }
9432 : }
9433 320252 : if (ZN1 == 0 && ZN2 > 0) {
9434 : // Find a linkage from outdoors to this zone
9435 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
9436 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9437 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9438 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9439 0 : exchangeData(ZN2).SumMCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9440 0 : exchangeData(ZN2).SumMCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * Tamb;
9441 : } else {
9442 0 : exchangeData(ZN2).SumMVCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9443 0 : exchangeData(ZN2).SumMVCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * Tamb;
9444 : }
9445 0 : exchangeData(ZN2).SumMHr += AirflowNetworkLinkSimu(i).FLOW;
9446 0 : exchangeData(ZN2).SumMHrW += AirflowNetworkLinkSimu(i).FLOW * m_state.dataEnvrn->OutHumRat;
9447 0 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9448 0 : exchangeData(ZN2).SumMHrCO += AirflowNetworkLinkSimu(i).FLOW * m_state.dataContaminantBalance->OutdoorCO2;
9449 : }
9450 0 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9451 0 : exchangeData(ZN2).SumMHrGC += AirflowNetworkLinkSimu(i).FLOW * m_state.dataContaminantBalance->OutdoorGC;
9452 : }
9453 : }
9454 320252 : if (ZN1 > 0 && ZN2 > 0) {
9455 : // Find a linkage from outdoors to this zone
9456 33729 : CpAir = PsyCpAirFnW(ANZW(ZN1));
9457 33729 : exchangeData(ZN2).SumMMCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9458 33729 : exchangeData(ZN2).SumMMCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * ANZT(ZN1);
9459 33729 : exchangeData(ZN2).SumMMHr += AirflowNetworkLinkSimu(i).FLOW;
9460 33729 : exchangeData(ZN2).SumMMHrW += AirflowNetworkLinkSimu(i).FLOW * ANZW(ZN1);
9461 33729 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9462 0 : exchangeData(ZN2).SumMMHrCO += AirflowNetworkLinkSimu(i).FLOW * ANCO(ZN1);
9463 : }
9464 33729 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9465 0 : exchangeData(ZN2).SumMMHrGC += AirflowNetworkLinkSimu(i).FLOW * ANGC(ZN1);
9466 : }
9467 33729 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9468 33729 : exchangeData(ZN1).SumMMCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9469 33729 : exchangeData(ZN1).SumMMCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * ANZT(ZN2);
9470 33729 : exchangeData(ZN1).SumMMHr += AirflowNetworkLinkSimu(i).FLOW2;
9471 33729 : exchangeData(ZN1).SumMMHrW += AirflowNetworkLinkSimu(i).FLOW2 * ANZW(ZN2);
9472 33729 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9473 0 : exchangeData(ZN1).SumMMHrCO += AirflowNetworkLinkSimu(i).FLOW2 * ANCO(ZN2);
9474 : }
9475 33729 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9476 0 : exchangeData(ZN1).SumMMHrGC += AirflowNetworkLinkSimu(i).FLOW2 * ANGC(ZN2);
9477 : }
9478 : }
9479 : }
9480 : }
9481 : // End of update of multizone airflow calculations
9482 :
9483 : // Initialize these values
9484 67427 : for (auto &e : exchangeData) {
9485 50571 : e.LeakSen = 0.0;
9486 50571 : e.CondSen = 0.0;
9487 50571 : e.LeakLat = 0.0;
9488 50571 : e.DiffLat = 0.0;
9489 50571 : e.MultiZoneSen = 0.0;
9490 50571 : e.MultiZoneLat = 0.0;
9491 50571 : e.RadGain = 0.0;
9492 16856 : }
9493 :
9494 : // Rewrite AirflowNetwork airflow rate
9495 337108 : for (int i = 1; i <= NumOfLinksMultiZone; ++i) {
9496 320252 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkLinkageData(i).NodeHeights[0]);
9497 320252 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, Tamb, m_state.dataEnvrn->OutHumRat);
9498 320252 : AirflowNetworkLinkSimu(i).VolFLOW = AirflowNetworkLinkSimu(i).FLOW / AirDensity;
9499 320252 : AirflowNetworkLinkSimu(i).VolFLOW2 = AirflowNetworkLinkSimu(i).FLOW2 / AirDensity;
9500 : }
9501 :
9502 657440 : for (std::size_t i = 0; i < linkReport.size(); ++i) {
9503 640584 : auto &r = linkReport[i];
9504 640584 : auto const &s = AirflowNetworkLinkSimu[i];
9505 640584 : r.FLOW = s.FLOW;
9506 640584 : r.FLOW2 = s.FLOW2;
9507 640584 : r.VolFLOW = s.VolFLOW;
9508 640584 : r.VolFLOW2 = s.VolFLOW2;
9509 : }
9510 :
9511 : // Save zone loads from multizone calculation for later summation
9512 16856 : bool OnOffFanFlag = false;
9513 16859 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
9514 16857 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
9515 16854 : OnOffFanFlag = true;
9516 16854 : break;
9517 : }
9518 : }
9519 16856 : if (present(FirstHVACIteration)) {
9520 16853 : if (FirstHVACIteration && OnOffFanFlag) {
9521 2820 : multiExchangeData = exchangeData;
9522 11280 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
9523 8460 : nodeReport(i).PZ = AirflowNetworkNodeSimu(i).PZ;
9524 8460 : nodeReport(i).PZOFF = AirflowNetworkNodeSimu(i).PZ;
9525 8460 : nodeReport(i).PZON = 0.0;
9526 : }
9527 56400 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
9528 53580 : linkReport1(i).FLOW = AirflowNetworkLinkSimu(i).FLOW;
9529 53580 : linkReport1(i).FLOW2 = AirflowNetworkLinkSimu(i).FLOW2;
9530 53580 : linkReport1(i).VolFLOW = AirflowNetworkLinkSimu(i).VolFLOW;
9531 53580 : linkReport1(i).VolFLOW2 = AirflowNetworkLinkSimu(i).VolFLOW2;
9532 53580 : linkReport1(i).FLOWOFF = AirflowNetworkLinkSimu(i).FLOW;
9533 53580 : linkReport1(i).FLOW2OFF = AirflowNetworkLinkSimu(i).FLOW2;
9534 53580 : linkReport1(i).VolFLOWOFF = AirflowNetworkLinkSimu(i).VolFLOW;
9535 53580 : linkReport1(i).VolFLOW2OFF = AirflowNetworkLinkSimu(i).VolFLOW2;
9536 53580 : linkReport1(i).DP = AirflowNetworkLinkSimu(i).DP;
9537 53580 : linkReport1(i).DPOFF = AirflowNetworkLinkSimu(i).DP;
9538 53580 : linkReport1(i).DPON = 0.0;
9539 : }
9540 : }
9541 : }
9542 :
9543 16856 : if (!AirflowNetworkFanActivated && distribution_simulated) {
9544 87080 : for (int i = NumOfNodesMultiZone + NumOfNodesIntraZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
9545 81279 : AirflowNetworkNodeSimu(i).PZ = 0.0;
9546 : }
9547 116107 : for (int i = AirflowNetworkNumOfSurfaces + 1; i <= AirflowNetworkNumOfLinks; ++i) {
9548 110306 : AirflowNetworkLinkSimu(i).DP = 0.0;
9549 110306 : linkReport(i).FLOW = 0.0;
9550 110306 : linkReport(i).FLOW2 = 0.0;
9551 110306 : linkReport(i).VolFLOW = 0.0;
9552 110306 : linkReport(i).VolFLOW2 = 0.0;
9553 : }
9554 : }
9555 :
9556 16856 : if (!(AirflowNetworkFanActivated && distribution_simulated)) {
9557 5802 : return;
9558 : }
9559 :
9560 11054 : if (distribution_simulated) {
9561 221080 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
9562 210026 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9563 210026 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9564 210026 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
9565 210026 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
9566 : // Find a linkage from a zone to outdoors
9567 210026 : if (ZN1 > 0 && ZN2 == 0) {
9568 187918 : Tamb = Zone(ZN1).OutDryBulbTemp;
9569 187918 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9570 187918 : exchangeData(ZN1).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - ANZT(ZN1));
9571 187918 : exchangeData(ZN1).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - ANZW(ZN1));
9572 : }
9573 210026 : if (ZN1 == 0 && ZN2 > 0) {
9574 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
9575 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9576 0 : exchangeData(ZN2).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - ANZT(ZN2));
9577 0 : exchangeData(ZN2).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - ANZW(ZN2));
9578 : }
9579 :
9580 210026 : if (ZN1 > 0 && ZN2 > 0) {
9581 22108 : if (AirflowNetworkLinkSimu(i).FLOW > 0) { // Flow from ZN1 to ZN2
9582 11502 : CpAir = PsyCpAirFnW(ANZW(ZN1));
9583 11502 : exchangeData(ZN2).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW * CpAir * (ANZT(ZN1) - ANZT(ZN2));
9584 11502 : exchangeData(ZN2).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW * (ANZW(ZN1) - ANZW(ZN2));
9585 11502 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9586 11502 : exchangeData(ZN1).MultiZoneSen += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * (ANZT(ZN2) - ANZT(ZN1));
9587 11502 : exchangeData(ZN1).MultiZoneLat += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * (ANZW(ZN2) - ANZW(ZN1));
9588 : } else {
9589 10606 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9590 10606 : exchangeData(ZN1).MultiZoneSen += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * (ANZT(ZN2) - ANZT(ZN1));
9591 10606 : exchangeData(ZN1).MultiZoneLat += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * (ANZW(ZN2) - ANZW(ZN1));
9592 : }
9593 : }
9594 : }
9595 : }
9596 :
9597 : int AirLoopNum;
9598 : int FanNum;
9599 11054 : Real64 MaxPartLoadRatio = 0.0;
9600 11054 : Real64 OnOffFanRunTimeFraction = 0.0;
9601 11054 : MaxOnOffFanRunTimeFraction = 0.0;
9602 22108 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9603 11054 : MaxPartLoadRatio = max(MaxPartLoadRatio, m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio);
9604 11054 : MaxOnOffFanRunTimeFraction = max(MaxOnOffFanRunTimeFraction, LoopOnOffFanRunTimeFraction(AirLoopNum));
9605 : }
9606 22108 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9607 11054 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9608 11054 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9609 11054 : break;
9610 : }
9611 : }
9612 11054 : PartLoadRatio = 1.0;
9613 11054 : LoopPartLoadRatio(AirLoopNum) = 1.0;
9614 11054 : OnOffFanRunTimeFraction = 1.0;
9615 11054 : LoopOnOffFanRunTimeFraction(AirLoopNum) = 1.0;
9616 : // Calculate the part load ratio, can't be greater than 1 for a simple ONOFF fan
9617 11054 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff &&
9618 22108 : Node(DisSysCompCVFData(FanNum).InletNode).MassFlowRate > VerySmallMassFlow &&
9619 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling) {
9620 : // Hard code here
9621 11054 : PartLoadRatio = m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
9622 11054 : LoopPartLoadRatio(AirLoopNum) = m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
9623 11054 : OnOffFanRunTimeFraction = max(m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF,
9624 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopOnOffFanRTF,
9625 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF);
9626 11054 : LoopOnOffFanRunTimeFraction(AirLoopNum) = max(m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF,
9627 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopOnOffFanRTF,
9628 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF);
9629 : }
9630 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0;
9631 :
9632 11054 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopPartLoadRatio(AirLoopNum) < 1.0) {
9633 197340 : for (std::size_t i = 0; i < linkReport.size(); ++i) {
9634 192280 : auto &r(linkReport[i]);
9635 192280 : auto const &s(AirflowNetworkLinkSimu[i]);
9636 192280 : auto const &t(AirflowNetworkLinkageData[i]);
9637 192280 : if (t.AirLoopNum == AirLoopNum) {
9638 96140 : r.FLOW = s.FLOW * LoopPartLoadRatio(AirLoopNum);
9639 96140 : r.FLOW2 = s.FLOW2 * LoopPartLoadRatio(AirLoopNum);
9640 96140 : r.VolFLOW = s.VolFLOW * LoopPartLoadRatio(AirLoopNum);
9641 96140 : r.VolFLOW2 = s.VolFLOW2 * LoopPartLoadRatio(AirLoopNum);
9642 : }
9643 192280 : if (t.AirLoopNum == 0) {
9644 96140 : r.FLOW = s.FLOW * MaxPartLoadRatio;
9645 96140 : r.FLOW2 = s.FLOW2 * MaxPartLoadRatio;
9646 96140 : r.VolFLOW = s.VolFLOW * MaxPartLoadRatio;
9647 96140 : r.VolFLOW2 = s.VolFLOW2 * MaxPartLoadRatio;
9648 : }
9649 : }
9650 : }
9651 : }
9652 :
9653 : // One time warning
9654 11054 : if (UpdateAirflowNetworkMyOneTimeFlag) {
9655 22108 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9656 11054 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9657 11054 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9658 11054 : break;
9659 : }
9660 : }
9661 22108 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff &&
9662 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Continuous) {
9663 0 : OnOffRatio = std::abs((m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate -
9664 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate) /
9665 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate);
9666 0 : if (OnOffRatio > 0.1) {
9667 0 : ShowWarningError(m_state,
9668 : "The absolute percent difference of supply air mass flow rate between HVAC operation and No HVAC operation "
9669 : "is above 10% with fan operation mode = ContFanCycCoil.");
9670 0 : ShowContinueError(m_state,
9671 : "The added zone loads using the AirflowNetwork model may not be accurate because the zone loads are "
9672 : "calculated based on the mass flow rate during HVAC operation.");
9673 0 : ShowContinueError(
9674 : m_state,
9675 0 : format("The mass flow rate during HVAC operation = {:.2R} The mass flow rate during no HVAC operation = {:.2R}",
9676 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate,
9677 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate));
9678 0 : UpdateAirflowNetworkMyOneTimeFlag = false;
9679 : }
9680 : }
9681 : }
9682 : }
9683 :
9684 : // Check mass flow differences in the zone inlet zones and splitter nodes between node and AFN links
9685 11054 : if (UpdateAirflowNetworkMyOneTimeFlag1) {
9686 1 : if ((!VAVSystem) && m_state.dataGlobal->DisplayExtraWarnings) {
9687 0 : bool WriteFlag = false;
9688 0 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9689 0 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9690 0 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9691 0 : if (AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::SPI ||
9692 0 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::SPO ||
9693 0 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::ZIN) {
9694 : int Node3;
9695 0 : if (AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::SPI) {
9696 0 : Node3 = Node1;
9697 : } else {
9698 0 : Node3 = Node2;
9699 : }
9700 0 : if (AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::ZIN) {
9701 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::Invalid) {
9702 0 : continue;
9703 : }
9704 : }
9705 0 : NodeMass = Node(AirflowNetworkNodeData(Node3).EPlusNodeNum).MassFlowRate;
9706 0 : AFNMass = AirflowNetworkLinkSimu(i).FLOW;
9707 0 : if (NodeMass > 0.0 && AFNMass > NodeMass + 0.01) {
9708 0 : ShowWarningError(m_state,
9709 0 : "The mass flow rate difference is found between System Node = '" +
9710 0 : m_state.dataLoopNodes->NodeID(AirflowNetworkNodeData(Node3).EPlusNodeNum) + "' and AFN Link = '" +
9711 0 : AirflowNetworkLinkageData(i).Name + "'.");
9712 0 : ShowContinueError(m_state,
9713 0 : format("The system node max mass flow rate = {:.3R} kg/s. The AFN node mass flow rate = {:.3R} kg.s.",
9714 : NodeMass,
9715 : AFNMass));
9716 0 : WriteFlag = true;
9717 : }
9718 : }
9719 : }
9720 0 : UpdateAirflowNetworkMyOneTimeFlag1 = false;
9721 0 : if (WriteFlag) {
9722 0 : ShowWarningError(m_state,
9723 : "Please adjust the rate of Maximum Air Flow Rate field in the terminal objects or duct pressure resistance.");
9724 : }
9725 : } else {
9726 1 : UpdateAirflowNetworkMyOneTimeFlag1 = false;
9727 : }
9728 : }
9729 :
9730 : // Assign airflows to EPLus nodes
9731 431106 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9732 718510 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC ||
9733 298458 : AirflowNetworkLinkageData(i).VAVTermDamper) {
9734 : // Exclude envelope leakage Crack element
9735 121594 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9736 121594 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9737 :
9738 121594 : int j = AirflowNetworkNodeData(Node1).EPlusNodeNum;
9739 121594 : if (j > 0 && AirflowNetworkNodeData(Node1).EPlusZoneNum == 0) {
9740 66324 : Node(j).MassFlowRate = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node1).AirLoopNum);
9741 66324 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
9742 0 : Node(j).MassFlowRate = 0.0;
9743 : }
9744 132648 : if (!(AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::DIN ||
9745 66324 : AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::DOU)) {
9746 66324 : Node(j).MassFlowRateMaxAvail = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node1).AirLoopNum);
9747 66324 : Node(j).MassFlowRateMax = AirflowNetworkLinkSimu(i).FLOW;
9748 : }
9749 : }
9750 :
9751 121594 : j = AirflowNetworkNodeData(Node2).EPlusNodeNum;
9752 121594 : if (j > 0) {
9753 77378 : Node(j).MassFlowRate = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node2).AirLoopNum);
9754 77378 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
9755 0 : Node(j).MassFlowRate = 0.0;
9756 : }
9757 154756 : if (!(AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::DIN ||
9758 77378 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::DOU)) {
9759 77378 : Node(j).MassFlowRateMaxAvail = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node2).AirLoopNum);
9760 77378 : Node(j).MassFlowRateMax = AirflowNetworkLinkSimu(i).FLOW;
9761 : }
9762 : }
9763 : }
9764 : }
9765 :
9766 : // Assign AirflowNetwork nodal values to Node array
9767 386890 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
9768 375836 : int j = AirflowNetworkNodeData(i).EPlusNodeNum;
9769 375836 : if (j > 0) {
9770 121594 : Node(j).Enthalpy = PsyHFnTdbW(AirflowNetworkNodeSimu(i).TZ, AirflowNetworkNodeSimu(i).WZ);
9771 121594 : Node(j).Temp = AirflowNetworkNodeSimu(i).TZ;
9772 121594 : Node(j).HumRat = AirflowNetworkNodeSimu(i).WZ;
9773 121594 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9774 0 : Node(j).CO2 = AirflowNetworkNodeSimu(i).CO2Z;
9775 : }
9776 121594 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9777 0 : Node(j).GenContam = AirflowNetworkNodeSimu(i).GCZ;
9778 : }
9779 : }
9780 : }
9781 :
9782 : // Calculate sensible loads from forced air flow
9783 431106 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9784 420052 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9785 420052 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9786 420052 : CpAir = PsyCpAirFnW((AirflowNetworkNodeSimu(Node1).WZ + AirflowNetworkNodeSimu(Node2).WZ) / 2.0);
9787 : // Calculate sensible loads from duct conduction losses and loads from duct radiation
9788 497430 : if (AirflowNetworkLinkageData(i).ZoneNum > 0 &&
9789 77378 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC) {
9790 77378 : Qsen = AirflowNetworkLinkSimu(i).FLOW * CpAir * (AirflowNetworkNodeSimu(Node2).TZ - AirflowNetworkNodeSimu(Node1).TZ);
9791 77378 : if (AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum != 0) {
9792 0 : auto const &DuctRadObj(AirflowNetworkLinkageViewFactorData(AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum));
9793 0 : Qsen -= DuctRadObj.QRad;
9794 0 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).RadGain -= DuctRadObj.QRad;
9795 : }
9796 : // When the Airloop is shut off, no duct sensible losses
9797 77378 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
9798 0 : Qsen = 0.0;
9799 : }
9800 77378 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).CondSen -= Qsen;
9801 : }
9802 : // Calculate sensible leakage losses
9803 840104 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::PLR ||
9804 420052 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::ELR) {
9805 : // Calculate supply leak sensible losses
9806 55270 : if ((AirflowNetworkNodeData(Node2).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node1).EPlusNodeNum == 0) &&
9807 11054 : (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
9808 11054 : ZN2 = AirflowNetworkNodeData(Node2).EPlusZoneNum;
9809 11054 : Qsen = AirflowNetworkLinkSimu(i).FLOW * CpAir * (AirflowNetworkNodeSimu(Node1).TZ - AirflowNetworkNodeSimu(Node2).TZ);
9810 11054 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
9811 0 : Qsen = 0.0;
9812 : }
9813 11054 : exchangeData(ZN2).LeakSen += Qsen;
9814 : }
9815 66324 : if ((AirflowNetworkNodeData(Node1).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node2).EPlusNodeNum == 0) &&
9816 22108 : (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
9817 0 : ZN1 = AirflowNetworkNodeData(Node1).EPlusZoneNum;
9818 0 : Qsen = AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (AirflowNetworkNodeSimu(Node2).TZ - AirflowNetworkNodeSimu(Node1).TZ);
9819 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
9820 0 : Qsen = 0.0;
9821 : }
9822 0 : exchangeData(ZN1).LeakSen += Qsen;
9823 : }
9824 : }
9825 : }
9826 :
9827 : // Calculate latent loads from forced air flow
9828 431106 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9829 420052 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9830 420052 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9831 : // Calculate latent loads from duct conduction losses
9832 497430 : if (AirflowNetworkLinkageData(i).ZoneNum > 0 &&
9833 77378 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC) {
9834 77378 : Qlat = AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node2).WZ - AirflowNetworkNodeSimu(Node1).WZ);
9835 77378 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
9836 0 : Qlat = 0.0;
9837 : }
9838 77378 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).DiffLat -= Qlat;
9839 : }
9840 : // Calculate latent leakage losses
9841 840104 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::PLR ||
9842 420052 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::ELR) {
9843 : // Calculate supply leak latent losses
9844 55270 : if ((AirflowNetworkNodeData(Node2).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node1).EPlusNodeNum == 0) &&
9845 11054 : (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
9846 11054 : ZN2 = AirflowNetworkNodeData(Node2).EPlusZoneNum;
9847 11054 : Qlat = AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).WZ - AirflowNetworkNodeSimu(Node2).WZ);
9848 11054 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
9849 0 : Qlat = 0.0;
9850 : }
9851 11054 : exchangeData(ZN2).LeakLat += Qlat;
9852 11054 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9853 0 : exchangeData(ZN2).TotalCO2 +=
9854 0 : AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).CO2Z - AirflowNetworkNodeSimu(Node2).CO2Z);
9855 : }
9856 11054 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9857 0 : exchangeData(ZN2).TotalGC +=
9858 0 : AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).GCZ - AirflowNetworkNodeSimu(Node2).GCZ);
9859 : }
9860 : }
9861 66324 : if ((AirflowNetworkNodeData(Node1).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node2).EPlusNodeNum == 0) &&
9862 22108 : (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
9863 0 : ZN1 = AirflowNetworkNodeData(Node1).EPlusZoneNum;
9864 0 : Qlat = AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).WZ - AirflowNetworkNodeSimu(Node1).WZ);
9865 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
9866 0 : Qlat = 0.0;
9867 : }
9868 0 : exchangeData(ZN1).LeakLat += Qlat;
9869 0 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9870 0 : exchangeData(ZN1).TotalCO2 +=
9871 0 : AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).CO2Z - AirflowNetworkNodeSimu(Node1).CO2Z);
9872 : }
9873 0 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9874 0 : exchangeData(ZN1).TotalGC +=
9875 0 : AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).GCZ - AirflowNetworkNodeSimu(Node1).GCZ);
9876 : }
9877 : }
9878 : }
9879 : }
9880 :
9881 : // Sum all the loads
9882 44216 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9883 33162 : exchangeData(i).TotalSen = exchangeData(i).LeakSen + exchangeData(i).CondSen + exchangeData(i).RadGain;
9884 33162 : exchangeData(i).TotalLat = exchangeData(i).LeakLat + exchangeData(i).DiffLat;
9885 : }
9886 :
9887 : // Simple ONOFF fan
9888 22108 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9889 11054 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9890 11054 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9891 11054 : break;
9892 : }
9893 : }
9894 11054 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && OnOffFanRunTimeFraction < 1.0) {
9895 20244 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9896 15183 : exchangeData(i).MultiZoneSen *= OnOffFanRunTimeFraction;
9897 15183 : exchangeData(i).MultiZoneLat *= OnOffFanRunTimeFraction;
9898 15183 : exchangeData(i).LeakSen *= OnOffFanRunTimeFraction;
9899 15183 : exchangeData(i).LeakLat *= OnOffFanRunTimeFraction;
9900 15183 : exchangeData(i).CondSen *= OnOffFanRunTimeFraction;
9901 15183 : exchangeData(i).DiffLat *= OnOffFanRunTimeFraction;
9902 15183 : exchangeData(i).RadGain *= OnOffFanRunTimeFraction;
9903 15183 : exchangeData(i).TotalSen *= OnOffFanRunTimeFraction;
9904 15183 : exchangeData(i).TotalLat *= OnOffFanRunTimeFraction;
9905 15183 : exchangeData(i).SumMCp *= OnOffFanRunTimeFraction;
9906 15183 : exchangeData(i).SumMCpT *= OnOffFanRunTimeFraction;
9907 15183 : exchangeData(i).SumMVCp *= OnOffFanRunTimeFraction;
9908 15183 : exchangeData(i).SumMVCpT *= OnOffFanRunTimeFraction;
9909 15183 : exchangeData(i).SumMHr *= OnOffFanRunTimeFraction;
9910 15183 : exchangeData(i).SumMHrW *= OnOffFanRunTimeFraction;
9911 15183 : exchangeData(i).SumMMCp *= OnOffFanRunTimeFraction;
9912 15183 : exchangeData(i).SumMMCpT *= OnOffFanRunTimeFraction;
9913 15183 : exchangeData(i).SumMMHr *= OnOffFanRunTimeFraction;
9914 15183 : exchangeData(i).SumMMHrW *= OnOffFanRunTimeFraction;
9915 15183 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9916 0 : exchangeData(i).SumMHrCO *= OnOffFanRunTimeFraction;
9917 0 : exchangeData(i).SumMMHrCO *= OnOffFanRunTimeFraction;
9918 : }
9919 15183 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9920 0 : exchangeData(i).SumMHrGC *= OnOffFanRunTimeFraction;
9921 0 : exchangeData(i).SumMMHrGC *= OnOffFanRunTimeFraction;
9922 : }
9923 : }
9924 5061 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling) {
9925 20244 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9926 15183 : exchangeData(i).SumMCp += multiExchangeData(i).SumMCp * (1.0 - OnOffFanRunTimeFraction);
9927 15183 : exchangeData(i).SumMCpT += multiExchangeData(i).SumMCpT * (1.0 - OnOffFanRunTimeFraction);
9928 15183 : exchangeData(i).SumMVCp += multiExchangeData(i).SumMVCp * (1.0 - OnOffFanRunTimeFraction);
9929 15183 : exchangeData(i).SumMVCpT += multiExchangeData(i).SumMVCpT * (1.0 - OnOffFanRunTimeFraction);
9930 15183 : exchangeData(i).SumMHr += multiExchangeData(i).SumMHr * (1.0 - OnOffFanRunTimeFraction);
9931 15183 : exchangeData(i).SumMHrW += multiExchangeData(i).SumMHrW * (1.0 - OnOffFanRunTimeFraction);
9932 15183 : exchangeData(i).SumMMCp += multiExchangeData(i).SumMMCp * (1.0 - OnOffFanRunTimeFraction);
9933 15183 : exchangeData(i).SumMMCpT += multiExchangeData(i).SumMMCpT * (1.0 - OnOffFanRunTimeFraction);
9934 15183 : exchangeData(i).SumMMHr += multiExchangeData(i).SumMMHr * (1.0 - OnOffFanRunTimeFraction);
9935 15183 : exchangeData(i).SumMMHrW += multiExchangeData(i).SumMMHrW * (1.0 - OnOffFanRunTimeFraction);
9936 15183 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9937 0 : exchangeData(i).SumMHrCO += multiExchangeData(i).SumMHrCO * (1.0 - OnOffFanRunTimeFraction);
9938 0 : exchangeData(i).SumMMHrCO += multiExchangeData(i).SumMMHrCO * (1.0 - OnOffFanRunTimeFraction);
9939 : }
9940 15183 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9941 0 : exchangeData(i).SumMHrGC += multiExchangeData(i).SumMHrGC * (1.0 - OnOffFanRunTimeFraction);
9942 0 : exchangeData(i).SumMMHrGC += multiExchangeData(i).SumMMHrGC * (1.0 - OnOffFanRunTimeFraction);
9943 : }
9944 : }
9945 : }
9946 : }
9947 :
9948 11054 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff) {
9949 44216 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
9950 33162 : if (AirflowNetworkNodeData(i).AirLoopNum == AirLoopNum) {
9951 22108 : nodeReport(i).PZ = AirflowNetworkNodeSimu(i).PZ * LoopPartLoadRatio(AirLoopNum) +
9952 22108 : nodeReport(i).PZOFF * (1.0 - LoopPartLoadRatio(AirLoopNum));
9953 22108 : nodeReport(i).PZON = AirflowNetworkNodeSimu(i).PZ;
9954 : }
9955 : }
9956 221080 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
9957 210026 : PartLoadRatio = MaxPartLoadRatio;
9958 840104 : for (int j = 1; j <= AirflowNetworkNumOfZones; ++j) {
9959 630078 : if (MultizoneZoneData(j).ZoneNum == MultizoneSurfaceData(i).ZonePtr) {
9960 0 : if (AirflowNetworkNodeData(j).AirLoopNum == AirLoopNum) {
9961 0 : PartLoadRatio = LoopPartLoadRatio(AirLoopNum);
9962 0 : break;
9963 : }
9964 : }
9965 : }
9966 210026 : linkReport1(i).FLOW = AirflowNetworkLinkSimu(i).FLOW * PartLoadRatio + linkReport1(i).FLOWOFF * (1.0 - PartLoadRatio);
9967 210026 : linkReport1(i).FLOW2 = AirflowNetworkLinkSimu(i).FLOW2 * PartLoadRatio + linkReport1(i).FLOW2OFF * (1.0 - PartLoadRatio);
9968 210026 : linkReport1(i).VolFLOW = AirflowNetworkLinkSimu(i).VolFLOW * PartLoadRatio + linkReport1(i).VolFLOWOFF * (1.0 - PartLoadRatio);
9969 210026 : linkReport1(i).VolFLOW2 = AirflowNetworkLinkSimu(i).VolFLOW2 * PartLoadRatio + linkReport1(i).VolFLOW2OFF * (1.0 - PartLoadRatio);
9970 210026 : linkReport1(i).DP = AirflowNetworkLinkSimu(i).DP * PartLoadRatio + linkReport1(i).DPOFF * (1.0 - PartLoadRatio);
9971 210026 : linkReport1(i).DPON = AirflowNetworkLinkSimu(i).DP;
9972 : }
9973 : }
9974 : }
9975 :
9976 : // Save values
9977 386890 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
9978 375836 : AirflowNetworkNodeSimu(i).TZlast = AirflowNetworkNodeSimu(i).TZ;
9979 375836 : AirflowNetworkNodeSimu(i).WZlast = AirflowNetworkNodeSimu(i).WZ;
9980 375836 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9981 0 : AirflowNetworkNodeSimu(i).CO2Zlast = AirflowNetworkNodeSimu(i).CO2Z;
9982 : }
9983 375836 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9984 0 : AirflowNetworkNodeSimu(i).GCZlast = AirflowNetworkNodeSimu(i).GCZ;
9985 : }
9986 : }
9987 : }
9988 :
9989 14 : void Solver::venting_control(int const i, // AirflowNetwork surface number
9990 : Real64 &OpenFactor // Window or door opening factor (used to calculate airflow)
9991 : )
9992 : {
9993 : // SUBROUTINE INFORMATION:
9994 : // AUTHOR Fred Winkelmann
9995 : // DATE WRITTEN April 2003
9996 : // MODIFIED Feb 2004, FCW: allow venting control of interior window/door
9997 : // MODIFIED Nov. 2005, LG: to fit the requirement for AirflowNetwork Model
9998 : // RE-ENGINEERED
9999 :
10000 : // PURPOSE OF THIS SUBROUTINE:
10001 : // Determines the venting opening factor for an exterior or interior window or door
10002 : // as determined by the venting control method.
10003 :
10004 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10005 : Real64 VentTemp; // Venting temperature (C)
10006 : Real64 ZoneAirEnthalpy; // Enthalpy of zone air (J/kg)
10007 : Real64 OpenFactorMult; // Window/door opening modulation multiplier on venting open factor
10008 : Real64 DelTemp; // Inside-outside air temperature difference (K)
10009 : Real64 DelEnthal; // Inside-outside air enthalpy difference (J/kg)
10010 : int IZ; // AirflowNetwork zone number
10011 : int ZoneNum; // EnergyPlus zone number
10012 : int SurfNum; // Heat transfer surface number
10013 : Real64 LimValVentOpenFacMult; // Limiting value of venting opening factor multiplier
10014 : Real64 LowerValInOutTempDiff; // Lower value of inside/outside temperature difference for opening factor modulation
10015 : Real64 UpperValInOutTempDiff; // Upper value of inside/outside temperature difference for opening factor modulation
10016 : Real64 LowerValInOutEnthalDiff; // Lower value of inside/outside enthalpy difference for opening factor modulation
10017 : Real64 UpperValInOutEnthalDiff; // Upper value of inside/outside enthalpy difference for opening factor modulation
10018 : bool VentingAllowed; // True if venting schedule allows venting
10019 : int VentCtrlNum; // Venting control strategy 1: Temperature control; 2: Enthalpy control
10020 : Real64 VentingSchVal; // Current time step value of venting schedule
10021 : Real64 Tamb; // Outdoor dry bulb temperature at surface centroid height
10022 : int PeopleInd;
10023 :
10024 14 : if (MultizoneSurfaceData(i).EMSOpenFactorActuated) { // EMS sets value to use
10025 0 : OpenFactor = MultizoneSurfaceData(i).EMSOpenFactor;
10026 0 : SurfNum = MultizoneSurfaceData(i).SurfNum;
10027 0 : if (MultizoneSurfaceData(i).Factor > 0.0) {
10028 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactor / MultizoneSurfaceData(i).Factor;
10029 : } else {
10030 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactor;
10031 : }
10032 0 : return;
10033 : }
10034 :
10035 14 : SurfNum = MultizoneSurfaceData(i).SurfNum;
10036 :
10037 14 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10038 :
10039 : // Get venting temperature and venting strategy for exterior window or door
10040 : // and determine whether venting is allowed
10041 :
10042 14 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 1.0;
10043 14 : VentingAllowed = true;
10044 14 : IZ = MultizoneSurfaceData(i).NodeNums[0];
10045 : // Revise for RoomAirflowNetwork model
10046 14 : if (MultizoneSurfaceData(i).RAFNflag) {
10047 0 : IZ = MultizoneSurfaceData(i).ZonePtr;
10048 : }
10049 14 : ZoneNum = MultizoneZoneData(IZ).ZoneNum;
10050 :
10051 : // Note in the following that individual venting control for a window/door takes
10052 : // precedence over zone-level control
10053 14 : if (MultizoneSurfaceData(i).IndVentControl) {
10054 0 : VentTemp = MultizoneSurfaceData(i).ventTempControlSched ? MultizoneSurfaceData(i).ventTempControlSched->getCurrentVal() : 0.0;
10055 0 : VentCtrlNum = MultizoneSurfaceData(i).VentSurfCtrNum;
10056 0 : if (MultizoneSurfaceData(i).ventAvailSched != nullptr) {
10057 0 : VentingSchVal = MultizoneSurfaceData(i).ventAvailSched->getCurrentVal();
10058 0 : if (VentingSchVal <= 0.0) {
10059 0 : VentingAllowed = false;
10060 0 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 0.0;
10061 : }
10062 : }
10063 : } else {
10064 : // Zone level only by Gu on Nov. 8, 2005
10065 14 : VentTemp = MultizoneZoneData(IZ).ventTempControlSched ? MultizoneZoneData(IZ).ventTempControlSched->getCurrentVal() : 0.0;
10066 14 : VentCtrlNum = MultizoneZoneData(IZ).VentCtrNum;
10067 14 : if (MultizoneZoneData(IZ).ventAvailSched != nullptr) {
10068 12 : VentingSchVal = MultizoneZoneData(IZ).ventAvailSched->getCurrentVal();
10069 12 : if (VentingSchVal <= 0.0) {
10070 0 : VentingAllowed = false;
10071 0 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 0.0;
10072 : }
10073 : }
10074 : }
10075 :
10076 14 : m_state.dataSurface->SurfWinInsideTempForVentingRep(SurfNum) = VentTemp;
10077 14 : OpenFactor = 0.0;
10078 :
10079 : // Venting based on inside-outside air temperature difference
10080 :
10081 14 : if ((VentCtrlNum == VentControlType::Temp || VentCtrlNum == VentControlType::AdjTemp) && VentingAllowed) {
10082 12 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(SurfNum);
10083 : // Check whether this surface is an interior wall or not. If Yes, use adjacent zone conditions
10084 12 : if (VentCtrlNum == VentControlType::AdjTemp && MultizoneSurfaceData(i).IndVentControl) {
10085 0 : Tamb = ANZT(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum);
10086 : }
10087 12 : if (ANZT(ZoneNum) > Tamb && ANZT(ZoneNum) > VentTemp) {
10088 6 : OpenFactor = MultizoneSurfaceData(i).Factor;
10089 6 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10090 : // Modulation of OpenFactor
10091 6 : if (MultizoneSurfaceData(i).IndVentControl) {
10092 0 : LimValVentOpenFacMult = MultizoneSurfaceData(i).ModulateFactor;
10093 0 : LowerValInOutTempDiff = MultizoneSurfaceData(i).LowValueTemp;
10094 0 : UpperValInOutTempDiff = MultizoneSurfaceData(i).UpValueTemp;
10095 : } else {
10096 6 : LimValVentOpenFacMult = MultizoneZoneData(IZ).OpenFactor;
10097 6 : LowerValInOutTempDiff = MultizoneZoneData(IZ).LowValueTemp;
10098 6 : UpperValInOutTempDiff = MultizoneZoneData(IZ).UpValueTemp;
10099 : }
10100 6 : if (LimValVentOpenFacMult != 1.0) {
10101 4 : DelTemp = ANZT(ZoneNum) - Tamb;
10102 4 : if (DelTemp <= LowerValInOutTempDiff) {
10103 0 : OpenFactorMult = 1.0;
10104 4 : } else if (DelTemp >= UpperValInOutTempDiff) {
10105 4 : OpenFactorMult = LimValVentOpenFacMult;
10106 : } else {
10107 0 : OpenFactorMult =
10108 : LimValVentOpenFacMult +
10109 0 : ((UpperValInOutTempDiff - DelTemp) / (UpperValInOutTempDiff - LowerValInOutTempDiff)) * (1 - LimValVentOpenFacMult);
10110 : }
10111 4 : OpenFactor *= OpenFactorMult;
10112 4 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactorMult;
10113 : }
10114 : } else {
10115 6 : OpenFactor = 0.0;
10116 6 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10117 : }
10118 : }
10119 :
10120 : // Venting based on inside-outside air enthalpy difference
10121 :
10122 14 : if ((VentCtrlNum == VentControlType::Enth || VentCtrlNum == VentControlType::AdjEnth) && VentingAllowed) {
10123 0 : ZoneAirEnthalpy = PsyHFnTdbW(ANZT(ZoneNum), ANZW(ZoneNum));
10124 : // Check whether this surface is an interior wall or not. If Yes, use adjacent zone conditions
10125 0 : if (VentCtrlNum == VentControlType::AdjEnth && MultizoneSurfaceData(i).IndVentControl) {
10126 0 : m_state.dataEnvrn->OutEnthalpy = PsyHFnTdbW(ANZT(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum),
10127 0 : ANZW(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum));
10128 : }
10129 0 : if (ZoneAirEnthalpy > m_state.dataEnvrn->OutEnthalpy && ANZT(ZoneNum) > VentTemp) {
10130 0 : OpenFactor = MultizoneSurfaceData(i).Factor;
10131 : // Modulation of OpenFactor
10132 0 : if (MultizoneSurfaceData(i).IndVentControl) {
10133 0 : LimValVentOpenFacMult = MultizoneSurfaceData(i).ModulateFactor;
10134 0 : LowerValInOutEnthalDiff = MultizoneSurfaceData(i).LowValueEnth;
10135 0 : UpperValInOutEnthalDiff = MultizoneSurfaceData(i).UpValueEnth;
10136 : } else {
10137 0 : LimValVentOpenFacMult = MultizoneZoneData(IZ).OpenFactor;
10138 0 : LowerValInOutEnthalDiff = MultizoneZoneData(IZ).LowValueEnth;
10139 0 : UpperValInOutEnthalDiff = MultizoneZoneData(IZ).UpValueEnth;
10140 : }
10141 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10142 :
10143 0 : if (LimValVentOpenFacMult != 1.0) {
10144 0 : DelEnthal = ZoneAirEnthalpy - m_state.dataEnvrn->OutEnthalpy;
10145 0 : if (DelEnthal <= LowerValInOutEnthalDiff) {
10146 0 : OpenFactorMult = 1.0;
10147 0 : } else if (DelEnthal >= UpperValInOutEnthalDiff) {
10148 0 : OpenFactorMult = LimValVentOpenFacMult;
10149 : } else {
10150 0 : OpenFactorMult =
10151 0 : LimValVentOpenFacMult + ((UpperValInOutEnthalDiff - DelEnthal) / (UpperValInOutEnthalDiff - LowerValInOutEnthalDiff)) *
10152 0 : (1 - LimValVentOpenFacMult);
10153 : }
10154 0 : OpenFactor *= OpenFactorMult;
10155 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactorMult;
10156 : }
10157 : } else {
10158 0 : OpenFactor = 0.0;
10159 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10160 : }
10161 : }
10162 :
10163 : // Constant venting (opening factor as specified in IDF) - C-PH - added by Philip Haves 3/8/01
10164 : // subject to venting availability
10165 :
10166 14 : if (VentCtrlNum == VentControlType::Const && VentingAllowed) { // Constant
10167 2 : OpenFactor = MultizoneSurfaceData(i).Factor;
10168 2 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10169 : }
10170 :
10171 14 : if (VentCtrlNum == VentControlType::ASH55) {
10172 0 : if (VentingAllowed && (!m_state.dataGlobal->BeginEnvrnFlag) && (!m_state.dataGlobal->WarmupFlag)) {
10173 0 : PeopleInd = MultizoneZoneData(IZ).ASH55PeopleInd;
10174 0 : if (PeopleInd > 0 && m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortAdaptiveASH5590 != -1) {
10175 0 : if (m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortOpTemp >
10176 0 : m_state.dataThermalComforts->ThermalComfortData(PeopleInd).TComfASH55) {
10177 0 : OpenFactor = MultizoneSurfaceData(i).Factor;
10178 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10179 : } else {
10180 0 : OpenFactor = 0.0;
10181 : }
10182 : } else {
10183 0 : OpenFactor = 0.0;
10184 : }
10185 : } else {
10186 0 : OpenFactor = 0.0;
10187 : }
10188 : }
10189 :
10190 14 : if (VentCtrlNum == VentControlType::CEN15251) {
10191 0 : if (VentingAllowed && (!m_state.dataGlobal->BeginEnvrnFlag) && (!m_state.dataGlobal->WarmupFlag)) {
10192 0 : PeopleInd = MultizoneZoneData(IZ).CEN15251PeopleInd;
10193 0 : if (PeopleInd > 0 && m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortAdaptiveCEN15251CatI != -1) {
10194 0 : if (m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortOpTemp >
10195 0 : m_state.dataThermalComforts->ThermalComfortData(PeopleInd).TComfCEN15251) {
10196 0 : OpenFactor = MultizoneSurfaceData(i).Factor;
10197 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10198 : } else {
10199 0 : OpenFactor = 0.0;
10200 : }
10201 : } else {
10202 0 : OpenFactor = 0.0;
10203 : }
10204 : } else {
10205 0 : OpenFactor = 0.0;
10206 : }
10207 : }
10208 :
10209 : // No venting, i.e, window/door always closed - added YJH 8 Aug 02
10210 :
10211 14 : if (VentCtrlNum == VentControlType::NoVent) { // Novent
10212 0 : OpenFactor = 0.0;
10213 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10214 : }
10215 : }
10216 :
10217 17 : void Solver::validate_distribution()
10218 : {
10219 :
10220 : // SUBROUTINE INFORMATION:
10221 : // AUTHOR Lixing Gu
10222 : // DATE WRITTEN Oct. 2005
10223 : // MODIFIED L. Gu, Jan. 2009: allow a desuperheater coil and three heat exchangers
10224 : // RE-ENGINEERED na
10225 :
10226 : // PURPOSE OF THIS SUBROUTINE:
10227 : // This subroutine validates the inputs of distribution system, since node data from a primary airloop
10228 : // are not available in the first call during reading input data of airflownetwork objects.
10229 : // Note: this routine shouldn't be called more than once
10230 :
10231 : // Using/Aliasing
10232 : using BranchNodeConnections::GetNodeConnectionType;
10233 : using MixedAir::GetNumOAMixers;
10234 : using MixedAir::GetOAMixerInletNodeNumber;
10235 : using MixedAir::GetOAMixerReliefNodeNumber;
10236 : using SingleDuct::GetHVACSingleDuctSysIndex;
10237 : using namespace DataLoopNode;
10238 17 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
10239 : using DXCoils::SetDXCoilAirLoopNumber;
10240 : using HeatingCoils::SetHeatingCoilAirLoopNumber;
10241 : using HVACStandAloneERV::GetStandAloneERVNodeNumber;
10242 : using HVACVariableRefrigerantFlow::getVRFTUNodeNumber;
10243 : using SplitterComponent::GetSplitterNodeNumbers;
10244 : using SplitterComponent::GetSplitterOutletNumber;
10245 : using UnitarySystems::getUnitarySystemNodeNumber;
10246 : using WaterThermalTanks::GetHeatPumpWaterHeaterNodeNumber;
10247 : using WindowAC::getWindowACNodeNumber;
10248 : using ZoneDehumidifier::GetZoneDehumidifierNodeNumber;
10249 :
10250 : // SUBROUTINE PARAMETER DEFINITIONS:
10251 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::validate_distribution: "); // include trailing blank space
10252 :
10253 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10254 : int n;
10255 : bool LocalError;
10256 17 : Array1D_bool NodeFound;
10257 :
10258 17 : bool ErrorsFound(false);
10259 17 : bool IsNotOK(false);
10260 17 : bool errFlag(false);
10261 17 : EPVector<DataLoopNode::ConnectionType> NodeConnectionType; // Specifies the type of node connection
10262 17 : std::string CurrentModuleObject;
10263 :
10264 17 : bool hpwhFound(false); // Flag for HPWH identification
10265 17 : bool standaloneERVFound(false); // Flag for Standalone ERV (ZoneHVAC:EnergyRecoveryVentilator) identification
10266 17 : bool packagedUnitaryFound(false); // Flag for packaged unitary systems (ZoneHVAC:PackagedTerminalAirConditioner,
10267 : // ZoneHVAC:PackagedTerminalHeatPump, ZoneHVAC:WaterToAirHeatPump) identification
10268 17 : bool vrfTUFound(false);
10269 17 : bool windowACFound(false); // Flag for Window AC (ZoneHVAC:WindowAirConditioner) identification
10270 :
10271 : // Validate supply and return connections
10272 17 : NodeFound.dimension(m_state.dataLoopNodes->NumOfNodes, false);
10273 : // Validate inlet and outlet nodes for zone exhaust fans
10274 18 : for (int i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
10275 1 : NodeFound(MultizoneCompExhaustFanData(i).InletNode) = true;
10276 1 : NodeFound(MultizoneCompExhaustFanData(i).OutletNode) = true;
10277 : }
10278 : // Validate EPlus Node names and types
10279 31 : for (int i = 1; i <= DisSysNumOfNodes; ++i) {
10280 14 : if (Util::SameString(DisSysNodeData(i).EPlusName, "") || Util::SameString(DisSysNodeData(i).EPlusName, "Other")) {
10281 4 : continue;
10282 : }
10283 10 : LocalError = false;
10284 94 : for (int j = 1; j <= m_state.dataLoopNodes->NumOfNodes; ++j) { // NodeID
10285 94 : if (DisSysNodeData(i).EPlusName == m_state.dataLoopNodes->NodeID(j)) {
10286 10 : DisSysNodeData(i).AirLoopNum = get_airloop_number(j);
10287 10 : if (DisSysNodeData(i).AirLoopNum == 0) {
10288 0 : ShowSevereError(m_state,
10289 0 : format(RoutineName) + "The Node or Component Name defined in " + DisSysNodeData(i).Name +
10290 : " is not found in the AirLoopHVAC.");
10291 0 : ShowContinueError(m_state,
10292 0 : "The entered name is " + DisSysNodeData(i).EPlusName + " in an AirflowNetwork:Distribution:Node object.");
10293 0 : ErrorsFound = true;
10294 : }
10295 10 : DisSysNodeData(i).EPlusNodeNum = j;
10296 10 : AirflowNetworkNodeData(NumOfNodesMultiZone + i).EPlusNodeNum = j;
10297 10 : AirflowNetworkNodeData(NumOfNodesMultiZone + i).AirLoopNum = DisSysNodeData(i).AirLoopNum;
10298 10 : NodeFound(j) = true;
10299 10 : LocalError = true;
10300 10 : break;
10301 : }
10302 : }
10303 : // Check outdoor air node
10304 20 : if (Util::SameString(DisSysNodeData(i).EPlusType, "OutdoorAir:NodeList") ||
10305 20 : Util::SameString(DisSysNodeData(i).EPlusType, "OutdoorAir:Node")) {
10306 0 : if (!LocalError) {
10307 0 : ShowSevereError(m_state,
10308 0 : format(RoutineName) + "The Node or Component Name defined in " + DisSysNodeData(i).Name +
10309 0 : " is not found in the " + DisSysNodeData(i).EPlusType);
10310 0 : ShowContinueError(m_state,
10311 0 : "The entered name is " + DisSysNodeData(i).EPlusName + " in an AirflowNetwork:Distribution:Node object.");
10312 0 : ErrorsFound = true;
10313 : }
10314 : }
10315 10 : if (DisSysNodeData(i).EPlusNodeNum == 0) {
10316 0 : ShowSevereError(m_state,
10317 0 : format(RoutineName) +
10318 0 : "Primary Air Loop Node is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " + DisSysNodeData(i).Name);
10319 0 : ErrorsFound = true;
10320 : }
10321 : }
10322 :
10323 : // Determine node numbers for zone inlets and outlets
10324 32 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
10325 15 : if (!m_state.dataZoneEquip->ZoneEquipConfig(i).IsControlled) {
10326 2 : continue;
10327 : }
10328 15 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumInletNodes; ++j) {
10329 60 : for (int k = 1; k <= AirflowNetworkNumOfNodes; ++k) {
10330 59 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).InletNode(j) == AirflowNetworkNodeData(k).EPlusNodeNum) {
10331 1 : AirflowNetworkNodeData(k).EPlusTypeNum = iEPlusNodeType::ZIN;
10332 1 : break;
10333 : }
10334 : }
10335 : }
10336 14 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumReturnNodes; ++j) {
10337 26 : for (int k = 1; k <= AirflowNetworkNumOfNodes; ++k) {
10338 26 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).ReturnNode(j) == AirflowNetworkNodeData(k).EPlusNodeNum) {
10339 1 : AirflowNetworkNodeData(k).EPlusTypeNum = iEPlusNodeType::ZOU;
10340 1 : break;
10341 : }
10342 : }
10343 : }
10344 : }
10345 :
10346 : // Eliminate node not related to AirLoopHVAC
10347 88 : for (int k = 1; k <= m_state.dataBranchNodeConnections->NumOfNodeConnections; ++k) {
10348 71 : if (NodeFound(m_state.dataBranchNodeConnections->NodeConnections(k).NodeNumber)) {
10349 30 : continue;
10350 : }
10351 41 : if (m_state.dataBranchNodeConnections->NodeConnections(k).FluidStream == NodeInputManager::CompFluidStream::Secondary) {
10352 0 : NodeFound(m_state.dataBranchNodeConnections->NodeConnections(k).NodeNumber) = true;
10353 : }
10354 : }
10355 :
10356 : // Eliminate nodes with fluidtype = water
10357 82 : for (int k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
10358 65 : if (NodeFound(k)) {
10359 12 : continue;
10360 : }
10361 53 : if (m_state.dataLoopNodes->Node(k).FluidType == DataLoopNode::NodeFluidType::Water) {
10362 0 : NodeFound(k) = true;
10363 : }
10364 : }
10365 :
10366 : // Eliminate local external air node for network
10367 82 : for (int k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
10368 65 : if (NodeFound(k)) {
10369 12 : continue;
10370 : }
10371 53 : if (m_state.dataLoopNodes->Node(k).IsLocalNode) {
10372 0 : NodeFound(k) = true;
10373 : }
10374 : }
10375 :
10376 : // Ensure all the nodes used in Eplus are a subset of AirflowNetwork Nodes
10377 82 : for (int i = 1; i <= m_state.dataLoopNodes->NumOfNodes; ++i) {
10378 65 : if (NodeFound(i)) {
10379 12 : continue;
10380 : }
10381 : // Skip the inlet and outlet nodes of zone dehumidifiers
10382 53 : if (GetZoneDehumidifierNodeNumber(m_state, i)) {
10383 2 : NodeFound(i) = true;
10384 : }
10385 :
10386 53 : if (simulation_control.allow_unsupported_zone_equipment) {
10387 : // Skip HPWH nodes that don't have to be included in the AFN
10388 42 : if (GetHeatPumpWaterHeaterNodeNumber(m_state, i)) {
10389 2 : NodeFound(i) = true;
10390 2 : hpwhFound = true;
10391 : }
10392 :
10393 : // Skip Standalone ERV nodes that don't have to be included in the AFN
10394 42 : if (GetStandAloneERVNodeNumber(m_state, i)) {
10395 4 : NodeFound(i) = true;
10396 4 : standaloneERVFound = true;
10397 : }
10398 :
10399 : // Skip zonal unitary system based nodes that don't have to be included in the AFN
10400 42 : if (getUnitarySystemNodeNumber(m_state, i)) {
10401 8 : NodeFound(i) = true;
10402 8 : packagedUnitaryFound = true;
10403 : }
10404 :
10405 : // Skip zonal vrf terminal nodes that don't have to be included in the AFN
10406 42 : if (getVRFTUNodeNumber(m_state, i)) {
10407 10 : NodeFound(i) = true;
10408 10 : vrfTUFound = true;
10409 : }
10410 :
10411 : // Skip Window AC with no OA
10412 42 : if (getWindowACNodeNumber(m_state, i)) {
10413 2 : NodeFound(i) = true;
10414 2 : windowACFound = true;
10415 : }
10416 : }
10417 :
10418 97 : for (int zoneNum = 1; zoneNum <= m_state.dataGlobal->NumOfZones; ++zoneNum) {
10419 57 : if (!m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).IsControlled) {
10420 4 : continue;
10421 : }
10422 53 : if (m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneNode == i) {
10423 13 : if (zoneNum > AirflowNetworkNumOfNodes) {
10424 2 : ShowSevereError(m_state,
10425 2 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10426 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10427 2 : ShowContinueError(
10428 2 : m_state, "This Node is the zone air node for Zone '" + m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneName + "'.");
10429 1 : ErrorsFound = true;
10430 : } else {
10431 12 : NodeFound(i) = true;
10432 26 : for (int iZone = 1; iZone <= AirflowNetworkNumOfZones; iZone++) {
10433 14 : if (MultizoneZoneData(iZone).ZoneNum == zoneNum) {
10434 12 : AirflowNetworkNodeData(iZone).EPlusNodeNum = i;
10435 : }
10436 : }
10437 : }
10438 13 : break;
10439 : }
10440 : }
10441 :
10442 : // skip nodes that are not part of an airflow network
10443 :
10444 : // DX COIL CONDENSER NODE TEST:
10445 : // Outside air nodes are used for DX coil condenser inlet nodes, these are specified in an outside air node or
10446 : // OutdoorAir:NodeList object (and classified with NodeConnectionType as OutsideAir). In addition,
10447 : // this same node is specified in a Coil:DX:CoolingBypassFactorEmpirical object (and classified with
10448 : // NodeConnectionType as OutsideAirReference). In the NodeConnectionType structure, both of these nodes have a
10449 : // unique index but have the same node number. The Outside Air Node will usually be listed first. Search for all
10450 : // indexes with the same node number and check if it is classified as NodeConnectionType = OutsideAirReference.
10451 : // Mark this node as found since it is not used in an airflownetwork simulation.
10452 : // Example (using AirflowNetwork_MultiZone_SmallOffice.idf with a single OA Mixer):
10453 : // (the example shown below is identical to AirflowNetwork_SimpleHouse.idf with no OA Mixer except
10454 : // that the NodeConnections indexes are (7) and (31), respectively and the NodeNumber = 6)
10455 : // The GetNodeConnectionType CALL below returns DataLoopNode::NodeConnectionType::OutsideAir = 7 and
10456 : // DataLoopNode::NodeConnectionType::OutsideAirReference = 14.
10457 : // NodeConnections info from OUTSIDE AIR NODE object read:
10458 : // NodeConnections(9)NodeNumber = 10
10459 : // NodeConnections(9)NodeName = ACDXCOIL 1 CONDENSER NODE
10460 : // NodeConnections(9)ObjectType = OUTSIDE AIR NODE
10461 : // NodeConnections(9)ObjectName = OUTSIDE AIR NODE
10462 : // NodeConnections(9)ConnectionType = OutsideAir
10463 : // NodeConnections info from Coil:DX:CoolingBypassFactorEmpirical object read:
10464 : // NodeConnections(64)NodeNumber = 10
10465 : // NodeConnections(64)NodeName = ACDXCOIL 1 CONDENSER NODE
10466 : // NodeConnections(64)ObjectType = COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
10467 : // NodeConnections(64)ObjectName = ACDXCOIL 1
10468 : // NodeConnections(64)ConnectionType = OutsideAirReference
10469 :
10470 53 : errFlag = false;
10471 53 : GetNodeConnectionType(m_state, i, NodeConnectionType, errFlag); // Gets all connection types for a given node number
10472 53 : if (errFlag) {
10473 42 : ShowContinueError(m_state, "...occurs in Airflow Network simulation.");
10474 : } else {
10475 : // skip nodes for air cooled condensers
10476 80 : for (int j = 1; j <= isize(NodeConnectionType); ++j) {
10477 41 : if (NodeConnectionType(j) == DataLoopNode::ConnectionType::OutsideAirReference) {
10478 0 : NodeFound(i) = true;
10479 : }
10480 : }
10481 : }
10482 :
10483 53 : if (!NodeFound(i)) {
10484 : // Check if this node is the OA relief node. For the time being, OA relief node is not used
10485 13 : if (GetNumOAMixers(m_state) > 1) {
10486 : // ShowSevereError(m_state, format(RoutineName) + "Only one OutdoorAir:Mixer is allowed in the
10487 : // AirflowNetwork model." ); ErrorsFound = true;
10488 : int OAFanNum;
10489 : int OARelNum;
10490 : int OAMixerNum;
10491 :
10492 0 : for (OAFanNum = 1; OAFanNum <= NumOfOAFans; ++OAFanNum) {
10493 0 : DisSysCompOutdoorAirData(OAFanNum).InletNode =
10494 0 : GetOAMixerInletNodeNumber(m_state, DisSysCompOutdoorAirData(OAFanNum).OAMixerNum);
10495 : // NodeFound( DisSysCompOutdoorAirData( OAFanNum ).InletNode
10496 : // ) = true;
10497 : }
10498 0 : for (OARelNum = 1; OARelNum <= NumOfReliefFans; ++OARelNum) {
10499 0 : DisSysCompReliefAirData(OARelNum).OutletNode =
10500 0 : GetOAMixerInletNodeNumber(m_state, DisSysCompReliefAirData(OARelNum).OAMixerNum);
10501 : // NodeFound( DisSysCompOutdoorAirData( OAFanNum ).InletNode
10502 : // ) = true;
10503 : }
10504 : // Check NodeFound status
10505 0 : for (OAMixerNum = 1; OAMixerNum <= GetNumOAMixers(m_state); ++OAMixerNum) {
10506 0 : if (i == GetOAMixerReliefNodeNumber(m_state, OAMixerNum)) {
10507 0 : NodeFound(i) = true;
10508 0 : break;
10509 0 : } else if (i == GetOAMixerInletNodeNumber(m_state, OAMixerNum)) {
10510 0 : NodeFound(i) = true;
10511 0 : break;
10512 : } else {
10513 0 : if (OAMixerNum == GetNumOAMixers(m_state)) {
10514 0 : ShowSevereError(m_state,
10515 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10516 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10517 0 : ErrorsFound = true;
10518 : }
10519 : }
10520 : }
10521 13 : } else if (GetNumOAMixers(m_state) == 0) {
10522 26 : ShowSevereError(m_state,
10523 26 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10524 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10525 13 : ErrorsFound = true;
10526 : } else {
10527 : // TODO: I fail to see how you could enter this block given than NumOAMixers (returned by GetNumOAMixers())
10528 : // is initialized to zero, and we check above if '> 0' or '== 0'
10529 0 : if (NumOfOAFans == 1 && DisSysCompOutdoorAirData(1).InletNode == 0) {
10530 0 : DisSysCompOutdoorAirData(1).InletNode = GetOAMixerInletNodeNumber(m_state, 1);
10531 : }
10532 0 : if (NumOfReliefFans == 1 && DisSysCompReliefAirData(1).OutletNode == 0) {
10533 0 : DisSysCompReliefAirData(1).OutletNode = GetOAMixerInletNodeNumber(m_state, 1);
10534 : }
10535 0 : if (i == GetOAMixerReliefNodeNumber(m_state, 1)) {
10536 0 : NodeFound(i) = true;
10537 0 : } else if (i == GetOAMixerInletNodeNumber(m_state, 1)) {
10538 0 : NodeFound(i) = true;
10539 : } else {
10540 0 : ShowSevereError(m_state,
10541 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10542 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10543 0 : ErrorsFound = true;
10544 : }
10545 : }
10546 : }
10547 : }
10548 17 : if (hpwhFound) {
10549 2 : ShowWarningError(m_state,
10550 2 : format(RoutineName) + "Heat pump water heater is simulated along with an AirflowNetwork but is not included in "
10551 : "the AirflowNetwork.");
10552 : }
10553 17 : if (standaloneERVFound) {
10554 2 : ShowWarningError(m_state,
10555 2 : format(RoutineName) + "A ZoneHVAC:EnergyRecoveryVentilator is simulated along with an AirflowNetwork but is not "
10556 : "included in the AirflowNetwork.");
10557 : }
10558 17 : if (packagedUnitaryFound) {
10559 2 : ShowWarningError(m_state,
10560 2 : format(RoutineName) + "A ZoneHVAC:PackagedTerminalAirConditioner, ZoneHVAC:PackagedTerminalHeatPump, or "
10561 : "ZoneHVAC:WaterToAirHeatPump is simulated along with an AirflowNetwork but is not "
10562 : "included in the AirflowNetwork.");
10563 : }
10564 17 : if (vrfTUFound) {
10565 2 : ShowWarningError(m_state,
10566 2 : format(RoutineName) +
10567 : "A ZoneHVAC:TerminalUnit:VariableRefrigerantFlow is simulated along with an AirflowNetwork but is not "
10568 : "included in the AirflowNetwork.");
10569 : }
10570 17 : if (windowACFound) {
10571 2 : ShowWarningError(m_state,
10572 2 : format(RoutineName) + "A ZoneHVAC:WindowAirConditioner is simulated along with an AirflowNetwork but is not "
10573 : "included in the AirflowNetwork.");
10574 : }
10575 17 : NodeFound.deallocate();
10576 :
10577 : // Assign AirLoop Number to every node and linkage
10578 : // Zone first
10579 31 : for (int i = 1; i <= AirflowNetworkNumOfZones; i++) {
10580 34 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; j++) {
10581 20 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) {
10582 6 : continue;
10583 : }
10584 14 : if ((MultizoneZoneData(i).ZoneNum == j) && (m_state.dataZoneEquip->ZoneEquipConfig(j).NumInletNodes > 0)) {
10585 : // No multiple Airloop
10586 1 : AirflowNetworkNodeData(i).AirLoopNum = m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(1);
10587 : }
10588 : }
10589 : }
10590 : // Air Distribution system
10591 36 : for (int i = AirflowNetworkNumOfSurfaces + 1; i <= AirflowNetworkNumOfLinks; ++i) {
10592 19 : int j = AirflowNetworkLinkageData(i).NodeNums[0];
10593 19 : int k = AirflowNetworkLinkageData(i).NodeNums[1];
10594 19 : if (AirflowNetworkNodeData(j).AirLoopNum == 0 && AirflowNetworkNodeData(k).AirLoopNum == 0) {
10595 : // Error messaage
10596 0 : ShowSevereError(m_state,
10597 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(i).Name +
10598 : " is not valid for AirLoopNum assignment");
10599 0 : ShowContinueError(m_state,
10600 0 : "AirLoopNum is not found in both nodes for the linkage: " + AirflowNetworkLinkageData(i).NodeNames[0] + " and " +
10601 0 : AirflowNetworkLinkageData(i).NodeNames[1]);
10602 0 : ShowContinueError(m_state,
10603 : "Please ensure one of two AIRFLOWNETWORK:DISTRIBUTION:NODEs in the first AIRFLOWNETWORK:DISTRIBUTION:LINKAGE "
10604 : "object should be defined as EnergyPlus NodeID.");
10605 0 : ErrorsFound = true;
10606 : }
10607 19 : if (AirflowNetworkNodeData(j).AirLoopNum > 0 && AirflowNetworkNodeData(k).AirLoopNum == 0) {
10608 6 : AirflowNetworkNodeData(k).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10609 : }
10610 19 : if (AirflowNetworkNodeData(j).AirLoopNum == 0 && AirflowNetworkNodeData(k).AirLoopNum > 0) {
10611 0 : AirflowNetworkNodeData(j).AirLoopNum = AirflowNetworkNodeData(k).AirLoopNum;
10612 : }
10613 19 : if (AirflowNetworkNodeData(j).AirLoopNum == AirflowNetworkNodeData(k).AirLoopNum) {
10614 19 : AirflowNetworkLinkageData(i).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10615 : }
10616 19 : if (AirflowNetworkNodeData(j).AirLoopNum != AirflowNetworkNodeData(k).AirLoopNum && AirflowNetworkNodeData(j).AirLoopNum > 0 &&
10617 0 : AirflowNetworkNodeData(k).AirLoopNum > 0) {
10618 0 : AirflowNetworkLinkageData(i).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10619 0 : ShowSevereError(m_state,
10620 0 : "The AirLoopNum defined in both AIRFLOWNETWORK:DISTRIBUTION:NODE objects in " + AirflowNetworkLinkageData(i).Name +
10621 : " are not the same. Please make sure both nodes should be listed in the same AirLoop as a valid linkage.");
10622 0 : ShowContinueError(m_state,
10623 0 : "AirLoop defined in " + AirflowNetworkNodeData(j).Name + " is " +
10624 0 : m_state.dataAirSystemsData->PrimaryAirSystems(AirflowNetworkNodeData(j).AirLoopNum).Name +
10625 0 : ", and AirLoop defined in " + AirflowNetworkNodeData(k).Name + " is " +
10626 0 : m_state.dataAirSystemsData->PrimaryAirSystems(AirflowNetworkNodeData(k).AirLoopNum).Name);
10627 0 : ErrorsFound = true;
10628 : }
10629 : // Set AirLoopNum to fans and coils
10630 19 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::FAN) {
10631 1 : n = m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).FanIndex;
10632 1 : m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).AirLoopNum =
10633 1 : AirflowNetworkLinkageData(i).AirLoopNum;
10634 1 : if (m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).FanModelFlag) {
10635 0 : m_state.dataFans
10636 0 : ->fans(m_state.afn->DisSysCompCVFData(m_state.afn->AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum)
10637 : .FanIndex)
10638 0 : ->airLoopNum = AirflowNetworkLinkageData(i).AirLoopNum;
10639 0 : m_state.dataFans
10640 0 : ->fans(m_state.afn->DisSysCompCVFData(m_state.afn->AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum)
10641 : .FanIndex)
10642 0 : ->isAFNFan = true;
10643 : } else {
10644 1 : m_state.dataFans->fans(n)->airLoopNum = AirflowNetworkLinkageData(i).AirLoopNum;
10645 1 : m_state.dataFans->fans(n)->isAFNFan = true;
10646 : }
10647 : }
10648 19 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::COI) {
10649 3 : m_state.afn->DisSysCompCoilData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).AirLoopNum =
10650 3 : AirflowNetworkLinkageData(i).AirLoopNum;
10651 : }
10652 : }
10653 :
10654 : // Validate coil name and type
10655 17 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Coil";
10656 17 : MultiSpeedHPIndicator = 0;
10657 28 : for (int i = 1; i <= DisSysNumOfCoils; ++i) {
10658 : {
10659 11 : auto const SELECT_CASE_var(Util::makeUPPER(DisSysCompCoilData(i).EPlusType));
10660 :
10661 11 : if (SELECT_CASE_var == "COIL:COOLING:DX") {
10662 0 : ValidateComponent(m_state, "Coil:Cooling:DX", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10663 0 : if (IsNotOK) {
10664 0 : ErrorsFound = true;
10665 : } else {
10666 : // Replace the convenience function with in-place code
10667 0 : std::string mycoil = DisSysCompCoilData(i).name;
10668 0 : auto it = std::find_if(m_state.dataCoilCoolingDX->coilCoolingDXs.begin(),
10669 0 : m_state.dataCoilCoolingDX->coilCoolingDXs.end(),
10670 0 : [&mycoil](const CoilCoolingDX &coil) { return coil.name == mycoil; });
10671 0 : if (it != m_state.dataCoilCoolingDX->coilCoolingDXs.end()) {
10672 : // Set the airloop number on the CoilCoolingDX object, which is used to collect the runtime fraction
10673 0 : it->airLoopNum = DisSysCompCoilData(i).AirLoopNum;
10674 : } else {
10675 0 : ShowSevereError(m_state, "SetDXCoilAirLoopNumber: Could not find Coil \"Name=\"" + DisSysCompCoilData(i).name + "\"");
10676 : }
10677 0 : }
10678 11 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:SINGLESPEED") {
10679 2 : ValidateComponent(
10680 3 : m_state, "Coil:Cooling:DX:SingleSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10681 1 : if (IsNotOK) {
10682 0 : ErrorsFound = true;
10683 : } else {
10684 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10685 : }
10686 :
10687 10 : } else if (SELECT_CASE_var == "COIL:HEATING:DX:SINGLESPEED") {
10688 2 : ValidateComponent(
10689 3 : m_state, "Coil:Heating:DX:SingleSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10690 1 : if (IsNotOK) {
10691 0 : ErrorsFound = true;
10692 : } else {
10693 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10694 : }
10695 :
10696 9 : } else if (SELECT_CASE_var == "COIL:HEATING:FUEL") {
10697 0 : ValidateComponent(m_state, "Coil:Heating:Fuel", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10698 0 : if (IsNotOK) {
10699 0 : ErrorsFound = true;
10700 : } else {
10701 0 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10702 : }
10703 :
10704 9 : } else if (SELECT_CASE_var == "COIL:HEATING:ELECTRIC") {
10705 2 : ValidateComponent(
10706 3 : m_state, "Coil:Heating:Electric", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10707 1 : if (IsNotOK) {
10708 0 : ErrorsFound = true;
10709 : } else {
10710 1 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10711 : }
10712 :
10713 8 : } else if (SELECT_CASE_var == "COIL:COOLING:WATER") {
10714 0 : ValidateComponent(m_state, "Coil:Cooling:Water", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10715 0 : if (IsNotOK) {
10716 0 : ErrorsFound = true;
10717 : }
10718 :
10719 8 : } else if (SELECT_CASE_var == "COIL:HEATING:WATER") {
10720 0 : ValidateComponent(m_state, "Coil:Heating:Water", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10721 0 : if (IsNotOK) {
10722 0 : ErrorsFound = true;
10723 : }
10724 :
10725 8 : } else if (SELECT_CASE_var == "COIL:COOLING:WATER:DETAILEDGEOMETRY") {
10726 0 : ValidateComponent(m_state,
10727 : "Coil:Cooling:Water:DetailedGeometry",
10728 0 : DisSysCompCoilData(i).name,
10729 : IsNotOK,
10730 0 : format(RoutineName) + CurrentModuleObject);
10731 0 : if (IsNotOK) {
10732 0 : ErrorsFound = true;
10733 : }
10734 :
10735 8 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:TWOSTAGEWITHHUMIDITYCONTROLMODE") {
10736 0 : ValidateComponent(m_state,
10737 : "Coil:Cooling:DX:TwoStageWithHumidityControlMode",
10738 0 : DisSysCompCoilData(i).name,
10739 : IsNotOK,
10740 0 : format(RoutineName) + CurrentModuleObject);
10741 0 : if (IsNotOK) {
10742 0 : ErrorsFound = true;
10743 : } else {
10744 0 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10745 : }
10746 :
10747 8 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:MULTISPEED") {
10748 0 : ValidateComponent(
10749 0 : m_state, "Coil:Cooling:DX:MultiSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10750 0 : ++MultiSpeedHPIndicator;
10751 0 : if (IsNotOK) {
10752 0 : ErrorsFound = true;
10753 : } else {
10754 0 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10755 : }
10756 :
10757 8 : } else if (SELECT_CASE_var == "COIL:HEATING:DX:MULTISPEED") {
10758 0 : ValidateComponent(
10759 0 : m_state, "Coil:Heating:DX:MultiSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10760 0 : ++MultiSpeedHPIndicator;
10761 0 : if (IsNotOK) {
10762 0 : ErrorsFound = true;
10763 : } else {
10764 0 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10765 : }
10766 :
10767 8 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:VARIABLESPEED") {
10768 2 : ValidateComponent(
10769 3 : m_state, "Coil:Cooling:DX:VariableSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10770 1 : ++MultiSpeedHPIndicator;
10771 1 : if (IsNotOK) {
10772 0 : ErrorsFound = true;
10773 : } else {
10774 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10775 : }
10776 :
10777 7 : } else if (SELECT_CASE_var == "COIL:HEATING:DX:VARIABLESPEED") {
10778 2 : ValidateComponent(
10779 3 : m_state, "Coil:Heating:DX:VariableSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10780 1 : ++MultiSpeedHPIndicator;
10781 1 : if (IsNotOK) {
10782 0 : ErrorsFound = true;
10783 : } else {
10784 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10785 : }
10786 6 : } else if (SELECT_CASE_var == "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") {
10787 2 : ValidateComponent(m_state,
10788 : "Coil:Cooling:WaterToAirHeatPump:EquationFit",
10789 1 : DisSysCompCoilData(i).name,
10790 : IsNotOK,
10791 2 : format(RoutineName) + CurrentModuleObject);
10792 1 : if (IsNotOK) {
10793 0 : ErrorsFound = true;
10794 : }
10795 :
10796 5 : } else if (SELECT_CASE_var == "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT") {
10797 2 : ValidateComponent(m_state,
10798 : "Coil:Heating:WaterToAirHeatPump:EquationFit",
10799 1 : DisSysCompCoilData(i).name,
10800 : IsNotOK,
10801 2 : format(RoutineName) + CurrentModuleObject);
10802 1 : if (IsNotOK) {
10803 0 : ErrorsFound = true;
10804 : }
10805 4 : } else if (SELECT_CASE_var == "COIL:COOLING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT") {
10806 2 : ValidateComponent(m_state,
10807 : "Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit",
10808 1 : DisSysCompCoilData(i).name,
10809 : IsNotOK,
10810 2 : format(RoutineName) + CurrentModuleObject);
10811 1 : if (IsNotOK) {
10812 0 : ErrorsFound = true;
10813 : }
10814 :
10815 3 : } else if (SELECT_CASE_var == "COIL:HEATING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT") {
10816 2 : ValidateComponent(m_state,
10817 : "Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit",
10818 1 : DisSysCompCoilData(i).name,
10819 : IsNotOK,
10820 2 : format(RoutineName) + CurrentModuleObject);
10821 1 : if (IsNotOK) {
10822 0 : ErrorsFound = true;
10823 : }
10824 :
10825 2 : } else if (SELECT_CASE_var == "COIL:HEATING:DESUPERHEATER") {
10826 0 : ValidateComponent(
10827 0 : m_state, "Coil:Heating:Desuperheater", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10828 0 : if (IsNotOK) {
10829 0 : ErrorsFound = true;
10830 : }
10831 :
10832 2 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:TWOSPEED") {
10833 0 : ValidateComponent(
10834 0 : m_state, "Coil:Cooling:DX:TwoSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10835 0 : if (IsNotOK) {
10836 0 : ErrorsFound = true;
10837 : } else {
10838 0 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10839 : }
10840 2 : } else if (SELECT_CASE_var == "COIL:HEATING:ELECTRIC:MULTISTAGE") {
10841 2 : ValidateComponent(
10842 3 : m_state, "Coil:Heating:Electric:MultiStage", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10843 1 : if (IsNotOK) {
10844 0 : ErrorsFound = true;
10845 : } else {
10846 1 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10847 : }
10848 1 : } else if (SELECT_CASE_var == "COIL:HEATING:GAS:MULTISTAGE") {
10849 2 : ValidateComponent(
10850 3 : m_state, "Coil:Heating:Gas:MultiStage", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10851 1 : if (IsNotOK) {
10852 0 : ErrorsFound = true;
10853 : } else {
10854 1 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10855 : }
10856 : } else {
10857 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " Invalid coil type = " + DisSysCompCoilData(i).name);
10858 0 : ErrorsFound = true;
10859 : }
10860 11 : }
10861 : }
10862 :
10863 : // Validate terminal unit name and type
10864 17 : for (int i = 1; i <= DisSysNumOfTermUnits; ++i) {
10865 0 : if (Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:ConstantVolume:Reheat") ||
10866 0 : Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
10867 0 : LocalError = false;
10868 0 : if (Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:ConstantVolume:Reheat")) {
10869 0 : GetHVACSingleDuctSysIndex(
10870 0 : m_state, DisSysCompTermUnitData(i).name, n, LocalError, "AirflowNetwork:Distribution:Component:TerminalUnit");
10871 : }
10872 0 : if (Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
10873 0 : GetHVACSingleDuctSysIndex(m_state,
10874 0 : DisSysCompTermUnitData(i).name,
10875 : n,
10876 : LocalError,
10877 : "AirflowNetwork:Distribution:Component:TerminalUnit",
10878 0 : DisSysCompTermUnitData(i).DamperInletNode,
10879 0 : DisSysCompTermUnitData(i).DamperOutletNode);
10880 : }
10881 0 : if (LocalError) {
10882 0 : ErrorsFound = true;
10883 : }
10884 0 : if (VAVSystem) {
10885 0 : for (int j = 1; j <= DisSysNumOfCVFs; j++) {
10886 0 : if (DisSysCompCVFData(j).fanType == HVAC::FanType::VAV) {
10887 0 : if (DisSysCompCVFData(j).AirLoopNum == DisSysCompTermUnitData(i).AirLoopNum &&
10888 0 : !Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
10889 0 : ShowSevereError(m_state,
10890 0 : format(RoutineName) + CurrentModuleObject +
10891 0 : " Invalid terminal type for a VAV system = " + DisSysCompTermUnitData(i).name);
10892 0 : ShowContinueError(m_state, "The input type = " + DisSysCompTermUnitData(i).EPlusType);
10893 0 : ShowContinueError(m_state, "A VAV system requires all terminal units with type = AirTerminal:SingleDuct:VAV:Reheat");
10894 0 : ErrorsFound = true;
10895 : }
10896 : }
10897 : }
10898 : }
10899 : } else {
10900 0 : ShowSevereError(m_state,
10901 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT TERMINAL UNIT: Invalid Terminal unit type = " +
10902 0 : DisSysCompTermUnitData(i).name);
10903 0 : ErrorsFound = true;
10904 : }
10905 : }
10906 :
10907 : // Validate heat exchanger name and type
10908 17 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:HeatExchanger";
10909 17 : for (int i = 1; i <= DisSysNumOfHXs; ++i) {
10910 : {
10911 0 : auto const SELECT_CASE_var(Util::makeUPPER(DisSysCompHXData(i).EPlusType));
10912 :
10913 0 : if (SELECT_CASE_var == "HEATEXCHANGER:AIRTOAIR:FLATPLATE") {
10914 0 : ValidateComponent(
10915 0 : m_state, "HeatExchanger:AirToAir:FlatPlate", DisSysCompHXData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10916 0 : if (IsNotOK) {
10917 0 : ErrorsFound = true;
10918 : }
10919 :
10920 0 : } else if (SELECT_CASE_var == "HEATEXCHANGER:AIRTOAIR:SENSIBLEANDLATENT") {
10921 0 : ValidateComponent(m_state,
10922 : "HeatExchanger:AirToAir:SensibleAndLatent",
10923 0 : DisSysCompHXData(i).name,
10924 : IsNotOK,
10925 0 : format(RoutineName) + CurrentModuleObject);
10926 0 : if (IsNotOK) {
10927 0 : ErrorsFound = true;
10928 : }
10929 :
10930 0 : } else if (SELECT_CASE_var == "HEATEXCHANGER:DESICCANT:BALANCEDFLOW") {
10931 0 : ValidateComponent(m_state,
10932 : "HeatExchanger:Desiccant:BalancedFlow",
10933 0 : DisSysCompHXData(i).name,
10934 : IsNotOK,
10935 0 : format(RoutineName) + CurrentModuleObject);
10936 0 : if (IsNotOK) {
10937 0 : ErrorsFound = true;
10938 : }
10939 :
10940 : } else {
10941 0 : ShowSevereError(m_state,
10942 0 : format(RoutineName) + CurrentModuleObject + " Invalid heat exchanger type = " + DisSysCompHXData(i).EPlusType);
10943 0 : ErrorsFound = true;
10944 : }
10945 0 : }
10946 : }
10947 :
10948 : // Assign supply and return connection
10949 18 : for (int j = 1; j <= NumPrimaryAirSys; ++j) {
10950 1 : int S1 = 0;
10951 1 : int S2 = 0;
10952 1 : int R1 = 0;
10953 1 : int R2 = 0;
10954 35 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
10955 34 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).AirLoopSupplyNodeNum(1)) {
10956 1 : S1 = i;
10957 : }
10958 34 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).ZoneEquipSupplyNodeNum(1)) {
10959 1 : S2 = i;
10960 : }
10961 34 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).ZoneEquipReturnNodeNum(1)) {
10962 1 : R1 = i;
10963 : }
10964 34 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).AirLoopReturnNodeNum(1)) {
10965 1 : R2 = i;
10966 : }
10967 : }
10968 39 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
10969 38 : if (AirflowNetworkLinkageData(i).NodeNums[0] == R1 && AirflowNetworkLinkageData(i).NodeNums[1] == R2) {
10970 1 : AirflowNetworkLinkageData(i).ConnectionFlag = iEPlusComponentType::RCN;
10971 : }
10972 38 : if (AirflowNetworkLinkageData(i).NodeNums[0] == S1 && AirflowNetworkLinkageData(i).NodeNums[1] == S2) {
10973 1 : AirflowNetworkLinkageData(i).ConnectionFlag = iEPlusComponentType::SCN;
10974 : }
10975 : }
10976 : }
10977 :
10978 : // Assign fan inlet and outlet node, and coil outlet
10979 55 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
10980 38 : int j = AirflowNetworkLinkageData(i).CompNum;
10981 38 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::CVF) {
10982 1 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::Invalid) {
10983 1 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum = iEPlusNodeType::FIN;
10984 : }
10985 1 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::FOU;
10986 : }
10987 38 : if (AirflowNetworkCompData(j).EPlusTypeNum == iEPlusComponentType::COI) {
10988 3 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::COU;
10989 : }
10990 38 : if (AirflowNetworkCompData(j).EPlusTypeNum == iEPlusComponentType::HEX) {
10991 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::HXO;
10992 : }
10993 38 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::TMU) {
10994 0 : if (DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperInletNode > 0) {
10995 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum ==
10996 0 : DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperInletNode &&
10997 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum ==
10998 0 : DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperOutletNode) {
10999 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum = iEPlusNodeType::DIN;
11000 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::DOU;
11001 0 : AirflowNetworkLinkageData(i).VAVTermDamper = true;
11002 : }
11003 : }
11004 : }
11005 : }
11006 :
11007 : // Validate the position of constant pressure drop component
11008 17 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ConstantPressureDrop";
11009 55 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
11010 38 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::CPD) {
11011 0 : for (int j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
11012 0 : if (AirflowNetworkLinkageData(i).NodeNums[0] == AirflowNetworkLinkageData(j).NodeNums[1]) {
11013 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(j).CompNum).CompTypeNum != iComponentTypeNum::DWC) {
11014 0 : ShowSevereError(m_state,
11015 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName +
11016 : ')');
11017 0 : ShowContinueError(m_state, "must connect a duct component upstream and not " + AirflowNetworkLinkageData(j).Name);
11018 0 : ErrorsFound = true;
11019 : }
11020 : }
11021 : }
11022 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::SPL) {
11023 0 : ShowSevereError(m_state,
11024 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
11025 0 : ShowContinueError(m_state,
11026 0 : "does not allow a AirLoopHVAC:ZoneSplitter node = " +
11027 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
11028 0 : ErrorsFound = true;
11029 : }
11030 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum == iEPlusNodeType::SPL) {
11031 0 : ShowSevereError(m_state,
11032 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
11033 0 : ShowContinueError(m_state,
11034 0 : "does not allow a AirLoopHVAC:ZoneSplitter node = " +
11035 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
11036 0 : ErrorsFound = true;
11037 : }
11038 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::MIX) {
11039 0 : ShowSevereError(m_state,
11040 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
11041 0 : ShowContinueError(m_state,
11042 0 : "does not allow a AirLoopHVAC:ZoneMixer node = " +
11043 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
11044 0 : ErrorsFound = true;
11045 : }
11046 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum == iEPlusNodeType::MIX) {
11047 0 : ShowSevereError(m_state,
11048 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
11049 0 : ShowContinueError(m_state,
11050 0 : "does not allow a AirLoopHVAC:ZoneMixer node = " +
11051 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
11052 0 : ErrorsFound = true;
11053 : }
11054 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
11055 0 : ShowSevereError(m_state,
11056 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
11057 0 : ShowContinueError(m_state,
11058 0 : "does not allow to connect an EnergyPlus node = " +
11059 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
11060 0 : ErrorsFound = true;
11061 : }
11062 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
11063 0 : ShowSevereError(m_state,
11064 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
11065 0 : ShowContinueError(m_state,
11066 0 : "does not allow to connect an EnergyPlus node = " +
11067 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
11068 0 : ErrorsFound = true;
11069 : }
11070 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) {
11071 0 : ShowSevereError(m_state,
11072 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
11073 0 : ShowContinueError(m_state,
11074 0 : "does not allow to connect an EnergyPlus zone = " +
11075 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
11076 0 : ErrorsFound = true;
11077 : }
11078 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) {
11079 0 : ShowSevereError(m_state,
11080 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
11081 0 : ShowContinueError(m_state,
11082 0 : "does not allow to connect an EnergyPlus zone = " +
11083 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
11084 0 : ErrorsFound = true;
11085 : }
11086 : }
11087 : }
11088 :
11089 42 : for (int i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
11090 25 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::SPL) {
11091 1 : LocalError = false;
11092 1 : int j = GetSplitterOutletNumber(m_state, "", 1, LocalError);
11093 1 : SplitterNodeNumbers.allocate(j + 2);
11094 1 : SplitterNodeNumbers = GetSplitterNodeNumbers(m_state, "", 1, LocalError);
11095 1 : if (LocalError) {
11096 0 : ErrorsFound = true;
11097 : }
11098 : }
11099 : }
11100 :
11101 : // Assigning inlet and outlet nodes for a splitter
11102 62 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
11103 45 : if (AirflowNetworkNodeData(i).EPlusNodeNum == SplitterNodeNumbers(1)) {
11104 1 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::Invalid) {
11105 1 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPI;
11106 : }
11107 : }
11108 79 : for (int j = 1; j <= SplitterNodeNumbers(2); ++j) {
11109 34 : if (AirflowNetworkNodeData(i).EPlusNodeNum == SplitterNodeNumbers(j + 2)) {
11110 1 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::Invalid) {
11111 1 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPO;
11112 : }
11113 : }
11114 : }
11115 : }
11116 :
11117 : // Add additional output variables
11118 17 : if (DisSysNumOfCVFs > 1) {
11119 0 : bool OnOffFanFlag = false;
11120 0 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
11121 0 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff && !DisSysCompCVFData(i).FanModelFlag) {
11122 0 : OnOffFanFlag = true;
11123 0 : break;
11124 : }
11125 0 : if (DisSysCompCVFData(i).FanModelFlag && DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
11126 0 : int fanIndex = Fans::GetFanIndex(m_state, DisSysCompCVFData(i).name);
11127 0 : if (m_state.dataFans->fans(fanIndex)->airPathFlag) {
11128 0 : DisSysCompCVFData(i).fanType = HVAC::FanType::Constant;
11129 : } else {
11130 0 : OnOffFanFlag = true;
11131 0 : break;
11132 : }
11133 : }
11134 : }
11135 0 : if (OnOffFanFlag) {
11136 0 : for (int j = 1; j <= AirflowNetworkNumOfZones; ++j) {
11137 0 : if (!m_state.dataZoneEquip->ZoneEquipConfig(AirflowNetworkNodeData(j).EPlusZoneNum).IsControlled) {
11138 0 : continue;
11139 : }
11140 0 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
11141 0 : if (DisSysCompCVFData(i).AirLoopNum == AirflowNetworkNodeData(j).AirLoopNum &&
11142 0 : DisSysCompCVFData(i).fanType != HVAC::FanType::OnOff) {
11143 0 : SetupOutputVariable(m_state,
11144 : "AFN Node Total Pressure",
11145 : Constant::Units::Pa,
11146 0 : AirflowNetworkNodeSimu(j).PZ,
11147 : OutputProcessor::TimeStepType::System,
11148 : OutputProcessor::StoreType::Average,
11149 0 : AirflowNetworkNodeData(j).Name);
11150 : }
11151 : }
11152 : }
11153 0 : for (int i = 1; i <= NumOfLinksMultiZone; ++i) {
11154 0 : if (!m_state.dataZoneEquip->ZoneEquipConfig(AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum)
11155 0 : .IsControlled) {
11156 0 : continue;
11157 : }
11158 0 : for (int j = 1; j <= DisSysNumOfCVFs; j++) {
11159 0 : if (DisSysCompCVFData(j).AirLoopNum == AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).AirLoopNum &&
11160 0 : DisSysCompCVFData(j).fanType != HVAC::FanType::OnOff) {
11161 0 : SetupOutputVariable(m_state,
11162 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
11163 : Constant::Units::kg_s,
11164 0 : linkReport(i).FLOW,
11165 : OutputProcessor::TimeStepType::System,
11166 : OutputProcessor::StoreType::Average,
11167 0 : AirflowNetworkLinkageData(i).Name);
11168 0 : SetupOutputVariable(m_state,
11169 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
11170 : Constant::Units::kg_s,
11171 0 : linkReport(i).FLOW2,
11172 : OutputProcessor::TimeStepType::System,
11173 : OutputProcessor::StoreType::Average,
11174 0 : AirflowNetworkLinkageData(i).Name);
11175 0 : SetupOutputVariable(m_state,
11176 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
11177 : Constant::Units::m3_s,
11178 0 : linkReport(i).VolFLOW,
11179 : OutputProcessor::TimeStepType::System,
11180 : OutputProcessor::StoreType::Average,
11181 0 : AirflowNetworkLinkageData(i).Name);
11182 0 : SetupOutputVariable(m_state,
11183 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
11184 : Constant::Units::m3_s,
11185 0 : linkReport(i).VolFLOW2,
11186 : OutputProcessor::TimeStepType::System,
11187 : OutputProcessor::StoreType::Average,
11188 0 : AirflowNetworkLinkageData(i).Name);
11189 0 : SetupOutputVariable(m_state,
11190 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
11191 : Constant::Units::Pa,
11192 0 : AirflowNetworkLinkSimu(i).DP,
11193 : OutputProcessor::TimeStepType::System,
11194 : OutputProcessor::StoreType::Average,
11195 0 : AirflowNetworkLinkageData(i).Name);
11196 : }
11197 : }
11198 : }
11199 : }
11200 : }
11201 17 : bool FanModelConstFlag = false;
11202 18 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
11203 1 : if (DisSysCompCVFData(i).FanModelFlag) {
11204 0 : int fanIndex = Fans::GetFanIndex(m_state, DisSysCompCVFData(i).name); // What is this accomplishing here?
11205 0 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff && m_state.dataFans->fans(fanIndex)->airPathFlag) {
11206 0 : DisSysCompCVFData(i).fanType = HVAC::FanType::Constant;
11207 0 : supplyFanType = HVAC::FanType::Constant;
11208 0 : FanModelConstFlag = true;
11209 0 : break;
11210 : }
11211 : }
11212 : }
11213 17 : if (FanModelConstFlag) {
11214 0 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
11215 0 : if (supplyFanType == HVAC::FanType::Constant) {
11216 0 : SetupOutputVariable(m_state,
11217 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
11218 : Constant::Units::kg_s,
11219 0 : linkReport(i).FLOW,
11220 : OutputProcessor::TimeStepType::System,
11221 : OutputProcessor::StoreType::Average,
11222 0 : AirflowNetworkLinkageData(i).Name);
11223 0 : SetupOutputVariable(m_state,
11224 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
11225 : Constant::Units::kg_s,
11226 0 : linkReport(i).FLOW2,
11227 : OutputProcessor::TimeStepType::System,
11228 : OutputProcessor::StoreType::Average,
11229 0 : AirflowNetworkLinkageData(i).Name);
11230 0 : SetupOutputVariable(m_state,
11231 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
11232 : Constant::Units::m3_s,
11233 0 : linkReport(i).VolFLOW,
11234 : OutputProcessor::TimeStepType::System,
11235 : OutputProcessor::StoreType::Average,
11236 0 : AirflowNetworkLinkageData(i).Name);
11237 0 : SetupOutputVariable(m_state,
11238 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
11239 : Constant::Units::m3_s,
11240 0 : linkReport(i).VolFLOW2,
11241 : OutputProcessor::TimeStepType::System,
11242 : OutputProcessor::StoreType::Average,
11243 0 : AirflowNetworkLinkageData(i).Name);
11244 0 : SetupOutputVariable(m_state,
11245 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
11246 : Constant::Units::Pa,
11247 0 : AirflowNetworkLinkSimu(i).DP,
11248 : OutputProcessor::TimeStepType::System,
11249 : OutputProcessor::StoreType::Average,
11250 0 : AirflowNetworkLinkageData(i).Name);
11251 : }
11252 : }
11253 : }
11254 :
11255 : // Add AirLoopNum to pressure control object
11256 17 : for (int i = 1; i <= NumOfPressureControllers; ++i) {
11257 0 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11258 0 : if (PressureControllerData(i).ZoneNum == j) {
11259 0 : for (int k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumInletNodes; ++k) {
11260 0 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(k) > 0) {
11261 0 : PressureControllerData(i).AirLoopNum = m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(k);
11262 0 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlRelief) {
11263 0 : PressureControllerData(i).OANodeNum =
11264 0 : m_state.dataAirSystemsData->PrimaryAirSystems(PressureControllerData(i).AirLoopNum).OAMixOAInNodeNum;
11265 0 : for (n = 1; n <= NumOfReliefFans; ++n) {
11266 0 : if (DisSysCompReliefAirData(n).OutletNode == PressureControllerData(i).OANodeNum) {
11267 0 : DisSysCompReliefAirData(n).PressCtrlNum = i;
11268 : }
11269 : }
11270 : }
11271 0 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlExhaust) {
11272 0 : PressureControllerData(i).OANodeNum =
11273 0 : m_state.dataZoneEquip->ZoneEquipConfig(PressureControllerData(i).ZoneNum).ExhaustNode(1);
11274 0 : for (n = 1; n <= AirflowNetworkNumOfExhFan; ++n) {
11275 0 : if (MultizoneCompExhaustFanData(n).EPlusZoneNum == PressureControllerData(i).ZoneNum) {
11276 0 : MultizoneCompExhaustFanData(n).PressCtrlNum = i;
11277 : }
11278 : }
11279 : }
11280 : }
11281 : }
11282 : }
11283 : }
11284 : }
11285 :
11286 : // Check number of fans specified in an AirLoop #6748
11287 : int BranchNum;
11288 : int NumOfFans;
11289 17 : std::string FanNames;
11290 33 : for (BranchNum = 1; BranchNum <= m_state.dataAirSystemsData->PrimaryAirSystems(1).NumBranches; ++BranchNum) {
11291 17 : NumOfFans = 0;
11292 17 : FanNames = "";
11293 37 : for (int CompNum = 1; CompNum <= m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).TotalComponents; ++CompNum) {
11294 29 : if (Util::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf, "Fan:ConstantVolume") ||
11295 29 : Util::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf, "Fan:OnOff") ||
11296 29 : Util::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf, "Fan:VariableVolume")) {
11297 14 : NumOfFans++;
11298 14 : if (NumOfFans > 1) {
11299 1 : FanNames += m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).Name;
11300 1 : break;
11301 : } else {
11302 13 : FanNames += m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).Name + ",";
11303 : }
11304 : }
11305 : }
11306 17 : if (NumOfFans > 1) {
11307 1 : break;
11308 : }
11309 : }
11310 17 : if (NumOfFans > 1) {
11311 2 : ShowSevereError(m_state,
11312 2 : format(RoutineName) + "An AirLoop branch, " + m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Name +
11313 2 : ", has two or more fans: " + FanNames);
11314 2 : ShowContinueError(m_state,
11315 : "The AirflowNetwork model allows a single supply fan in an AirLoop only. Please make changes in the input "
11316 : "file accordingly.");
11317 1 : ErrorsFound = true;
11318 : }
11319 :
11320 17 : if (ErrorsFound) {
11321 12 : ShowFatalError(m_state, format("{}Program terminates for preceding reason(s).", RoutineName));
11322 : }
11323 35 : }
11324 :
11325 1 : void Solver::validate_fan_flowrate()
11326 : {
11327 :
11328 : // Catch a fan flow rate from EPlus input file and add a flag for VAV terminal damper
11329 39 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
11330 38 : switch (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum) {
11331 1 : case iComponentTypeNum::CVF: { // 'CVF'
11332 1 : int typeNum = AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum;
11333 1 : if (DisSysCompCVFData(typeNum).fanType == HVAC::FanType::VAV) {
11334 0 : DisSysCompCVFData(typeNum).MaxAirMassFlowRate =
11335 0 : m_state.dataFans->fans(DisSysCompCVFData(typeNum).FanIndex)->maxAirFlowRate * m_state.dataEnvrn->StdRhoAir;
11336 : }
11337 1 : } break;
11338 0 : case iComponentTypeNum::FAN:
11339 : case iComponentTypeNum::SOP:
11340 : case iComponentTypeNum::TMU:
11341 0 : break;
11342 37 : default:
11343 37 : break;
11344 : }
11345 : }
11346 1 : }
11347 :
11348 16853 : void Solver::validate_exhaust_fan_input()
11349 : {
11350 :
11351 : // SUBROUTINE INFORMATION:
11352 : // AUTHOR Lixing Gu
11353 : // DATE WRITTEN Dec. 2006
11354 : // MODIFIED na
11355 : // RE-ENGINEERED na
11356 :
11357 : // PURPOSE OF THIS SUBROUTINE:
11358 : // This subroutine validate zone exhaust fan and associated surface
11359 :
11360 : // SUBROUTINE PARAMETER DEFINITIONS:
11361 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::validate_exhaust_fan_input: "); // include trailing blank space
11362 :
11363 : // Validate supply and return connections
11364 16853 : if (ValidateExhaustFanInputOneTimeFlag) {
11365 2 : bool ErrorsFound = false;
11366 2 : std::string const CurrentModuleObject = "AirflowNetwork:MultiZone:Component:ZoneExhaustFan";
11367 2 : if (std::any_of(m_state.dataZoneEquip->ZoneEquipConfig.begin(),
11368 2 : m_state.dataZoneEquip->ZoneEquipConfig.end(),
11369 2 : [](DataZoneEquipment::EquipConfiguration const &e) { return e.IsControlled; })) {
11370 2 : AirflowNetworkZoneExhaustFan.dimension(m_state.dataGlobal->NumOfZones, false);
11371 : }
11372 : // Ensure the number of exhaust fan defined in the AirflowNetwork model matches the number of Zone Exhaust Fan objects
11373 2 : if (NumOfExhaustFans != AirflowNetworkNumOfExhFan) {
11374 0 : ShowSevereError(
11375 : m_state,
11376 0 : format("{}The number of {} is not equal to the number of Fan:ZoneExhaust fans defined in ZoneHVAC:EquipmentConnections",
11377 : RoutineName,
11378 : CurrentModuleObject));
11379 0 : ShowContinueError(m_state, format("The number of {} is {}", CurrentModuleObject, AirflowNetworkNumOfExhFan));
11380 0 : ShowContinueError(m_state,
11381 0 : format("The number of Zone exhaust fans defined in ZoneHVAC:EquipmentConnections is {}", NumOfExhaustFans));
11382 0 : ErrorsFound = true;
11383 : }
11384 :
11385 4 : for (int i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
11386 : // Get zone number
11387 8 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11388 6 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) {
11389 4 : continue;
11390 : }
11391 5 : for (int k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumExhaustNodes; ++k) {
11392 4 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).ExhaustNode(k) == MultizoneCompExhaustFanData(i).InletNode) {
11393 1 : MultizoneCompExhaustFanData(i).EPlusZoneNum = j;
11394 1 : break;
11395 : }
11396 : }
11397 : }
11398 2 : if (MultizoneCompExhaustFanData(i).EPlusZoneNum == 0) {
11399 0 : ShowSevereError(m_state,
11400 0 : format("{}Zone name in {} = {} does not match the zone name in ZoneHVAC:EquipmentConnections",
11401 : RoutineName,
11402 : CurrentModuleObject,
11403 0 : MultizoneCompExhaustFanData(i).name));
11404 0 : ErrorsFound = true;
11405 : }
11406 : // Ensure a surface using zone exhaust fan to expose to the same zone
11407 2 : bool found = false;
11408 : int j;
11409 38 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
11410 38 : if (Util::SameString(MultizoneSurfaceData(j).OpeningName, MultizoneCompExhaustFanData(i).name)) {
11411 2 : found = true;
11412 2 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond != ExternalEnvironment &&
11413 0 : !(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
11414 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
11415 0 : ShowSevereError(m_state,
11416 0 : format("{}The surface using {} is not an exterior surface: {}",
11417 : RoutineName,
11418 : CurrentModuleObject,
11419 0 : MultizoneSurfaceData(j).SurfName));
11420 0 : ErrorsFound = true;
11421 : }
11422 2 : break;
11423 : }
11424 : }
11425 2 : if (!found) {
11426 0 : ShowSevereError(m_state, CurrentModuleObject + " = " + MultizoneCompExhaustFanData(i).name + " is defined and never used.");
11427 0 : ErrorsFound = true;
11428 : } else {
11429 2 : if (MultizoneCompExhaustFanData(i).EPlusZoneNum != m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Zone) {
11430 0 : ShowSevereError(m_state,
11431 0 : format("{}Zone name in {} = {} does not match the zone name",
11432 : RoutineName,
11433 : CurrentModuleObject,
11434 0 : MultizoneCompExhaustFanData(i).name));
11435 0 : ShowContinueError(m_state, "the surface is exposed to " + m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Name);
11436 0 : ErrorsFound = true;
11437 : } else {
11438 2 : AirflowNetworkZoneExhaustFan(MultizoneCompExhaustFanData(i).EPlusZoneNum) = true;
11439 : }
11440 : }
11441 : }
11442 :
11443 : // Ensure all zone exhaust fans are defined
11444 8 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11445 6 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) {
11446 4 : continue;
11447 : }
11448 8 : for (int EquipTypeNum = 1; EquipTypeNum <= m_state.dataZoneEquip->ZoneEquipList(j).NumOfEquipTypes; ++EquipTypeNum) {
11449 6 : if (m_state.dataZoneEquip->ZoneEquipList(j).EquipType(EquipTypeNum) == DataZoneEquipment::ZoneEquipType::ExhaustFan) {
11450 2 : bool found = false;
11451 6 : for (int k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumExhaustNodes; ++k) {
11452 8 : for (int i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
11453 4 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).ExhaustNode(k) == MultizoneCompExhaustFanData(i).InletNode) {
11454 1 : MultizoneCompExhaustFanData(i).EPlusZoneNum = j;
11455 1 : found = true;
11456 : }
11457 : }
11458 : }
11459 2 : if (!found) {
11460 1 : ShowSevereError(m_state, format("{}Fan:ZoneExhaust is not defined in {}", RoutineName, CurrentModuleObject));
11461 2 : ShowContinueError(
11462 : m_state,
11463 2 : format("The inlet node of the {} Fan:ZoneExhaust is not defined in the {}'s ZoneHVAC:EquipmentConnections",
11464 1 : m_state.dataZoneEquip->ZoneEquipList(j).EquipName,
11465 1 : m_state.dataZoneEquip->ZoneEquipConfig(j).ZoneName));
11466 1 : ErrorsFound = true;
11467 : }
11468 : }
11469 : }
11470 : }
11471 :
11472 2 : ValidateExhaustFanInputOneTimeFlag = false;
11473 2 : if (ErrorsFound) {
11474 2 : ShowFatalError(m_state, format("{}Program terminates for preceding reason(s).", RoutineName));
11475 : }
11476 2 : } // End if OneTimeFlag_FindFirstLastPtr
11477 16852 : }
11478 :
11479 0 : void Solver::hybrid_ventilation_control()
11480 : {
11481 :
11482 : // SUBROUTINE INFORMATION:
11483 : // AUTHOR Lixing Gu
11484 : // DATE WRITTEN Dec. 2006
11485 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone hybrid ventilation managers
11486 :
11487 : // PURPOSE OF THIS SUBROUTINE:
11488 : // This subroutine performs hybrid ventilation control
11489 :
11490 : // SUBROUTINE PARAMETER DEFINITIONS:
11491 0 : int constexpr IndividualCtrlType(0); // Individual window or door control
11492 0 : int constexpr GlobalCtrlType(1); // Global window or door control
11493 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::hybrid_ventilation_control: "); // include trailing blank space
11494 :
11495 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11496 : int SysAvailNum; // Hybrid ventilation control number
11497 : int ControlledZoneNum; // Controlled zone number
11498 : int ANSurfaceNum; // AirflowNetwork Surface Number
11499 : int SurfNum; // Surface number
11500 : int ControlType; // Hybrid ventilation control type: 0 individual; 1 global
11501 :
11502 0 : for (auto &e : MultizoneSurfaceData) {
11503 0 : e.HybridVentClose = false;
11504 0 : e.HybridCtrlGlobal = false;
11505 0 : e.HybridCtrlMaster = false;
11506 0 : e.WindModifier = 1.0;
11507 0 : }
11508 0 : ControlType = IndividualCtrlType;
11509 :
11510 0 : for (SysAvailNum = 1; SysAvailNum <= m_state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
11511 0 : auto &hybridVentMgr = m_state.dataAvail->HybridVentData(SysAvailNum);
11512 0 : int AirLoopNum = hybridVentMgr.AirLoopNum;
11513 0 : ventCtrlStatus = hybridVentMgr.ctrlStatus;
11514 0 : if (hybridVentMgr.afnControlTypeSched != nullptr) {
11515 0 : ControlType = static_cast<int>(hybridVentMgr.afnControlTypeSched->getCurrentVal());
11516 : }
11517 0 : bool Found = false; // Logical to indicate whether a master surface is found or not
11518 0 : int ActualZoneNum = 0;
11519 0 : for (ControlledZoneNum = 1; ControlledZoneNum <= m_state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
11520 0 : if (!m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).IsControlled) {
11521 0 : continue;
11522 : }
11523 : // Ensure all the zones served by this AirLoopHVAC to be controlled by the hybrid ventilation
11524 0 : for (int zoneInNode = 1; zoneInNode <= m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
11525 0 : if (AirLoopNum > 0) {
11526 0 : if (AirLoopNum == m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode)) {
11527 0 : ActualZoneNum = ControlledZoneNum;
11528 0 : break;
11529 : }
11530 : } else {
11531 0 : if (hybridVentMgr.ControlledZoneNum == ControlledZoneNum) {
11532 0 : ActualZoneNum = hybridVentMgr.ControlledZoneNum;
11533 : }
11534 : }
11535 : }
11536 0 : if (ActualZoneNum > 0) {
11537 0 : for (ANSurfaceNum = 1; ANSurfaceNum <= AirflowNetworkNumOfSurfaces; ++ANSurfaceNum) {
11538 0 : SurfNum = MultizoneSurfaceData(ANSurfaceNum).SurfNum;
11539 0 : auto const &surf = m_state.dataSurface->Surface(SurfNum);
11540 :
11541 0 : if (surf.Zone == ActualZoneNum) {
11542 0 : if (ventCtrlStatus == Avail::VentCtrlStatus::Close) {
11543 0 : MultizoneSurfaceData(ANSurfaceNum).HybridVentClose = true;
11544 : } else {
11545 0 : if (hybridVentMgr.WindModifier >= 0) {
11546 0 : MultizoneSurfaceData(ANSurfaceNum).WindModifier = hybridVentMgr.WindModifier;
11547 : }
11548 0 : if (ControlType == GlobalCtrlType) {
11549 0 : MultizoneSurfaceData(ANSurfaceNum).HybridCtrlGlobal = true;
11550 0 : if (hybridVentMgr.Master == ActualZoneNum) {
11551 0 : if ((surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
11552 0 : surf.OriginalClass == SurfaceClass::GlassDoor) &&
11553 0 : surf.ExtBoundCond == ExternalEnvironment) {
11554 0 : MultizoneSurfaceData(ANSurfaceNum).HybridCtrlMaster = true;
11555 0 : Found = true;
11556 : }
11557 : }
11558 : }
11559 : }
11560 : }
11561 : }
11562 : }
11563 : }
11564 0 : if (ControlType == GlobalCtrlType && !Found && !m_state.dataGlobal->WarmupFlag && ventCtrlStatus != Avail::VentCtrlStatus::Close) {
11565 0 : ++HybridGlobalErrCount;
11566 0 : if (HybridGlobalErrCount < 2) {
11567 0 : ShowWarningError(m_state,
11568 0 : format("{}The hybrid ventilation control schedule value indicates global control in the controlled zone = {}",
11569 : RoutineName,
11570 0 : m_state.dataHeatBal->Zone(hybridVentMgr.Master).Name));
11571 0 : ShowContinueError(m_state,
11572 : "The exterior surface containing an opening component in the controlled zone is not found. No global control "
11573 : "will not be modeled.");
11574 0 : ShowContinueError(m_state, "The individual control is assumed.");
11575 0 : ShowContinueErrorTimeStamp(m_state, "");
11576 : } else {
11577 0 : ShowRecurringWarningErrorAtEnd(
11578 : m_state,
11579 0 : format("{}The hybrid ventilation control requires a global control. The individual control continues...", RoutineName),
11580 0 : HybridGlobalErrIndex,
11581 0 : double(ControlType),
11582 0 : double(ControlType));
11583 : }
11584 : }
11585 : }
11586 0 : }
11587 :
11588 2 : void Solver::single_sided_Cps(std::vector<std::vector<Real64>> &valsByFacade, int numWindDir)
11589 : {
11590 : // SUBROUTINE INFORMATION:
11591 : // AUTHOR Sam Brunswick
11592 : // DATE WRITTEN September 2013
11593 : // MODIFIED Revised by J. DeGraw, May 2017, to use tables
11594 : // RE-ENGINEERED n/a
11595 :
11596 : // PURPOSE OF THIS SUBROUTINE:
11597 : // Modify the wind pressure coefficients for single sided ventilation.
11598 :
11599 : // Using/Aliasing
11600 : using namespace DataEnvironment;
11601 :
11602 : // Locals
11603 : int windDirNum;
11604 :
11605 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11606 : int AFNZnNum; // counters
11607 : int SrfNum;
11608 : int ExtOpenNum;
11609 : int ZnNum;
11610 : int DetOpenNum; // row index of surface in MultizoneCompDetOpeningData
11611 : int SimOpenNum; // row index of surface in MultizoneCompSimOpeningData
11612 : int MZDZoneNum; // row index of surface zone in MultizoneZoneData
11613 : Real64 X1;
11614 : Real64 Y1;
11615 : Real64 X2;
11616 : Real64 Y2;
11617 : Real64 ZoneAng1;
11618 : Real64 ZoneAng2;
11619 : Real64 ZoneAngDiff;
11620 2 : Array1D<Real64> ZoneAng; // Azimuth angle of the exterior wall of the zone
11621 2 : Array1D<Real64> PiFormula; // Formula for the mean pressure difference
11622 2 : Array1D<Real64> SigmaFormula; // Formula for the fluctuating pressure difference
11623 2 : Array1D<Real64> Sprime; // The dimensionless ratio of the window separation to the building width
11624 2 : Array1D<Real64> CPV1; // Wind pressure coefficient for the first opening in the zone
11625 2 : Array1D<Real64> CPV2; // Wind pressure coefficient for the second opening in the zone
11626 2 : Array1D_int NumofExtSurfInZone; // List of the number of exterior openings in each zone
11627 :
11628 : struct AFNExtSurfacesProp // External opening information
11629 : {
11630 : // Members
11631 : int SurfNum; // row index of the external opening in the Surface array
11632 : std::string SurfName; // Surface name
11633 : int MSDNum; // row index of the external opening in the MultizoneSurfaceData array
11634 : int ZoneNum; // EnergyPlus zone number
11635 : int MZDZoneNum; // row index of the zone in the MultizoneZoneData array
11636 : int ExtNodeNum; // External node number; = row index in MultizoneExternalNodeData array +
11637 : // AirflowNetworkNumOfZones
11638 : std::string ZoneName; // EnergyPlus zone name
11639 : int facadeNum;
11640 : int curve; // wind pressure coefficient curve index
11641 : iComponentTypeNum CompTypeNum; // Opening type (detailed, simple, etc.)
11642 : Real64 NodeHeight; // Elevation of the opening node
11643 : Real64 OpeningArea; // Opening area (=Height*Width)
11644 : Real64 Height; // Opening height = MultizoneSurfaceData()%Height
11645 : Real64 Width; // Opening width = MultizoneSurfaceData()%Width
11646 : Real64 DischCoeff; // Opening discharge coefficient
11647 :
11648 : // Default Constructor
11649 4 : AFNExtSurfacesProp()
11650 12 : : SurfNum(0), MSDNum(0), ZoneNum(0), MZDZoneNum(0), ExtNodeNum(0), facadeNum(0), curve(0), CompTypeNum(iComponentTypeNum::Invalid),
11651 4 : NodeHeight(0.0), OpeningArea(0.0), Height(0.0), Width(0.0), DischCoeff(0.0)
11652 : {
11653 4 : }
11654 : };
11655 :
11656 : // Object Data
11657 2 : Array1D<AFNExtSurfacesProp> AFNExtSurfaces; // Surface numbers of all exterior openings
11658 : // Count the total number of exterior simple and detailed openings and the number in each zone
11659 : // Verify that each zone with "ADVANCED" single sided wind pressure coefficients has exactly two openings.
11660 : // If it doesn't have two openings, change "ADVANCED" to "STANDARD"
11661 2 : NumofExtSurfInZone.dimension(AirflowNetworkNumOfZones, 0);
11662 4 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
11663 2 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
11664 8 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11665 6 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond ==
11666 : ExternalEnvironment) { // check if outdoor boundary condition
11667 6 : MZDZoneNum = Util::FindItemInList(m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName,
11668 6 : MultizoneZoneData,
11669 : &MultizoneZoneProp::ZoneName);
11670 6 : if (MZDZoneNum == AFNZnNum) {
11671 : // This is terrible, should not do it this way
11672 6 : auto afe = elements.find(MultizoneSurfaceData(SrfNum).OpeningName);
11673 6 : if (afe != elements.end()) {
11674 6 : auto type = afe->second->type();
11675 6 : if (type == ComponentType::DOP) {
11676 4 : ++AFNNumOfExtOpenings;
11677 4 : ++NumofExtSurfInZone(AFNZnNum);
11678 2 : } else if (type == ComponentType::SOP) {
11679 0 : ++AFNNumOfExtOpenings;
11680 0 : ++NumofExtSurfInZone(AFNZnNum);
11681 : }
11682 : }
11683 6 : }
11684 : }
11685 : }
11686 2 : if (NumofExtSurfInZone(AFNZnNum) == 0) {
11687 0 : ShowWarningError(m_state,
11688 0 : "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName +
11689 : " has single side wind pressure coefficient type \"ADVANCED\", but has no exterior "
11690 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or AirflowNetwork:MultiZone:Component:SimpleOpening "
11691 : "objects.");
11692 0 : ShowContinueError(m_state,
11693 : "Zones must have exactly two exterior openings in order for the \"ADVANCED\" single sided wind pressure "
11694 : "coefficient model to be used.");
11695 0 : ShowContinueError(m_state,
11696 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11697 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11698 2 : } else if (NumofExtSurfInZone(AFNZnNum) == 1) {
11699 0 : ShowWarningError(m_state, "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName);
11700 0 : ShowContinueError(m_state,
11701 : "has single side wind pressure coefficient type \"ADVANCED\", but has only one exterior "
11702 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or "
11703 : "AirflowNetwork:MultiZone:Component:SimpleOpening objects.");
11704 0 : ShowContinueError(m_state,
11705 : "Zones must have exactly two openings in order for the \"ADVANCED\" single side wind pressure coefficient "
11706 : "model to be used.");
11707 0 : ShowContinueError(m_state,
11708 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11709 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11710 2 : } else if (NumofExtSurfInZone(AFNZnNum) > 2) {
11711 0 : ShowWarningError(m_state,
11712 0 : format("AirflowNetwork:Multizone:Zone = {} has single side wind pressure coefficient type "
11713 : "\"ADVANCED\", but has {} exterior "
11714 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or "
11715 : "AirflowNetwork:MultiZone:Component:SimpleOpening objects.",
11716 0 : MultizoneZoneData(AFNZnNum).ZoneName,
11717 : NumofExtSurfInZone(AFNZnNum)));
11718 0 : ShowContinueError(m_state,
11719 : "Zones must have exactly two openings in order for the \"ADVANCED\" single side wind pressure coefficient "
11720 : "model to be used.");
11721 0 : ShowContinueError(m_state,
11722 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11723 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11724 : }
11725 : }
11726 : }
11727 2 : if (AFNNumOfExtOpenings == 0) {
11728 0 : return;
11729 : }
11730 : // Recount the number of single sided zones
11731 2 : AirflowNetworkNumOfSingleSideZones = 0;
11732 4 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
11733 2 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
11734 2 : ++AirflowNetworkNumOfSingleSideZones;
11735 : }
11736 : }
11737 2 : if (AirflowNetworkNumOfSingleSideZones == 0) {
11738 0 : return; // Bail if no zones call for the advanced single sided model.
11739 : }
11740 : // Recount the number of detailed and simple exterior openings in zones with "ADVANCED" single sided wind pressure coefficients
11741 2 : AFNNumOfExtOpenings = 0;
11742 8 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11743 6 : MZDZoneNum = Util::FindItemInList(
11744 6 : m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11745 6 : if (MultizoneZoneData(MZDZoneNum).SingleSidedCpType == "ADVANCED") {
11746 6 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond ==
11747 : ExternalEnvironment) { // check if outdoor boundary condition
11748 : // This is terrible, should not do it this way
11749 6 : auto afe = elements.find(MultizoneSurfaceData(SrfNum).OpeningName);
11750 6 : if (afe != elements.end()) {
11751 6 : auto type = afe->second->type();
11752 6 : if (type == ComponentType::DOP) {
11753 4 : ++AFNNumOfExtOpenings;
11754 2 : } else if (type == ComponentType::SOP) {
11755 0 : ++AFNNumOfExtOpenings;
11756 : }
11757 : }
11758 6 : }
11759 : }
11760 : }
11761 2 : AFNExtSurfaces.allocate(AFNNumOfExtOpenings);
11762 : // Create array of properties for all the exterior single sided openings
11763 2 : ExtOpenNum = 1;
11764 8 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11765 6 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond == ExternalEnvironment) {
11766 6 : if (AirflowNetworkNumOfDetOpenings > 0) {
11767 6 : DetOpenNum = Util::FindItemInList(
11768 6 : MultizoneSurfaceData(SrfNum).OpeningName, MultizoneCompDetOpeningData, &AirflowNetwork::DetailedOpening::name);
11769 6 : MZDZoneNum = Util::FindItemInList(
11770 6 : m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11771 6 : if (MultizoneZoneData(MZDZoneNum).SingleSidedCpType == "ADVANCED") {
11772 6 : if (DetOpenNum > 0) {
11773 4 : AFNExtSurfaces(ExtOpenNum).MSDNum = SrfNum;
11774 4 : AFNExtSurfaces(ExtOpenNum).SurfNum = MultizoneSurfaceData(SrfNum).SurfNum;
11775 4 : AFNExtSurfaces(ExtOpenNum).NodeHeight = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.z;
11776 4 : AFNExtSurfaces(ExtOpenNum).SurfName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Name;
11777 4 : AFNExtSurfaces(ExtOpenNum).ZoneNum = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Zone;
11778 4 : AFNExtSurfaces(ExtOpenNum).ZoneName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName;
11779 8 : AFNExtSurfaces(ExtOpenNum).MZDZoneNum =
11780 4 : Util::FindItemInList(AFNExtSurfaces(ExtOpenNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11781 4 : AFNExtSurfaces(ExtOpenNum).CompTypeNum = iComponentTypeNum::DOP;
11782 4 : AFNExtSurfaces(ExtOpenNum).Height = MultizoneSurfaceData(SrfNum).Height;
11783 4 : AFNExtSurfaces(ExtOpenNum).Width = MultizoneSurfaceData(SrfNum).Width;
11784 8 : AFNExtSurfaces(ExtOpenNum).OpeningArea =
11785 4 : MultizoneSurfaceData(SrfNum).Width * MultizoneSurfaceData(SrfNum).Height * MultizoneSurfaceData(SrfNum).OpenFactor;
11786 4 : AFNExtSurfaces(ExtOpenNum).ExtNodeNum = MultizoneSurfaceData(ExtOpenNum).NodeNums[1];
11787 8 : AFNExtSurfaces(ExtOpenNum).facadeNum =
11788 4 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum;
11789 8 : AFNExtSurfaces(ExtOpenNum).curve =
11790 4 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).curve;
11791 4 : AFNExtSurfaces(ExtOpenNum).DischCoeff = MultizoneCompDetOpeningData(DetOpenNum).DischCoeff2;
11792 4 : ++ExtOpenNum;
11793 : }
11794 : }
11795 0 : } else if (AirflowNetworkNumOfSimOpenings > 0) {
11796 0 : SimOpenNum = Util::FindItemInList(
11797 0 : MultizoneSurfaceData(SrfNum).OpeningName, MultizoneCompSimpleOpeningData, &AirflowNetwork::SimpleOpening::name);
11798 0 : if (SimOpenNum > 0) {
11799 0 : AFNExtSurfaces(ExtOpenNum).MSDNum = SrfNum;
11800 0 : AFNExtSurfaces(ExtOpenNum).SurfNum = MultizoneSurfaceData(SrfNum).SurfNum;
11801 0 : AFNExtSurfaces(ExtOpenNum).SurfName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Name;
11802 0 : AFNExtSurfaces(ExtOpenNum).ZoneNum = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Zone;
11803 0 : AFNExtSurfaces(ExtOpenNum).ZoneName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName;
11804 0 : AFNExtSurfaces(ExtOpenNum).MZDZoneNum =
11805 0 : Util::FindItemInList(AFNExtSurfaces(ExtOpenNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11806 0 : AFNExtSurfaces(ExtOpenNum).CompTypeNum = iComponentTypeNum::SOP;
11807 0 : AFNExtSurfaces(ExtOpenNum).Height = MultizoneSurfaceData(SrfNum).Height;
11808 0 : AFNExtSurfaces(ExtOpenNum).Width = MultizoneSurfaceData(SrfNum).Width;
11809 0 : AFNExtSurfaces(ExtOpenNum).OpeningArea =
11810 0 : MultizoneSurfaceData(SrfNum).Width * MultizoneSurfaceData(SrfNum).Height * MultizoneSurfaceData(SrfNum).OpenFactor;
11811 0 : AFNExtSurfaces(ExtOpenNum).ExtNodeNum = MultizoneSurfaceData(ExtOpenNum).NodeNums[1];
11812 0 : AFNExtSurfaces(ExtOpenNum).curve =
11813 0 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).curve;
11814 0 : AFNExtSurfaces(ExtOpenNum).DischCoeff = MultizoneCompSimpleOpeningData(SimOpenNum).DischCoeff;
11815 0 : ++ExtOpenNum;
11816 : }
11817 : }
11818 : }
11819 : }
11820 : // Calculate the azimuth and the coordinates of the centroid of each opening.
11821 : // Calculate Sprime and DeltaCp for each zone.
11822 2 : PiFormula.allocate(numWindDir);
11823 2 : SigmaFormula.allocate(numWindDir);
11824 2 : DeltaCp.allocate(AirflowNetworkNumOfZones);
11825 2 : EPDeltaCP.allocate(AirflowNetworkNumOfZones);
11826 2 : Sprime.allocate(AirflowNetworkNumOfZones);
11827 2 : ZoneAng.allocate(AirflowNetworkNumOfZones);
11828 4 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11829 2 : DeltaCp(ZnNum).WindDir.allocate(numWindDir);
11830 2 : EPDeltaCP(ZnNum).WindDir.allocate(numWindDir);
11831 74 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11832 72 : DeltaCp(ZnNum).WindDir(windDirNum) = 0.0;
11833 72 : EPDeltaCP(ZnNum).WindDir(windDirNum) = 0.0;
11834 : }
11835 : }
11836 2 : Sprime = 0.0;
11837 2 : ZoneAng = 0.0;
11838 4 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11839 2 : if (MultizoneZoneData(ZnNum).SingleSidedCpType == "ADVANCED") {
11840 2 : OpenNuminZone = 1;
11841 6 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11842 4 : if (OpenNuminZone > 2) {
11843 0 : break; // Tuned
11844 : }
11845 4 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11846 4 : if (OpenNuminZone == 1) {
11847 2 : X1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.x;
11848 2 : Y1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.y;
11849 2 : ZoneAng1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Azimuth;
11850 2 : ++OpenNuminZone;
11851 2 : } else if (OpenNuminZone == 2) {
11852 2 : X2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.x;
11853 2 : Y2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.y;
11854 2 : ZoneAng2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Azimuth;
11855 2 : ++OpenNuminZone;
11856 : }
11857 : }
11858 : }
11859 2 : ZoneAngDiff = ZoneAng1 - ZoneAng2;
11860 2 : if (ZoneAngDiff > 0.01) {
11861 0 : ShowWarningError(m_state,
11862 0 : "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName +
11863 : " has single side wind pressure coefficient type \"ADVANCED\", but has openings which are not coplanar.");
11864 0 : ShowContinueError(m_state, "The openings should be coplanar for the model to be valid. Simulation Continues.");
11865 : }
11866 2 : ZoneAng(ZnNum) = ZoneAng1;
11867 2 : Sprime(ZnNum) = std::sqrt(pow_2(X1 - X2) + pow_2(Y1 - Y2)) / MultizoneZoneData(ZnNum).BuildWidth;
11868 : // Calculate DeltaCp for each wind direction for each zone
11869 74 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11870 72 : m_state.dataEnvrn->WindDir = (windDirNum - 1) * 10.0;
11871 72 : Real64 WindAng = (windDirNum - 1) * 10.0;
11872 72 : IncAng = std::abs(WindAng - ZoneAng(ZnNum));
11873 72 : if (std::abs(IncAng) > 180.0) {
11874 18 : IncAng -= 360.0;
11875 : }
11876 72 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
11877 72 : if (std::abs(IncAng) <= 67.5) {
11878 26 : PiFormula(windDirNum) = 0.44 * sign(std::sin(2.67 * std::abs(IncAng) * Constant::Pi / 180.0), IncAng);
11879 46 : } else if (std::abs(IncAng) <= 180.0) {
11880 46 : PiFormula(windDirNum) = -0.69 * sign(std::sin((288 - 1.6 * std::abs(IncAng)) * Constant::Pi / 180.0), IncAng);
11881 : }
11882 72 : SigmaFormula(windDirNum) = 0.423 - 0.00163 * std::abs(IncAng);
11883 72 : DeltaCp(ZnNum).WindDir(windDirNum) =
11884 72 : (0.02 + (0.346 * std::abs(PiFormula(windDirNum)) + 0.084 * SigmaFormula(windDirNum)) * Sprime(ZnNum));
11885 : }
11886 : }
11887 : }
11888 : }
11889 :
11890 : // Calculate the single sided Cp arrays from DeltaCp for each single sided opening
11891 2 : CPV1.allocate(numWindDir); // These two arrays should probably be removed
11892 2 : CPV2.allocate(numWindDir);
11893 2 : CPV1 = 0.0;
11894 2 : CPV2 = 0.0;
11895 2 : SrfNum = 6;
11896 4 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11897 2 : if (MultizoneZoneData(ZnNum).SingleSidedCpType == "ADVANCED") {
11898 2 : OpenNuminZone = 1;
11899 6 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11900 4 : if (OpenNuminZone > 2) {
11901 0 : break; // Tuned
11902 : }
11903 4 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11904 4 : Real64 const VelRatio_2(std::pow(10.0 / AFNExtSurfaces(ExtOpenNum).NodeHeight, 2.0 * m_state.dataEnvrn->SiteWindExp));
11905 4 : Real64 const AFNEExtSurface_fac(0.5 * (1.0 / pow_2(AFNExtSurfaces(ExtOpenNum).DischCoeff)));
11906 4 : if (OpenNuminZone == 1) {
11907 2 : std::vector<Real64> cpvalues(numWindDir);
11908 74 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11909 72 : Real64 unmodifiedValue = valsByFacade[AFNExtSurfaces(ExtOpenNum).facadeNum - 1][windDirNum - 1] +
11910 72 : AFNEExtSurface_fac * DeltaCp(ZnNum).WindDir(windDirNum);
11911 72 : cpvalues[windDirNum - 1] = CPV1(windDirNum) = VelRatio_2 * unmodifiedValue;
11912 : }
11913 2 : valsByFacade.push_back(cpvalues);
11914 2 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum = SrfNum;
11915 2 : ++OpenNuminZone;
11916 2 : ++SrfNum;
11917 4 : } else if (OpenNuminZone == 2) {
11918 2 : std::vector<Real64> cpvalues(numWindDir);
11919 74 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11920 72 : Real64 unmodifiedValue = valsByFacade[AFNExtSurfaces(ExtOpenNum).facadeNum - 1][windDirNum - 1] -
11921 72 : AFNEExtSurface_fac * DeltaCp(ZnNum).WindDir(windDirNum);
11922 72 : cpvalues[windDirNum - 1] = CPV2(windDirNum) = VelRatio_2 * unmodifiedValue;
11923 72 : EPDeltaCP(ZnNum).WindDir(windDirNum) = std::abs(CPV2(windDirNum) - CPV1(windDirNum));
11924 : }
11925 2 : valsByFacade.push_back(cpvalues);
11926 2 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum = SrfNum;
11927 2 : ++OpenNuminZone;
11928 2 : ++SrfNum;
11929 2 : }
11930 : }
11931 : }
11932 : }
11933 : }
11934 : // Rewrite the CPVNum for all nodes that correspond with a simple or detailed opening
11935 : // Does this loop really do anything?
11936 4 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11937 2 : OpenNuminZone = 1;
11938 6 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11939 4 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11940 4 : if (OpenNuminZone == 1) {
11941 2 : ++OpenNuminZone;
11942 2 : } else if (OpenNuminZone == 2) {
11943 2 : ++OpenNuminZone;
11944 : }
11945 : }
11946 : }
11947 : }
11948 2 : }
11949 :
11950 306607 : Real64 Solver::zone_OA_change_rate(int const ZoneNum) // hybrid ventilation system controlled zone number
11951 : {
11952 :
11953 : // SUBROUTINE INFORMATION:
11954 : // AUTHOR Lixing Gu
11955 : // DATE WRITTEN May. 2007
11956 :
11957 : // PURPOSE OF THIS SUBROUTINE:
11958 : // This function outputs air change per hour in a given zone
11959 :
11960 306607 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
11961 306607 : auto &thisZoneHB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
11962 :
11963 306607 : Real64 CpAir = PsyCpAirFnW(thisZoneHB.airHumRat);
11964 306607 : Real64 RhoAir = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.airHumRat);
11965 306607 : Real64 InfilVolume = ((exchangeData(ZoneNum).SumMCp + exchangeData(ZoneNum).SumMVCp) / CpAir / RhoAir) * TimeStepSys * Constant::rSecsInHour;
11966 306607 : Real64 ACH = InfilVolume / (TimeStepSys * m_state.dataHeatBal->Zone(ZoneNum).Volume);
11967 :
11968 306607 : return ACH;
11969 : }
11970 :
11971 10 : int Solver::get_airloop_number(int const NodeNumber) // Get air loop number for each distribution node and linkage
11972 : {
11973 : // SUBROUTINE INFORMATION:
11974 : // AUTHOR Lixing Gu
11975 : // DATE WRITTEN Feb. 2018
11976 :
11977 : // PURPOSE OF THIS SUBROUTINE:
11978 : // This function outputs an AirLoopNum based on node number
11979 :
11980 : // Using/Aliasing
11981 : using BranchNodeConnections::GetChildrenData;
11982 : using BranchNodeConnections::GetNumChildren;
11983 : using BranchNodeConnections::IsParentObject;
11984 10 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
11985 : using SingleDuct::GetHVACSingleDuctSysIndex;
11986 :
11987 : // Return value
11988 10 : int AirLoopNumber = 0;
11989 :
11990 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11991 : int BranchNum;
11992 : int NumOfNodes;
11993 : int NodeNum;
11994 : int OutNum;
11995 : int SupAirPath;
11996 : int SupAirPathOutNodeNum;
11997 : int CtrlZoneNum;
11998 : int ZoneInNum;
11999 : int ZoneOutNum;
12000 : int AirLoopNum;
12001 10 : int TUNum = 0;
12002 10 : int TermNum = 0;
12003 : bool LocalError;
12004 : int NumOfComp;
12005 : int NumOfSubComp;
12006 : bool ErrorsFound;
12007 : int NumOfSubSubComp;
12008 :
12009 12 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
12010 : // Check OAMixer OA inlet node
12011 10 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).OAMixOAInNodeNum) {
12012 0 : return AirLoopNum;
12013 : }
12014 : // Check branch
12015 15 : for (BranchNum = 1; BranchNum <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
12016 10 : NumOfNodes = m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalNodes;
12017 27 : for (NodeNum = 1; NodeNum <= NumOfNodes; ++NodeNum) {
12018 19 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).NodeNum(NodeNum)) {
12019 2 : return AirLoopNum;
12020 : }
12021 : }
12022 13 : for (NumOfComp = 1; NumOfComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
12023 : ++NumOfComp) {
12024 8 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NodeNumIn) {
12025 0 : return AirLoopNum;
12026 : }
12027 8 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NodeNumOut) {
12028 0 : return AirLoopNum;
12029 : }
12030 8 : if (m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NumSubComps == 0) {
12031 8 : DataLoopNode::ConnectionObjectType TypeOfComp = static_cast<DataLoopNode::ConnectionObjectType>(EnergyPlus::getEnumValue(
12032 : BranchNodeConnections::ConnectionObjectTypeNamesUC,
12033 8 : m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).TypeOf));
12034 : std::string const &NameOfComp =
12035 8 : m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).Name;
12036 8 : if (IsParentObject(m_state, TypeOfComp, NameOfComp)) {
12037 :
12038 8 : int NumChildren = GetNumChildren(m_state, TypeOfComp, NameOfComp);
12039 8 : EPVector<DataLoopNode::ConnectionObjectType> SubCompTypes;
12040 8 : Array1D_string SubCompNames;
12041 8 : Array1D_string InletNodeNames;
12042 8 : Array1D_int InletNodeNumbers;
12043 8 : Array1D_string OutletNodeNames;
12044 8 : Array1D_int OutletNodeNumbers;
12045 :
12046 8 : SubCompTypes.allocate(NumChildren);
12047 8 : SubCompNames.allocate(NumChildren);
12048 8 : InletNodeNames.allocate(NumChildren);
12049 8 : InletNodeNumbers.allocate(NumChildren);
12050 8 : OutletNodeNames.allocate(NumChildren);
12051 8 : OutletNodeNumbers.allocate(NumChildren);
12052 :
12053 8 : GetChildrenData(m_state,
12054 : TypeOfComp,
12055 : NameOfComp,
12056 : NumChildren,
12057 : SubCompTypes,
12058 : SubCompNames,
12059 : InletNodeNames,
12060 : InletNodeNumbers,
12061 : OutletNodeNames,
12062 : OutletNodeNumbers,
12063 : ErrorsFound);
12064 :
12065 31 : for (NumOfSubComp = 1; NumOfSubComp <= NumChildren; ++NumOfSubComp) {
12066 26 : if (NodeNumber == InletNodeNumbers(NumOfSubComp)) {
12067 0 : SubCompTypes.deallocate();
12068 0 : SubCompNames.deallocate();
12069 0 : InletNodeNames.deallocate();
12070 0 : InletNodeNumbers.deallocate();
12071 0 : OutletNodeNames.deallocate();
12072 0 : OutletNodeNumbers.deallocate();
12073 0 : return AirLoopNum;
12074 : }
12075 26 : if (NodeNumber == OutletNodeNumbers(NumOfSubComp)) {
12076 3 : SubCompTypes.deallocate();
12077 3 : SubCompNames.deallocate();
12078 3 : InletNodeNames.deallocate();
12079 3 : InletNodeNumbers.deallocate();
12080 3 : OutletNodeNames.deallocate();
12081 3 : OutletNodeNumbers.deallocate();
12082 3 : return AirLoopNum;
12083 : }
12084 : }
12085 25 : for (NumOfSubComp = 1; NumOfSubComp <= NumChildren; ++NumOfSubComp) {
12086 20 : DataLoopNode::ConnectionObjectType TypeOfSubComp = SubCompTypes(NumOfSubComp);
12087 20 : std::string NameOfSubComp = SubCompNames(NumOfSubComp);
12088 20 : if (IsParentObject(m_state, TypeOfSubComp, NameOfSubComp)) {
12089 :
12090 0 : int NumGrandChildren = GetNumChildren(m_state, TypeOfSubComp, NameOfSubComp);
12091 0 : EPVector<DataLoopNode::ConnectionObjectType> SubSubCompTypes;
12092 0 : Array1D_string SubSubCompNames;
12093 0 : Array1D_string SubSubInletNodeNames;
12094 0 : Array1D_int SubSubInletNodeNumbers;
12095 0 : Array1D_string SubSubOutletNodeNames;
12096 0 : Array1D_int SubSubOutletNodeNumbers;
12097 :
12098 0 : SubSubCompTypes.allocate(NumGrandChildren);
12099 0 : SubSubCompNames.allocate(NumGrandChildren);
12100 0 : SubSubInletNodeNames.allocate(NumGrandChildren);
12101 0 : SubSubInletNodeNumbers.allocate(NumGrandChildren);
12102 0 : SubSubOutletNodeNames.allocate(NumGrandChildren);
12103 0 : SubSubOutletNodeNumbers.allocate(NumGrandChildren);
12104 :
12105 0 : GetChildrenData(m_state,
12106 : TypeOfSubComp,
12107 : NameOfSubComp,
12108 : NumGrandChildren,
12109 : SubSubCompTypes,
12110 : SubSubCompNames,
12111 : SubSubInletNodeNames,
12112 : SubSubInletNodeNumbers,
12113 : SubSubOutletNodeNames,
12114 : SubSubOutletNodeNumbers,
12115 : ErrorsFound);
12116 0 : for (int SubSubCompNum = 1; SubSubCompNum <= NumGrandChildren; ++SubSubCompNum) {
12117 0 : if (NodeNumber == SubSubInletNodeNumbers(SubSubCompNum)) {
12118 0 : SubSubCompTypes.deallocate();
12119 0 : SubSubCompNames.deallocate();
12120 0 : SubSubInletNodeNames.deallocate();
12121 0 : SubSubInletNodeNumbers.deallocate();
12122 0 : SubSubOutletNodeNames.deallocate();
12123 0 : SubSubOutletNodeNumbers.deallocate();
12124 0 : SubCompTypes.deallocate();
12125 0 : SubCompNames.deallocate();
12126 0 : InletNodeNames.deallocate();
12127 0 : InletNodeNumbers.deallocate();
12128 0 : OutletNodeNames.deallocate();
12129 0 : OutletNodeNumbers.deallocate();
12130 0 : return AirLoopNum;
12131 : }
12132 0 : if (NodeNumber == SubSubOutletNodeNumbers(SubSubCompNum)) {
12133 0 : SubSubCompTypes.deallocate();
12134 0 : SubSubCompNames.deallocate();
12135 0 : SubSubInletNodeNames.deallocate();
12136 0 : SubSubInletNodeNumbers.deallocate();
12137 0 : SubSubOutletNodeNames.deallocate();
12138 0 : SubSubOutletNodeNumbers.deallocate();
12139 0 : SubCompTypes.deallocate();
12140 0 : SubCompNames.deallocate();
12141 0 : InletNodeNames.deallocate();
12142 0 : InletNodeNumbers.deallocate();
12143 0 : OutletNodeNames.deallocate();
12144 0 : OutletNodeNumbers.deallocate();
12145 0 : return AirLoopNum;
12146 : }
12147 : }
12148 0 : SubSubCompTypes.deallocate();
12149 0 : SubSubCompNames.deallocate();
12150 0 : SubSubInletNodeNames.deallocate();
12151 0 : SubSubInletNodeNumbers.deallocate();
12152 0 : SubSubOutletNodeNames.deallocate();
12153 0 : SubSubOutletNodeNumbers.deallocate();
12154 0 : }
12155 20 : }
12156 :
12157 5 : SubCompTypes.deallocate();
12158 5 : SubCompNames.deallocate();
12159 5 : InletNodeNames.deallocate();
12160 5 : InletNodeNumbers.deallocate();
12161 5 : OutletNodeNames.deallocate();
12162 5 : OutletNodeNumbers.deallocate();
12163 23 : }
12164 : } else {
12165 0 : for (NumOfSubComp = 1;
12166 0 : NumOfSubComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NumSubComps;
12167 : ++NumOfSubComp) {
12168 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
12169 0 : .Branch(BranchNum)
12170 0 : .Comp(NumOfComp)
12171 0 : .SubComp(NumOfSubComp)
12172 0 : .NodeNumIn) {
12173 0 : return AirLoopNum;
12174 : }
12175 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
12176 0 : .Branch(BranchNum)
12177 0 : .Comp(NumOfComp)
12178 0 : .SubComp(NumOfSubComp)
12179 0 : .NodeNumOut) {
12180 0 : return AirLoopNum;
12181 : }
12182 0 : for (NumOfSubSubComp = 1; NumOfSubSubComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
12183 0 : .Branch(BranchNum)
12184 0 : .Comp(NumOfComp)
12185 0 : .SubComp(NumOfSubComp)
12186 0 : .NumSubSubComps;
12187 : ++NumOfSubSubComp) {
12188 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
12189 0 : .Branch(BranchNum)
12190 0 : .Comp(NumOfComp)
12191 0 : .SubComp(NumOfSubComp)
12192 0 : .SubSubComp(NumOfSubSubComp)
12193 0 : .NodeNumIn) {
12194 0 : return AirLoopNum;
12195 : }
12196 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
12197 0 : .Branch(BranchNum)
12198 0 : .Comp(NumOfComp)
12199 0 : .SubComp(NumOfSubComp)
12200 0 : .SubSubComp(NumOfSubSubComp)
12201 0 : .NodeNumOut) {
12202 0 : return AirLoopNum;
12203 : }
12204 : }
12205 : }
12206 : }
12207 : }
12208 : }
12209 :
12210 : // Check connection between supply and demand
12211 7 : for (OutNum = 1; OutNum <= m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumSupplyNodes; ++OutNum) {
12212 : // AirLoop supply outlet node
12213 5 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopSupplyNodeNum(OutNum) == NodeNumber) {
12214 0 : return AirLoopNum;
12215 : }
12216 5 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(OutNum) == NodeNumber) {
12217 1 : return AirLoopNum;
12218 : }
12219 : // supply path
12220 7 : for (SupAirPath = 1; SupAirPath <= m_state.dataZoneEquip->NumSupplyAirPaths; ++SupAirPath) {
12221 4 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).InletNodeNum ==
12222 4 : m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(OutNum)) {
12223 7 : for (SupAirPathOutNodeNum = 1; SupAirPathOutNodeNum <= m_state.dataZoneEquip->SupplyAirPath(SupAirPath).NumOutletNodes;
12224 : ++SupAirPathOutNodeNum) {
12225 4 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).OutletNode(SupAirPathOutNodeNum) == NodeNumber) {
12226 1 : return AirLoopNum;
12227 : }
12228 3 : for (TUNum = 1; TUNum <= DisSysNumOfTermUnits; ++TUNum) {
12229 0 : if (Util::SameString(DisSysCompTermUnitData(TUNum).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
12230 0 : LocalError = false;
12231 0 : GetHVACSingleDuctSysIndex(m_state,
12232 0 : DisSysCompTermUnitData(TUNum).name,
12233 : TermNum,
12234 : LocalError,
12235 : "AirflowNetwork:Distribution:Component:TerminalUnit",
12236 0 : DisSysCompTermUnitData(TUNum).DamperInletNode,
12237 0 : DisSysCompTermUnitData(TUNum).DamperOutletNode);
12238 0 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).OutletNode(SupAirPathOutNodeNum) ==
12239 0 : DisSysCompTermUnitData(TUNum).DamperInletNode) {
12240 0 : if (DisSysCompTermUnitData(TUNum).DamperOutletNode == NodeNumber) {
12241 0 : DisSysCompTermUnitData(TUNum).AirLoopNum = AirLoopNum;
12242 0 : return AirLoopNum;
12243 : }
12244 : }
12245 0 : if (LocalError) {
12246 : }
12247 : }
12248 : }
12249 : }
12250 : }
12251 : }
12252 : // return path
12253 3 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopReturnNodeNum(OutNum) == NodeNumber) {
12254 0 : return AirLoopNum;
12255 : }
12256 3 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipReturnNodeNum(OutNum) == NodeNumber) {
12257 1 : return AirLoopNum;
12258 : }
12259 4 : for (int retPathNum = 1; retPathNum <= m_state.dataZoneEquip->NumReturnAirPaths; ++retPathNum) {
12260 2 : if (m_state.dataZoneEquip->ReturnAirPath(retPathNum).OutletNodeNum ==
12261 2 : m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipReturnNodeNum(1)) {
12262 2 : if (m_state.dataZoneEquip->ReturnAirPath(retPathNum).OutletNodeNum == NodeNumber) {
12263 0 : return AirLoopNum;
12264 : }
12265 : }
12266 : }
12267 : // Supply inlet node
12268 :
12269 : // Terminal damper node
12270 : }
12271 : }
12272 :
12273 2 : for (CtrlZoneNum = 1; CtrlZoneNum <= m_state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
12274 2 : if (!m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) {
12275 0 : continue;
12276 : }
12277 5 : for (ZoneInNum = 1; ZoneInNum <= m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumInletNodes; ++ZoneInNum) {
12278 4 : if (m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNode(ZoneInNum) == NodeNumber) {
12279 1 : return m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNodeAirLoopNum(ZoneInNum);
12280 : }
12281 : }
12282 1 : for (ZoneOutNum = 1; ZoneOutNum <= m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumReturnNodes; ++ZoneOutNum) {
12283 1 : if (m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ReturnNode(ZoneOutNum) == NodeNumber) {
12284 1 : return m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ReturnNodeAirLoopNum(ZoneOutNum);
12285 : }
12286 : }
12287 : }
12288 :
12289 0 : return AirLoopNumber;
12290 : }
12291 :
12292 3 : void Solver::SizeDucts()
12293 : {
12294 3 : Real64 constexpr EPS(0.001);
12295 3 : int constexpr MaxIte(500);
12296 3 : Real64 constexpr MinVelocity(0.5); // minimum airflow velocity (m/s)
12297 3 : Real64 constexpr MaxVelocity(20.0); // maximum airflow velocity (m/s)
12298 :
12299 3 : int NodeLoopSupply = 0;
12300 3 : int NodeLoopReturn = 0;
12301 3 : int NodeSplitter = 0;
12302 3 : int NodeMixer = 0;
12303 3 : int NodeZoneIntlet = 0;
12304 3 : int NodeZoneReturn = 0;
12305 : int AFNNodeNum;
12306 : int AFNLinkNum;
12307 : int AFNLinkNum1;
12308 3 : Real64 SumLength = 0.0;
12309 3 : Real64 DynamicLoss = 0.0;
12310 3 : Real64 MaxRough = 0.0;
12311 : bool DuctSizingSTFlag;
12312 : bool DuctSizingSBFlag;
12313 : bool DuctSizingRTFlag;
12314 : bool DuctSizingRBFlag;
12315 3 : Real64 hydraulicDiameter = 0.0;
12316 3 : Real64 SupplyTrunkD = 0.0;
12317 3 : Real64 SupplyTrunkArea = 0.0;
12318 3 : Real64 SupplyBranchD = 0.0;
12319 3 : Real64 SupplyBranchArea = 0.0;
12320 3 : Real64 ReturnTrunkD = 0.0;
12321 3 : Real64 ReturnTrunkArea = 0.0;
12322 3 : Real64 ReturnBranchD = 0.0;
12323 3 : Real64 ReturnBranchArea = 0.0;
12324 3 : Real64 MdotBranch = 0.0;
12325 3 : int SolFla = 0;
12326 :
12327 3 : int NumOfCtrlZones = 0;
12328 12 : for (int ZoneNum = 1; ZoneNum <= m_state.dataGlobal->NumOfZones; ++ZoneNum) {
12329 9 : if (!m_state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) {
12330 6 : continue;
12331 : }
12332 3 : NumOfCtrlZones++;
12333 3 : for (int EquipTypeNum = 1; EquipTypeNum <= m_state.dataZoneEquip->ZoneEquipList(ZoneNum).NumOfEquipTypes; ++EquipTypeNum) {
12334 3 : if (m_state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipType(EquipTypeNum) == DataZoneEquipment::ZoneEquipType::AirDistributionUnit) {
12335 3 : int AirDistUnitNum = m_state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipIndex(EquipTypeNum);
12336 3 : MdotBranch = m_state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).MassFlowRateTU;
12337 3 : break;
12338 : }
12339 : }
12340 : }
12341 3 : if (NumOfCtrlZones != 1) {
12342 0 : ShowWarningError(m_state, "AirflowNetwork Duct Sizing: The current restriction is limited to a single controlled zone only");
12343 0 : ShowContinueError(m_state, format("The number of controlled zone is {}", NumOfCtrlZones));
12344 0 : ShowContinueError(m_state, "..Duct sizing is not performed");
12345 0 : simulation_control.autosize_ducts = false;
12346 0 : simulation_control.iWPCCnt = iWPCCntr::Input;
12347 0 : simulation_control.allow_unsupported_zone_equipment = false;
12348 : }
12349 3 : Real64 factor = simulation_control.ductSizing.factor;
12350 :
12351 3 : NodeLoopSupply = m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipSupplyNodeNum(1);
12352 3 : NodeLoopReturn = m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipReturnNodeNum(1);
12353 66 : for (AFNNodeNum = 1; AFNNodeNum <= AirflowNetworkNumOfNodes; AFNNodeNum++) {
12354 63 : if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::SPL) {
12355 3 : NodeSplitter = AFNNodeNum;
12356 60 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::MIX) {
12357 3 : NodeMixer = AFNNodeNum;
12358 57 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipSupplyNodeNum(1)) {
12359 3 : NodeLoopSupply = AFNNodeNum;
12360 54 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipReturnNodeNum(1)) {
12361 3 : NodeLoopReturn = AFNNodeNum;
12362 51 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::ZIN) {
12363 3 : NodeZoneIntlet = AFNNodeNum;
12364 48 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::ZOU) {
12365 3 : NodeZoneReturn = AFNNodeNum;
12366 : }
12367 : }
12368 :
12369 : // find trunk ducts
12370 3 : DuctSizingSTFlag = false;
12371 3 : DuctSizingSBFlag = false;
12372 3 : int CompNum = 0;
12373 3 : int TypeNum = 0;
12374 :
12375 72 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12376 69 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12377 69 : iComponentTypeNum CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
12378 69 : SumLength = 0.0;
12379 69 : DynamicLoss = 0.0;
12380 69 : MaxRough = 0.0;
12381 : // supply duct trunk
12382 69 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeLoopSupply) {
12383 3 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeSplitter) {
12384 : // A single trunk duct
12385 3 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12386 3 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12387 3 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12388 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12389 3 : SumLength = disSysCompDuct.L;
12390 3 : MaxRough = disSysCompDuct.roughness;
12391 3 : DynamicLoss = disSysCompDuct.TurDynCoef;
12392 3 : DuctSizingSTFlag = true;
12393 : }
12394 : } else {
12395 0 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1];
12396 : int CompNum1;
12397 : iComponentTypeNum CompTypeNum1;
12398 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12399 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12400 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12401 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12402 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12403 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12404 0 : SumLength += disSysCompDuct.L;
12405 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12406 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12407 : // NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12408 0 : DuctSizingSBFlag = true;
12409 : }
12410 0 : while (NodeNum1 != NodeSplitter) {
12411 0 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12412 0 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
12413 0 : continue;
12414 : }
12415 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC) {
12416 0 : continue;
12417 : }
12418 0 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
12419 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12420 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12421 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12422 0 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::SupplyTrunk;
12423 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12424 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12425 0 : SumLength += disSysCompDuct.L;
12426 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12427 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12428 0 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1];
12429 0 : DuctSizingSTFlag = true;
12430 0 : break;
12431 : }
12432 : }
12433 : }
12434 : }
12435 : }
12436 3 : if (DuctSizingSTFlag) {
12437 3 : Real64 Velocity = 0.0;
12438 3 : Real64 flowrate = DisSysCompCVFData(1).FlowRate / m_state.dataEnvrn->StdRhoAir;
12439 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12440 1 : SupplyTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12441 1 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * Constant::Pi;
12442 : } else {
12443 2 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12444 2 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12445 2 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12446 2 : Real64 const deltaP = simulation_control.ductSizing.supply_trunk_pressure_loss;
12447 2 : Real64 const MassFlowRate = DisSysCompCVFData(1).FlowRate;
12448 222 : auto f = [&thisState, deltaP, MassFlowRate, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12449 222 : return DuctDResidual(thisState, D, deltaP, MassFlowRate, SumLength, DynamicLoss, MaxRough);
12450 2 : };
12451 2 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12452 2 : if (SolFla == -1) {
12453 0 : if (!m_state.dataGlobal->WarmupFlag) {
12454 0 : if (ErrCountDuct == 0) {
12455 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12456 0 : ShowWarningError(m_state,
12457 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Supply Duct Trunk size.");
12458 0 : ShowContinueErrorTimeStamp(m_state, format("Supply Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12459 : } else {
12460 0 : ++ErrCountDuct;
12461 0 : ShowRecurringWarningErrorAtEnd(
12462 : m_state,
12463 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Trunk "
12464 : "size. Supply Trunk is calculated using velocity at 5m/s. Simulation continues...",
12465 0 : ErrIndexDuct,
12466 : hydraulicDiameter,
12467 : hydraulicDiameter);
12468 : }
12469 : }
12470 2 : } else if (SolFla == -2) {
12471 0 : ShowFatalError(
12472 : m_state,
12473 : "Duct Autosizing for Supply Trunk calculation failed: iteration limits exceeded. Supply Trunk is calculated "
12474 : "using velocity at 5m/s.");
12475 : }
12476 2 : if (SolFla < 0) {
12477 0 : SupplyTrunkD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12478 : } else {
12479 2 : SupplyTrunkD = hydraulicDiameter * factor;
12480 : }
12481 2 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * Constant::Pi;
12482 2 : Velocity = flowrate / SupplyTrunkArea;
12483 : }
12484 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12485 1 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12486 0 : SupplyTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12487 0 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * Constant::Pi;
12488 0 : ShowWarningError(
12489 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Supply Trunk size");
12490 0 : ShowContinueError(
12491 : m_state,
12492 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12493 0 : simulation_control.ductSizing.max_velocity,
12494 : Velocity));
12495 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Supply Trunk Diameter");
12496 : }
12497 : }
12498 : }
12499 : }
12500 : // supply duct branch
12501 69 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeZoneIntlet) {
12502 3 : SumLength = 0.0;
12503 3 : DynamicLoss = 0.0;
12504 3 : MaxRough = 0.0;
12505 3 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeSplitter) {
12506 : // A single branch duct
12507 0 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12508 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12509 0 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12510 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12511 0 : SumLength = disSysCompDuct.L;
12512 0 : MaxRough = disSysCompDuct.roughness;
12513 0 : DynamicLoss = disSysCompDuct.TurDynCoef;
12514 0 : DuctSizingSTFlag = true;
12515 : }
12516 : } else {
12517 3 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12518 : int CompNum1;
12519 : iComponentTypeNum CompTypeNum1;
12520 3 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12521 3 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12522 3 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12523 3 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyBranch;
12524 3 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12525 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12526 3 : SumLength += disSysCompDuct.L;
12527 3 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12528 3 : DynamicLoss += disSysCompDuct.TurDynCoef;
12529 3 : DuctSizingSBFlag = true;
12530 : }
12531 9 : while (NodeNum1 != NodeSplitter) {
12532 24 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12533 24 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
12534 21 : continue;
12535 : }
12536 3 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC) {
12537 0 : continue;
12538 : }
12539 3 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
12540 3 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12541 3 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12542 3 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12543 3 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::SupplyBranch;
12544 3 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12545 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12546 3 : SumLength += disSysCompDuct.L;
12547 3 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12548 3 : DynamicLoss += disSysCompDuct.TurDynCoef;
12549 3 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0];
12550 3 : DuctSizingSBFlag = true;
12551 3 : break;
12552 : }
12553 : }
12554 : }
12555 : }
12556 : }
12557 3 : if (DuctSizingSBFlag) {
12558 3 : SolFla = 0;
12559 : Real64 Velocity;
12560 3 : Real64 flowrate = MdotBranch / m_state.dataEnvrn->StdRhoAir;
12561 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12562 1 : SupplyBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12563 1 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * Constant::Pi;
12564 : } else {
12565 2 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12566 2 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12567 2 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12568 2 : Real64 const deltaP = simulation_control.ductSizing.supply_branch_pressure_loss;
12569 138 : auto f = [&thisState, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12570 138 : return DuctDResidual(thisState, D, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough);
12571 2 : };
12572 2 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12573 2 : if (SolFla == -1) {
12574 0 : if (!m_state.dataGlobal->WarmupFlag) {
12575 0 : if (ErrCountDuct == 0) {
12576 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12577 0 : ShowWarningError(m_state,
12578 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Supply Duct Branch size.");
12579 0 : ShowContinueErrorTimeStamp(m_state, format("Supply Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12580 : } else {
12581 0 : ++ErrCountDuct;
12582 0 : ShowRecurringWarningErrorAtEnd(
12583 : m_state,
12584 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Branch "
12585 : "size. Supply Branch is calculated using velocity at 5m/s. Simulation continues...",
12586 0 : ErrIndexDuct,
12587 : hydraulicDiameter,
12588 : hydraulicDiameter);
12589 : }
12590 : }
12591 2 : } else if (SolFla == -2) {
12592 0 : ShowFatalError(
12593 : m_state,
12594 : "Duct Autosizing for Supply Branch calculation failed: iteration limits exceeded. Supply Branch is calculated "
12595 : "using velocity at 5m/s.");
12596 : }
12597 2 : if (SolFla < 0) {
12598 0 : SupplyBranchD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12599 : } else {
12600 2 : SupplyBranchD = hydraulicDiameter * factor;
12601 : }
12602 2 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * Constant::Pi;
12603 2 : Velocity = flowrate / SupplyBranchArea;
12604 : }
12605 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12606 1 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12607 1 : SupplyBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12608 1 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * Constant::Pi;
12609 2 : ShowWarningError(
12610 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Supply Branch size");
12611 2 : ShowContinueError(
12612 : m_state,
12613 2 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12614 1 : simulation_control.ductSizing.max_velocity,
12615 : Velocity));
12616 3 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Supply Branch Diameter");
12617 : }
12618 : }
12619 : }
12620 : }
12621 :
12622 69 : DuctSizingRTFlag = false;
12623 69 : DuctSizingRBFlag = false;
12624 :
12625 : // return duct trunk
12626 69 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeLoopReturn) {
12627 3 : SumLength = 0.0;
12628 3 : DynamicLoss = 0.0;
12629 3 : MaxRough = 0.0;
12630 3 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeMixer) {
12631 : // A single branch duct
12632 3 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12633 3 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnTrunk;
12634 3 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12635 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12636 3 : SumLength = disSysCompDuct.L;
12637 3 : MaxRough = disSysCompDuct.roughness;
12638 3 : DynamicLoss = disSysCompDuct.TurDynCoef;
12639 3 : DuctSizingRTFlag = true;
12640 : }
12641 : } else {
12642 0 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12643 : int CompNum1;
12644 : iComponentTypeNum CompTypeNum1;
12645 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12646 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12647 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12648 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnTrunk;
12649 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12650 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12651 0 : SumLength += disSysCompDuct.L;
12652 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12653 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12654 0 : DuctSizingRTFlag = true;
12655 : }
12656 0 : while (NodeNum1 != NodeMixer) {
12657 0 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12658 0 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
12659 0 : continue;
12660 : }
12661 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC) {
12662 0 : continue;
12663 : }
12664 0 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
12665 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12666 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12667 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12668 0 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::ReturnTrunk;
12669 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12670 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12671 0 : SumLength += disSysCompDuct.L;
12672 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12673 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12674 0 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0];
12675 0 : DuctSizingRTFlag = true;
12676 0 : break;
12677 : }
12678 : }
12679 : }
12680 : }
12681 : }
12682 3 : if (DuctSizingRTFlag) {
12683 3 : SolFla = 0;
12684 : Real64 Velocity;
12685 3 : Real64 flowrate = DisSysCompCVFData(1).FlowRate / m_state.dataEnvrn->StdRhoAir;
12686 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12687 1 : ReturnTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12688 1 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * Constant::Pi;
12689 : } else {
12690 2 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12691 2 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12692 2 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12693 2 : Real64 const deltaP = simulation_control.ductSizing.return_trunk_pressure_loss;
12694 2 : Real64 const massFlowRate = DisSysCompCVFData(1).FlowRate;
12695 378 : auto f = [&thisState, deltaP, massFlowRate, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12696 378 : return DuctDResidual(thisState, D, deltaP, massFlowRate, SumLength, DynamicLoss, MaxRough);
12697 2 : };
12698 2 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12699 2 : if (SolFla == -1) {
12700 0 : if (!m_state.dataGlobal->WarmupFlag) {
12701 0 : if (ErrCountDuct == 0) {
12702 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12703 0 : ShowWarningError(m_state,
12704 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Return Duct Trunk size.");
12705 0 : ShowContinueErrorTimeStamp(m_state, format("Return Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12706 : } else {
12707 0 : ++ErrCountDuct;
12708 0 : ShowRecurringWarningErrorAtEnd(
12709 : m_state,
12710 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Return Duct Trunk "
12711 : "size. Supply Branch is calculated using velocity at 5m/s. Simulation continues...",
12712 0 : ErrIndexDuct,
12713 : hydraulicDiameter,
12714 : hydraulicDiameter);
12715 : }
12716 : }
12717 2 : } else if (SolFla == -2) {
12718 0 : ShowFatalError(
12719 : m_state,
12720 : "Duct Autosizing for Return Trunk calculation failed: iteration limits exceeded. Return Trunk is calculated "
12721 : "using velocity at 5m/s.");
12722 : }
12723 2 : if (SolFla < 0) {
12724 0 : ReturnTrunkD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12725 : } else {
12726 2 : ReturnTrunkD = hydraulicDiameter * factor;
12727 : }
12728 2 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * Constant::Pi;
12729 2 : Velocity = flowrate / SupplyBranchArea;
12730 : }
12731 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12732 1 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12733 0 : ReturnTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12734 0 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * Constant::Pi;
12735 0 : ShowWarningError(
12736 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Return Trunk size");
12737 0 : ShowContinueError(
12738 : m_state,
12739 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12740 0 : simulation_control.ductSizing.max_velocity,
12741 : Velocity));
12742 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Return Trunk Diameter");
12743 : }
12744 : }
12745 : }
12746 : }
12747 :
12748 : // return duct branch
12749 69 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeZoneReturn) {
12750 3 : SumLength = 0.0;
12751 3 : DynamicLoss = 0.0;
12752 3 : MaxRough = 0.0;
12753 3 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeMixer) {
12754 : // A single trunk duct
12755 0 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12756 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnBranch;
12757 0 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12758 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12759 0 : SumLength = disSysCompDuct.L;
12760 0 : MaxRough = disSysCompDuct.roughness;
12761 0 : DynamicLoss = disSysCompDuct.TurDynCoef;
12762 0 : DuctSizingRBFlag = true;
12763 : }
12764 : } else {
12765 3 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1];
12766 : int CompNum1;
12767 : iComponentTypeNum CompTypeNum1;
12768 3 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12769 3 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12770 3 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12771 3 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnBranch;
12772 3 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12773 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12774 3 : SumLength += disSysCompDuct.L;
12775 3 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12776 3 : DynamicLoss += disSysCompDuct.TurDynCoef;
12777 3 : DuctSizingRBFlag = true;
12778 : }
12779 9 : while (NodeNum1 != NodeMixer) {
12780 39 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12781 39 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
12782 36 : continue;
12783 : }
12784 3 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC) {
12785 0 : continue;
12786 : }
12787 3 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
12788 3 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12789 3 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12790 3 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12791 3 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::ReturnBranch;
12792 3 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12793 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12794 3 : SumLength += disSysCompDuct.L;
12795 3 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12796 3 : DynamicLoss += disSysCompDuct.TurDynCoef;
12797 3 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1];
12798 3 : DuctSizingRBFlag = true;
12799 3 : break;
12800 : }
12801 : }
12802 : }
12803 : }
12804 : }
12805 3 : if (DuctSizingRBFlag) {
12806 3 : SolFla = 0;
12807 : Real64 Velocity;
12808 3 : Real64 flowrate = MdotBranch / m_state.dataEnvrn->StdRhoAir;
12809 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12810 1 : ReturnBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12811 1 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * Constant::Pi;
12812 : } else {
12813 2 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12814 2 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12815 2 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12816 2 : Real64 const deltaP = simulation_control.ductSizing.return_branch_pressure_loss;
12817 346 : auto f = [&thisState, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12818 346 : return DuctDResidual(thisState, D, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough);
12819 2 : };
12820 2 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12821 2 : if (SolFla == -1) {
12822 0 : if (!m_state.dataGlobal->WarmupFlag) {
12823 0 : if (ErrCountDuct == 0) {
12824 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12825 0 : ShowWarningError(m_state,
12826 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Return Duct Branch size.");
12827 0 : ShowContinueErrorTimeStamp(m_state, format("Return Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12828 : } else {
12829 0 : ++ErrCountDuct;
12830 0 : ShowRecurringWarningErrorAtEnd(
12831 : m_state,
12832 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Branch "
12833 : "size. Return Branch is calculated using velocity at 5m/s. Simulation continues...",
12834 0 : ErrIndexDuct,
12835 : hydraulicDiameter,
12836 : hydraulicDiameter);
12837 : }
12838 : }
12839 2 : } else if (SolFla == -2) {
12840 0 : ShowFatalError(
12841 : m_state,
12842 : "Duct Autosizing for Return Branch calculation failed: iteration limits exceeded. Return Branch is calculated "
12843 : "using velocity at 5m/s.");
12844 : }
12845 2 : if (SolFla < 0) {
12846 0 : ReturnBranchD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12847 : } else {
12848 2 : ReturnBranchD = hydraulicDiameter * factor;
12849 : }
12850 2 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * Constant::Pi;
12851 2 : Velocity = flowrate / ReturnBranchArea;
12852 : }
12853 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12854 1 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12855 0 : ReturnBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12856 0 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * Constant::Pi;
12857 0 : ShowWarningError(
12858 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Return Branch size");
12859 0 : ShowContinueError(
12860 : m_state,
12861 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12862 0 : simulation_control.ductSizing.max_velocity,
12863 : Velocity));
12864 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Return Branch Diameter");
12865 : }
12866 : }
12867 : }
12868 : }
12869 : }
12870 : // Assign autosize values in Duct element
12871 72 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12872 69 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12873 69 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12874 69 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12875 69 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyTrunk) {
12876 3 : disSysCompDuct.hydraulicDiameter = SupplyTrunkD;
12877 3 : disSysCompDuct.A = SupplyTrunkArea;
12878 3 : disSysCompDuct.RelRough = disSysCompDuct.roughness / SupplyTrunkD; // e/D: relative roughness
12879 3 : disSysCompDuct.RelL = disSysCompDuct.L / SupplyTrunkD; // L/D: relative length
12880 3 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12881 3 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12882 66 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyBranch) {
12883 6 : disSysCompDuct.hydraulicDiameter = SupplyBranchD;
12884 6 : disSysCompDuct.A = SupplyBranchArea;
12885 6 : disSysCompDuct.RelRough = disSysCompDuct.roughness / SupplyBranchD; // e/D: relative roughness
12886 6 : disSysCompDuct.RelL = disSysCompDuct.L / SupplyBranchD; // L/D: relative length
12887 6 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12888 6 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12889 60 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnTrunk) {
12890 3 : disSysCompDuct.hydraulicDiameter = ReturnTrunkD;
12891 3 : disSysCompDuct.A = ReturnTrunkArea;
12892 3 : disSysCompDuct.RelRough = disSysCompDuct.roughness / ReturnTrunkD; // e/D: relative roughness
12893 3 : disSysCompDuct.RelL = disSysCompDuct.L / ReturnTrunkD; // L/D: relative length
12894 3 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12895 3 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12896 57 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnBranch) {
12897 6 : disSysCompDuct.hydraulicDiameter = ReturnBranchD;
12898 6 : disSysCompDuct.A = ReturnBranchArea;
12899 6 : disSysCompDuct.RelRough = disSysCompDuct.roughness / ReturnBranchD; // e/D: relative roughness
12900 6 : disSysCompDuct.RelL = disSysCompDuct.L / ReturnBranchD; // L/D: relative length
12901 6 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12902 6 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12903 : }
12904 : }
12905 :
12906 : // Print data in eio
12907 3 : print(m_state.files.eio,
12908 : "! <AirflowNetwork Model:Duct Autosizing>, Linkage Name, Duct Type, Duct Name, Duct Hydraunic Diameter, Duct Cross Section Area\n");
12909 :
12910 : // Assign autosize values in Duct element
12911 72 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12912 69 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12913 69 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12914 69 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12915 69 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyTrunk) {
12916 3 : print(m_state.files.eio,
12917 : "AirflowNetwork Model:Duct Autosizing, {}, Supply Trunk, {}, ",
12918 3 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12919 3 : disSysCompDuct.name);
12920 3 : print(m_state.files.eio, "{:.4R},{:.4R}\n", SupplyTrunkD, SupplyTrunkArea);
12921 : }
12922 69 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyBranch) {
12923 6 : print(m_state.files.eio,
12924 : "AirflowNetwork Model:Duct Autosizing, {}, Supply Branch, {}, ",
12925 6 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12926 6 : disSysCompDuct.name);
12927 6 : print(m_state.files.eio, "{:.4R},{:.4R}\n", SupplyBranchD, SupplyBranchArea);
12928 : }
12929 69 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnTrunk) {
12930 3 : print(m_state.files.eio,
12931 : "AirflowNetwork Model:Duct Autosizing, {}, Return Trunk, {}, ",
12932 3 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12933 3 : disSysCompDuct.name);
12934 3 : print(m_state.files.eio, "{:.4R},{:.4R}\n", ReturnTrunkD, ReturnTrunkArea);
12935 : }
12936 69 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnBranch) {
12937 6 : print(m_state.files.eio,
12938 : "AirflowNetwork Model:Duct Autosizing, {}, Return Branch, {}, ",
12939 6 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12940 6 : disSysCompDuct.name);
12941 6 : print(m_state.files.eio, "{:.4R},{:.4R}\n", ReturnBranchD, ReturnBranchArea);
12942 : }
12943 : }
12944 3 : }
12945 :
12946 1084 : Real64 Solver::CalcDuctDiameter(Real64 hydraulicDiameter, Real64 DeltaP, Real64 MassFlowrate, Real64 TotalL, Real64 TotalLossCoe, Real64 MaxRough)
12947 : {
12948 1084 : Real64 CalcDeltaP = 0.0;
12949 :
12950 : Real64 A;
12951 : Real64 A0;
12952 : Real64 A1;
12953 : Real64 A2;
12954 : Real64 B;
12955 : Real64 D;
12956 : Real64 S2;
12957 : Real64 CDM;
12958 : Real64 FL; // friction factor for laminar flow.
12959 : Real64 FT; // friction factor for turbulent flow.
12960 : Real64 FTT;
12961 : Real64 RE; // Reynolds number.
12962 : Real64 ed;
12963 : Real64 ld;
12964 : Real64 g;
12965 : Real64 AA1;
12966 : Real64 velocity;
12967 1084 : Real64 constexpr LamDynCoef(64.0);
12968 1084 : Real64 constexpr LamFriCoef(0.001);
12969 1084 : Real64 constexpr EPS(0.001);
12970 1084 : Real64 constexpr C(0.868589);
12971 :
12972 : //// Initial guess with 5 m/s
12973 1084 : Real64 flowrate = MassFlowrate / m_state.dataEnvrn->StdRhoAir;
12974 :
12975 1084 : ed = MaxRough / hydraulicDiameter;
12976 1084 : ld = TotalL / hydraulicDiameter;
12977 1084 : g = 1.14 - 0.868589 * std::log(ed);
12978 1084 : AA1 = g;
12979 1084 : A = hydraulicDiameter * hydraulicDiameter / 4.0 * Constant::Pi;
12980 1084 : Real64 viscosity{AirflowNetwork::AIRDYNAMICVISCOSITY_CONSTEXPR(20)};
12981 1084 : velocity = flowrate / A;
12982 :
12983 : if (LamFriCoef >= 0.001) {
12984 1084 : A2 = LamFriCoef / (2.0 * m_state.dataEnvrn->StdRhoAir * A * A);
12985 1084 : A1 = (viscosity * LamDynCoef * ld) / (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter);
12986 1084 : A0 = -DeltaP;
12987 1084 : CDM = std::sqrt(A1 * A1 - 4.0 * A2 * A0);
12988 1084 : FL = (CDM - A1) / (2.0 * A2);
12989 1084 : CDM = 1.0 / CDM;
12990 : } else {
12991 : CDM = (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter) / (viscosity * LamDynCoef * ld);
12992 : FL = CDM * DeltaP;
12993 : }
12994 :
12995 : // CDM = (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter) / (viscosity * LamDynCoef * ld);
12996 : // FL = CDM * DeltaP;
12997 :
12998 1084 : RE = FL * hydraulicDiameter / (viscosity * A);
12999 1084 : S2 = std::sqrt(2.0 * m_state.dataEnvrn->StdRhoAir * DeltaP) * A;
13000 1084 : FTT = S2 / std::sqrt(ld / pow_2(g) + TotalLossCoe);
13001 : while (true) {
13002 2144 : FT = FTT;
13003 2144 : B = (9.3 * viscosity * A) / (FT * MaxRough);
13004 2144 : D = 1.0 + g * B;
13005 2144 : g -= (g - AA1 + C * std::log(D)) / (1.0 + C * B / D);
13006 2144 : FTT = S2 / std::sqrt(ld / pow_2(g) + TotalLossCoe);
13007 2144 : if (std::abs(FTT - FT) / FTT < EPS) {
13008 1084 : break;
13009 : }
13010 : }
13011 1084 : FT = FTT;
13012 :
13013 1084 : Real64 f = 1.0 / (g * g);
13014 :
13015 : // CalcDeltaP = ((FT * TotalL) / hydraulicDiameter + TotalLossCoe) * (m_state.dataEnvrn->StdRhoAir * velocity * velocity / 2.0);
13016 1084 : CalcDeltaP = ((f * TotalL) / hydraulicDiameter + TotalLossCoe) * (m_state.dataEnvrn->StdRhoAir * velocity * velocity / 2.0);
13017 :
13018 1084 : return CalcDeltaP;
13019 : }
13020 :
13021 1084 : Real64 DuctDResidual(EnergyPlusData &state,
13022 : Real64 D, // duct diameter
13023 : Real64 DeltaP,
13024 : Real64 MassFlowrate,
13025 : Real64 TotalL,
13026 : Real64 TotalLossCoe,
13027 : Real64 MaxRough)
13028 : {
13029 1084 : Real64 CalcDeltaP = state.afn->CalcDuctDiameter(D, DeltaP, MassFlowrate, TotalL, TotalLossCoe, MaxRough);
13030 1084 : return (CalcDeltaP - DeltaP) / DeltaP;
13031 : }
13032 :
13033 8 : void OccupantVentilationControlProp::calc(EnergyPlusData &state,
13034 : int const ZoneNum,
13035 : Real64 const TimeOpenDuration,
13036 : Real64 const TimeCloseDuration,
13037 : int &OpeningStatus,
13038 : int &OpeningProbStatus,
13039 : int &ClosingProbStatus)
13040 : {
13041 :
13042 : Real64 Tcomfort; // Thermal comfort temperature
13043 : Real64 ComfortBand; // Thermal comfort band
13044 : Real64 Toperative; // Operative temperature
13045 : Real64 OutDryBulb; // Outdoor dry-bulb temperature
13046 :
13047 8 : auto &Zone(state.dataHeatBal->Zone);
13048 :
13049 8 : if (TimeOpenDuration > 0) {
13050 4 : if (TimeOpenDuration >= MinOpeningTime) {
13051 3 : OpeningStatus = OpenStatus::FreeOperation; // free operation
13052 : } else {
13053 1 : OpeningStatus = OpenStatus::MinCheckForceOpen; // forced to open
13054 : }
13055 : }
13056 8 : if (TimeCloseDuration > 0) {
13057 4 : if (TimeCloseDuration >= MinClosingTime) {
13058 3 : OpeningStatus = OpenStatus::FreeOperation; // free operation
13059 : } else {
13060 1 : OpeningStatus = OpenStatus::MinCheckForceClose; // forced to close
13061 : }
13062 : }
13063 :
13064 8 : if (MinTimeControlOnly) {
13065 4 : return;
13066 : }
13067 :
13068 4 : if (Zone(ZoneNum).LinkedOutAirNode > 0) {
13069 0 : OutDryBulb = Zone(ZoneNum).OutDryBulbTemp;
13070 : } else {
13071 4 : OutDryBulb = OutDryBulbTempAt(state, Zone(ZoneNum).Centroid.z);
13072 : }
13073 :
13074 4 : if (OutDryBulb < ComfortBouPoint) {
13075 0 : Tcomfort = CurveValue(state, ComfortLowTempCurveNum, OutDryBulb);
13076 : } else {
13077 4 : Tcomfort = CurveValue(state, ComfortHighTempCurveNum, OutDryBulb);
13078 : }
13079 4 : ComfortBand = -0.0028 * (100 - MaxPPD) * (100 - MaxPPD) + 0.3419 * (100 - MaxPPD) - 6.6275;
13080 4 : Toperative = 0.5 * (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT +
13081 4 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MRT);
13082 :
13083 4 : if (Toperative > (Tcomfort + ComfortBand)) {
13084 3 : if (opening_probability(state, ZoneNum, TimeCloseDuration)) {
13085 2 : OpeningProbStatus = ProbabilityCheck::ForceChange;
13086 : ; // forced to open
13087 : } else {
13088 1 : OpeningProbStatus = ProbabilityCheck::KeepStatus; // Keep previous status
13089 : }
13090 : } else {
13091 1 : OpeningProbStatus = ProbabilityCheck::NoAction; // free operation
13092 : }
13093 :
13094 4 : if (Toperative < (Tcomfort - ComfortBand)) {
13095 1 : if (closing_probability(state, TimeOpenDuration)) {
13096 1 : ClosingProbStatus = ProbabilityCheck::ForceChange; // forced to close
13097 : } else {
13098 0 : ClosingProbStatus = ProbabilityCheck::KeepStatus; // Keep previous status
13099 : }
13100 : } else {
13101 3 : ClosingProbStatus = ProbabilityCheck::NoAction; // free operation
13102 : }
13103 : }
13104 :
13105 : bool
13106 3 : OccupantVentilationControlProp::opening_probability(EnergyPlusData &state,
13107 : int const ZoneNum,
13108 : Real64 const TimeCloseDuration) // function to perform calculations of opening probability
13109 : {
13110 : Real64 SchValue;
13111 : Real64 RandomValue;
13112 3 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
13113 3 : auto &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
13114 :
13115 3 : if (TimeCloseDuration < MinClosingTime) {
13116 1 : return false;
13117 : }
13118 2 : if (OccupancyCheck) {
13119 0 : if (state.dataHeatBal->ZoneIntGain(ZoneNum).NOFOCC <= 0.0) {
13120 0 : return false;
13121 : }
13122 : }
13123 :
13124 2 : switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
13125 0 : case HVAC::SetptType::SingleHeat: {
13126 0 : if (thisZoneHB.MAT <= zoneTstatSetpt.setptLo) {
13127 0 : return false;
13128 : }
13129 0 : } break;
13130 :
13131 0 : case HVAC::SetptType::SingleCool: {
13132 0 : if (thisZoneHB.MAT >= zoneTstatSetpt.setptHi) {
13133 0 : return false;
13134 : }
13135 0 : } break;
13136 0 : case HVAC::SetptType::SingleHeatCool: {
13137 0 : return false;
13138 : } break;
13139 :
13140 1 : case HVAC::SetptType::DualHeatCool: {
13141 1 : if (thisZoneHB.MAT < zoneTstatSetpt.setptLo || thisZoneHB.MAT > zoneTstatSetpt.setptHi) {
13142 0 : return false;
13143 : }
13144 1 : } break;
13145 :
13146 1 : default: {
13147 1 : } break;
13148 : } // switch
13149 :
13150 2 : if (openingProbSched == nullptr) {
13151 2 : return true;
13152 : } else {
13153 0 : SchValue = openingProbSched->getCurrentVal();
13154 0 : RandomValue = Real64(rand()) / RAND_MAX;
13155 0 : if (SchValue > RandomValue) {
13156 0 : return true;
13157 : } else {
13158 0 : return false;
13159 : }
13160 : }
13161 : }
13162 :
13163 1 : bool OccupantVentilationControlProp::closing_probability(EnergyPlusData &state,
13164 : Real64 const TimeOpenDuration) // function to perform calculations of closing probability
13165 : {
13166 : Real64 SchValue;
13167 : Real64 RandomValue;
13168 :
13169 1 : if (TimeOpenDuration < MinOpeningTime) {
13170 0 : return false;
13171 : }
13172 1 : if (closingProbSched == nullptr) {
13173 1 : return true;
13174 : } else {
13175 0 : SchValue = closingProbSched->getCurrentVal();
13176 0 : RandomValue = Real64(rand()) / RAND_MAX;
13177 0 : if (SchValue > RandomValue) {
13178 0 : return true;
13179 : } else {
13180 0 : return false;
13181 : }
13182 : }
13183 : }
13184 :
13185 24 : void Solver::allocate()
13186 : {
13187 :
13188 : // SUBROUTINE INFORMATION:
13189 : // AUTHOR Lixing Gu
13190 : // DATE WRITTEN Aug. 2003
13191 : // MODIFIED na
13192 : // RE-ENGINEERED na
13193 :
13194 : // PURPOSE OF THIS SUBROUTINE:
13195 : // This subroutine allocates dynamic arrays for AirflowNetworkSolver.
13196 :
13197 : // METHODOLOGY EMPLOYED:
13198 : // na
13199 :
13200 : // REFERENCES:
13201 : // na
13202 :
13203 : // USE STATEMENTS:
13204 : // na
13205 :
13206 : // Locals
13207 : // SUBROUTINE ARGUMENT DEFINITIONS:
13208 : // na
13209 :
13210 : // SUBROUTINE PARAMETER DEFINITIONS:
13211 : // na
13212 :
13213 : // INTERFACE BLOCK SPECIFICATIONS
13214 : // na
13215 :
13216 : // DERIVED TYPE DEFINITIONS
13217 : // na
13218 :
13219 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13220 : int i;
13221 : iComponentTypeNum j;
13222 : int n;
13223 :
13224 : // Formats
13225 :
13226 : // Assume a network to simulate multizone airflow is a subset of the network to simulate air distribution system.
13227 : // Network array size is allocated based on the network of air distribution system.
13228 : // If multizone airflow is simulated only, the array size is allocated based on the multizone network.
13229 :
13230 24 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13231 24 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13232 :
13233 24 : NetworkNumOfLinks = AirflowNetworkNumOfLinks;
13234 24 : NetworkNumOfNodes = AirflowNetworkNumOfNodes;
13235 :
13236 24 : AFECTL.allocate(NetworkNumOfLinks);
13237 24 : AFLOW2.allocate(NetworkNumOfLinks);
13238 24 : AFLOW.allocate(NetworkNumOfLinks);
13239 24 : PW.allocate(NetworkNumOfLinks);
13240 24 : PS.allocate(NetworkNumOfLinks);
13241 :
13242 : // TZ.allocate(NetworkNumOfNodes);
13243 : // WZ.allocate(NetworkNumOfNodes);
13244 24 : PZ.allocate(NetworkNumOfNodes);
13245 : // RHOZ.allocate(NetworkNumOfNodes);
13246 : // SQRTDZ.allocate(NetworkNumOfNodes);
13247 : // VISCZ.allocate(NetworkNumOfNodes);
13248 24 : SUMAF.allocate(NetworkNumOfNodes);
13249 :
13250 335 : for (int it = 0; it <= NetworkNumOfNodes + 1; ++it) {
13251 311 : node_states.emplace_back(properties.density(101325.0, 20.0, 0.0));
13252 : }
13253 :
13254 24 : ID.allocate(NetworkNumOfNodes);
13255 24 : IK.allocate(NetworkNumOfNodes + 1);
13256 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13257 24 : newIK.allocate(NetworkNumOfNodes + 1);
13258 : #endif
13259 24 : AD.allocate(NetworkNumOfNodes);
13260 24 : SUMF.allocate(NetworkNumOfNodes);
13261 :
13262 24 : n = 0;
13263 328 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
13264 304 : j = AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum;
13265 304 : if (j == iComponentTypeNum::DOP) {
13266 6 : ++n;
13267 : }
13268 : }
13269 :
13270 24 : dos.allocate(AirflowNetworkNumOfLinks, n);
13271 :
13272 24 : PB = 101325.0;
13273 : // LIST = 5
13274 : // LIST = 0;
13275 :
13276 287 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13277 263 : ID(n) = n;
13278 : }
13279 328 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13280 304 : AFECTL(i) = 1.0;
13281 304 : AFLOW(i) = 0.0;
13282 304 : AFLOW2(i) = 0.0;
13283 : }
13284 :
13285 287 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13286 : // TZ(i) = AirflowNetworkNodeSimu(i).TZ;
13287 : // WZ(i) = AirflowNetworkNodeSimu(i).WZ;
13288 263 : PZ(i) = AirflowNetworkNodeSimu(i).PZ;
13289 263 : node_states[i].temperature = AirflowNetworkNodeSimu(i).TZ;
13290 263 : node_states[i].humidity_ratio = AirflowNetworkNodeSimu(i).WZ;
13291 : // properties[i].pressure = AirflowNetworkNodeSimu(i).PZ;
13292 : }
13293 :
13294 : // Assign linkage values
13295 328 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13296 304 : PW(i) = 0.0;
13297 : }
13298 : // Write an ouput file used for AIRNET input
13299 : /*
13300 : if (LIST >= 5) {
13301 : Unit11 = GetNewUnitNumber();
13302 : ObjexxFCL::gio::open(Unit11, DataStringGlobals::eplusADSFileName);
13303 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13304 : ObjexxFCL::gio::write(Unit11, Format_901) << i << state.afn->AirflowNetworkNodeData(i).NodeTypeNum <<
13305 : state.afn->AirflowNetworkNodeData(i).NodeHeight << TZ(i)
13306 : << PZ(i);
13307 : }
13308 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13309 : for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
13310 : j = state.afn->AirflowNetworkCompData(i).TypeNum;
13311 : {
13312 : auto const SELECT_CASE_var(state.afn->AirflowNetworkCompData(i).CompTypeNum);
13313 : if (SELECT_CASE_var == CompTypeNum_PLR) { //'PLR' Power law component
13314 : // WRITE(Unit11,902)
13315 : state.afn->AirflowNetworkCompData(i)%CompNum,1,DisSysCompLeakData(j)%FlowCoef, &
13316 : // DisSysCompLeakData(j)%FlowCoef,DisSysCompLeakData(j)%FlowCoef,DisSysCompLeakData(j)%FlowExpo
13317 : } else if (SELECT_CASE_var == CompTypeNum_SCR) { //'SCR' Surface crack component
13318 : ObjexxFCL::gio::write(Unit11, Format_902) << state.afn->AirflowNetworkCompData(i).CompNum << 1 <<
13319 : MultizoneSurfaceCrackData(j).FlowCoef
13320 : << MultizoneSurfaceCrackData(j).FlowCoef << MultizoneSurfaceCrackData(j).FlowCoef
13321 : << MultizoneSurfaceCrackData(j).FlowExpo;
13322 : } else if (SELECT_CASE_var == CompTypeNum_DWC) { //'DWC' Duct component
13323 : // WRITE(Unit11,902)
13324 : state.afn->AirflowNetworkCompData(i)%CompNum,2,DisSysCompDuctData(j)%L,DisSysCompDuctData(j)%D, &
13325 : // DisSysCompDuctData(j)%A,DisSysCompDuctData(j)%Rough
13326 : // WRITE(Unit11,903) DisSysCompDuctData(i)%TurDynCoef,DisSysCompDuctData(j)%LamFriCoef, &
13327 : // DisSysCompDuctData(j)%LamFriCoef,DisSysCompDuctData(j)%InitLamCoef
13328 : // CASE (CompTypeNum_CVF) ! 'CVF' Constant volume fan component
13329 : // WRITE(Unit11,904) state.afn->AirflowNetworkCompData(i)%CompNum,4,DisSysCompCVFData(j)%FlowRate
13330 : } else if (SELECT_CASE_var == CompTypeNum_EXF) { // 'EXF' Zone exhaust fan
13331 : ObjexxFCL::gio::write(Unit11, Format_904) << state.afn->AirflowNetworkCompData(i).CompNum << 4 <<
13332 : MultizoneCompExhaustFanData(j).FlowRate; } else {
13333 : }
13334 : }
13335 : }
13336 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13337 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13338 : gio::write(Unit11, Format_910) << i << state.afn->AirflowNetworkLinkageData(i).NodeNums[0] <<
13339 : state.afn->AirflowNetworkLinkageData(i).NodeHeights[0]
13340 : << state.afn->AirflowNetworkLinkageData(i).NodeNums[1] <<
13341 : state.afn->AirflowNetworkLinkageData(i).NodeHeights[1]
13342 : << state.afn->AirflowNetworkLinkageData(i).CompNum << 0 << 0;
13343 : }
13344 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13345 : }
13346 : */
13347 24 : setsky();
13348 :
13349 : // SETSKY figures out the IK stuff -- which is why E+ doesn't allocate AU until here
13350 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13351 : // ! only printing to screen, can be commented
13352 : // print*, "SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS is defined"
13353 : // write(*,'(2(a,i8))') "AllocateAirflowNetworkData: after SETSKY, allocating AU. NetworkNumOfNodes=", &
13354 : // NetworkNumOfNodes, " IK(NetworkNumOfNodes+1)= NNZE=", IK(NetworkNumOfNodes+1)
13355 : // print*, " NetworkNumOfLinks=", NetworkNumOfLinks
13356 : // allocate same size as others -- this will be maximum !noel
13357 24 : newAU.allocate(IK(NetworkNumOfNodes + 1));
13358 : #endif
13359 :
13360 : // noel, GNU says the AU is indexed above its upper bound
13361 : // ALLOCATE(AU(IK(NetworkNumOfNodes+1)-1))
13362 24 : AU.allocate(IK(NetworkNumOfNodes + 1));
13363 24 : }
13364 :
13365 16874 : void Solver::initialize_calculation()
13366 : {
13367 :
13368 : // SUBROUTINE INFORMATION:
13369 : // AUTHOR Lixing Gu
13370 : // DATE WRITTEN Aug. 2003
13371 : // MODIFIED na
13372 : // RE-ENGINEERED na
13373 :
13374 : // PURPOSE OF THIS SUBROUTINE:
13375 : // This subroutine initializes variables for AirflowNetworkSolver.
13376 :
13377 : // METHODOLOGY EMPLOYED:
13378 : // na
13379 :
13380 : // REFERENCES:
13381 : // na
13382 :
13383 : // USE STATEMENTS:
13384 : // na
13385 :
13386 : // Locals
13387 : // SUBROUTINE ARGUMENT DEFINITIONS:
13388 : // na
13389 :
13390 : // SUBROUTINE PARAMETER DEFINITIONS:
13391 : // na
13392 :
13393 : // INTERFACE BLOCK SPECIFICATIONS
13394 : // na
13395 :
13396 : // DERIVED TYPE DEFINITIONS
13397 : // na
13398 :
13399 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13400 :
13401 509242 : for (int i = 1; i <= ActualNumOfNodes; ++i) {
13402 492368 : ID(i) = i;
13403 : }
13404 547956 : for (int i = 1; i <= ActualNumOfLinks; ++i) {
13405 531082 : AFECTL(i) = 1.0;
13406 531082 : AFLOW(i) = 0.0;
13407 531082 : AFLOW2(i) = 0.0;
13408 : }
13409 :
13410 509242 : for (int i = 1; i <= ActualNumOfNodes; ++i) {
13411 : // TZ(i) = AirflowNetworkNodeSimu(i).TZ;
13412 : // WZ(i) = AirflowNetworkNodeSimu(i).WZ;
13413 492368 : PZ(i) = AirflowNetworkNodeSimu(i).PZ;
13414 492368 : node_states[i].temperature = AirflowNetworkNodeSimu(i).TZ;
13415 492368 : node_states[i].humidity_ratio = AirflowNetworkNodeSimu(i).WZ;
13416 : // properties[i].pressure = AirflowNetworkNodeSimu(i).PZ;
13417 : }
13418 16874 : }
13419 :
13420 24 : void Solver::setsky()
13421 : {
13422 : // SUBROUTINE INFORMATION:
13423 : // AUTHOR George Walton
13424 : // DATE WRITTEN 1998
13425 : // MODIFIED Feb. 2006 (L. Gu) to meet requirements of AirflowNetwork
13426 : // RE-ENGINEERED na
13427 :
13428 : // PURPOSE OF THIS SUBROUTINE:
13429 : // This subroutine sets up the "IK" array describing the sparse matrix [A] in skyline
13430 : // form by using the location matrix.
13431 :
13432 : // METHODOLOGY EMPLOYED:
13433 : // na
13434 :
13435 : // REFERENCES:
13436 : // AIRNET
13437 :
13438 : // USE STATEMENTS:
13439 : // na
13440 :
13441 : // Locals
13442 : // SUBROUTINE ARGUMENT DEFINITIONS:
13443 : // na
13444 :
13445 : // SUBROUTINE PARAMETER DEFINITIONS:
13446 : // na
13447 :
13448 : // INTERFACE BLOCK SPECIFICATIONS
13449 : // na
13450 :
13451 : // DERIVED TYPE DEFINITIONS
13452 : // na
13453 :
13454 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13455 : // IK(K) - pointer to the top of column/row "K".
13456 : int i;
13457 : int j;
13458 : int k;
13459 : int L;
13460 : int M;
13461 : int N1;
13462 : int N2;
13463 :
13464 : // Initialize "IK".
13465 311 : for (i = 1; i <= ActualNumOfNodes + 1; ++i) {
13466 287 : IK(i) = 0;
13467 : }
13468 : // Determine column heights.
13469 328 : for (M = 1; M <= ActualNumOfLinks; ++M) {
13470 304 : j = AirflowNetworkLinkageData(M).NodeNums[1];
13471 304 : if (j == 0) {
13472 0 : continue;
13473 : }
13474 304 : L = ID(j);
13475 304 : i = AirflowNetworkLinkageData(M).NodeNums[0];
13476 304 : k = ID(i);
13477 304 : N1 = std::abs(L - k);
13478 304 : N2 = max(k, L);
13479 304 : IK(N2) = max(IK(N2), N1);
13480 : }
13481 : // Convert heights to column addresses.
13482 24 : j = IK(1);
13483 24 : IK(1) = 1;
13484 287 : for (k = 1; k <= ActualNumOfNodes; ++k) {
13485 263 : i = IK(k + 1);
13486 263 : IK(k + 1) = IK(k) + j;
13487 263 : j = i;
13488 : }
13489 24 : }
13490 :
13491 16873 : void Solver::airmov()
13492 : {
13493 : // SUBROUTINE INFORMATION:
13494 : // AUTHOR George Walton
13495 : // DATE WRITTEN Extracted from AIRNETf
13496 : // MODIFIED Lixing Gu, 2/1/04
13497 : // Revised the subroutine to meet E+ needs
13498 : // MODIFIED Lixing Gu, 6/8/05
13499 : // RE-ENGINEERED na
13500 :
13501 : // PURPOSE OF THIS SUBROUTINE:
13502 : // This subroutine is a driver for AIRNET to calculate nodal pressures and linkage airflows
13503 :
13504 : // METHODOLOGY EMPLOYED:
13505 : // na
13506 :
13507 : // REFERENCES:
13508 : // na
13509 :
13510 : // USE STATEMENTS:
13511 :
13512 : // Locals
13513 : // SUBROUTINE ARGUMENT DEFINITIONS:
13514 : // na
13515 :
13516 : // SUBROUTINE PARAMETER DEFINITIONS:
13517 : // na
13518 :
13519 : // INTERFACE BLOCK SPECIFICATIONS
13520 : // na
13521 :
13522 : // DERIVED TYPE DEFINITIONS
13523 : // na
13524 :
13525 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13526 : int i;
13527 : int m;
13528 : int n;
13529 : int ITER;
13530 :
13531 : // Formats
13532 :
13533 : // static ObjexxFCL::gio::Fmt Format_900("(,/,11X,'i n m DP',12x,'F1',12X,'F2')");
13534 : // static ObjexxFCL::gio::Fmt Format_901("(1X,A6,3I5,3F14.6)");
13535 : // static ObjexxFCL::gio::Fmt Format_902("(,/,11X,'n P',12x,'sumF')");
13536 : // static ObjexxFCL::gio::Fmt Format_903("(1X,A6,I5,3F14.6)");
13537 : // static ObjexxFCL::gio::Fmt Format_907("(,/,' CPU seconds for ',A,F12.3)");
13538 :
13539 16873 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13540 16873 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13541 :
13542 : // Initialize pressure for pressure control and for Initialization Type = LinearInitializationMethod
13543 16873 : if ((simulation_control.InitFlag == 0) || (PressureSetFlag > 0 && AirflowNetworkFanActivated)) {
13544 333 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13545 324 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13546 270 : PZ(n) = 0.0;
13547 : }
13548 : }
13549 : }
13550 : // Compute zone air properties.
13551 509205 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13552 984664 : node_states[n].density =
13553 492332 : properties.density(m_state.dataEnvrn->StdBaroPress + PZ(n), node_states[n].temperature, node_states[n].humidity_ratio);
13554 : // RHOZ(n) = PsyRhoAirFnPbTdbW(StdBaroPress + PZ(n), TZ(n), WZ(n));
13555 492332 : if (AirflowNetworkNodeData(n).ExtNodeNum > 0) {
13556 573162 : node_states[n].density =
13557 286581 : properties.density(m_state.dataEnvrn->StdBaroPress + PZ(n), m_state.dataEnvrn->OutDryBulbTemp, m_state.dataEnvrn->OutHumRat);
13558 286581 : node_states[n].temperature = m_state.dataEnvrn->OutDryBulbTemp;
13559 286581 : node_states[n].humidity_ratio = m_state.dataEnvrn->OutHumRat;
13560 : }
13561 492332 : node_states[n].sqrt_density = std::sqrt(node_states[n].density);
13562 492332 : node_states[n].viscosity = 1.71432e-5 + 4.828e-8 * node_states[n].temperature;
13563 : // if (LIST >= 2) ObjexxFCL::gio::write(outputFile, Format_903) << "D,V:" << n << properties[n].density << properties[n].viscosity;
13564 : }
13565 : // Compute stack pressures.
13566 547896 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13567 531023 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13568 531023 : m = AirflowNetworkLinkageData(i).NodeNums[1];
13569 531023 : if (AFLOW(i) > 0.0) {
13570 0 : PS(i) = 9.80 * (node_states[n].density * (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13571 0 : m_state.afn->AirflowNetworkLinkageData(i).NodeHeights[1] * (node_states[m].density - node_states[n].density));
13572 531023 : } else if (AFLOW(i) < 0.0) {
13573 0 : PS(i) = 9.80 * (node_states[m].density * (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13574 0 : AirflowNetworkLinkageData(i).NodeHeights[0] * (node_states[m].density - node_states[n].density));
13575 : } else {
13576 1062046 : PS(i) = 4.90 * ((node_states[n].density + node_states[m].density) *
13577 531023 : (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13578 531023 : (AirflowNetworkLinkageData(i).NodeHeights[0] + AirflowNetworkLinkageData(i).NodeHeights[1]) *
13579 531023 : (node_states[m].density - node_states[n].density));
13580 : }
13581 : }
13582 :
13583 : // Calculate pressure field in a large opening
13584 16873 : dos.pstack(m_state, node_states, PZ);
13585 16873 : solvzp(ITER);
13586 :
13587 : // Report element flows and zone pressures.
13588 509205 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13589 492332 : SUMAF(n) = 0.0;
13590 : }
13591 : // if (LIST >= 1) ObjexxFCL::gio::write(outputFile, Format_900);
13592 547896 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13593 531023 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13594 531023 : m = AirflowNetworkLinkageData(i).NodeNums[1];
13595 : // if (LIST >= 1) {
13596 : // gio::write(outputFile, Format_901) << "Flow: " << i << n << m << AirflowNetworkLinkSimu(i).DP << AFLOW(i) << AFLOW2(i);
13597 : //}
13598 531023 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
13599 0 : SUMAF(n) = SUMAF(n) - AFLOW(i);
13600 0 : SUMAF(m) += AFLOW(i);
13601 : } else {
13602 531023 : SUMAF(n) = SUMAF(n) - AFLOW(i) - AFLOW2(i);
13603 531023 : SUMAF(m) += AFLOW(i) + AFLOW2(i);
13604 : }
13605 : }
13606 : // for (n = 1; n <= NetworkNumOfNodes; ++n) {
13607 : // if (LIST >= 1) gio::write(outputFile, Format_903) << "Room: " << n << PZ(n) << SUMAF(n) << properties[n].temperature;
13608 : //}
13609 :
13610 547896 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13611 531023 : if (AFLOW2(i) != 0.0) {
13612 : }
13613 531023 : if (AFLOW(i) > 0.0) {
13614 366378 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i);
13615 366378 : AirflowNetworkLinkSimu(i).FLOW2 = 0.0;
13616 : } else {
13617 164645 : AirflowNetworkLinkSimu(i).FLOW = 0.0;
13618 164645 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i);
13619 : }
13620 531023 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
13621 0 : if (AFLOW(i) > 0.0) {
13622 0 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i) + AFLOW2(i);
13623 0 : AirflowNetworkLinkSimu(i).FLOW2 = AFLOW2(i);
13624 : } else {
13625 0 : AirflowNetworkLinkSimu(i).FLOW = AFLOW2(i);
13626 0 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i) + AFLOW2(i);
13627 : }
13628 : }
13629 531023 : if (AirflowNetworkLinkageData(i).DetOpenNum > 0) {
13630 2 : if (AFLOW2(i) != 0.0) {
13631 2 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i) + AFLOW2(i);
13632 2 : AirflowNetworkLinkSimu(i).FLOW2 = AFLOW2(i);
13633 : }
13634 : }
13635 531023 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SOP && AFLOW2(i) != 0.0) {
13636 0 : if (AFLOW(i) >= 0.0) {
13637 0 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i);
13638 0 : AirflowNetworkLinkSimu(i).FLOW2 = std::abs(AFLOW2(i));
13639 : } else {
13640 0 : AirflowNetworkLinkSimu(i).FLOW = std::abs(AFLOW2(i));
13641 0 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i);
13642 : }
13643 : }
13644 : }
13645 :
13646 509205 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13647 492332 : AirflowNetworkNodeSimu(i).PZ = PZ(i);
13648 : }
13649 16873 : }
13650 :
13651 16873 : void Solver::solvzp(int &ITER) // number of iterations
13652 : {
13653 :
13654 : // SUBROUTINE INFORMATION:
13655 : // AUTHOR George Walton
13656 : // DATE WRITTEN Extracted from AIRNET
13657 : // MODIFIED Lixing Gu, 2/1/04
13658 : // Revised the subroutine to meet E+ needs
13659 : // MODIFIED Lixing Gu, 6/8/05
13660 : // RE-ENGINEERED na
13661 :
13662 : // PURPOSE OF THIS SUBROUTINE:
13663 : // This subroutine solves zone pressures by modified Newton-Raphson iteration
13664 :
13665 : // METHODOLOGY EMPLOYED:
13666 : // na
13667 :
13668 : // REFERENCES:
13669 : // na
13670 :
13671 16873 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13672 : // auto &NetworkNumOfLinks = ActualNumOfLinks;
13673 :
13674 : // Argument array dimensioning (these used to be arguments, need to also test newAU and newIK)
13675 16873 : EP_SIZE_CHECK(IK, NetworkNumOfNodes + 1);
13676 16873 : EP_SIZE_CHECK(AD, NetworkNumOfNodes);
13677 16873 : EP_SIZE_CHECK(AU, IK(NetworkNumOfNodes + 1));
13678 :
13679 : // Locals
13680 : // SUBROUTINE ARGUMENT DEFINITIONS:
13681 : // noel GNU says AU is being indexed beyound bounds
13682 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
13683 :
13684 : // SUBROUTINE PARAMETER DEFINITIONS:
13685 :
13686 : // INTERFACE BLOCK SPECIFICATIONS
13687 : // na
13688 :
13689 : // DERIVED TYPE DEFINITIONS
13690 : // na
13691 :
13692 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13693 :
13694 : // NNZE - number of nonzero entries in the "AU" array.
13695 : // LFLAG - if = 1, use laminar relationship (initialization).
13696 : // I - element number.
13697 : // N - number of node/zone 1.
13698 : // M - number of node/zone 2.
13699 : // F - flows through the element (kg/s).
13700 : // DF - partial derivatives: DF/DP.
13701 : // NF - number of flows, 1 or 2.
13702 : // SUMF - sum of flows into node/zone.
13703 : // CCF - current pressure correction (Pa).
13704 : // PCF - previous pressure correction (Pa).
13705 : // CEF - convergence enhancement factor.
13706 : int n;
13707 : int NNZE;
13708 : int NSYM;
13709 : bool LFLAG;
13710 : int CONVG;
13711 : int ACCEL;
13712 16873 : Array1D<Real64> PCF(NetworkNumOfNodes);
13713 16873 : Array1D<Real64> CEF(NetworkNumOfNodes);
13714 : Real64 C;
13715 : Real64 SSUMF;
13716 : Real64 SSUMAF;
13717 : Real64 ACC0;
13718 : Real64 ACC1;
13719 16873 : Array1D<Real64> CCF(NetworkNumOfNodes);
13720 :
13721 : // auto &outputFile = std::cout;
13722 :
13723 16873 : ACC1 = 0.0;
13724 16873 : ACCEL = 0;
13725 16873 : NSYM = 0;
13726 16873 : NNZE = IK(NetworkNumOfNodes + 1) - 1;
13727 : // if (LIST >= 2) print(outputFile, "Initialization{:16}{:16}{:16}\n", NetworkNumOfNodes, NetworkNumOfLinks, NNZE);
13728 16873 : ITER = 0;
13729 :
13730 509205 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13731 492332 : PCF(n) = 0.0;
13732 492332 : CEF(n) = 0.0;
13733 : }
13734 :
13735 16873 : if (simulation_control.InitFlag != 1) {
13736 : // Initialize node/zone pressure values by assuming only linear relationship between
13737 : // airflows and pressure drops.
13738 0 : LFLAG = true;
13739 0 : filjac(NNZE, LFLAG);
13740 0 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13741 0 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13742 0 : PZ(n) = SUMF(n);
13743 : }
13744 : }
13745 : // Data dump.
13746 : // if (LIST >= 3) {
13747 : // DUMPVD("AD:", AD, NetworkNumOfNodes, outputFile);
13748 : // DUMPVD("AU:", AU, NNZE, outputFile);
13749 : // DUMPVR("AF:", SUMF, NetworkNumOfNodes, outputFile);
13750 : // }
13751 : // Solve linear system for approximate PZ.
13752 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13753 0 : facsky(newAU, AD, newAU, newIK, NetworkNumOfNodes, NSYM); // noel
13754 0 : slvsky(newAU, AD, newAU, PZ, newIK, NetworkNumOfNodes, NSYM); // noel
13755 : #else
13756 : facsky(AU, AD, AU, IK, NetworkNumOfNodes, NSYM);
13757 : slvsky(AU, AD, AU, PZ, IK, NetworkNumOfNodes, NSYM);
13758 : #endif
13759 : // if (LIST >= 2) DUMPVD("PZ:", PZ, NetworkNumOfNodes, outputFile);
13760 : }
13761 : // Solve nonlinear airflow network equations by modified Newton's method.
13762 196676 : while (ITER < simulation_control.maximum_iterations) {
13763 196676 : LFLAG = false;
13764 196676 : ++ITER;
13765 : // if (LIST >= 2) {
13766 : // print(outputFile, "Begin iteration {}\n", ITER);
13767 : // }
13768 : // Set up the Jacobian matrix.
13769 196676 : filjac(NNZE, LFLAG);
13770 : // Data dump.
13771 : // if (LIST >= 3) {
13772 : // DUMPVR("SUMF:", SUMF, NetworkNumOfNodes, outputFile);
13773 : // DUMPVR("SUMAF:", SUMAF, NetworkNumOfNodes, outputFile);
13774 : // }
13775 : // Check convergence.
13776 196676 : CONVG = 1;
13777 196676 : SSUMF = 0.0;
13778 196676 : SSUMAF = 0.0;
13779 6417520 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13780 6220844 : SSUMF += std::abs(SUMF(n));
13781 6220844 : SSUMAF += SUMAF(n);
13782 6220844 : if (CONVG == 1) {
13783 2795876 : if (std::abs(SUMF(n)) <= simulation_control.absolute_convergence_tolerance) {
13784 2533853 : continue;
13785 : }
13786 262023 : if (std::abs(SUMF(n) / SUMAF(n)) > simulation_control.relative_convergence_tolerance) {
13787 179803 : CONVG = 0;
13788 : }
13789 : }
13790 : }
13791 196676 : ACC0 = ACC1;
13792 196676 : if (SSUMAF > 0.0) {
13793 196676 : ACC1 = SSUMF / SSUMAF;
13794 : }
13795 196676 : if (CONVG == 1 && ITER > 1) {
13796 16873 : return;
13797 : }
13798 179803 : if (ITER >= simulation_control.maximum_iterations) {
13799 0 : break;
13800 : }
13801 : // Data dump.
13802 : // if (LIST >= 3) {
13803 : // DUMPVD("AD:", AD, NetworkNumOfNodes, outputFile);
13804 : // DUMPVD("AU:", AU, NNZE, outputFile);
13805 : // }
13806 : // Solve AA * CCF = SUMF.
13807 5908315 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13808 5728512 : CCF(n) = SUMF(n);
13809 : }
13810 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13811 179803 : facsky(newAU, AD, newAU, newIK, NetworkNumOfNodes, NSYM); // noel
13812 179803 : slvsky(newAU, AD, newAU, CCF, newIK, NetworkNumOfNodes, NSYM); // noel
13813 : #else
13814 : facsky(AU, AD, AU, IK, NetworkNumOfNodes, NSYM);
13815 : slvsky(AU, AD, AU, CCF, IK, NetworkNumOfNodes, NSYM);
13816 : #endif
13817 : // Revise PZ (Steffensen iteration on the N-R correction factors to handle oscillating corrections).
13818 179803 : if (ACCEL == 1) {
13819 61529 : ACCEL = 0;
13820 : } else {
13821 118274 : if (ITER > 2 && ACC1 > 0.5 * ACC0) {
13822 61557 : ACCEL = 1;
13823 : }
13824 : }
13825 5908315 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13826 5728512 : if (AirflowNetworkNodeData(n).NodeTypeNum == 1) {
13827 3054623 : continue;
13828 : }
13829 2673889 : CEF(n) = 1.0;
13830 2673889 : if (ACCEL == 1) {
13831 985263 : C = CCF(n) / PCF(n);
13832 985263 : if (C < simulation_control.convergence_acceleration_limit) {
13833 431617 : CEF(n) = 1.0 / (1.0 - C);
13834 : }
13835 985263 : C = CCF(n) * CEF(n);
13836 : } else {
13837 : // IF (CCF(N) .EQ. 0.0d0) CCF(N)=TINY(CCF(N)) ! 1.0E-40
13838 1688626 : if (CCF(n) == 0.0) {
13839 0 : CCF(n) = Constant::rTinyValue; // 1.0E-40 (Epsilon)
13840 : }
13841 1688626 : PCF(n) = CCF(n);
13842 1688626 : C = CCF(n);
13843 : }
13844 2673889 : if (std::abs(C) > simulation_control.MaxPressure) {
13845 0 : CEF(n) *= simulation_control.MaxPressure / std::abs(C);
13846 0 : PZ(n) -= CCF(n) * CEF(n);
13847 : } else {
13848 2673889 : PZ(n) -= C;
13849 : }
13850 : }
13851 : // Data revision dump.
13852 : // if (LIST >= 2) {
13853 : // for (n = 1; n <= NetworkNumOfNodes; ++n) {
13854 : // if (state.afn->AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13855 : // print(outputFile, "Rev: {:5}{:3}{:14.6E} {:8.4F}{:24.14F}", n, SUMF(n), CCF(n), CEF(n), PZ(n));
13856 : // }
13857 : // }
13858 : // }
13859 : }
13860 :
13861 : // Error termination.
13862 0 : ShowSevereError(m_state, "Too many iterations (SOLVZP) in Airflow Network simulation");
13863 0 : ++ExtLargeOpeningErrCount;
13864 0 : if (ExtLargeOpeningErrCount < 2) {
13865 0 : ShowWarningError(m_state,
13866 : "AirflowNetwork: SOLVER, Changing values for initialization flag, Relative airflow convergence, Absolute airflow "
13867 : "convergence, Convergence acceleration limit or Maximum Iteration Number may solve the problem.");
13868 0 : ShowContinueErrorTimeStamp(m_state, "");
13869 0 : ShowContinueError(m_state,
13870 0 : "..Iterations=" + std::to_string(ITER) + ", Max allowed=" + std::to_string(simulation_control.maximum_iterations));
13871 0 : ShowFatalError(m_state, "AirflowNetwork: SOLVER, The previous error causes termination.");
13872 : } else {
13873 0 : ShowRecurringWarningErrorAtEnd(
13874 0 : m_state, "AirFlowNetwork: Too many iterations (SOLVZP) in AirflowNetwork simulation continues.", ExtLargeOpeningErrIndex);
13875 : }
13876 50619 : }
13877 :
13878 196676 : void Solver::filjac(int const NNZE, // number of nonzero entries in the "AU" array.
13879 : bool const LFLAG // if = 1, use laminar relationship (initialization).
13880 : )
13881 : {
13882 :
13883 : // SUBROUTINE INFORMATION:
13884 : // AUTHOR George Walton
13885 : // DATE WRITTEN Extracted from AIRNET
13886 : // MODIFIED Lixing Gu, 2/1/04
13887 : // Revised the subroutine to meet E+ needs
13888 : // MODIFIED Lixing Gu, 6/8/05
13889 : // RE-ENGINEERED na
13890 :
13891 : // PURPOSE OF THIS SUBROUTINE:
13892 : // This subroutine creates matrices for solution of flows
13893 :
13894 : // METHODOLOGY EMPLOYED:
13895 : // na
13896 :
13897 : // REFERENCES:
13898 : // na
13899 :
13900 : // USE STATEMENTS:
13901 : // na
13902 :
13903 : // Locals
13904 : // SUBROUTINE ARGUMENT DEFINITIONS:
13905 :
13906 : // SUBROUTINE PARAMETER DEFINITIONS:
13907 : // na
13908 :
13909 : // INTERFACE BLOCK SPECIFICATIONS
13910 : // na
13911 :
13912 : // DERIVED TYPE DEFINITIONS
13913 : // na
13914 :
13915 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13916 :
13917 : // I - component number.
13918 : // N - number of node/zone 1.
13919 : // M - number of node/zone 2.
13920 : // F - flows through the element (kg/s).
13921 : // DF - partial derivatives: DF/DP.
13922 : // NF - number of flows, 1 or 2.
13923 : int i;
13924 : int j;
13925 : int n;
13926 : int FLAG;
13927 : int NF;
13928 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13929 : int LHK; // noel
13930 : int JHK;
13931 : int JHK1;
13932 : int newsum;
13933 : int newh;
13934 : int ispan;
13935 : int thisIK;
13936 : bool allZero; // noel
13937 : #endif
13938 196676 : Array1D<Real64> X(4);
13939 : Real64 DP;
13940 196676 : std::array<Real64, 2> F{{0.0, 0.0}};
13941 196676 : std::array<Real64, 2> DF{{0.0, 0.0}};
13942 :
13943 196676 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13944 196676 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13945 :
13946 6417520 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13947 6220844 : SUMF(n) = 0.0;
13948 6220844 : SUMAF(n) = 0.0;
13949 6220844 : if (AirflowNetworkNodeData(n).NodeTypeNum == 1) {
13950 3341204 : AD(n) = 1.0;
13951 : } else {
13952 2879640 : AD(n) = 0.0;
13953 : }
13954 : }
13955 56392737 : for (n = 1; n <= NNZE; ++n) {
13956 56196061 : AU(n) = 0.0;
13957 : }
13958 : // Loop(s) to calculate control, etc.
13959 : // Set up the Jacobian matrix.
13960 7040245 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13961 6843569 : if (AirflowNetworkLinkageData(i).element == nullptr) {
13962 0 : continue;
13963 : }
13964 6843569 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13965 6843569 : int m = AirflowNetworkLinkageData(i).NodeNums[1];
13966 : //!!! Check array of DP. DpL is used for multizone air flow calculation only
13967 : //!!! and is not for forced air calculation
13968 6843569 : if (i > NumOfLinksMultiZone) {
13969 3107535 : DP = PZ(n) - PZ(m) + PS(i) + PW(i);
13970 : } else {
13971 3736034 : DP = PZ(n) - PZ(m) + dos.DpL(i, 1) + PW(i);
13972 : }
13973 6843569 : Real64 multiplier = 1.0;
13974 6843569 : Real64 control = AirflowNetworkLinkageData(i).control;
13975 : // if (LIST >= 4) ObjexxFCL::gio::write(outputFile, Format_901) << "PS:" << i << n << M << PS(i) << PW(i) << AirflowNetworkLinkSimu(i).DP;
13976 6843569 : j = AirflowNetworkLinkageData(i).CompNum;
13977 :
13978 6843569 : NF = AirflowNetworkLinkageData(i).element->calculate(m_state, LFLAG, DP, i, multiplier, control, node_states[n], node_states[m], F, DF);
13979 6843569 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::CPD && DP != 0.0) {
13980 120 : DP = DisSysCompCPDData(AirflowNetworkCompData(j).TypeNum).DP;
13981 : }
13982 :
13983 6843569 : AirflowNetworkLinkSimu(i).DP = DP;
13984 6843569 : AFLOW(i) = F[0];
13985 6843569 : AFLOW2(i) = 0.0;
13986 6843569 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DOP) {
13987 14 : AFLOW2(i) = F[1];
13988 : }
13989 : // if (LIST >= 3) ObjexxFCL::gio::write(outputFile, Format_901) << " NRi:" << i << n << M << AirflowNetworkLinkSimu(i).DP << F[0] <<
13990 : // DF[0];
13991 6843569 : FLAG = 1;
13992 6843569 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13993 6843397 : ++FLAG;
13994 6843397 : X(1) = DF[0];
13995 6843397 : X(2) = -DF[0];
13996 6843397 : SUMF(n) += F[0];
13997 6843397 : SUMAF(n) += std::abs(F[0]);
13998 : }
13999 6843569 : if (AirflowNetworkNodeData(m).NodeTypeNum == 0) {
14000 3501101 : FLAG += 2;
14001 3501101 : X(4) = DF[0];
14002 3501101 : X(3) = -DF[0];
14003 3501101 : SUMF(m) -= F[0];
14004 3501101 : SUMAF(m) += std::abs(F[0]);
14005 : }
14006 6843569 : if (FLAG != 1) {
14007 6843569 : filsky(X, AirflowNetworkLinkageData(i).NodeNums, IK, AU, AD, FLAG);
14008 : }
14009 6843569 : if (NF == 1) {
14010 6843569 : continue;
14011 : }
14012 0 : AFLOW2(i) = F[1];
14013 : // if (LIST >= 3) ObjexxFCL::gio::write(outputFile, Format_901) << " NRj:" << i << n << m << AirflowNetworkLinkSimu(i).DP << F[1] <<
14014 : // DF[1];
14015 0 : FLAG = 1;
14016 0 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
14017 0 : ++FLAG;
14018 0 : X(1) = DF[1];
14019 0 : X(2) = -DF[1];
14020 0 : SUMF(n) += F[1];
14021 0 : SUMAF(n) += std::abs(F[1]);
14022 : }
14023 0 : if (AirflowNetworkNodeData(m).NodeTypeNum == 0) {
14024 0 : FLAG += 2;
14025 0 : X(4) = DF[1];
14026 0 : X(3) = -DF[1];
14027 0 : SUMF(m) -= F[1];
14028 0 : SUMAF(m) += std::abs(F[1]);
14029 : }
14030 0 : if (FLAG != 1) {
14031 0 : filsky(X, AirflowNetworkLinkageData(i).NodeNums, IK, AU, AD, FLAG);
14032 : }
14033 : }
14034 :
14035 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
14036 :
14037 : // After the matrix values have been set, we can look at them and see if any columns are filled with zeros.
14038 : // If they are, let's remove them from the matrix -- but only for the purposes of doing the solve.
14039 : // They way I do this is building a separate IK array (newIK) that simply changes the column heights.
14040 : // So the affected SOLVEs would use this newIK and nothing else changes.
14041 6614196 : for (n = 1; n <= NetworkNumOfNodes + 1; ++n) {
14042 6417520 : newIK(n) = IK(n);
14043 : // print*, " NetworkNumOfNodes n=", n, " IK(n)=", IK(n)
14044 : }
14045 :
14046 196676 : newsum = IK(2) - IK(1); // always 0?
14047 :
14048 196676 : JHK = 1;
14049 6220844 : for (n = 2; n <= NetworkNumOfNodes; ++n) {
14050 6024168 : JHK1 = IK(n + 1); // starts at IK(3)-IK(2)
14051 6024168 : LHK = JHK1 - JHK;
14052 6024168 : if (LHK <= 0) {
14053 163441 : newIK(n + 1) = newIK(n);
14054 163441 : continue;
14055 : }
14056 : // write(*,'(4(a,i8))') "n=", n, " ik=", ik(n), " JHK=", JHK, " LHK=", LHK
14057 :
14058 : // is the entire column zero? noel
14059 5860727 : allZero = true;
14060 39431122 : for (i = 0; i <= LHK - 1; ++i) {
14061 35926509 : if (AU(JHK + i) != 0.0) {
14062 2356114 : allZero = false;
14063 2356114 : break;
14064 : }
14065 : }
14066 :
14067 5860727 : newh = LHK;
14068 5860727 : if (allZero) {
14069 : // print*, "allzero n=", n
14070 3504613 : newh = 0;
14071 : } else {
14072 : // DO i=0,LHK-1
14073 : // write(*, '(2(a,i8),a, f15.3)') " n=", n, " i=", i, " AU(JHK+i)=", AU(JHK+i)
14074 : // enddo
14075 : }
14076 5860727 : newIK(n + 1) = newIK(n) + newh;
14077 5860727 : newsum += newh;
14078 :
14079 : // do i = LHK-1,0, -1
14080 : // write(*, '(2(a,i8),a, f15.3)') " n=", n, " i=", i, " AU(JHK+i)=", AU(JHK+i)
14081 : // enddo
14082 5860727 : JHK = JHK1;
14083 : }
14084 :
14085 : // this is just a print to screen, is not necessary
14086 : // if (firstTime) then
14087 : // write(*, '(2(a,i8))') " After SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS: newsum=", newsum, " oldsum=", IK(NetworkNumOfNodes+1)
14088 : // firstTime=.FALSE.
14089 : // endif
14090 :
14091 : // Now fill newAU from AU, using newIK
14092 6220844 : for (n = 2; n <= NetworkNumOfNodes; ++n) {
14093 6024168 : thisIK = newIK(n);
14094 6024168 : ispan = newIK(n + 1) - thisIK;
14095 :
14096 6024168 : if (ispan <= 0) {
14097 3668054 : continue;
14098 : }
14099 24981780 : for (i = 0; i <= ispan - 1; ++i) {
14100 22625666 : newAU(thisIK + i) = AU(IK(n) + i);
14101 : }
14102 : }
14103 : #endif
14104 196676 : }
14105 :
14106 179803 : void Solver::facsky(Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
14107 : Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
14108 : Array1D<Real64> &AL, // the lower triangle of [A] before and after factoring
14109 : const Array1D_int &IK, // pointer to the top of column/row "K"
14110 : int const NEQ, // number of equations
14111 : int const NSYM // symmetry: 0 = symmetric matrix, 1 = non-symmetric
14112 : )
14113 : {
14114 :
14115 : // SUBROUTINE INFORMATION:
14116 : // AUTHOR George Walton
14117 : // DATE WRITTEN Extracted from AIRNET
14118 : // MODIFIED Lixing Gu, 2/1/04
14119 : // Revised the subroutine to meet E+ needs
14120 : // MODIFIED Lixing Gu, 6/8/05
14121 : // RE-ENGINEERED This subroutine is revised from FACSKY developed by George Walton, NIST
14122 :
14123 : // PURPOSE OF THIS SUBROUTINE:
14124 : // This subroutine performs L-U factorization of a skyline ordered matrix, [A]
14125 : // The algorithm has been restructured for clarity.
14126 : // Note dependence on compiler for optimizing the inner do loops.
14127 :
14128 : // METHODOLOGY EMPLOYED:
14129 : // L-U factorization of a skyline ordered matrix, [A], used for
14130 : // solution of simultaneous linear algebraic equations [A] * X = B.
14131 : // No pivoting! No scaling! No warnings!!!
14132 : // Related routines: SLVSKY, SETSKY, FILSKY.
14133 :
14134 : // REFERENCES:
14135 : // Algorithm is described in "The Finite Element Method Displayed",
14136 : // by G. Dhatt and G. Touzot, John Wiley & Sons, New York, 1984.
14137 :
14138 : // USE STATEMENTS:
14139 : // na
14140 :
14141 : // Argument array dimensioning
14142 179803 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
14143 179803 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
14144 179803 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
14145 179803 : EP_SIZE_CHECK(AL, IK(ActualNumOfNodes + 1) - 1);
14146 :
14147 : // Locals
14148 : // SUBROUTINE ARGUMENT DEFINITIONS:
14149 : // noel, GNU says the AU is indexed above its upper bound
14150 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
14151 :
14152 : // SUBROUTINE PARAMETER DEFINITIONS:
14153 : // na
14154 :
14155 : // INTERFACE BLOCK SPECIFICATIONS
14156 : // na
14157 :
14158 : // DERIVED TYPE DEFINITIONS
14159 : // na
14160 :
14161 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14162 : int JHK;
14163 : int LHK1;
14164 : int IMIN;
14165 : int IMIN1;
14166 : int JHJ;
14167 : int JHJ1;
14168 : int IC;
14169 : int i;
14170 : int j;
14171 : int k;
14172 : Real64 T1;
14173 : Real64 T2;
14174 : Real64 SDOT;
14175 : Real64 SUMD;
14176 :
14177 179803 : AD(1) = 1.0 / AD(1);
14178 179803 : JHK = 1;
14179 5728512 : for (k = 2; k <= NEQ; ++k) {
14180 5548709 : SUMD = 0.0;
14181 5548709 : int JHK1 = IK(k + 1);
14182 5548709 : int LHK = JHK1 - JHK;
14183 5548709 : if (LHK > 0) {
14184 2189376 : LHK1 = LHK - 1;
14185 2189376 : IMIN = k - LHK1;
14186 2189376 : IMIN1 = IMIN - 1;
14187 2189376 : if (NSYM == 1) {
14188 0 : AL(JHK) *= AD(IMIN1);
14189 : }
14190 2189376 : if (LHK1 != 0) {
14191 1067601 : JHJ = IK(IMIN);
14192 1067601 : if (NSYM == 0) {
14193 19963949 : for (j = 1; j <= LHK1; ++j) {
14194 18896348 : JHJ1 = IK(IMIN + j);
14195 18896348 : IC = min(j, JHJ1 - JHJ);
14196 18896348 : if (IC > 0) {
14197 5039385 : SDOT = 0.0;
14198 44555044 : for (i = 0; i <= IC - 1; ++i) {
14199 39515659 : SDOT += AU(JHJ1 - IC + i) * AU(JHK + j - IC + i);
14200 : }
14201 5039385 : AU(JHK + j) -= SDOT;
14202 : }
14203 18896348 : JHJ = JHJ1;
14204 : }
14205 : } else {
14206 0 : for (j = 1; j <= LHK1; ++j) {
14207 0 : JHJ1 = IK(IMIN + j);
14208 0 : IC = min(j, JHJ1 - JHJ);
14209 0 : SDOT = 0.0;
14210 0 : if (IC > 0) {
14211 0 : for (i = 0; i <= IC - 1; ++i) {
14212 0 : SDOT += AL(JHJ1 - IC + i) * AU(JHK + j - IC + i);
14213 : }
14214 0 : AU(JHK + j) -= SDOT;
14215 0 : SDOT = 0.0;
14216 0 : for (i = 0; i <= IC - 1; ++i) {
14217 0 : SDOT += AU(JHJ1 - IC + i) * AL(JHK + j - IC + i);
14218 : }
14219 : }
14220 0 : AL(JHK + j) = (AL(JHK + j) - SDOT) * AD(IMIN1 + j);
14221 0 : JHJ = JHJ1;
14222 : }
14223 : }
14224 : }
14225 2189376 : if (NSYM == 0) {
14226 23275100 : for (i = 0; i <= LHK1; ++i) {
14227 21085724 : T1 = AU(JHK + i);
14228 21085724 : T2 = T1 * AD(IMIN1 + i);
14229 21085724 : AU(JHK + i) = T2;
14230 21085724 : SUMD += T1 * T2;
14231 : }
14232 : } else {
14233 0 : for (i = 0; i <= LHK1; ++i) {
14234 0 : SUMD += AU(JHK + i) * AL(JHK + i);
14235 : }
14236 : }
14237 : }
14238 5548709 : if (AD(k) - SUMD == 0.0) {
14239 0 : ShowSevereError(m_state, "AirflowNetworkSolver: L-U factorization in Subroutine FACSKY.");
14240 0 : ShowContinueError(
14241 : m_state,
14242 0 : "The denominator used in L-U factorizationis equal to 0.0 at node = " + m_state.afn->AirflowNetworkNodeData(k).Name + '.');
14243 0 : ShowContinueError(
14244 : m_state, "One possible cause is that this node may not be connected directly, or indirectly via airflow network connections ");
14245 0 : ShowContinueError(
14246 : m_state, "(e.g., AirflowNetwork:Multizone:SurfaceCrack, AirflowNetwork:Multizone:Component:SimpleOpening, etc.), to an external");
14247 0 : ShowContinueError(m_state, "node (AirflowNetwork:MultiZone:Surface).");
14248 0 : ShowContinueError(m_state,
14249 : "Please send your input file and weather file to EnergyPlus support/development team for further investigation.");
14250 0 : ShowFatalError(m_state, "Preceding condition causes termination.");
14251 : }
14252 5548709 : AD(k) = 1.0 / (AD(k) - SUMD);
14253 5548709 : JHK = JHK1;
14254 : }
14255 179803 : }
14256 :
14257 179803 : void Solver::slvsky(const Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
14258 : const Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
14259 : const Array1D<Real64> &AL, // the lower triangle of [A] before and after factoring
14260 : Array1D<Real64> &B, // "B" vector (input); "X" vector (output).
14261 : const Array1D_int &IK, // pointer to the top of column/row "K"
14262 : int const NEQ, // number of equations
14263 : int const NSYM // symmetry: 0 = symmetric matrix, 1 = non-symmetric
14264 : )
14265 : {
14266 :
14267 : // SUBROUTINE INFORMATION:
14268 : // AUTHOR George Walton
14269 : // DATE WRITTEN Extracted from AIRNET
14270 : // MODIFIED Lixing Gu, 2/1/04
14271 : // Revised the subroutine to meet E+ needs
14272 : // MODIFIED Lixing Gu, 6/8/05
14273 : // RE-ENGINEERED This subroutine is revised from CLVSKY developed by George Walton, NIST
14274 :
14275 : // PURPOSE OF THIS SUBROUTINE:
14276 : // This subroutine solves simultaneous linear algebraic equations [A] * X = B
14277 : // using L-U factored skyline form of [A] from "FACSKY"
14278 :
14279 : // METHODOLOGY EMPLOYED:
14280 : // na
14281 :
14282 : // REFERENCES:
14283 : // na
14284 :
14285 : // USE STATEMENTS:
14286 : // na
14287 :
14288 : // Argument array dimensioning
14289 179803 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
14290 179803 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
14291 179803 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
14292 179803 : EP_SIZE_CHECK(AL, IK(ActualNumOfNodes + 1) - 1);
14293 179803 : EP_SIZE_CHECK(B, ActualNumOfNodes);
14294 :
14295 : // Locals
14296 : // SUBROUTINE ARGUMENT DEFINITIONS:
14297 : // noel, GNU says the AU is indexed above its upper bound
14298 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
14299 :
14300 : // SUBROUTINE PARAMETER DEFINITIONS:
14301 : // na
14302 :
14303 : // INTERFACE BLOCK SPECIFICATIONS
14304 : // na
14305 :
14306 : // DERIVED TYPE DEFINITIONS
14307 : // na
14308 :
14309 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14310 :
14311 : int i;
14312 : int JHK;
14313 : int JHK1;
14314 : int k;
14315 : Real64 SDOT;
14316 : Real64 T1;
14317 :
14318 179803 : JHK = 1;
14319 5728512 : for (k = 2; k <= NEQ; ++k) {
14320 5548709 : JHK1 = IK(k + 1);
14321 5548709 : int LHK = JHK1 - JHK;
14322 5548709 : if (LHK <= 0) {
14323 3359333 : continue;
14324 : }
14325 2189376 : SDOT = 0.0;
14326 2189376 : if (NSYM == 0) {
14327 23275100 : for (i = 0; i <= LHK - 1; ++i) {
14328 21085724 : SDOT += AU(JHK + i) * B(k - LHK + i);
14329 : }
14330 : } else {
14331 0 : for (i = 0; i <= LHK - 1; ++i) {
14332 0 : SDOT += AL(JHK + i) * B(k - LHK + i);
14333 : }
14334 : }
14335 2189376 : B(k) -= SDOT;
14336 2189376 : JHK = JHK1;
14337 : }
14338 179803 : if (NSYM == 0) {
14339 5908315 : for (k = 1; k <= NEQ; ++k) {
14340 5728512 : B(k) *= AD(k);
14341 : }
14342 : }
14343 179803 : k = NEQ + 1;
14344 179803 : JHK1 = IK(k);
14345 5728512 : while (k != 1) {
14346 5728512 : --k;
14347 5728512 : if (NSYM == 1) {
14348 0 : B(k) *= AD(k);
14349 : }
14350 5728512 : if (k == 1) {
14351 179803 : break;
14352 : }
14353 : // IF(K.EQ.1) RETURN
14354 5548709 : JHK = IK(k);
14355 5548709 : T1 = B(k);
14356 26634433 : for (i = 0; i <= JHK1 - JHK - 1; ++i) {
14357 21085724 : B(k - JHK1 + JHK + i) -= AU(JHK + i) * T1;
14358 : }
14359 5548709 : JHK1 = JHK;
14360 : }
14361 179803 : }
14362 :
14363 6843569 : void Solver::filsky(const Array1D<Real64> &X, // element array (row-wise sequence)
14364 : std::array<int, 2> const LM, // location matrix
14365 : const Array1D_int &IK, // pointer to the top of column/row "K"
14366 : Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
14367 : Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
14368 : int const FLAG // mode of operation
14369 : )
14370 : {
14371 :
14372 : // SUBROUTINE INFORMATION:
14373 : // AUTHOR George Walton
14374 : // DATE WRITTEN Extracted from AIRNET
14375 : // MODIFIED Lixing Gu, 2/1/04
14376 : // Revised the subroutine to meet E+ needs
14377 : // MODIFIED Lixing Gu, 6/8/05
14378 : // RE-ENGINEERED This subroutine is revised from FILSKY developed by George Walton, NIST
14379 :
14380 : // PURPOSE OF THIS SUBROUTINE:
14381 : // This subroutine adds element array "X" to the sparse skyline matrix [A]
14382 :
14383 : // Argument array dimensioning
14384 6843569 : EP_SIZE_CHECK(X, 4);
14385 6843569 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
14386 6843569 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
14387 6843569 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
14388 :
14389 : // SUBROUTINE ARGUMENT DEFINITIONS:
14390 : // noel, GNU says the AU is indexed above its upper bound
14391 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
14392 :
14393 : // K = row number, L = column number.
14394 6843569 : if (FLAG > 1) {
14395 6843569 : int k = LM[0];
14396 6843569 : int L = LM[1];
14397 6843569 : if (FLAG == 4) {
14398 3500929 : AD(k) += X(1);
14399 3500929 : if (k < L) {
14400 2487037 : int j = IK(L + 1) - L + k;
14401 2487037 : AU(j) += X(2);
14402 : } else {
14403 1013892 : int j = IK(k + 1) - k + L;
14404 1013892 : AU(j) += X(3);
14405 : }
14406 3500929 : AD(L) += X(4);
14407 3342640 : } else if (FLAG == 3) {
14408 172 : AD(L) += X(4);
14409 3342468 : } else if (FLAG == 2) {
14410 3342468 : AD(k) += X(1);
14411 : }
14412 : }
14413 6843569 : }
14414 :
14415 : } // namespace AirflowNetwork
14416 :
14417 : } // namespace EnergyPlus
|