Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #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/HVACFan.hh>
90 : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
91 : #include <EnergyPlus/HVACStandAloneERV.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/UtilityRoutines.hh>
105 : #include <EnergyPlus/WaterThermalTanks.hh>
106 : #include <EnergyPlus/ZoneDehumidifier.hh>
107 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
108 :
109 : namespace EnergyPlus {
110 :
111 : namespace AirflowNetwork {
112 :
113 : // MODULE INFORMATION:
114 : // AUTHOR Lixing Gu, Don Shirey, and Muthusamy V. Swami
115 : // DATE WRITTEN July 2005
116 : // MODIFIED na
117 : // RE-ENGINEERED na
118 :
119 : // PURPOSE OF THIS MODULE:
120 : // This module is used to simulate airflows and pressures. The module is modified to
121 : // meet requirements of EnergyPLus based on AIRNET, developed by
122 : // National Institute of Standards and Technology (NIST).
123 :
124 : // METHODOLOGY EMPLOYED:
125 : // An airflow network approach is used. It consists of nodes connected by airflow elements.
126 : // The Newton's method is applied to solve a sparse matrix. When a new solver is available, this
127 : // module will be replaced or updated.
128 :
129 : // REFERENCES:
130 : // Walton, G. N., 1989, "AIRNET - A Computer Program for Building Airflow Network Modeling,"
131 : // NISTIR 89-4072, National Institute of Standards and Technology, Gaithersburg, Maryland
132 :
133 : // Using/Aliasing
134 : using Curve::CurveValue;
135 : using Curve::GetCurveIndex;
136 : using DataEnvironment::OutDryBulbTempAt;
137 : using DataHVACGlobals::ContFanCycCoil;
138 : using DataHVACGlobals::CycFanCycCoil;
139 : using DataHVACGlobals::FanType_SimpleConstVolume;
140 : using DataHVACGlobals::FanType_SimpleOnOff;
141 : using DataHVACGlobals::FanType_SimpleVAV;
142 : using DataHVACGlobals::FanType_ZoneExhaust;
143 : using DataSurfaces::cExtBoundCondition;
144 : using DataSurfaces::ExternalEnvironment;
145 : using DataSurfaces::OtherSideCoefNoCalcExt;
146 : using DataSurfaces::SurfaceClass;
147 : using Fans::GetFanIndex;
148 : using Fans::GetFanInletNode;
149 : using Fans::GetFanOutletNode;
150 : using Fans::GetFanType;
151 : using Fans::GetFanVolFlow;
152 : using Psychrometrics::PsyCpAirFnW;
153 : using Psychrometrics::PsyHFnTdbW;
154 : using Psychrometrics::PsyRhoAirFnPbTdbW;
155 : using ScheduleManager::GetCurrentScheduleValue;
156 : using ScheduleManager::GetScheduleIndex;
157 :
158 771 : Solver::Solver(EnergyPlusData &state) : m_state(state), properties(state)
159 : {
160 771 : }
161 :
162 : int constexpr NumOfVentCtrTypes(6); // Number of zone level venting control types
163 :
164 657644 : void Solver::manage_balance(Optional_bool_const FirstHVACIteration, // True when solution technique on first iteration
165 : Optional_int_const Iter, // Iteration number
166 : Optional_bool ResimulateAirZone // True when solution technique on third iteration
167 : )
168 : {
169 :
170 : // SUBROUTINE INFORMATION:
171 : // AUTHOR Lixing Gu
172 : // DATE WRITTEN July 28, 2005
173 : // MODIFIED na
174 : // RE-ENGINEERED na
175 :
176 : // PURPOSE OF THIS SUBROUTINE:
177 : // This subroutine performs simulation of air distribution system.
178 :
179 : // Using/Aliasing
180 657644 : auto &TurnFansOn = m_state.dataHVACGlobal->TurnFansOn;
181 : using DataHVACGlobals::VerySmallMassFlow;
182 :
183 : // Locals
184 : int i;
185 657644 : int AFNSupplyFanType = 0;
186 :
187 657644 : if (AirflowNetworkGetInputFlag) {
188 771 : get_input();
189 771 : AirflowNetworkGetInputFlag = false;
190 771 : return;
191 : }
192 :
193 656873 : if (present(ResimulateAirZone)) {
194 357307 : ResimulateAirZone = false;
195 : }
196 :
197 656873 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) return;
198 :
199 656873 : if (m_state.dataGlobal->BeginEnvrnFlag) {
200 2228 : TurnFansOn = false; // The FAN should be off when BeginEnvrnFlag = .True.
201 : }
202 :
203 656873 : initialize();
204 :
205 656873 : auto &NetworkNumOfNodes = ActualNumOfNodes;
206 656873 : auto &NetworkNumOfLinks = ActualNumOfLinks;
207 :
208 656873 : NetworkNumOfNodes = NumOfNodesMultiZone;
209 656873 : NetworkNumOfLinks = NumOfLinksMultiZone;
210 :
211 656873 : AirflowNetworkFanActivated = false;
212 :
213 656873 : if (present(FirstHVACIteration) && distribution_simulated) {
214 555029 : if (FirstHVACIteration) {
215 106576 : if (allocated(m_state.dataAirLoop->AirLoopAFNInfo)) {
216 216741 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
217 110184 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopHeatingCoilMaxRTF = 0.0;
218 110184 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopOnOffFanRTF = 0.0;
219 110184 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopDXCoilRTF = 0.0;
220 110184 : m_state.dataAirLoop->AirLoopAFNInfo(i).LoopOnOffFanPartLoadRatio = 0.0;
221 : }
222 : }
223 : }
224 555029 : Real64 FanMassFlowRate = 0.0;
225 555029 : int FanOperModeCyc = 0;
226 555029 : AFNSupplyFanType = 0;
227 :
228 788204 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
229 571719 : AFNSupplyFanType = DisSysCompCVFData(i).FanTypeNum;
230 571719 : FanMassFlowRate = max(FanMassFlowRate, m_state.dataLoopNodes->Node(DisSysCompCVFData(i).OutletNode).MassFlowRate);
231 : // VAV take high priority
232 571719 : if (DisSysCompCVFData(i).FanTypeNum == FanType_SimpleVAV) {
233 20520 : AFNSupplyFanType = DisSysCompCVFData(i).FanTypeNum;
234 20520 : break;
235 : }
236 870128 : if (FanMassFlowRate > VerySmallMassFlow && m_state.dataAirLoop->AirLoopAFNInfo(i).LoopFanOperationMode == CycFanCycCoil &&
237 318929 : m_state.dataAirLoop->AirLoopAFNInfo(i).LoopSystemOnMassFlowrate > 0.0) {
238 318024 : FanOperModeCyc = CycFanCycCoil;
239 318024 : AFNSupplyFanType = DisSysCompCVFData(i).FanTypeNum;
240 318024 : if (AFNSupplyFanType == FanType_SimpleOnOff) {
241 318024 : break;
242 : }
243 : }
244 : }
245 : // Revised to meet heat exchanger requirement
246 555029 : if ((FanMassFlowRate > VerySmallMassFlow) && (!FirstHVACIteration)) {
247 385398 : if (AFNSupplyFanType == FanType_SimpleOnOff && FanOperModeCyc == CycFanCycCoil) {
248 280369 : AirflowNetworkFanActivated = true;
249 105029 : } else if (AFNSupplyFanType == FanType_SimpleVAV) {
250 6761 : if (present(Iter) && Iter > 1) AirflowNetworkFanActivated = true;
251 98268 : } else if (AirflowNetworkUnitarySystem) {
252 0 : if (present(Iter) && Iter > 1) AirflowNetworkFanActivated = true;
253 : } else {
254 98268 : AirflowNetworkFanActivated = true;
255 : }
256 : }
257 : }
258 746250 : if (allocated(m_state.dataZoneEquip->ZoneEquipConfig) && m_state.dataHVACGlobal->NumHybridVentSysAvailMgrs > 0 &&
259 89377 : allocated(m_state.dataAirSystemsData->PrimaryAirSystems)) {
260 82448 : hybrid_ventilation_control();
261 : }
262 656873 : if (VentilationCtrl == 1 && m_state.dataHVACGlobal->NumHybridVentSysAvailMgrs > 0) {
263 12104 : AirflowNetworkFanActivated = false;
264 : }
265 :
266 656873 : if (present(Iter) && present(ResimulateAirZone) && distribution_simulated) {
267 327070 : if (AirflowNetworkFanActivated && Iter < 3 && AFNSupplyFanType == FanType_SimpleOnOff) {
268 160934 : ResimulateAirZone = true;
269 : }
270 327070 : if (AFNSupplyFanType == FanType_SimpleVAV) {
271 9344 : if (!AirflowNetworkFanActivated && Iter < 3) ResimulateAirZone = true;
272 : }
273 327070 : if (AirflowNetworkUnitarySystem) {
274 0 : if (!AirflowNetworkFanActivated && Iter < 3) ResimulateAirZone = true;
275 : }
276 : }
277 656873 : if (AirflowNetworkFanActivated && distribution_simulated) {
278 380734 : NetworkNumOfNodes = AirflowNetworkNumOfNodes;
279 380734 : NetworkNumOfLinks = AirflowNetworkNumOfLinks;
280 : }
281 :
282 656873 : if (allocated(m_state.dataZoneEquip->ZoneEquipConfig)) validate_exhaust_fan_input();
283 :
284 : // VAV terminal set only
285 656873 : if (present(FirstHVACIteration) && FirstHVACIteration) VAVTerminalRatio = 0.0;
286 :
287 : // Set AirLoop Number for fans
288 656873 : if (FirstHVACIteration && AssignFanAirLoopNumFlag) {
289 34 : assign_fan_airloop();
290 34 : AssignFanAirLoopNumFlag = false;
291 : }
292 :
293 656873 : if (AirflowNetworkFanActivated && distribution_simulated) {
294 380734 : if (ValidateDistributionSystemFlag) {
295 23 : validate_distribution();
296 23 : validate_fan_flowrate();
297 23 : ValidateDistributionSystemFlag = false;
298 23 : if (simulation_control.autosize_ducts) {
299 1 : SizeDucts();
300 : }
301 : }
302 : }
303 656873 : calculate_balance();
304 :
305 656873 : if (AirflowNetworkFanActivated && distribution_simulated) {
306 :
307 380734 : LoopOnOffFlag = false;
308 772135 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
309 391401 : if (DisSysCompCVFData(i).AirLoopNum > 0) {
310 391401 : if (m_state.dataLoopNodes->Node(DisSysCompCVFData(i).InletNode).MassFlowRate > 0.0) {
311 390677 : LoopOnOffFlag(DisSysCompCVFData(i).AirLoopNum) = true;
312 : }
313 : }
314 : }
315 :
316 380734 : calculate_heat_balance();
317 380734 : calculate_moisture_balance();
318 380734 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) calculate_CO2_balance();
319 380734 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) calculate_GC_balance();
320 : }
321 :
322 656873 : update(FirstHVACIteration);
323 : }
324 :
325 34 : bool Solver::get_element_input()
326 : {
327 : // SUBROUTINE INFORMATION:
328 : // AUTHOR Jason DeGraw
329 : // DATE WRITTEN Oct. 2018
330 : // MODIFIED na
331 : // RE-ENGINEERED na
332 :
333 : // PURPOSE OF THIS SUBROUTINE:
334 : // This subroutine reads airflow element inputs (eventually)
335 :
336 : static constexpr std::string_view RoutineName{"get_element_input"};
337 68 : std::string CurrentModuleObject;
338 34 : bool success{true};
339 :
340 : // *** Read AirflowNetwork simulation reference crack conditions
341 68 : std::unordered_map<std::string, ReferenceConditions> referenceConditions; // Map for lookups
342 68 : ReferenceConditions defaultReferenceConditions("Default"); // Defaulted conditions
343 34 : bool conditionsAreDefaulted(true); // Conditions are defaulted?
344 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:ReferenceCrackConditions";
345 68 : auto instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
346 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
347 : // globalSolverObject.referenceConditions.clear();
348 32 : auto &instancesValue = instances.value();
349 64 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
350 32 : auto const &fields = instance.value();
351 64 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
352 32 : Real64 temperature(20.0);
353 32 : if (fields.find("reference_temperature") != fields.end()) { // required field, has default value
354 32 : temperature = fields.at("reference_temperature").get<Real64>();
355 : }
356 32 : Real64 pressure(101325.0);
357 32 : if (fields.find("reference_barometric_pressure") != fields.end()) { // not required field, has default value
358 32 : pressure = fields.at("reference_barometric_pressure").get<Real64>();
359 32 : if (std::abs((pressure - m_state.dataEnvrn->StdBaroPress) / m_state.dataEnvrn->StdBaroPress) > 0.1) { // 10% off
360 3 : ShowWarningError(m_state,
361 3 : format("{}: {}: Pressure = {:.0R} differs by more than 10% from Standard Barometric Pressure = {:.0R}.",
362 : RoutineName,
363 : CurrentModuleObject,
364 : pressure,
365 2 : m_state.dataEnvrn->StdBaroPress));
366 1 : ShowContinueError(m_state, "...occurs in " + CurrentModuleObject + " = " + thisObjectName);
367 : }
368 32 : if (pressure <= 31000.0) {
369 0 : ShowSevereError(m_state,
370 0 : format("{}: {}: {}. Reference Barometric Pressure must be greater than 31000 Pa.",
371 : RoutineName,
372 : CurrentModuleObject,
373 0 : thisObjectName));
374 0 : success = false;
375 : }
376 : }
377 32 : Real64 humidity(0.0);
378 32 : if (fields.find("reference_humidity_ratio") != fields.end()) { // not required field, has default value
379 32 : humidity = fields.at("reference_humidity_ratio").get<Real64>();
380 : }
381 : // globalSolverObject.referenceConditions.emplace_back(thisObjectName, temperature, pressure, humidity);
382 32 : referenceConditions.emplace(std::piecewise_construct,
383 64 : std::forward_as_tuple(thisObjectName),
384 64 : std::forward_as_tuple(instance.key(), temperature, pressure, humidity));
385 : }
386 : // Check that there is more than one
387 32 : if (referenceConditions.size() == 1) {
388 64 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
389 64 : referenceConditions.begin()->second.name);
390 32 : defaultReferenceConditions = referenceConditions.begin()->second;
391 :
392 : } else {
393 0 : conditionsAreDefaulted = false;
394 : }
395 : }
396 34 : if (!success) {
397 0 : return false;
398 : }
399 :
400 : // *** Read AirflowNetwork simulation surface crack component
401 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface:Crack";
402 34 : AirflowNetworkNumOfSurCracks =
403 34 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
404 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
405 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
406 32 : int i = 1; // Temporary workaround
407 32 : MultizoneSurfaceCrackData.allocate(AirflowNetworkNumOfSurCracks); // Temporary workaround
408 32 : auto &instancesValue = instances.value();
409 115 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
410 83 : auto const &fields = instance.value();
411 166 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
412 83 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
413 :
414 83 : Real64 coeff{fields.at("air_mass_flow_coefficient_at_reference_conditions")}; // Required field
415 83 : Real64 expnt{0.65};
416 83 : if (fields.find("air_mass_flow_exponent") != fields.end()) { // not required field, has default value
417 83 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
418 : }
419 83 : Real64 refT = defaultReferenceConditions.temperature;
420 83 : Real64 refP = defaultReferenceConditions.pressure;
421 83 : Real64 refW = defaultReferenceConditions.humidity_ratio;
422 83 : if (!conditionsAreDefaulted) {
423 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
424 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
425 0 : auto result = referenceConditions.find(UtilityRoutines::MakeUPPERCase(refCrackCondName));
426 0 : if (result == referenceConditions.end()) {
427 0 : ShowSevereError(m_state,
428 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
429 : RoutineName,
430 : CurrentModuleObject,
431 : thisObjectName,
432 0 : refCrackCondName));
433 0 : success = false;
434 : } else {
435 0 : refT = result->second.temperature;
436 0 : refP = result->second.pressure;
437 0 : refW = result->second.humidity_ratio;
438 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
439 0 : result->second.name);
440 : }
441 : }
442 : }
443 : // globalSolverObject.cracks[thisObjectName] = SurfaceCrack(coeff, expnt, refT, refP, refW);
444 83 : MultizoneSurfaceCrackData(i).name = thisObjectName; // Name of surface crack component
445 83 : MultizoneSurfaceCrackData(i).coefficient = coeff; // Air Mass Flow Coefficient
446 83 : MultizoneSurfaceCrackData(i).exponent = expnt; // Air Mass Flow exponent
447 83 : MultizoneSurfaceCrackData(i).reference_density = properties.density(refP, refT, refW);
448 83 : MultizoneSurfaceCrackData(i).reference_viscosity = properties.dynamic_viscosity(refT);
449 :
450 : // This is the first element that is being added to the lookup table, so no check of naming overlaps
451 83 : elements[thisObjectName] = &MultizoneSurfaceCrackData(i); // Yet another workaround
452 :
453 83 : ++i;
454 : }
455 : }
456 :
457 : // *** Read AirflowNetwork simulation zone exhaust fan component
458 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:ZoneExhaustFan";
459 34 : AirflowNetworkNumOfExhFan =
460 34 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
461 34 : NumOfExhaustFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "Fan:ZoneExhaust"); // Temporary workaround
462 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
463 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
464 14 : int i = 1; // Temporary workaround
465 14 : MultizoneCompExhaustFanData.allocate(AirflowNetworkNumOfExhFan); // Temporary workaround
466 14 : auto &instancesValue = instances.value();
467 28 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
468 14 : auto const &fields = instance.value();
469 28 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
470 14 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
471 :
472 14 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_the_zone_exhaust_fan_is_off_at_reference_conditions")}; // Required field
473 14 : Real64 expnt{0.65};
474 14 : if (fields.find("air_mass_flow_exponent_when_the_zone_exhaust_fan_is_off") != fields.end()) { // not required field, has default value
475 14 : expnt = fields.at("air_mass_flow_exponent_when_the_zone_exhaust_fan_is_off").get<Real64>();
476 : }
477 :
478 : // This breaks the component model, need to fix
479 14 : bool fanErrorFound = false;
480 : int fanIndex;
481 14 : GetFanIndex(m_state, thisObjectName, fanIndex, fanErrorFound);
482 14 : if (fanErrorFound) {
483 0 : ShowSevereError(m_state,
484 0 : format("{}: {} = {} is not found in Fan:ZoneExhaust objects.", RoutineName, CurrentModuleObject, thisObjectName));
485 0 : success = false;
486 : }
487 : Real64 flowRate;
488 :
489 14 : GetFanVolFlow(m_state, fanIndex, flowRate);
490 14 : flowRate *= m_state.dataEnvrn->StdRhoAir;
491 14 : bool nodeErrorsFound{false};
492 14 : int inletNode = GetFanInletNode(m_state, "Fan:ZoneExhaust", thisObjectName, nodeErrorsFound);
493 14 : int outletNode = GetFanOutletNode(m_state, "Fan:ZoneExhaust", thisObjectName, nodeErrorsFound);
494 14 : if (nodeErrorsFound) {
495 0 : success = false;
496 : }
497 : int fanType_Num;
498 14 : GetFanType(m_state, thisObjectName, fanType_Num, fanErrorFound);
499 14 : if (fanType_Num != FanType_ZoneExhaust) {
500 0 : ShowSevereError(m_state,
501 0 : format("{}: {} = {}. The specified Name is not found as a valid Fan:ZoneExhaust object.",
502 : RoutineName,
503 : CurrentModuleObject,
504 0 : thisObjectName));
505 0 : success = false;
506 : }
507 :
508 14 : Real64 refT = defaultReferenceConditions.temperature;
509 14 : Real64 refP = defaultReferenceConditions.pressure;
510 14 : Real64 refW = defaultReferenceConditions.humidity_ratio;
511 14 : if (!conditionsAreDefaulted) {
512 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
513 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
514 0 : auto result = referenceConditions.find(UtilityRoutines::MakeUPPERCase(refCrackCondName));
515 0 : if (result == referenceConditions.end()) {
516 0 : ShowSevereError(m_state,
517 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
518 : RoutineName,
519 : CurrentModuleObject,
520 : thisObjectName,
521 0 : fields.at("reference_crack_conditions").get<std::string>()));
522 0 : success = false;
523 : } else {
524 0 : refT = result->second.temperature;
525 0 : refP = result->second.pressure;
526 0 : refW = result->second.humidity_ratio;
527 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
528 0 : result->second.name);
529 : }
530 : }
531 : }
532 :
533 14 : MultizoneCompExhaustFanData(i).name = thisObjectName; // Name of zone exhaust fan component
534 14 : MultizoneCompExhaustFanData(i).FlowCoef = coeff; // flow coefficient
535 14 : MultizoneCompExhaustFanData(i).FlowExpo = expnt; // Flow exponent
536 :
537 14 : MultizoneCompExhaustFanData(i).FlowRate = flowRate;
538 14 : MultizoneCompExhaustFanData(i).InletNode = inletNode;
539 14 : MultizoneCompExhaustFanData(i).OutletNode = outletNode;
540 :
541 14 : MultizoneCompExhaustFanData(i).StandardT = refT;
542 14 : MultizoneCompExhaustFanData(i).StandardP = refP;
543 14 : MultizoneCompExhaustFanData(i).StandardW = refW;
544 :
545 : // Add the element to the lookup table, check for name overlaps
546 14 : if (elements.find(thisObjectName) == elements.end()) {
547 14 : elements[thisObjectName] = &MultizoneCompExhaustFanData(i); // Yet another workaround
548 : } else {
549 0 : ShowSevereError(
550 : m_state,
551 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
552 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
553 0 : success = false;
554 : }
555 :
556 14 : ++i;
557 : }
558 : }
559 :
560 : // Read Outdoor Airflow object
561 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:OutdoorAirFlow";
562 34 : NumOfOAFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
563 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
564 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
565 2 : int i = 1; // Temporary workaround
566 2 : DisSysCompOutdoorAirData.allocate(NumOfOAFans); // Temporary workaround
567 2 : auto &instancesValue = instances.value();
568 4 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
569 2 : auto const &fields = instance.value();
570 4 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
571 2 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
572 :
573 4 : std::string mixer_name = UtilityRoutines::MakeUPPERCase(fields.at("outdoor_air_mixer_name").get<std::string>());
574 2 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_no_outdoor_air_flow_at_reference_conditions")};
575 2 : Real64 expnt{0.65};
576 2 : if (fields.find("air_mass_flow_exponent_when_no_outdoor_air_flow") != fields.end()) {
577 2 : expnt = fields.at("air_mass_flow_exponent_when_no_outdoor_air_flow").get<Real64>();
578 : }
579 :
580 2 : int OAMixerNum = MixedAir::GetOAMixerNumber(m_state, mixer_name);
581 2 : if (OAMixerNum == 0) {
582 0 : ShowSevereError(m_state,
583 0 : format("{}: {}: {}. Invalid Outdoor Air Mixer Name \"{}\" given.",
584 : RoutineName,
585 : CurrentModuleObject,
586 : thisObjectName,
587 0 : mixer_name));
588 0 : success = false;
589 : }
590 :
591 2 : Real64 refT = defaultReferenceConditions.temperature;
592 2 : Real64 refP = defaultReferenceConditions.pressure;
593 2 : Real64 refW = defaultReferenceConditions.humidity_ratio;
594 2 : if (!conditionsAreDefaulted) {
595 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
596 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
597 0 : auto result = referenceConditions.find(UtilityRoutines::MakeUPPERCase(refCrackCondName));
598 0 : if (result == referenceConditions.end()) {
599 0 : ShowSevereError(m_state,
600 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
601 : RoutineName,
602 : CurrentModuleObject,
603 : thisObjectName,
604 0 : refCrackCondName));
605 0 : success = false;
606 : } else {
607 0 : refT = result->second.temperature;
608 0 : refP = result->second.pressure;
609 0 : refW = result->second.humidity_ratio;
610 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
611 0 : result->second.name);
612 : }
613 : }
614 : }
615 :
616 2 : DisSysCompOutdoorAirData(i).name = thisObjectName; // Name of zone exhaust fan component
617 2 : DisSysCompOutdoorAirData(i).FlowCoef = coeff; // flow coefficient
618 2 : DisSysCompOutdoorAirData(i).FlowExpo = expnt; // Flow exponent
619 :
620 2 : DisSysCompOutdoorAirData(i).OAMixerNum = OAMixerNum;
621 :
622 2 : DisSysCompOutdoorAirData(i).StandardT = refT;
623 2 : DisSysCompOutdoorAirData(i).StandardP = refP;
624 2 : DisSysCompOutdoorAirData(i).StandardW = refW;
625 :
626 : // Add the element to the lookup table, check for name overlaps
627 2 : if (elements.find(thisObjectName) == elements.end()) {
628 2 : elements[thisObjectName] = &DisSysCompOutdoorAirData(i); // Yet another workaround
629 : } else {
630 0 : ShowSevereError(
631 : m_state,
632 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
633 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
634 0 : success = false;
635 : }
636 :
637 2 : ++i;
638 : }
639 : }
640 :
641 : // Read Relief Airflow object
642 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ReliefAirFlow";
643 34 : NumOfReliefFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
644 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
645 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
646 2 : int i = 1; // Temporary workaround
647 2 : DisSysCompReliefAirData.allocate(m_state.afn->NumOfReliefFans); // Temporary workaround
648 2 : auto &instancesValue = instances.value();
649 4 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
650 2 : auto const &fields = instance.value();
651 4 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
652 2 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
653 :
654 4 : std::string mixer_name = UtilityRoutines::MakeUPPERCase(fields.at("outdoor_air_mixer_name").get<std::string>());
655 2 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_no_outdoor_air_flow_at_reference_conditions")};
656 2 : Real64 expnt{0.65};
657 2 : if (fields.find("air_mass_flow_exponent_when_no_outdoor_air_flow") != fields.end()) {
658 2 : expnt = fields.at("air_mass_flow_exponent_when_no_outdoor_air_flow").get<Real64>();
659 : }
660 :
661 2 : int OAMixerNum{MixedAir::GetOAMixerNumber(m_state, mixer_name)};
662 2 : if (OAMixerNum == 0) {
663 0 : ShowSevereError(m_state,
664 0 : format(RoutineName) + ": " + CurrentModuleObject + " object " + thisObjectName + ". Invalid " +
665 0 : "Outdoor Air Mixer Name" + " \"" + mixer_name + "\" given.");
666 0 : success = false;
667 : }
668 :
669 2 : Real64 refT = defaultReferenceConditions.temperature;
670 2 : Real64 refP = defaultReferenceConditions.pressure;
671 2 : Real64 refW = defaultReferenceConditions.humidity_ratio;
672 2 : if (!conditionsAreDefaulted) {
673 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
674 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
675 0 : auto result = referenceConditions.find(UtilityRoutines::MakeUPPERCase(refCrackCondName));
676 0 : if (result == referenceConditions.end()) {
677 0 : ShowSevereError(m_state,
678 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
679 : RoutineName,
680 : CurrentModuleObject,
681 : thisObjectName,
682 0 : refCrackCondName));
683 0 : success = false;
684 : } else {
685 0 : refT = result->second.temperature;
686 0 : refP = result->second.pressure;
687 0 : refW = result->second.humidity_ratio;
688 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
689 0 : result->second.name);
690 : }
691 : }
692 : }
693 :
694 2 : DisSysCompReliefAirData(i).name = thisObjectName; // Name of zone exhaust fan component
695 2 : DisSysCompReliefAirData(i).FlowCoef = coeff; // flow coefficient
696 2 : DisSysCompReliefAirData(i).FlowExpo = expnt; // Flow exponent
697 2 : DisSysCompReliefAirData(i).OAMixerNum = OAMixerNum;
698 2 : DisSysCompReliefAirData(i).StandardT = refT;
699 2 : DisSysCompReliefAirData(i).StandardP = refP;
700 2 : DisSysCompReliefAirData(i).StandardW = refW;
701 :
702 : // Add the element to the lookup table, check for name overlaps
703 2 : if (elements.find(thisObjectName) == elements.end()) {
704 2 : elements[thisObjectName] = &DisSysCompReliefAirData(i); // Yet another workaround
705 : } else {
706 0 : ShowSevereError(
707 : m_state,
708 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
709 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
710 0 : success = false;
711 : }
712 :
713 2 : ++i;
714 : }
715 : }
716 :
717 : // Read AirflowNetwork simulation detailed openings
718 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:DetailedOpening";
719 34 : AirflowNetworkNumOfDetOpenings =
720 34 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
721 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
722 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
723 34 : int i = 1; // Temporary workaround
724 34 : MultizoneCompDetOpeningData.allocate(AirflowNetworkNumOfDetOpenings); // Temporary workaround
725 34 : auto &instancesValue = instances.value();
726 65 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
727 31 : auto const &fields = instance.value();
728 62 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
729 31 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
730 :
731 31 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
732 31 : Real64 expnt{0.65};
733 31 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
734 31 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
735 : }
736 :
737 31 : int LVOtype{1};
738 62 : std::string LVOstring;
739 31 : if (fields.find("type_of_rectangular_large_vertical_opening_lvo_") != fields.end()) {
740 31 : LVOstring = fields.at("type_of_rectangular_large_vertical_opening_lvo_").get<std::string>();
741 31 : if (UtilityRoutines::SameString(LVOstring, "NonPivoted") || UtilityRoutines::SameString(LVOstring, "1")) {
742 31 : LVOtype = 1; // Large vertical opening type number
743 0 : } else if (UtilityRoutines::SameString(LVOstring, "HorizontallyPivoted") || UtilityRoutines::SameString(LVOstring, "2")) {
744 0 : LVOtype = 2; // Large vertical opening type number
745 : } else {
746 : // Code will never be executed, validation will catch invalid input
747 0 : ShowSevereError(m_state,
748 0 : format(RoutineName) + "Invalid Type of Rectangular Large Vertical Opening (LVO) = " + LVOstring + "in " +
749 0 : CurrentModuleObject + " = " + thisObjectName);
750 0 : ShowContinueError(m_state, "Valid choices are NonPivoted and HorizontallyPivoted.");
751 0 : success = false;
752 : }
753 : }
754 :
755 31 : Real64 extra{0.0};
756 31 : if (fields.find("extra_crack_length_or_height_of_pivoting_axis") != fields.end()) {
757 31 : extra = fields.at("extra_crack_length_or_height_of_pivoting_axis").get<Real64>();
758 : }
759 :
760 31 : int N{fields.at("number_of_sets_of_opening_factor_data")};
761 :
762 62 : std::vector<Real64> factors(N);
763 62 : std::vector<Real64> cds(N);
764 62 : std::vector<Real64> width_factors(N);
765 62 : std::vector<Real64> height_factors(N);
766 62 : std::vector<Real64> start_height_factors(N);
767 :
768 : // Real64 factor{0.0};
769 : // if (fields.find("opening_factor_1") != fields.end()) {
770 : // factor = fields.at("opening_factor_1");
771 : //}
772 31 : Real64 cd{0.001};
773 31 : if (fields.find("discharge_coefficient_for_opening_factor_1") != fields.end()) {
774 31 : cd = fields.at("discharge_coefficient_for_opening_factor_1").get<Real64>();
775 : }
776 31 : Real64 width_factor{0.0};
777 31 : if (fields.find("width_factor_for_opening_factor_1") != fields.end()) {
778 31 : width_factor = fields.at("width_factor_for_opening_factor_1").get<Real64>();
779 : }
780 31 : Real64 height_factor{0.0};
781 31 : if (fields.find("height_factor_for_opening_factor_1") != fields.end()) {
782 31 : height_factor = fields.at("height_factor_for_opening_factor_1").get<Real64>();
783 : }
784 31 : Real64 start_height_factor{0.0};
785 31 : if (fields.find("start_height_factor_for_opening_factor_1") != fields.end()) {
786 31 : start_height_factor = fields.at("start_height_factor_for_opening_factor_1").get<Real64>();
787 : }
788 :
789 31 : factors[0] = 0.0; // factor; // This factor must be zero
790 31 : cds[0] = cd;
791 31 : width_factors[0] = width_factor;
792 31 : height_factors[0] = height_factor;
793 31 : start_height_factors[0] = start_height_factor;
794 :
795 31 : Real64 factor{fields.at("opening_factor_2")};
796 31 : cd = 1.0;
797 31 : if (fields.find("discharge_coefficient_for_opening_factor_2") != fields.end()) {
798 31 : cd = fields.at("discharge_coefficient_for_opening_factor_2").get<Real64>();
799 : }
800 31 : width_factor = 1.0;
801 31 : if (fields.find("width_factor_for_opening_factor_2") != fields.end()) {
802 31 : width_factor = fields.at("width_factor_for_opening_factor_2").get<Real64>();
803 : }
804 31 : height_factor = 1.0;
805 31 : if (fields.find("height_factor_for_opening_factor_2") != fields.end()) {
806 31 : height_factor = fields.at("height_factor_for_opening_factor_2").get<Real64>();
807 : }
808 31 : start_height_factor = 0.0;
809 31 : if (fields.find("start_height_factor_for_opening_factor_2") != fields.end()) {
810 31 : start_height_factor = fields.at("start_height_factor_for_opening_factor_2").get<Real64>();
811 : }
812 :
813 31 : factors[1] = factor;
814 31 : cds[1] = cd;
815 31 : width_factors[1] = width_factor;
816 31 : height_factors[1] = height_factor;
817 31 : start_height_factors[1] = start_height_factor;
818 :
819 31 : if (N >= 3) {
820 0 : factor = fields.at("opening_factor_3").get<Real64>();
821 0 : cd = 0.0;
822 0 : if (fields.find("discharge_coefficient_for_opening_factor_3") != fields.end()) {
823 0 : cd = fields.at("discharge_coefficient_for_opening_factor_3").get<Real64>();
824 : }
825 0 : width_factor = 0.0;
826 0 : if (fields.find("width_factor_for_opening_factor_3") != fields.end()) {
827 0 : width_factor = fields.at("width_factor_for_opening_factor_3").get<Real64>();
828 : }
829 0 : height_factor = 0.0;
830 0 : if (fields.find("height_factor_for_opening_factor_3") != fields.end()) {
831 0 : height_factor = fields.at("height_factor_for_opening_factor_3").get<Real64>();
832 : }
833 0 : start_height_factor = 0.0;
834 0 : if (fields.find("start_height_factor_for_opening_factor_3") != fields.end()) {
835 0 : start_height_factor = fields.at("start_height_factor_for_opening_factor_3").get<Real64>();
836 : }
837 :
838 0 : factors[2] = factor;
839 0 : cds[2] = cd;
840 0 : width_factors[2] = width_factor;
841 0 : height_factors[2] = height_factor;
842 0 : start_height_factors[2] = start_height_factor;
843 :
844 0 : if (N >= 4) {
845 0 : factor = fields.at("opening_factor_4").get<Real64>();
846 0 : cd = 0.0;
847 0 : if (fields.find("discharge_coefficient_for_opening_factor_4") != fields.end()) {
848 0 : cd = fields.at("discharge_coefficient_for_opening_factor_4").get<Real64>();
849 : }
850 0 : width_factor = 0.0;
851 0 : if (fields.find("width_factor_for_opening_factor_4") != fields.end()) {
852 0 : width_factor = fields.at("width_factor_for_opening_factor_4").get<Real64>();
853 : }
854 0 : height_factor = 0.0;
855 0 : if (fields.find("height_factor_for_opening_factor_4") != fields.end()) {
856 0 : height_factor = fields.at("height_factor_for_opening_factor_4").get<Real64>();
857 : }
858 0 : start_height_factor = 0.0;
859 0 : if (fields.find("start_height_factor_for_opening_factor_4") != fields.end()) {
860 0 : start_height_factor = fields.at("start_height_factor_for_opening_factor_4").get<Real64>();
861 : }
862 :
863 0 : factors[3] = factor;
864 0 : cds[3] = cd;
865 0 : width_factors[3] = width_factor;
866 0 : height_factors[3] = height_factor;
867 0 : start_height_factors[3] = start_height_factor;
868 : }
869 : }
870 :
871 31 : MultizoneCompDetOpeningData(i).name = thisObjectName; // Name of large detailed opening component
872 31 : MultizoneCompDetOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
873 31 : MultizoneCompDetOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
874 31 : MultizoneCompDetOpeningData(i).TypeName = LVOstring; // Large vertical opening type
875 31 : MultizoneCompDetOpeningData(i).LVOType = LVOtype; // Large vertical opening type number
876 31 : MultizoneCompDetOpeningData(i).LVOValue = extra; // Extra crack length for LVO type 1 with multiple openable
877 : // parts, or Height of pivoting axis for LVO type 2
878 :
879 31 : MultizoneCompDetOpeningData(i).NumFac = N; // Number of Opening Factor Values
880 :
881 31 : MultizoneCompDetOpeningData(i).OpenFac1 = factors[0]; // Opening factor #1
882 31 : MultizoneCompDetOpeningData(i).DischCoeff1 = cds[0]; // Discharge coefficient for opening factor #1
883 31 : MultizoneCompDetOpeningData(i).WidthFac1 = width_factors[0]; // Width factor for for Opening factor #1
884 31 : MultizoneCompDetOpeningData(i).HeightFac1 = height_factors[0]; // Height factor for opening factor #1
885 31 : MultizoneCompDetOpeningData(i).StartHFac1 = start_height_factors[0]; // Start height factor for opening factor #1
886 31 : MultizoneCompDetOpeningData(i).OpenFac2 = factors[1]; // Opening factor #2
887 31 : MultizoneCompDetOpeningData(i).DischCoeff2 = cds[1]; // Discharge coefficient for opening factor #2
888 31 : MultizoneCompDetOpeningData(i).WidthFac2 = width_factors[1]; // Width factor for for Opening factor #2
889 31 : MultizoneCompDetOpeningData(i).HeightFac2 = height_factors[1]; // Height factor for opening factor #2
890 31 : MultizoneCompDetOpeningData(i).StartHFac2 = start_height_factors[1]; // Start height factor for opening factor #2
891 :
892 31 : MultizoneCompDetOpeningData(i).OpenFac3 = 0.0; // Opening factor #3
893 31 : MultizoneCompDetOpeningData(i).DischCoeff3 = 0.0; // Discharge coefficient for opening factor #3
894 31 : MultizoneCompDetOpeningData(i).WidthFac3 = 0.0; // Width factor for for Opening factor #3
895 31 : MultizoneCompDetOpeningData(i).HeightFac3 = 0.0; // Height factor for opening factor #3
896 31 : MultizoneCompDetOpeningData(i).StartHFac3 = 0.0; // Start height factor for opening factor #3
897 31 : MultizoneCompDetOpeningData(i).OpenFac4 = 0.0; // Opening factor #4
898 31 : MultizoneCompDetOpeningData(i).DischCoeff4 = 0.0; // Discharge coefficient for opening factor #4
899 31 : MultizoneCompDetOpeningData(i).WidthFac4 = 0.0; // Width factor for for Opening factor #4
900 31 : MultizoneCompDetOpeningData(i).HeightFac4 = 0.0; // Height factor for opening factor #4
901 31 : MultizoneCompDetOpeningData(i).StartHFac4 = 0.0; // Start height factor for opening factor #4
902 31 : if (N == 2) {
903 31 : if (factors[1] != 1.0) {
904 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
905 0 : ShowContinueError(
906 : m_state,
907 : "..This object specifies that only 3 opening factors will be used. So, the value of Opening Factor #2 is set to 1.0.");
908 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac2));
909 0 : MultizoneCompDetOpeningData(i).OpenFac2 = 1.0;
910 : }
911 0 : } else if (N >= 3) {
912 0 : MultizoneCompDetOpeningData(i).OpenFac3 = factors[2]; // Opening factor #3
913 0 : MultizoneCompDetOpeningData(i).DischCoeff3 = cds[2]; // Discharge coefficient for opening factor #3
914 0 : MultizoneCompDetOpeningData(i).WidthFac3 = width_factors[2]; // Width factor for for Opening factor #3
915 0 : MultizoneCompDetOpeningData(i).HeightFac3 = height_factors[2]; // Height factor for opening factor #3
916 0 : MultizoneCompDetOpeningData(i).StartHFac3 = start_height_factors[2]; // Start height factor for opening factor #3
917 0 : if (N >= 4) {
918 0 : MultizoneCompDetOpeningData(i).OpenFac4 = factors[3]; // Opening factor #4
919 0 : if (factors[3] != 1.0) {
920 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
921 0 : ShowContinueError(m_state,
922 : "..This object specifies that 4 opening factors will be used. So, the value of Opening Factor #4 "
923 : "is set to 1.0.");
924 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac4));
925 0 : MultizoneCompDetOpeningData(i).OpenFac4 = 1.0;
926 : }
927 0 : MultizoneCompDetOpeningData(i).DischCoeff4 = cds[3]; // Discharge coefficient for opening factor #4
928 0 : MultizoneCompDetOpeningData(i).WidthFac4 = width_factors[3]; // Width factor for for Opening factor #4
929 0 : MultizoneCompDetOpeningData(i).HeightFac4 = height_factors[3]; // Height factor for opening factor #4
930 0 : MultizoneCompDetOpeningData(i).StartHFac4 = start_height_factors[3]; // Start height factor for opening factor #4
931 : } else {
932 0 : if (factors[2] != 1.0) {
933 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
934 0 : ShowContinueError(m_state,
935 : "..This object specifies that only 3 opening factors will be used. So, the value of Opening Factor #3 "
936 : "is set to 1.0.");
937 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac3));
938 0 : MultizoneCompDetOpeningData(i).OpenFac3 = 1.0;
939 : }
940 : }
941 : }
942 :
943 : // Sanity checks, check sum of Height Factor and the Start Height Factor
944 31 : if (MultizoneCompDetOpeningData(i).HeightFac1 + MultizoneCompDetOpeningData(i).StartHFac1 > 1.0) {
945 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
946 0 : ShowContinueError(
947 : m_state, "..The sum of Height Factor for Opening Factor 1 and Start Height Factor for Opening Factor 1 is greater than 1.0");
948 0 : success = false;
949 : }
950 31 : if (MultizoneCompDetOpeningData(i).HeightFac2 + MultizoneCompDetOpeningData(i).StartHFac2 > 1.0) {
951 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
952 0 : ShowContinueError(
953 : m_state, "..The sum of Height Factor for Opening Factor 2 and Start Height Factor for Opening Factor 2 is greater than 1.0");
954 0 : success = false;
955 : }
956 31 : if (MultizoneCompDetOpeningData(i).NumFac > 2) {
957 0 : if (MultizoneCompDetOpeningData(i).OpenFac2 >= MultizoneCompDetOpeningData(i).OpenFac3) {
958 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
959 0 : ShowContinueError(m_state, "..The value of Opening Factor #2 >= the value of Opening Factor #3");
960 0 : success = false;
961 : }
962 0 : if (MultizoneCompDetOpeningData(i).HeightFac3 + MultizoneCompDetOpeningData(i).StartHFac3 > 1.0) {
963 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
964 0 : ShowContinueError(
965 : m_state,
966 : "..The sum of Height Factor for Opening Factor 3 and Start Height Factor for Opening Factor 3 is greater than 1.0");
967 0 : success = false;
968 : }
969 0 : if (MultizoneCompDetOpeningData(i).NumFac == 4) {
970 0 : if (MultizoneCompDetOpeningData(i).OpenFac3 >= MultizoneCompDetOpeningData(i).OpenFac4) {
971 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
972 0 : ShowContinueError(m_state, "..The value of Opening Factor #3 >= the value of Opening Factor #4");
973 0 : success = false;
974 : }
975 0 : if (MultizoneCompDetOpeningData(i).HeightFac4 + MultizoneCompDetOpeningData(i).StartHFac4 > 1.0) {
976 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
977 0 : ShowContinueError(
978 : m_state,
979 : "..The sum of Height Factor for Opening Factor 4 and Start Height Factor for Opening Factor 4 is greater than 1.0");
980 0 : success = false;
981 : }
982 : }
983 : }
984 :
985 : // Add the element to the lookup table, check for name overlaps
986 31 : if (elements.find(thisObjectName) == elements.end()) {
987 31 : elements[thisObjectName] = &MultizoneCompDetOpeningData(i); // Yet another workaround
988 : } else {
989 0 : ShowSevereError(
990 : m_state,
991 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
992 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
993 0 : success = false;
994 : }
995 :
996 31 : ++i;
997 : }
998 : }
999 :
1000 : // Read AirflowNetwork simulation simple openings
1001 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:SimpleOpening";
1002 34 : AirflowNetworkNumOfSimOpenings =
1003 34 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1004 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1005 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1006 12 : int i = 1; // Temporary workaround
1007 12 : MultizoneCompSimpleOpeningData.allocate(AirflowNetworkNumOfSimOpenings); // Temporary workaround
1008 12 : auto &instancesValue = instances.value();
1009 24 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1010 12 : auto const &fields = instance.value();
1011 24 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1012 12 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1013 :
1014 12 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
1015 12 : Real64 expnt{0.65};
1016 12 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
1017 12 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
1018 : }
1019 12 : Real64 diff{fields.at("minimum_density_difference_for_two_way_flow")};
1020 12 : Real64 dischargeCoeff{fields.at("discharge_coefficient")};
1021 :
1022 12 : MultizoneCompSimpleOpeningData(i).name = thisObjectName; // Name of large simple opening component
1023 12 : MultizoneCompSimpleOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
1024 12 : MultizoneCompSimpleOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
1025 12 : MultizoneCompSimpleOpeningData(i).MinRhoDiff = diff; // Minimum density difference for two-way flow
1026 12 : MultizoneCompSimpleOpeningData(i).DischCoeff = dischargeCoeff; // Discharge coefficient at full opening
1027 :
1028 : // Add the element to the lookup table, check for name overlaps
1029 12 : if (elements.find(thisObjectName) == elements.end()) {
1030 12 : elements[thisObjectName] = &MultizoneCompSimpleOpeningData(i); // Yet another workaround
1031 : } else {
1032 0 : ShowSevereError(
1033 : m_state,
1034 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1035 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1036 0 : success = false;
1037 : }
1038 :
1039 12 : ++i;
1040 : }
1041 : }
1042 :
1043 : // Read AirflowNetwork simulation horizontal openings
1044 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:HorizontalOpening";
1045 34 : AirflowNetworkNumOfHorOpenings =
1046 34 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1047 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1048 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1049 2 : int i = 1; // Temporary workaround
1050 2 : MultizoneCompHorOpeningData.allocate(AirflowNetworkNumOfHorOpenings); // Temporary workaround
1051 2 : auto &instancesValue = instances.value();
1052 4 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1053 2 : auto const &fields = instance.value();
1054 4 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1055 2 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1056 :
1057 2 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
1058 2 : Real64 expnt{0.65};
1059 2 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
1060 2 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
1061 : }
1062 2 : Real64 angle{90.0};
1063 2 : if (fields.find("sloping_plane_angle") != fields.end()) {
1064 2 : angle = fields.at("sloping_plane_angle").get<Real64>();
1065 : }
1066 2 : Real64 dischargeCoeff{fields.at("discharge_coefficient")};
1067 :
1068 2 : MultizoneCompHorOpeningData(i).name = thisObjectName; // Name of large simple opening component
1069 2 : MultizoneCompHorOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
1070 2 : MultizoneCompHorOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
1071 2 : MultizoneCompHorOpeningData(i).Slope = angle; // Sloping plane angle
1072 2 : MultizoneCompHorOpeningData(i).DischCoeff = dischargeCoeff; // Discharge coefficient at full opening
1073 :
1074 : // Add the element to the lookup table, check for name overlaps
1075 2 : if (elements.find(thisObjectName) == elements.end()) {
1076 2 : elements[thisObjectName] = &MultizoneCompHorOpeningData(i); // Yet another workaround
1077 : } else {
1078 0 : ShowSevereError(
1079 : m_state,
1080 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1081 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1082 0 : success = false;
1083 : }
1084 :
1085 2 : ++i;
1086 : }
1087 : }
1088 :
1089 : // *** Read AirflowNetwork simulation surface effective leakage area component
1090 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea";
1091 34 : AirflowNetworkNumOfSurELA =
1092 34 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1093 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1094 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1095 15 : int i = 1; // Temporary workaround
1096 15 : MultizoneSurfaceELAData.allocate(AirflowNetworkNumOfSurELA); // Temporary workaround
1097 15 : auto &instancesValue = instances.value();
1098 40 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1099 25 : auto const &fields = instance.value();
1100 50 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1101 25 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1102 :
1103 25 : Real64 ela{fields.at("effective_leakage_area")};
1104 25 : Real64 cd{1.0};
1105 25 : if (fields.find("discharge_coefficient") != fields.end()) {
1106 25 : cd = fields.at("discharge_coefficient").get<Real64>();
1107 : }
1108 25 : Real64 dp{4.0};
1109 25 : if (fields.find("reference_pressure_difference") != fields.end()) {
1110 25 : dp = fields.at("reference_pressure_difference").get<Real64>();
1111 : }
1112 25 : Real64 expnt{0.65};
1113 25 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1114 25 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1115 : }
1116 :
1117 25 : MultizoneSurfaceELAData(i).name = thisObjectName; // Name of surface effective leakage area component
1118 25 : MultizoneSurfaceELAData(i).ELA = ela; // Effective leakage area
1119 25 : MultizoneSurfaceELAData(i).DischCoeff = cd; // Discharge coefficient
1120 25 : MultizoneSurfaceELAData(i).RefDeltaP = dp; // Reference pressure difference
1121 25 : MultizoneSurfaceELAData(i).FlowExpo = expnt; // Air Mass Flow exponent
1122 25 : MultizoneSurfaceELAData(i).TestDeltaP = 0.0; // Testing pressure difference
1123 25 : MultizoneSurfaceELAData(i).TestDisCoef = 0.0; // Testing Discharge coefficient
1124 :
1125 : // Add the element to the lookup table, check for name overlaps
1126 25 : if (elements.find(thisObjectName) == elements.end()) {
1127 25 : elements[thisObjectName] = &MultizoneSurfaceELAData(i); // Yet another workaround
1128 : } else {
1129 0 : ShowSevereError(
1130 : m_state,
1131 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1132 0 : success = false;
1133 : }
1134 :
1135 25 : ++i;
1136 : }
1137 : }
1138 :
1139 : // *** Read AirflowNetwork simulation specified flow components
1140 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:SpecifiedFlowRate";
1141 34 : AirflowNetworkNumOfSFR =
1142 34 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1143 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1144 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1145 1 : int i_mass = 0; // Temporary workaround that increasingly looks like the long term solution
1146 1 : int i_vol = 0;
1147 1 : auto &instancesValue = instances.value();
1148 :
1149 1 : instancesValue = instances.value();
1150 2 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1151 1 : auto const &fields = instance.value();
1152 2 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1153 1 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1154 :
1155 1 : Real64 flow_rate{fields.at("air_flow_value")};
1156 1 : bool is_mass_flow = true;
1157 1 : if (fields.find("air_flow_units") != fields.end()) {
1158 1 : if (fields.at("air_flow_units") != "MassFlow") {
1159 0 : is_mass_flow = false;
1160 : }
1161 : }
1162 :
1163 : // Check for name overlaps
1164 1 : if (elements.find(thisObjectName) != elements.end()) {
1165 0 : ShowSevereError(
1166 : m_state,
1167 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1168 0 : success = false;
1169 : }
1170 :
1171 1 : if (is_mass_flow) {
1172 1 : SpecifiedMassFlowData.emplace_back();
1173 1 : SpecifiedMassFlowData[i_mass].name = thisObjectName;
1174 1 : SpecifiedMassFlowData[i_mass].mass_flow = flow_rate;
1175 1 : elements[thisObjectName] = &SpecifiedMassFlowData[i_mass]; // Yet another workaround
1176 1 : ++i_mass;
1177 : } else {
1178 0 : SpecifiedVolumeFlowData.emplace_back();
1179 0 : SpecifiedVolumeFlowData[i_vol].name = thisObjectName;
1180 0 : SpecifiedVolumeFlowData[i_vol].volume_flow = flow_rate;
1181 0 : elements[thisObjectName] = &SpecifiedVolumeFlowData[i_vol]; // Yet another workaround
1182 0 : ++i_vol;
1183 : }
1184 : }
1185 : }
1186 :
1187 : // Read AirflowNetwork Distribution system component: duct leakage
1188 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Leak";
1189 34 : DisSysNumOfLeaks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1190 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1191 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1192 11 : int i = 1; // Temporary workaround
1193 11 : DisSysCompLeakData.allocate(DisSysNumOfLeaks); // Temporary workaround
1194 11 : auto &instancesValue = instances.value();
1195 25 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1196 14 : auto const &fields = instance.value();
1197 28 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1198 14 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1199 :
1200 14 : Real64 coeff{fields.at("air_mass_flow_coefficient")};
1201 14 : Real64 expnt{0.65};
1202 14 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1203 14 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1204 : }
1205 :
1206 14 : DisSysCompLeakData(i).name = thisObjectName; // Name of duct leak component
1207 14 : DisSysCompLeakData(i).FlowCoef = coeff; // Air Mass Flow Coefficient
1208 14 : DisSysCompLeakData(i).FlowExpo = expnt; // Air Mass Flow exponent
1209 :
1210 : // Add the element to the lookup table, check for name overlaps
1211 14 : if (elements.find(thisObjectName) == elements.end()) {
1212 14 : elements[thisObjectName] = &DisSysCompLeakData(i); // Yet another workaround
1213 : } else {
1214 0 : ShowSevereError(
1215 : m_state,
1216 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1217 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1218 0 : success = false;
1219 : }
1220 :
1221 14 : ++i;
1222 : }
1223 : }
1224 :
1225 : // Read AirflowNetwork Distribution system component: duct effective leakage ratio
1226 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:LeakageRatio";
1227 34 : DisSysNumOfELRs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1228 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1229 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1230 22 : int i = 1; // Temporary workaround
1231 22 : DisSysCompELRData.allocate(DisSysNumOfELRs); // Temporary workaround
1232 22 : auto &instancesValue = instances.value();
1233 120 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1234 98 : auto const &fields = instance.value();
1235 196 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1236 98 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1237 :
1238 98 : Real64 elr{fields.at("effective_leakage_ratio")};
1239 98 : Real64 maxflow{fields.at("maximum_flow_rate")};
1240 98 : Real64 dp{fields.at("reference_pressure_difference")};
1241 98 : Real64 expnt{0.65};
1242 98 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1243 98 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1244 : }
1245 :
1246 98 : DisSysCompELRData(i).name = thisObjectName; // Name of duct effective leakage ratio component
1247 98 : DisSysCompELRData(i).ELR = elr; // Value of effective leakage ratio
1248 98 : DisSysCompELRData(i).FlowRate = maxflow * m_state.dataEnvrn->StdRhoAir; // Maximum airflow rate
1249 98 : DisSysCompELRData(i).RefPres = dp; // Reference pressure difference
1250 98 : DisSysCompELRData(i).FlowExpo = expnt; // Air Mass Flow exponent
1251 :
1252 : // Add the element to the lookup table, check for name overlaps
1253 98 : if (elements.find(thisObjectName) == elements.end()) {
1254 98 : elements[thisObjectName] = &DisSysCompELRData(i); // Yet another workaround
1255 : } else {
1256 0 : ShowSevereError(
1257 : m_state,
1258 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1259 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1260 0 : success = false;
1261 : }
1262 :
1263 98 : ++i;
1264 : }
1265 : }
1266 :
1267 : // Read AirflowNetwork Distribution system component: duct
1268 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Duct";
1269 34 : DisSysNumOfDucts = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1270 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1271 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1272 23 : int i = 1; // Temporary workaround
1273 23 : DisSysCompDuctData.allocate(DisSysNumOfDucts); // Temporary workaround
1274 23 : auto &instancesValue = instances.value();
1275 278 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1276 255 : auto const &fields = instance.value();
1277 510 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1278 255 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1279 :
1280 255 : Real64 L{fields.at("duct_length")};
1281 255 : Real64 D{fields.at("hydraulic_diameter")};
1282 255 : Real64 A{fields.at("cross_section_area")};
1283 255 : Real64 e{0.0009};
1284 255 : if (fields.find("surface_roughness") != fields.end()) {
1285 255 : e = fields.at("surface_roughness").get<Real64>();
1286 : }
1287 255 : Real64 dlc{0.0};
1288 255 : if (fields.find("coefficient_for_local_dynamic_loss_due_to_fitting") != fields.end()) {
1289 255 : dlc = fields.at("coefficient_for_local_dynamic_loss_due_to_fitting").get<Real64>();
1290 : }
1291 255 : Real64 U{0.943};
1292 255 : if (fields.find("heat_transmittance_coefficient_u_factor_for_duct_wall_construction") != fields.end()) {
1293 255 : U = fields.at("heat_transmittance_coefficient_u_factor_for_duct_wall_construction").get<Real64>();
1294 : }
1295 255 : Real64 Um{0.001};
1296 255 : if (fields.find("overall_moisture_transmittance_coefficient_from_air_to_air") != fields.end()) {
1297 255 : Um = fields.at("overall_moisture_transmittance_coefficient_from_air_to_air").get<Real64>();
1298 : }
1299 255 : Real64 hout{0.0};
1300 255 : if (fields.find("outside_convection_coefficient") != fields.end()) {
1301 218 : hout = fields.at("outside_convection_coefficient").get<Real64>();
1302 : }
1303 255 : Real64 hin{0.0};
1304 255 : if (fields.find("inside_convection_coefficient") != fields.end()) {
1305 218 : hin = fields.at("inside_convection_coefficient").get<Real64>();
1306 : }
1307 :
1308 255 : DisSysCompDuctData(i).name = thisObjectName; // Name of duct effective leakage ratio component
1309 255 : DisSysCompDuctData(i).L = L; // Duct length [m]
1310 255 : DisSysCompDuctData(i).hydraulicDiameter = D; // Hydraulic diameter [m]
1311 255 : DisSysCompDuctData(i).A = A; // Cross section area [m2]
1312 255 : DisSysCompDuctData(i).roughness = e; // Surface roughness [m]
1313 255 : DisSysCompDuctData(i).TurDynCoef = dlc; // Turbulent dynamic loss coefficient
1314 255 : DisSysCompDuctData(i).UThermConduct = U; // Conduction heat transmittance [W/m2.K]
1315 255 : DisSysCompDuctData(i).UMoisture = Um; // Overall moisture transmittance [kg/m2]
1316 255 : DisSysCompDuctData(i).OutsideConvCoeff = hout; // Outside convection coefficient [W/m2.K]
1317 255 : DisSysCompDuctData(i).InsideConvCoeff = hin; // Inside convection coefficient [W/m2.K]
1318 255 : DisSysCompDuctData(i).MThermal = 0.0; // Thermal capacity [J/K]
1319 255 : DisSysCompDuctData(i).MMoisture = 0.0; // Moisture capacity [kg]
1320 255 : DisSysCompDuctData(i).LamDynCoef = 64.0; // Laminar dynamic loss coefficient
1321 255 : DisSysCompDuctData(i).LamFriCoef = dlc; // Laminar friction loss coefficient
1322 255 : DisSysCompDuctData(i).InitLamCoef = 128.0; // Coefficient of linear initialization
1323 255 : DisSysCompDuctData(i).RelRough = e / D; // e/D: relative roughness
1324 255 : DisSysCompDuctData(i).RelL = L / D; // L/D: relative length
1325 255 : DisSysCompDuctData(i).A1 = 1.14 - 0.868589 * std::log(DisSysCompDuctData(i).RelRough); // 1.14 - 0.868589*ln(e/D)
1326 255 : DisSysCompDuctData(i).g = DisSysCompDuctData(i).A1; // 1/sqrt(Darcy friction factor)
1327 :
1328 : // Add the element to the lookup table, check for name overlaps
1329 255 : if (elements.find(thisObjectName) == elements.end()) {
1330 255 : elements[thisObjectName] = &DisSysCompDuctData(i); // Yet another workaround
1331 : } else {
1332 0 : ShowSevereError(
1333 : m_state,
1334 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1335 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1336 0 : success = false;
1337 : }
1338 :
1339 255 : ++i;
1340 : }
1341 : }
1342 :
1343 : // Read AirflowNetwork Distribution system component: constant volume fan
1344 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Fan";
1345 34 : DisSysNumOfCVFs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1346 34 : if (DisSysNumOfCVFs > 0 && DisSysNumOfCVFs != m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC")) {
1347 0 : ShowSevereError(m_state, format("The number of entered AirflowNetwork:Distribution:Component:Fan objects is {}", DisSysNumOfCVFs));
1348 0 : ShowSevereError(m_state,
1349 0 : format("The number of entered AirLoopHVAC objects is {}",
1350 0 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC")));
1351 0 : ShowContinueError(m_state, "Both numbers should be equal. Please check your inputs.");
1352 0 : success = false;
1353 : }
1354 :
1355 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1356 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1357 23 : int i = 1; // Temporary workaround
1358 23 : DisSysCompCVFData.allocate(DisSysNumOfCVFs); // Temporary workaround
1359 23 : auto &instancesValue = instances.value();
1360 47 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1361 24 : auto const &fields = instance.value();
1362 48 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1363 24 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1364 :
1365 48 : std::string fan_name = UtilityRoutines::MakeUPPERCase(fields.at("fan_name").get<std::string>());
1366 48 : std::string fan_type = fields.at("supply_fan_object_type").get<std::string>();
1367 :
1368 24 : bool FanErrorFound = false;
1369 : int fanIndex;
1370 24 : Real64 flowRate = 0.0;
1371 24 : int fanType_Num = 0;
1372 : int inletNode;
1373 : int outletNode;
1374 :
1375 24 : if (UtilityRoutines::SameString(UtilityRoutines::MakeUPPERCase(fan_type), "FAN:SYSTEMMODEL")) {
1376 1 : m_state.dataHVACFan->fanObjs.emplace_back(new HVACFan::FanSystem(m_state, fan_name));
1377 1 : fanIndex = HVACFan::getFanObjectVectorIndex(m_state, fan_name);
1378 1 : if (fanIndex < 0) {
1379 0 : ShowSevereError(m_state, "...occurs in " + CurrentModuleObject + " = " + DisSysCompCVFData(i).name);
1380 0 : success = false;
1381 : } else {
1382 1 : flowRate = m_state.dataHVACFan->fanObjs[fanIndex]->designAirVolFlowRate;
1383 1 : flowRate *= m_state.dataEnvrn->StdRhoAir;
1384 1 : DisSysCompCVFData(i).FanModelFlag = true;
1385 1 : inletNode = m_state.dataHVACFan->fanObjs[fanIndex]->inletNodeNum;
1386 1 : outletNode = m_state.dataHVACFan->fanObjs[fanIndex]->outletNodeNum;
1387 1 : if (m_state.dataHVACFan->fanObjs[fanIndex]->speedControl == HVACFan::FanSystem::SpeedControlMethod::Continuous) {
1388 0 : fanType_Num = FanType_SimpleVAV;
1389 0 : VAVSystem = true;
1390 : } else {
1391 1 : fanType_Num = FanType_SimpleOnOff;
1392 : }
1393 1 : SupplyFanType = fanType_Num;
1394 : }
1395 :
1396 : } else {
1397 :
1398 23 : GetFanIndex(m_state, fan_name, fanIndex, FanErrorFound);
1399 :
1400 23 : if (FanErrorFound) {
1401 0 : ShowSevereError(m_state, "...occurs in " + CurrentModuleObject + " = " + DisSysCompCVFData(i).name);
1402 0 : success = false;
1403 : }
1404 :
1405 23 : GetFanVolFlow(m_state, fanIndex, flowRate);
1406 23 : flowRate *= m_state.dataEnvrn->StdRhoAir;
1407 :
1408 23 : GetFanType(m_state, fan_name, fanType_Num, FanErrorFound);
1409 23 : SupplyFanType = fanType_Num;
1410 : }
1411 :
1412 24 : if (!(fanType_Num == FanType_SimpleConstVolume || fanType_Num == FanType_SimpleOnOff || fanType_Num == FanType_SimpleVAV)) {
1413 0 : ShowSevereError(m_state,
1414 0 : format(RoutineName) + "The Supply Fan Object Type in " + CurrentModuleObject + " = " + thisObjectName +
1415 : " is not a valid fan type.");
1416 0 : ShowContinueError(m_state, "Valid fan types are Fan:ConstantVolume, Fan:OnOff, Fan:VariableVolume, or Fan:SystemModel.");
1417 0 : success = false;
1418 : } else {
1419 24 : if (UtilityRoutines::SameString(fan_type, "Fan:ConstantVolume") && fanType_Num == FanType_SimpleOnOff) {
1420 0 : ShowSevereError(m_state, "The Supply Fan Object Type defined in " + CurrentModuleObject + " is " + fan_type);
1421 0 : ShowContinueError(m_state, "The Supply Fan Object Type defined in an AirLoopHVAC is Fan:OnOff");
1422 0 : success = false;
1423 : }
1424 24 : if (UtilityRoutines::SameString(fan_type, "Fan:OnOff") && fanType_Num == FanType_SimpleConstVolume) {
1425 0 : ShowSevereError(m_state, "The Supply Fan Object Type defined in " + CurrentModuleObject + " is " + fan_type);
1426 0 : ShowContinueError(m_state, "The Supply Fan Object Type defined in an AirLoopHVAC is Fan:ConstantVolume");
1427 0 : success = false;
1428 : }
1429 : }
1430 24 : bool ErrorsFound{false};
1431 24 : if (fanType_Num == FanType_SimpleConstVolume) {
1432 14 : inletNode = GetFanInletNode(m_state, "Fan:ConstantVolume", fan_name, ErrorsFound);
1433 14 : outletNode = GetFanOutletNode(m_state, "Fan:ConstantVolume", fan_name, ErrorsFound);
1434 : }
1435 24 : if (fanType_Num == FanType_SimpleOnOff && !DisSysCompCVFData(i).FanModelFlag) {
1436 8 : inletNode = GetFanInletNode(m_state, "Fan:OnOff", fan_name, ErrorsFound);
1437 8 : outletNode = GetFanOutletNode(m_state, "Fan:OnOff", fan_name, ErrorsFound);
1438 : }
1439 24 : if (fanType_Num == FanType_SimpleVAV && !DisSysCompCVFData(i).FanModelFlag) {
1440 1 : inletNode = GetFanInletNode(m_state, "Fan:VariableVolume", fan_name, ErrorsFound);
1441 1 : outletNode = GetFanOutletNode(m_state, "Fan:VariableVolume", fan_name, ErrorsFound);
1442 1 : VAVSystem = true;
1443 : }
1444 :
1445 24 : if (ErrorsFound) {
1446 0 : success = false;
1447 : }
1448 :
1449 24 : DisSysCompCVFData(i).name = fan_name; // Name of duct effective leakage ratio component
1450 24 : DisSysCompCVFData(i).Ctrl = 1.0; // Control ratio
1451 24 : DisSysCompCVFData(i).FanIndex = fanIndex;
1452 24 : DisSysCompCVFData(i).FlowRate = flowRate;
1453 24 : DisSysCompCVFData(i).FanTypeNum = fanType_Num;
1454 24 : DisSysCompCVFData(i).InletNode = inletNode;
1455 24 : DisSysCompCVFData(i).OutletNode = outletNode;
1456 :
1457 : // Add the element to the lookup table, check for name overlaps
1458 24 : if (elements.find(fan_name) == elements.end()) {
1459 24 : elements[fan_name] = &DisSysCompCVFData(i); // Yet another workaround
1460 : } else {
1461 0 : ShowSevereError(
1462 0 : m_state, format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, fan_name));
1463 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1464 0 : success = false;
1465 : }
1466 :
1467 24 : ++i;
1468 : }
1469 : }
1470 :
1471 : // Read AirflowNetwork Distribution system component: coil
1472 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Coil";
1473 34 : DisSysNumOfCoils = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1474 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1475 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1476 23 : int i = 1; // Temporary workaround
1477 23 : DisSysCompCoilData.allocate(DisSysNumOfCoils); // Temporary workaround
1478 23 : auto &instancesValue = instances.value();
1479 80 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1480 57 : auto const &fields = instance.value();
1481 : // auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1482 57 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1483 :
1484 114 : std::string coil_name = fields.at("coil_name").get<std::string>();
1485 114 : std::string coil_type = fields.at("coil_object_type").get<std::string>();
1486 57 : Real64 L{fields.at("air_path_length")};
1487 57 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1488 :
1489 57 : DisSysCompCoilData(i).name = UtilityRoutines::MakeUPPERCase(coil_name); // Name of associated EPlus coil component
1490 57 : DisSysCompCoilData(i).EPlusType = coil_type; // coil type
1491 57 : DisSysCompCoilData(i).L = L; // Air path length
1492 57 : DisSysCompCoilData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1493 :
1494 : // Add the element to the lookup table, check for name overlaps
1495 57 : if (elements.find(DisSysCompCoilData(i).name) == elements.end()) {
1496 57 : elements[DisSysCompCoilData(i).name] = &DisSysCompCoilData(i); // Yet another workaround
1497 : } else {
1498 0 : ShowSevereError(m_state,
1499 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1500 : RoutineName,
1501 : CurrentModuleObject,
1502 0 : DisSysCompCoilData(i).name));
1503 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1504 0 : success = false;
1505 : }
1506 :
1507 57 : ++i;
1508 : }
1509 : }
1510 :
1511 : // Read AirflowNetwork Distribution system component: heat exchanger
1512 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:HeatExchanger";
1513 34 : DisSysNumOfHXs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1514 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1515 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1516 1 : int i = 1; // Temporary workaround
1517 1 : DisSysCompHXData.allocate(DisSysNumOfHXs); // Temporary workaround
1518 1 : auto &instancesValue = instances.value();
1519 2 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1520 1 : auto const &fields = instance.value();
1521 : // auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1522 1 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1523 :
1524 2 : std::string hx_name = fields.at("heatexchanger_name").get<std::string>();
1525 2 : std::string hx_type = fields.at("heatexchanger_object_type").get<std::string>();
1526 1 : Real64 L{fields.at("air_path_length")};
1527 1 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1528 :
1529 1 : DisSysCompHXData(i).name = UtilityRoutines::MakeUPPERCase(hx_name); // Name of associated EPlus heat exchange component
1530 1 : DisSysCompHXData(i).EPlusType = hx_type; // coil type
1531 1 : DisSysCompHXData(i).L = L; // Air path length
1532 1 : DisSysCompHXData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1533 1 : DisSysCompHXData(i).CoilParentExists = HVACHXAssistedCoolingCoil::VerifyHeatExchangerParent(m_state, hx_type, hx_name);
1534 :
1535 : // Add the element to the lookup table, check for name overlaps
1536 1 : if (elements.find(DisSysCompHXData(i).name) == elements.end()) {
1537 1 : elements[DisSysCompHXData(i).name] = &DisSysCompHXData(i); // Yet another workaround
1538 : } else {
1539 0 : ShowSevereError(m_state,
1540 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1541 : RoutineName,
1542 : CurrentModuleObject,
1543 0 : DisSysCompHXData(i).name));
1544 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1545 0 : success = false;
1546 : }
1547 1 : ++i;
1548 : }
1549 : }
1550 :
1551 : // Read AirflowNetwork Distribution system component: terminal unit
1552 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:TerminalUnit";
1553 34 : DisSysNumOfTermUnits = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1554 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1555 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1556 12 : int i = 1; // Temporary workaround
1557 12 : DisSysCompTermUnitData.allocate(DisSysNumOfTermUnits); // Temporary workaround
1558 12 : auto &instancesValue = instances.value();
1559 36 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1560 24 : auto const &fields = instance.value();
1561 : // auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1562 24 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1563 :
1564 48 : std::string tu_name = fields.at("terminal_unit_name").get<std::string>();
1565 48 : std::string tu_type = fields.at("terminal_unit_object_type").get<std::string>();
1566 24 : Real64 L{fields.at("air_path_length")};
1567 24 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1568 :
1569 24 : DisSysCompTermUnitData(i).name = UtilityRoutines::MakeUPPERCase(tu_name); // Name of associated EPlus coil component
1570 24 : DisSysCompTermUnitData(i).EPlusType = tu_type; // Terminal unit type
1571 24 : DisSysCompTermUnitData(i).L = L; // Air path length
1572 24 : DisSysCompTermUnitData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1573 :
1574 : // Add the element to the lookup table, check for name overlaps
1575 24 : if (elements.find(DisSysCompTermUnitData(i).name) == elements.end()) {
1576 24 : elements[DisSysCompTermUnitData(i).name] = &DisSysCompTermUnitData(i); // Yet another workaround
1577 : } else {
1578 0 : ShowSevereError(m_state,
1579 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1580 : RoutineName,
1581 : CurrentModuleObject,
1582 0 : DisSysCompTermUnitData(i).name));
1583 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1584 0 : success = false;
1585 : }
1586 :
1587 24 : ++i;
1588 : }
1589 : }
1590 :
1591 : // Get input data of constant pressure drop component
1592 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ConstantPressureDrop";
1593 34 : DisSysNumOfCPDs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1594 34 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1595 34 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1596 12 : int i = 1; // Temporary workaround
1597 12 : DisSysCompCPDData.allocate(DisSysNumOfCPDs); // Temporary workaround
1598 12 : auto &instancesValue = instances.value();
1599 24 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1600 12 : auto const &fields = instance.value();
1601 24 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1602 12 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1603 :
1604 12 : Real64 dp{fields.at("pressure_difference_across_the_component")};
1605 :
1606 12 : DisSysCompCPDData(i).name = thisObjectName; // Name of constant pressure drop component
1607 12 : DisSysCompCPDData(i).A = 1.0; // cross section area
1608 12 : DisSysCompCPDData(i).DP = dp; // Pressure difference across the component
1609 :
1610 : // Add the element to the lookup table, check for name overlaps
1611 12 : if (elements.find(thisObjectName) == elements.end()) {
1612 12 : elements[thisObjectName] = &DisSysCompCPDData(i); // Yet another workaround
1613 : } else {
1614 0 : ShowSevereError(
1615 : m_state,
1616 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1617 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1618 0 : success = false;
1619 : }
1620 :
1621 12 : ++i;
1622 : }
1623 : }
1624 :
1625 34 : return success;
1626 : }
1627 :
1628 771 : void Solver::get_input()
1629 : {
1630 :
1631 : // SUBROUTINE INFORMATION:
1632 : // AUTHOR Lixing Gu
1633 : // DATE WRITTEN Aug. 2003
1634 : // MODIFIED Aug. 2005
1635 : // RE-ENGINEERED na
1636 :
1637 : // PURPOSE OF THIS SUBROUTINE:
1638 : // This subroutine reads inputs of air distribution system
1639 :
1640 : // Using/Aliasing
1641 : using Curve::GetCurveIndex;
1642 : using DataLoopNode::ObjectIsParent;
1643 : using HVACHXAssistedCoolingCoil::VerifyHeatExchangerParent;
1644 : using MixedAir::GetOAMixerNumber;
1645 : using NodeInputManager::GetOnlySingleNode;
1646 : using OutAirNodeManager::SetOutAirNodes;
1647 : using RoomAirModelManager::GetRAFNNodeNum;
1648 :
1649 : // SUBROUTINE PARAMETER DEFINITIONS:
1650 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::get_input: "); // include trailing blank space
1651 :
1652 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1653 : // int i;
1654 : int n;
1655 : int j;
1656 : int k;
1657 : int m;
1658 : int count;
1659 : bool NodeFound;
1660 : bool CompFound;
1661 : bool ErrorsFound;
1662 : bool found;
1663 : bool NodeFound1;
1664 : bool NodeFound2;
1665 : int NumAPL;
1666 805 : Array1D_string CompName(2);
1667 805 : std::string SimAirNetworkKey;
1668 : bool SimObjectError;
1669 805 : std::string StringOut;
1670 : int ZoneNum;
1671 : int NodeNum;
1672 :
1673 : // Declare variables used in this subroutine for debug purpose
1674 : bool AirflowNetworkInitFlag;
1675 805 : Array1D_int ZoneCheck;
1676 805 : Array1D_int ZoneBCCheck;
1677 : bool SurfaceFound;
1678 :
1679 : int NumAlphas; // Number of Alphas for each GetObjectItem call
1680 : int NumNumbers; // Number of Numbers for each GetObjectItem call
1681 : int IOStatus; // Used in GetObjectItem
1682 805 : std::string CurrentModuleObject;
1683 805 : Array1D_string Alphas; // Alpha input items for object
1684 805 : Array1D_string cAlphaFields; // Alpha field names
1685 805 : Array1D_string cNumericFields; // Numeric field names
1686 805 : Array1D<Real64> Numbers; // Numeric input items for object
1687 805 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
1688 805 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
1689 771 : int MaxNums(0); // Maximum number of numeric input fields
1690 771 : int MaxAlphas(0); // Maximum number of alpha input fields
1691 771 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
1692 : bool Errorfound1;
1693 : Real64 minHeight;
1694 : Real64 maxHeight;
1695 : Real64 baseratio;
1696 :
1697 771 : auto &Node(m_state.dataLoopNodes->Node);
1698 :
1699 : // Formats
1700 : static constexpr std::string_view Format_110(
1701 : "! <AirflowNetwork Model:Control>, No Multizone or Distribution/Multizone with Distribution/Multizone "
1702 : "without Distribution/Multizone with Distribution only during Fan Operation\n");
1703 : static constexpr std::string_view Format_120("AirflowNetwork Model:Control,{}\n");
1704 :
1705 : // Set the maximum numbers of input fields
1706 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1707 771 : m_state, "AirflowNetwork:SimulationControl", TotalArgs, NumAlphas, NumNumbers);
1708 771 : MaxNums = max(MaxNums, NumNumbers);
1709 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1710 771 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(m_state, "AirflowNetwork:MultiZone:Zone", TotalArgs, NumAlphas, NumNumbers);
1711 771 : MaxNums = max(MaxNums, NumNumbers);
1712 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1713 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1714 771 : m_state, "AirflowNetwork:MultiZone:Surface", TotalArgs, NumAlphas, NumNumbers);
1715 771 : MaxNums = max(MaxNums, NumNumbers);
1716 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1717 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1718 771 : m_state, "AirflowNetwork:MultiZone:Component:DetailedOpening", TotalArgs, NumAlphas, NumNumbers);
1719 771 : MaxNums = max(MaxNums, NumNumbers);
1720 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1721 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1722 771 : m_state, "AirflowNetwork:MultiZone:ExternalNode", TotalArgs, NumAlphas, NumNumbers);
1723 771 : MaxNums = max(MaxNums, NumNumbers);
1724 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1725 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1726 771 : m_state, "AirflowNetwork:MultiZone:WindPressureCoefficientArray", TotalArgs, NumAlphas, NumNumbers);
1727 771 : MaxNums = max(MaxNums, NumNumbers);
1728 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1729 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1730 771 : m_state, "AirflowNetwork:MultiZone:WindPressureCoefficientValues", TotalArgs, NumAlphas, NumNumbers);
1731 771 : MaxNums = max(MaxNums, NumNumbers);
1732 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1733 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1734 771 : m_state, "AirflowNetwork:Distribution:Node", TotalArgs, NumAlphas, NumNumbers);
1735 771 : MaxNums = max(MaxNums, NumNumbers);
1736 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1737 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1738 771 : m_state, "AirflowNetwork:Distribution:DuctViewFactors", TotalArgs, NumAlphas, NumNumbers);
1739 771 : MaxNums = max(MaxNums, NumNumbers);
1740 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1741 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1742 771 : m_state, "AirflowNetwork:Distribution:Linkage", TotalArgs, NumAlphas, NumNumbers);
1743 771 : MaxNums = max(MaxNums, NumNumbers);
1744 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1745 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1746 771 : m_state, "AirflowNetwork:OccupantVentilationControl", TotalArgs, NumAlphas, NumNumbers);
1747 771 : MaxNums = max(MaxNums, NumNumbers);
1748 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1749 771 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(m_state, "AirflowNetwork:IntraZone:Node", TotalArgs, NumAlphas, NumNumbers);
1750 771 : MaxNums = max(MaxNums, NumNumbers);
1751 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1752 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1753 771 : m_state, "AirflowNetwork:IntraZone:Linkage", TotalArgs, NumAlphas, NumNumbers);
1754 771 : MaxNums = max(MaxNums, NumNumbers);
1755 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1756 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1757 771 : m_state, "AirflowNetwork:ZoneControl:PressureController", TotalArgs, NumAlphas, NumNumbers);
1758 771 : MaxNums = max(MaxNums, NumNumbers);
1759 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1760 1542 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1761 771 : m_state, "AirflowNetwork:Distribution:DuctSizing", TotalArgs, NumAlphas, NumNumbers);
1762 771 : MaxNums = max(MaxNums, NumNumbers);
1763 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
1764 :
1765 771 : Alphas.allocate(MaxAlphas);
1766 771 : cAlphaFields.allocate(MaxAlphas);
1767 771 : cNumericFields.allocate(MaxNums);
1768 771 : Numbers.dimension(MaxNums, 0.0);
1769 771 : lAlphaBlanks.dimension(MaxAlphas, true);
1770 771 : lNumericBlanks.dimension(MaxNums, true);
1771 :
1772 771 : ErrorsFound = false;
1773 771 : AirflowNetworkInitFlag = false;
1774 :
1775 771 : auto &Zone(m_state.dataHeatBal->Zone);
1776 :
1777 : // Read AirflowNetwork OccupantVentilationControl before reading other AirflowNetwork objects, so that this object can be called by other
1778 : // simple ventilation objects
1779 771 : CurrentModuleObject = "AirflowNetwork:OccupantVentilationControl";
1780 771 : AirflowNetworkNumOfOccuVentCtrls = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1781 771 : if (AirflowNetworkNumOfOccuVentCtrls > 0) {
1782 1 : OccupantVentilationControl.allocate(AirflowNetworkNumOfOccuVentCtrls);
1783 2 : for (int i = 1; i <= AirflowNetworkNumOfOccuVentCtrls; ++i) {
1784 1 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
1785 : CurrentModuleObject,
1786 : i,
1787 : Alphas,
1788 : NumAlphas,
1789 : Numbers,
1790 : NumNumbers,
1791 : IOStatus,
1792 : lNumericBlanks,
1793 : lAlphaBlanks,
1794 : cAlphaFields,
1795 : cNumericFields);
1796 1 : UtilityRoutines::IsNameEmpty(m_state, Alphas(1), CurrentModuleObject, ErrorsFound);
1797 1 : OccupantVentilationControl(i).Name = Alphas(1); // Name of object
1798 1 : OccupantVentilationControl(i).MinOpeningTime = Numbers(1);
1799 1 : if (OccupantVentilationControl(i).MinOpeningTime < 0.0) {
1800 : // Code will never be executed, validation will catch invalid input
1801 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(1) + " < 0.0");
1802 0 : ShowContinueError(m_state,
1803 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", OccupantVentilationControl(i).MinOpeningTime));
1804 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1805 0 : OccupantVentilationControl(i).MinOpeningTime = 0.0;
1806 : }
1807 1 : OccupantVentilationControl(i).MinClosingTime = Numbers(2);
1808 1 : if (OccupantVentilationControl(i).MinClosingTime < 0.0) {
1809 : // Code will never be executed, validation will catch invalid input
1810 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " < 0.0");
1811 0 : ShowContinueError(m_state,
1812 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", OccupantVentilationControl(i).MinClosingTime));
1813 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1814 0 : OccupantVentilationControl(i).MinClosingTime = 0.0;
1815 : }
1816 1 : if (NumAlphas == 1 && NumNumbers == 2) {
1817 0 : OccupantVentilationControl(i).MinTimeControlOnly = true;
1818 : }
1819 1 : if (!lAlphaBlanks(2)) {
1820 1 : OccupantVentilationControl(i).ComfortLowTempCurveName = Alphas(2);
1821 1 : OccupantVentilationControl(i).ComfortLowTempCurveNum = GetCurveIndex(m_state, Alphas(2)); // convert curve name to number
1822 1 : if (OccupantVentilationControl(i).ComfortLowTempCurveNum == 0) {
1823 0 : OccupantVentilationControl(i).MinTimeControlOnly = true;
1824 0 : ShowWarningError(m_state,
1825 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(2) +
1826 0 : " not found = " + OccupantVentilationControl(i).ComfortLowTempCurveName);
1827 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1828 0 : ShowContinueError(
1829 : m_state,
1830 : "Thermal comfort will not be performed and minimum opening and closing times are checked only. Simulation continues.");
1831 : } else {
1832 3 : ErrorsFound |= Curve::CheckCurveDims(m_state,
1833 1 : OccupantVentilationControl(i).ComfortLowTempCurveNum, // Curve index
1834 : {1}, // Valid dimensions
1835 : RoutineName, // Routine name
1836 : CurrentModuleObject, // Object Type
1837 1 : OccupantVentilationControl(i).Name, // Object Name
1838 1 : cAlphaFields(2)); // Field Name
1839 : }
1840 : }
1841 1 : if (!lAlphaBlanks(3)) {
1842 1 : OccupantVentilationControl(i).ComfortHighTempCurveName = Alphas(3);
1843 1 : OccupantVentilationControl(i).ComfortHighTempCurveNum = GetCurveIndex(m_state, Alphas(3)); // convert curve name to number
1844 1 : if (OccupantVentilationControl(i).ComfortHighTempCurveNum > 0) {
1845 3 : ErrorsFound |= Curve::CheckCurveDims(m_state,
1846 1 : OccupantVentilationControl(i).ComfortHighTempCurveNum, // Curve index
1847 : {1}, // Valid dimensions
1848 : RoutineName, // Routine name
1849 : CurrentModuleObject, // Object Type
1850 1 : OccupantVentilationControl(i).Name, // Object Name
1851 1 : cAlphaFields(3)); // Field Name
1852 : } else {
1853 0 : ShowWarningError(m_state,
1854 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) +
1855 0 : " not found = " + OccupantVentilationControl(i).ComfortHighTempCurveName);
1856 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1857 0 : ShowContinueError(m_state, "A single curve of thermal comfort low temperature is used only. Simulation continues.");
1858 : }
1859 : }
1860 1 : if (OccupantVentilationControl(i).ComfortHighTempCurveNum > 0) {
1861 1 : OccupantVentilationControl(i).ComfortBouPoint = Numbers(3);
1862 1 : if (OccupantVentilationControl(i).ComfortBouPoint < 0.0) {
1863 : // Code will never be executed, validation will catch invalid input
1864 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(3) + " < 0.0");
1865 0 : ShowContinueError(
1866 : m_state,
1867 0 : format("..Input value = {:.1R}, Value will be reset to 10.0 as default", OccupantVentilationControl(i).ComfortBouPoint));
1868 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1869 0 : OccupantVentilationControl(i).ComfortBouPoint = 10.0;
1870 : }
1871 : }
1872 : // Check continuity of both curves at boundary point
1873 1 : if (OccupantVentilationControl(i).ComfortLowTempCurveNum > 0 && OccupantVentilationControl(i).ComfortHighTempCurveNum) {
1874 3 : if (std::abs(CurveValue(m_state, OccupantVentilationControl(i).ComfortLowTempCurveNum, Numbers(3)) -
1875 2 : CurveValue(m_state, OccupantVentilationControl(i).ComfortHighTempCurveNum, Numbers(3))) > 0.1) {
1876 0 : ShowSevereError(m_state,
1877 0 : format(RoutineName) + CurrentModuleObject +
1878 : " object: The difference of both curve values at boundary point > 0.1");
1879 0 : ShowContinueError(m_state, "Both curve names are = " + cAlphaFields(2) + " and " + cAlphaFields(3));
1880 0 : ShowContinueError(m_state,
1881 0 : format("The input value of {} = {:.1R}", cNumericFields(3), OccupantVentilationControl(i).ComfortBouPoint));
1882 0 : ErrorsFound = true;
1883 : }
1884 : }
1885 1 : if (!lNumericBlanks(4)) {
1886 1 : OccupantVentilationControl(i).MaxPPD = Numbers(4);
1887 1 : if (OccupantVentilationControl(i).MaxPPD < 0.0 || OccupantVentilationControl(i).MaxPPD > 100.0) {
1888 : // Code will never be executed, validation will catch invalid input
1889 0 : ShowWarningError(m_state,
1890 0 : format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " beyond 0.0 and 100.0");
1891 0 : ShowContinueError(
1892 0 : m_state, format("..Input value = {:.1R}, Value will be reset to 10.0 as default", OccupantVentilationControl(i).MaxPPD));
1893 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1894 0 : OccupantVentilationControl(i).MaxPPD = 10.0;
1895 : }
1896 : }
1897 1 : if (!lAlphaBlanks(4)) {
1898 1 : if (UtilityRoutines::SameString(Alphas(4), "Yes")) {
1899 1 : OccupantVentilationControl(i).OccupancyCheck = true;
1900 0 : } else if (UtilityRoutines::SameString(Alphas(4), "No")) {
1901 0 : OccupantVentilationControl(i).OccupancyCheck = false;
1902 : } else {
1903 : // Code will never be executed, validation will catch invalid input
1904 0 : ShowSevereError(m_state,
1905 0 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" invalid " + cAlphaFields(2) + "=\"" +
1906 0 : Alphas(2) + "\" illegal key.");
1907 0 : ShowContinueError(m_state, "Valid keys are: Yes or No");
1908 0 : ErrorsFound = true;
1909 : }
1910 : }
1911 1 : if (!lAlphaBlanks(5)) {
1912 0 : OccupantVentilationControl(i).OpeningProbSchName = Alphas(5); // a schedule name for opening probability
1913 0 : OccupantVentilationControl(i).OpeningProbSchNum = GetScheduleIndex(m_state, OccupantVentilationControl(i).OpeningProbSchName);
1914 0 : if (OccupantVentilationControl(i).OpeningProbSchNum == 0) {
1915 0 : ShowSevereError(m_state,
1916 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(5) +
1917 0 : " not found = " + OccupantVentilationControl(i).OpeningProbSchName);
1918 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1919 0 : ErrorsFound = true;
1920 : }
1921 : }
1922 1 : if (!lAlphaBlanks(6)) {
1923 0 : OccupantVentilationControl(i).ClosingProbSchName = Alphas(6); // a schedule name for closing probability
1924 0 : OccupantVentilationControl(i).ClosingProbSchNum = GetScheduleIndex(m_state, OccupantVentilationControl(i).ClosingProbSchName);
1925 0 : if (OccupantVentilationControl(i).OpeningProbSchNum == 0) {
1926 0 : ShowSevereError(m_state,
1927 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) +
1928 0 : " not found = " + OccupantVentilationControl(i).ClosingProbSchName);
1929 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1930 0 : ErrorsFound = true;
1931 : }
1932 : }
1933 : }
1934 : }
1935 :
1936 771 : if (ErrorsFound) {
1937 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
1938 : }
1939 :
1940 : // *** Read AirflowNetwork simulation parameters
1941 771 : CurrentModuleObject = "AirflowNetwork:SimulationControl";
1942 771 : NumAirflowNetwork = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1943 771 : if (NumAirflowNetwork == 0) {
1944 1474 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:Zone") >= 1 &&
1945 737 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:Surface") >= 2) {
1946 0 : control_defaulted = true;
1947 0 : simulation_control.name = "AFNDefaultControl";
1948 0 : simulation_control.type = ControlType::MultizoneWithoutDistribution;
1949 0 : simulation_control.WPCCntr = "SURFACEAVERAGECALCULATION";
1950 0 : simulation_control.HeightOption = "OPENINGHEIGHT";
1951 0 : simulation_control.BldgType = "LOWRISE";
1952 0 : simulation_control.InitType = "ZERONODEPRESSURES";
1953 0 : simulation_control.temperature_height_dependence = false;
1954 0 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
1955 : // Use default values for numerical fields
1956 0 : simulation_control.maximum_iterations = 500;
1957 0 : simulation_control.relative_convergence_tolerance = 1.E-4;
1958 0 : simulation_control.absolute_convergence_tolerance = 1.E-6;
1959 0 : simulation_control.convergence_acceleration_limit = -0.5;
1960 0 : simulation_control.azimuth = 0.0;
1961 0 : simulation_control.aspect_ratio = 1.0;
1962 0 : simulation_control.MaxPressure = 500.0; // Maximum pressure difference by default
1963 0 : SimAirNetworkKey = "MultizoneWithoutDistribution";
1964 0 : simulation_control.InitFlag = 1;
1965 0 : ShowWarningError(m_state, format("{}{} object is not found ", RoutineName, CurrentModuleObject));
1966 0 : ShowContinueError(m_state, "..The default behaviour values are assigned. Please see details in Input Output Reference.");
1967 : } else {
1968 737 : simulation_control.type = ControlType::NoMultizoneOrDistribution;
1969 737 : print(m_state.files.eio, Format_110);
1970 737 : print(m_state.files.eio, Format_120, "NoMultizoneOrDistribution");
1971 737 : return;
1972 : }
1973 : }
1974 34 : if (NumAirflowNetwork > 1) {
1975 0 : ShowFatalError(m_state, format("{}Only one (\"1\") {} object per simulation is allowed.", RoutineName, CurrentModuleObject));
1976 : }
1977 :
1978 34 : SimObjectError = false;
1979 34 : if (!control_defaulted) {
1980 34 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
1981 : CurrentModuleObject,
1982 : NumAirflowNetwork,
1983 : Alphas,
1984 : NumAlphas,
1985 : Numbers,
1986 : NumNumbers,
1987 : IOStatus,
1988 : lNumericBlanks,
1989 : lAlphaBlanks,
1990 : cAlphaFields,
1991 : cNumericFields);
1992 :
1993 34 : simulation_control.name = Alphas(1);
1994 34 : simulation_control.WPCCntr = Alphas(3);
1995 34 : simulation_control.HeightOption = Alphas(4);
1996 34 : simulation_control.BldgType = Alphas(5);
1997 :
1998 : // Retrieve flag allowing the support of zone equipment
1999 34 : simulation_control.allow_unsupported_zone_equipment = false;
2000 34 : if (UtilityRoutines::SameString(Alphas(9), "Yes")) {
2001 2 : simulation_control.allow_unsupported_zone_equipment = true;
2002 : }
2003 :
2004 : // Find a flag for possible combination of vent and distribution system
2005 : // This SELECT_CASE_var will go on input refactor, no need to fix
2006 : {
2007 68 : auto const SELECT_CASE_var(UtilityRoutines::MakeUPPERCase(Alphas(2)));
2008 34 : if (SELECT_CASE_var == "NOMULTIZONEORDISTRIBUTION") {
2009 0 : simulation_control.type = ControlType::NoMultizoneOrDistribution;
2010 0 : SimAirNetworkKey = "NoMultizoneOrDistribution";
2011 34 : } else if (SELECT_CASE_var == "MULTIZONEWITHOUTDISTRIBUTION") {
2012 11 : simulation_control.type = ControlType::MultizoneWithoutDistribution;
2013 11 : SimAirNetworkKey = "MultizoneWithoutDistribution";
2014 23 : } else if (SELECT_CASE_var == "MULTIZONEWITHDISTRIBUTIONONLYDURINGFANOPERATION") {
2015 2 : simulation_control.type = ControlType::MultizoneWithDistributionOnlyDuringFanOperation;
2016 2 : SimAirNetworkKey = "MultizoneWithDistributionOnlyDuringFanOperation";
2017 : } else { // if (SELECT_CASE_var == "MULTIZONEWITHDISTRIBUTION") {
2018 21 : simulation_control.type = ControlType::MultizoneWithDistribution;
2019 21 : SimAirNetworkKey = "MultizoneWithDistribution";
2020 : }
2021 : }
2022 : }
2023 :
2024 : // Determine a convenience boolean or two to simplify the checking
2025 : // The first one is true if distribution is simulated, replaces some > and >= comparisons
2026 : // SimulateAirflowNetwork > AirflowNetworkControlMultizone -> type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation
2027 : // type == ControlType::MultizoneWithDistribution
2028 : // SimulateAirflowNetwork >= AirflowNetworkControlSimpleADS -> type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation
2029 : // type == ControlType::MultizoneWithDistribution
2030 66 : distribution_simulated = simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation ||
2031 32 : simulation_control.type == ControlType::MultizoneWithDistribution;
2032 : // This one is true if the multizone simulation is ALWAYS done
2033 34 : multizone_always_simulated =
2034 34 : simulation_control.type == ControlType::MultizoneWithDistribution || simulation_control.type == ControlType::MultizoneWithoutDistribution;
2035 :
2036 : // Check the number of primary air loops
2037 34 : if (distribution_simulated) {
2038 23 : NumAPL = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC");
2039 23 : if (NumAPL > 0) {
2040 23 : LoopPartLoadRatio.allocate(NumAPL);
2041 23 : LoopOnOffFanRunTimeFraction.allocate(NumAPL);
2042 23 : LoopOnOffFlag.allocate(NumAPL);
2043 23 : LoopPartLoadRatio = 0.0;
2044 23 : LoopOnOffFanRunTimeFraction = 0.0;
2045 23 : LoopOnOffFlag = false;
2046 : }
2047 : }
2048 34 : print(m_state.files.eio, Format_110);
2049 34 : print(m_state.files.eio, Format_120, SimAirNetworkKey);
2050 :
2051 34 : if (control_defaulted) {
2052 0 : cAlphaFields(2) = "AirflowNetwork Control";
2053 : }
2054 :
2055 : // Check whether there are any objects from infiltration, ventilation, mixing and cross mixing
2056 68 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution ||
2057 34 : simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation) {
2058 6 : if (m_state.dataHeatBal->TotInfiltration + m_state.dataHeatBal->TotVentilation + m_state.dataHeatBal->TotMixing +
2059 6 : m_state.dataHeatBal->TotCrossMixing + m_state.dataHeatBal->TotZoneAirBalance +
2060 6 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneEarthtube") +
2061 6 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneThermalChimney") +
2062 4 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneCoolTower:Shower") ==
2063 : 0) {
2064 0 : ShowWarningError(m_state, format("{}{} = \"{}\"", RoutineName, cAlphaFields(2), SimAirNetworkKey));
2065 0 : ShowContinueError(
2066 : m_state,
2067 : "..but there are no Infiltration, Ventilation, Mixing, Cross Mixing or ZoneAirBalance objects. The simulation continues...");
2068 : }
2069 : }
2070 :
2071 : // Check whether a user wants to perform SIMPLE calculation only or not
2072 34 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) {
2073 0 : return;
2074 : }
2075 :
2076 34 : if (multizone_always_simulated) {
2077 32 : if (m_state.dataHeatBal->TotInfiltration > 0) {
2078 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2079 0 : ShowContinueError(m_state,
2080 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneInfiltration:* objects are present.");
2081 0 : ShowContinueError(m_state, "..ZoneInfiltration objects will not be simulated.");
2082 : }
2083 32 : if (m_state.dataHeatBal->TotVentilation > 0) {
2084 2 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2085 6 : ShowContinueError(m_state,
2086 4 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneVentilation:* objects are present.");
2087 2 : ShowContinueError(m_state, "..ZoneVentilation objects will not be simulated.");
2088 : }
2089 32 : if (m_state.dataHeatBal->TotMixing > 0) {
2090 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2091 0 : ShowContinueError(m_state, "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneMixing objects are present.");
2092 0 : ShowContinueError(m_state, "..ZoneMixing objects will not be simulated.");
2093 : }
2094 32 : if (m_state.dataHeatBal->TotCrossMixing > 0) {
2095 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2096 0 : ShowContinueError(m_state,
2097 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneCrossMixing objects are present.");
2098 0 : ShowContinueError(m_state, "..ZoneCrossMixing objects will not be simulated.");
2099 : }
2100 32 : if (m_state.dataHeatBal->TotZoneAirBalance > 0) {
2101 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2102 0 : ShowContinueError(
2103 0 : m_state, "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneAirBalance:OutdoorAir objects are present.");
2104 0 : ShowContinueError(m_state, "..ZoneAirBalance:OutdoorAir objects will not be simulated.");
2105 : }
2106 32 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneEarthtube") > 0) {
2107 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2108 0 : ShowContinueError(m_state,
2109 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneEarthtube objects are present.");
2110 0 : ShowContinueError(m_state, "..ZoneEarthtube objects will not be simulated.");
2111 : }
2112 32 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneThermalChimney") > 0) {
2113 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2114 0 : ShowContinueError(m_state,
2115 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneThermalChimney objects are present.");
2116 0 : ShowContinueError(m_state, "..ZoneThermalChimney objects will not be simulated.");
2117 : }
2118 32 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneCoolTower:Shower") > 0) {
2119 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2120 0 : ShowContinueError(m_state,
2121 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneCoolTower:Shower objects are present.");
2122 0 : ShowContinueError(m_state, "..ZoneCoolTower:Shower objects will not be simulated.");
2123 : }
2124 : }
2125 :
2126 34 : SetOutAirNodes(m_state);
2127 34 : if (!control_defaulted) {
2128 34 : if (UtilityRoutines::SameString(simulation_control.WPCCntr, "Input")) {
2129 27 : simulation_control.iWPCCnt = iWPCCntr::Input;
2130 27 : if (lAlphaBlanks(4)) {
2131 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) + " = INPUT.");
2132 0 : ShowContinueError(m_state, ".." + cAlphaFields(4) + " was not entered.");
2133 0 : ErrorsFound = true;
2134 0 : SimObjectError = true;
2135 : } else {
2136 54 : if (!(UtilityRoutines::SameString(simulation_control.HeightOption, "ExternalNode") ||
2137 27 : UtilityRoutines::SameString(simulation_control.HeightOption, "OpeningHeight"))) {
2138 0 : ShowSevereError(
2139 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(4) + " = " + Alphas(4) + " is invalid.");
2140 0 : ShowContinueError(m_state,
2141 0 : "Valid choices are ExternalNode or OpeningHeight. " + CurrentModuleObject + ": " + cAlphaFields(1) + " = " +
2142 : simulation_control.name);
2143 0 : ErrorsFound = true;
2144 0 : SimObjectError = true;
2145 : }
2146 : }
2147 7 : } else if (UtilityRoutines::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
2148 7 : simulation_control.iWPCCnt = iWPCCntr::SurfAvg;
2149 14 : if (!(UtilityRoutines::SameString(simulation_control.BldgType, "LowRise") ||
2150 7 : UtilityRoutines::SameString(simulation_control.BldgType, "HighRise"))) {
2151 0 : ShowSevereError(m_state,
2152 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(5) + " = " + Alphas(5) + " is invalid.");
2153 0 : ShowContinueError(m_state,
2154 0 : "Valid choices are LowRise or HighRise. " + CurrentModuleObject + ": " + cAlphaFields(1) + " = " +
2155 : simulation_control.name);
2156 0 : ErrorsFound = true;
2157 0 : SimObjectError = true;
2158 : }
2159 126 : for (k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
2160 119 : if (Node(k).IsLocalNode) {
2161 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(3) + "=" + Alphas(3));
2162 0 : ShowContinueError(m_state,
2163 : "A local air node is defined to INPUT the wind pressure coefficient curve, while Wind Pressure Coefficient "
2164 : "Type is set to SurfaceAverageCalculation.");
2165 0 : ShowContinueError(m_state, "It requires the Wind Pressure Coefficient Type be set to INPUT to use the local air node.");
2166 0 : ErrorsFound = true;
2167 0 : SimObjectError = true;
2168 0 : break;
2169 : }
2170 : }
2171 : } else {
2172 0 : ShowSevereError(m_state,
2173 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) + " = " + simulation_control.WPCCntr +
2174 : " is not valid.");
2175 0 : ShowContinueError(m_state,
2176 0 : "Valid choices are Input or SurfaceAverageCalculation. " + CurrentModuleObject + " = " + simulation_control.name);
2177 0 : ErrorsFound = true;
2178 0 : SimObjectError = true;
2179 : }
2180 :
2181 34 : simulation_control.InitType = Alphas(6);
2182 34 : if (UtilityRoutines::SameString(simulation_control.InitType, "LinearInitializationMethod")) {
2183 0 : simulation_control.InitFlag = 0;
2184 34 : } else if (UtilityRoutines::SameString(simulation_control.InitType, "ZeroNodePressures")) {
2185 34 : simulation_control.InitFlag = 1;
2186 0 : } else if (UtilityRoutines::SameString(simulation_control.InitType, "0")) {
2187 0 : simulation_control.InitFlag = 0;
2188 0 : } else if (UtilityRoutines::SameString(simulation_control.InitType, "1")) {
2189 0 : simulation_control.InitFlag = 1;
2190 : } else {
2191 : // Code will never be executed, validation will catch invalid input
2192 0 : ShowSevereError(m_state,
2193 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) + " = " + Alphas(6) + " is invalid.");
2194 0 : ShowContinueError(m_state,
2195 0 : "Valid choices are LinearInitializationMethod or ZeroNodePressures. " + CurrentModuleObject + " = " +
2196 : simulation_control.name);
2197 0 : ErrorsFound = true;
2198 0 : SimObjectError = true;
2199 : }
2200 :
2201 34 : if (!lAlphaBlanks(7) && UtilityRoutines::SameString(Alphas(7), "Yes")) simulation_control.temperature_height_dependence = true;
2202 :
2203 34 : if (lAlphaBlanks(8)) {
2204 33 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2205 1 : } else if (UtilityRoutines::SameString(Alphas(8), "SkylineLU")) {
2206 1 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2207 0 : } else if (UtilityRoutines::SameString(Alphas(8), "ConjugateGradient")) {
2208 0 : simulation_control.solver = SimulationControl::Solver::ConjugateGradient;
2209 : } else {
2210 0 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2211 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2212 0 : ShowContinueError(m_state, "..Specified " + cAlphaFields(8) + " = \"" + Alphas(8) + "\" is unrecognized.");
2213 0 : ShowContinueError(m_state, "..Default value \"SkylineLU\" will be used.");
2214 : }
2215 :
2216 : // Get inputs for duct sizing
2217 34 : simulation_control.autosize_ducts = false;
2218 34 : if (NumAlphas == 10) {
2219 34 : if (UtilityRoutines::SameString(Alphas(10), "YES")) {
2220 1 : simulation_control.autosize_ducts = true;
2221 1 : if (simulation_control.type == ControlType::MultizoneWithDistribution) {
2222 1 : if (NumAPL > 1) {
2223 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2224 0 : ShowContinueError(
2225 : m_state,
2226 0 : format("The number of AirLoopHAVC is greater than 1. The current requirement for Duct Sizing requires a "
2227 0 : "single AirLoopHVAC."));
2228 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2229 0 : simulation_control.autosize_ducts = false;
2230 : }
2231 : }
2232 : }
2233 : }
2234 :
2235 34 : if (SimObjectError) {
2236 0 : ShowFatalError(
2237 : m_state,
2238 0 : format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
2239 : }
2240 :
2241 34 : simulation_control.maximum_iterations = static_cast<int>(Numbers(1));
2242 34 : simulation_control.relative_convergence_tolerance = Numbers(2);
2243 34 : simulation_control.absolute_convergence_tolerance = Numbers(3);
2244 34 : simulation_control.convergence_acceleration_limit = Numbers(4);
2245 34 : simulation_control.azimuth = Numbers(5);
2246 34 : simulation_control.aspect_ratio = Numbers(6);
2247 34 : simulation_control.MaxPressure = 500.0; // Maximum pressure difference by default
2248 : }
2249 :
2250 34 : CurrentModuleObject = "AirflowNetwork:Distribution:DuctSizing";
2251 34 : int NumDuctSizing = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2252 34 : if (NumDuctSizing > 1) {
2253 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2254 0 : ShowContinueError(
2255 : m_state,
2256 0 : format("The number of AirflowNetwork:Distribution:DuctSizing is greater than 1. The current requirement for Duct Sizing requires a "
2257 0 : "single object."));
2258 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2259 0 : simulation_control.autosize_ducts = false;
2260 34 : } else if (simulation_control.autosize_ducts && NumDuctSizing == 0) {
2261 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2262 0 : ShowContinueError(
2263 : m_state,
2264 0 : format("The number of AirflowNetwork:Distribution:DuctSizing is not avalable. The current requirement for Duct Sizing requires a "
2265 0 : "single object."));
2266 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2267 0 : simulation_control.autosize_ducts = false;
2268 : }
2269 34 : if (simulation_control.autosize_ducts && NumDuctSizing == 1) {
2270 1 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2271 : CurrentModuleObject,
2272 : NumDuctSizing,
2273 : Alphas,
2274 : NumAlphas,
2275 : Numbers,
2276 : NumNumbers,
2277 : IOStatus,
2278 : lNumericBlanks,
2279 : lAlphaBlanks,
2280 : cAlphaFields,
2281 : cNumericFields);
2282 :
2283 1 : simulation_control.ductSizing.name = Alphas(1);
2284 1 : if (UtilityRoutines::SameString(Alphas(2), UtilityRoutines::MakeUPPERCase("MaximumVelocity"))) {
2285 0 : simulation_control.ductSizing.method = DuctSizingMethod::MaxVelocity;
2286 1 : } else if (UtilityRoutines::SameString(Alphas(2), UtilityRoutines::MakeUPPERCase("PressureLoss"))) {
2287 1 : simulation_control.ductSizing.method = DuctSizingMethod::PressureLoss;
2288 0 : } else if (UtilityRoutines::SameString(Alphas(2), UtilityRoutines::MakeUPPERCase("PressureLossWithMaximumVelocity"))) {
2289 0 : simulation_control.ductSizing.method = DuctSizingMethod::VelocityAndLoss;
2290 : } else {
2291 0 : ShowSevereError(m_state, format("{} {} object, {} = {} is invalid.", RoutineName, CurrentModuleObject, cAlphaFields(2), Alphas(2)));
2292 0 : ShowContinueError(m_state,
2293 0 : format("Valid choices are MaximumVelocity, PressureLoss, and PressureLossWithMaximumVelocity. {}: {} = {}",
2294 : CurrentModuleObject,
2295 : cAlphaFields(1),
2296 0 : Alphas(1)));
2297 0 : ErrorsFound = true;
2298 : }
2299 1 : if (simulation_control.type != ControlType::MultizoneWithDistribution) {
2300 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2301 0 : ShowContinueError(m_state,
2302 0 : format("Although {} = \"{}\" is entered, but {} is not MultizoneWithoutDistribution.",
2303 : cAlphaFields(10),
2304 : Alphas(10),
2305 0 : cAlphaFields(2)));
2306 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2307 0 : simulation_control.autosize_ducts = false;
2308 : }
2309 1 : simulation_control.ductSizing.factor = Numbers(1);
2310 1 : simulation_control.ductSizing.max_velocity = Numbers(2);
2311 1 : simulation_control.ductSizing.supply_trunk_pressure_loss = Numbers(3);
2312 1 : simulation_control.ductSizing.supply_branch_pressure_loss = Numbers(4);
2313 1 : simulation_control.ductSizing.return_trunk_pressure_loss = Numbers(5);
2314 1 : simulation_control.ductSizing.return_branch_pressure_loss = Numbers(6);
2315 : }
2316 :
2317 : // *** Read AirflowNetwork simulation zone data
2318 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:Zone";
2319 34 : AirflowNetworkNumOfZones = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2320 34 : if (AirflowNetworkNumOfZones > 0) {
2321 34 : MultizoneZoneData.allocate(AirflowNetworkNumOfZones);
2322 34 : AirflowNetworkZoneFlag.dimension(m_state.dataGlobal->NumOfZones, false); // AirflowNetwork zone flag
2323 146 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
2324 112 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2325 : CurrentModuleObject,
2326 : i,
2327 : Alphas,
2328 : NumAlphas,
2329 : Numbers,
2330 : NumNumbers,
2331 : IOStatus,
2332 : lNumericBlanks,
2333 : lAlphaBlanks,
2334 : cAlphaFields,
2335 : cNumericFields);
2336 112 : UtilityRoutines::IsNameEmpty(m_state, Alphas(1), CurrentModuleObject, ErrorsFound);
2337 112 : MultizoneZoneData(i).ZoneName = Alphas(1); // Name of Associated EnergyPlus Thermal Zone
2338 112 : if (!lAlphaBlanks(2)) MultizoneZoneData(i).VentControl = Alphas(2); // Ventilation Control Mode: "Temperature", "Enthalpy",
2339 : // "ASHRAE55ADAPTIVE", "CEN15251AdaptiveComfort,
2340 : // "Constant", or "NoVent"
2341 112 : MultizoneZoneData(i).VentSchName = Alphas(3); // Name of ventilation temperature control schedule
2342 112 : MultizoneZoneData(i).OpenFactor = Numbers(1); // Limit Value on Multiplier for Modulating Venting Open Factor,
2343 : // Not applicable if Vent Control Mode = CONSTANT or NOVENT
2344 112 : MultizoneZoneData(i).LowValueTemp = Numbers(2); // Lower Value on Inside/Outside Temperature Difference
2345 : // for Modulating the Venting Open Factor with temp control
2346 112 : MultizoneZoneData(i).UpValueTemp = Numbers(3); // Upper Value on Inside/Outside Temperature Difference
2347 : // for Modulating the Venting Open Factor with temp control
2348 112 : MultizoneZoneData(i).LowValueEnth = Numbers(4); // Lower Value on Inside/Outside Temperature Difference
2349 : // for Modulating the Venting Open Factor with Enthalpy control
2350 112 : MultizoneZoneData(i).UpValueEnth = Numbers(5); // Upper Value on Inside/Outside Temperature Difference
2351 : // for Modulating the Venting Open Factor with Enthalpy control
2352 112 : MultizoneZoneData(i).VentCtrNum = VentControlType::None;
2353 112 : MultizoneZoneData(i).SingleSidedCpType = Alphas(5);
2354 112 : MultizoneZoneData(i).BuildWidth = Numbers(6);
2355 :
2356 112 : if (!lAlphaBlanks(6)) {
2357 1 : MultizoneZoneData(i).OccupantVentilationControlName = Alphas(6);
2358 1 : MultizoneZoneData(i).OccupantVentilationControlNum =
2359 1 : UtilityRoutines::FindItemInList(MultizoneZoneData(i).OccupantVentilationControlName, OccupantVentilationControl);
2360 1 : if (MultizoneZoneData(i).OccupantVentilationControlNum == 0) {
2361 0 : ShowSevereError(m_state,
2362 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) +
2363 0 : " not found = " + MultizoneZoneData(i).OccupantVentilationControlName);
2364 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
2365 0 : ErrorsFound = true;
2366 : }
2367 : }
2368 112 : if (UtilityRoutines::SameString(MultizoneZoneData(i).VentControl, "Temperature"))
2369 55 : MultizoneZoneData(i).VentCtrNum = VentControlType::Temp;
2370 112 : if (UtilityRoutines::SameString(MultizoneZoneData(i).VentControl, "Enthalpy"))
2371 0 : MultizoneZoneData(i).VentCtrNum = VentControlType::Enth;
2372 112 : if (UtilityRoutines::SameString(MultizoneZoneData(i).VentControl, "Constant"))
2373 9 : MultizoneZoneData(i).VentCtrNum = VentControlType::Const;
2374 112 : if (UtilityRoutines::SameString(MultizoneZoneData(i).VentControl, "ASHRAE55Adaptive"))
2375 1 : MultizoneZoneData(i).VentCtrNum = VentControlType::ASH55;
2376 112 : if (UtilityRoutines::SameString(MultizoneZoneData(i).VentControl, "CEN15251Adaptive"))
2377 0 : MultizoneZoneData(i).VentCtrNum = VentControlType::CEN15251;
2378 112 : if (UtilityRoutines::SameString(MultizoneZoneData(i).VentControl, "NoVent"))
2379 47 : MultizoneZoneData(i).VentCtrNum = VentControlType::NoVent;
2380 :
2381 112 : if (MultizoneZoneData(i).VentCtrNum < NumOfVentCtrTypes) {
2382 65 : if (NumAlphas >= 4 && (!lAlphaBlanks(4))) {
2383 30 : MultizoneZoneData(i).VentingSchName = Alphas(4);
2384 30 : MultizoneZoneData(i).VentingSchNum = GetScheduleIndex(m_state, MultizoneZoneData(i).VentingSchName);
2385 30 : if (MultizoneZoneData(i).VentingSchNum == 0) {
2386 0 : ShowSevereError(m_state,
2387 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(4) +
2388 0 : " not found = " + MultizoneZoneData(i).VentingSchName);
2389 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
2390 0 : ErrorsFound = true;
2391 : }
2392 : }
2393 : } else {
2394 47 : MultizoneZoneData(i).VentingSchName = std::string();
2395 47 : MultizoneZoneData(i).VentingSchNum = 0;
2396 : }
2397 : }
2398 : } else {
2399 0 : ShowSevereError(m_state,
2400 0 : format(RoutineName) + "For an AirflowNetwork Simulation, at least one " + CurrentModuleObject +
2401 : " object is required but none were found.");
2402 0 : ShowFatalError(
2403 0 : m_state, format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
2404 : }
2405 :
2406 : // ==> Zone data validation
2407 146 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
2408 : // Zone name validation
2409 112 : MultizoneZoneData(i).ZoneNum = UtilityRoutines::FindItemInList(MultizoneZoneData(i).ZoneName, Zone);
2410 112 : if (MultizoneZoneData(i).ZoneNum == 0) {
2411 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(1) + " given.");
2412 0 : ShowContinueError(m_state, "..invalid " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\"");
2413 0 : ErrorsFound = true;
2414 : } else {
2415 112 : AirflowNetworkZoneFlag(MultizoneZoneData(i).ZoneNum) = true;
2416 112 : MultizoneZoneData(i).Height = Zone(MultizoneZoneData(i).ZoneNum).Centroid.z; // Nodal height
2417 : }
2418 112 : if (MultizoneZoneData(i).VentCtrNum == VentControlType::None) {
2419 0 : ShowSevereError(m_state,
2420 0 : format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(2) + " = " +
2421 0 : MultizoneZoneData(i).VentControl);
2422 0 : ShowContinueError(m_state, "Valid choices are Temperature, Enthalpy, Constant, or NoVent");
2423 0 : ShowContinueError(m_state, ".. in " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\"");
2424 0 : ErrorsFound = true;
2425 : }
2426 281 : if (UtilityRoutines::SameString(MultizoneZoneData(i).VentControl, "Temperature") ||
2427 169 : UtilityRoutines::SameString(MultizoneZoneData(i).VentControl, "Enthalpy")) {
2428 : // .or. &
2429 : // UtilityRoutines::SameString(MultizoneZoneData(i)%VentControl,'ASHRAE55Adaptive') .or. &
2430 : // UtilityRoutines::SameString(MultizoneZoneData(i)%VentControl,'CEN15251Adaptive')) then
2431 55 : MultizoneZoneData(i).VentSchNum = GetScheduleIndex(m_state, MultizoneZoneData(i).VentSchName);
2432 55 : if (MultizoneZoneData(i).VentSchName == std::string()) {
2433 0 : ShowSevereError(m_state,
2434 0 : format(RoutineName) + CurrentModuleObject + " object, No " + cAlphaFields(3) +
2435 0 : " was found, but is required when " + cAlphaFields(2) + " is Temperature or Enthalpy.");
2436 0 : ShowContinueError(m_state,
2437 0 : "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\", with " + cAlphaFields(2) + " = \"" +
2438 0 : MultizoneZoneData(i).VentControl + "\"");
2439 0 : ErrorsFound = true;
2440 55 : } else if (MultizoneZoneData(i).VentSchNum == 0) {
2441 0 : ShowSevereError(m_state,
2442 0 : format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(3) + ", required when " +
2443 0 : cAlphaFields(2) + " is Temperature or Enthalpy.");
2444 0 : ShowContinueError(m_state, ".." + cAlphaFields(3) + " in error = " + MultizoneZoneData(i).VentSchName);
2445 0 : ShowContinueError(m_state,
2446 0 : "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\", with " + cAlphaFields(2) + " = \"" +
2447 0 : MultizoneZoneData(i).VentControl + "\"");
2448 0 : ErrorsFound = true;
2449 : }
2450 : } else {
2451 57 : MultizoneZoneData(i).VentSchNum = GetScheduleIndex(m_state, MultizoneZoneData(i).VentSchName);
2452 57 : if (MultizoneZoneData(i).VentSchNum > 0) {
2453 6 : ShowWarningError(m_state,
2454 4 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) + " not required, when " +
2455 6 : cAlphaFields(2) + " is neither Temperature nor Enthalpy.");
2456 2 : ShowContinueError(m_state, ".." + cAlphaFields(3) + " specified = " + MultizoneZoneData(i).VentSchName);
2457 6 : ShowContinueError(m_state,
2458 4 : "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\", with " + cAlphaFields(2) + " = \"" +
2459 6 : MultizoneZoneData(i).VentControl + "\"");
2460 2 : MultizoneZoneData(i).VentSchNum = 0;
2461 2 : MultizoneZoneData(i).VentSchName = std::string();
2462 : }
2463 : }
2464 112 : if (MultizoneZoneData(i).OpenFactor > 1.0 || MultizoneZoneData(i).OpenFactor < 0.0) {
2465 : // Code will never be executed, validation will catch invalid input
2466 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(1) + " is out of range [0.0,1.0]");
2467 0 : ShowContinueError(m_state, format("..Input value = {:.2R}, Value will be set to 1.0", MultizoneZoneData(i).OpenFactor));
2468 0 : MultizoneZoneData(i).OpenFactor = 1.0;
2469 : }
2470 :
2471 : {
2472 : // These SELECT_CASE_vars will go on input refactor, no need to fix
2473 224 : auto const SELECT_CASE_var(UtilityRoutines::MakeUPPERCase(MultizoneZoneData(i).VentControl));
2474 112 : if (SELECT_CASE_var == "TEMPERATURE") { // checks on Temperature control
2475 55 : if (MultizoneZoneData(i).LowValueTemp < 0.0) {
2476 : // Code will never be executed, validation will catch invalid input
2477 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " < 0.0");
2478 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be set to 0.0", MultizoneZoneData(i).LowValueTemp));
2479 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2480 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
2481 : }
2482 55 : if (MultizoneZoneData(i).LowValueTemp >= 100.0) {
2483 : // Code will never be executed, validation will catch invalid input
2484 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " >= 100.0");
2485 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneZoneData(i).LowValueTemp));
2486 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2487 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
2488 : }
2489 55 : if (MultizoneZoneData(i).UpValueTemp <= MultizoneZoneData(i).LowValueTemp) {
2490 0 : ShowWarningError(m_state,
2491 0 : format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(3) + " <= " + cNumericFields(2));
2492 0 : ShowContinueError(m_state,
2493 0 : format("..Input value for {} = {:.1R}, Value will be reset to 100.0",
2494 : cNumericFields(3),
2495 0 : MultizoneZoneData(i).UpValueTemp));
2496 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2497 0 : MultizoneZoneData(i).UpValueTemp = 100.0;
2498 : }
2499 :
2500 57 : } else if (SELECT_CASE_var == "ENTHALPY") { // checks for Enthalpy control
2501 0 : if (MultizoneZoneData(i).LowValueEnth < 0.0) {
2502 : // Code will never be executed, validation will catch invalid input
2503 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " < 0.0");
2504 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneZoneData(i).LowValueEnth));
2505 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2506 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
2507 : }
2508 0 : if (MultizoneZoneData(i).LowValueEnth >= 300000.0) {
2509 : // Code will never be executed, validation will catch invalid input
2510 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " >= 300000.0");
2511 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0.", MultizoneZoneData(i).LowValueEnth));
2512 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2513 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
2514 : }
2515 0 : if (MultizoneZoneData(i).UpValueEnth <= MultizoneZoneData(i).LowValueEnth) {
2516 0 : ShowWarningError(m_state,
2517 0 : format("{}{} object, {} <= {}", RoutineName, CurrentModuleObject, cNumericFields(5), cNumericFields(4)));
2518 0 : ShowContinueError(m_state,
2519 0 : format("..Input value for {}= {:.1R}, Value will be reset to 300000.0",
2520 : cNumericFields(5),
2521 0 : MultizoneZoneData(i).UpValueEnth));
2522 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2523 0 : MultizoneZoneData(i).UpValueEnth = 300000.0;
2524 : }
2525 57 : } else if (SELECT_CASE_var == "ASHRAE55ADAPTIVE") {
2526 : // Check that for the given zone, there is a people object for which ASHRAE 55 calculations are carried out
2527 1 : ZoneNum = MultizoneZoneData(i).ZoneNum;
2528 2 : for (j = 1; j <= m_state.dataHeatBal->TotPeople; ++j) {
2529 1 : if (ZoneNum == m_state.dataHeatBal->People(j).ZonePtr && m_state.dataHeatBal->People(j).AdaptiveASH55) {
2530 1 : MultizoneZoneData(i).ASH55PeopleInd = j;
2531 : }
2532 : }
2533 1 : if (MultizoneZoneData(i).ASH55PeopleInd == 0) {
2534 0 : ShowFatalError(m_state,
2535 0 : "ASHRAE55 ventilation control for zone " + MultizoneZoneData(i).ZoneName +
2536 : " requires a people object with respective model calculations.");
2537 : }
2538 56 : } else if (SELECT_CASE_var == "CEN15251ADAPTIVE") {
2539 : // Check that for the given zone, there is a people object for which CEN-15251 calculations are carried out
2540 0 : ZoneNum = MultizoneZoneData(i).ZoneNum;
2541 0 : for (j = 1; j <= m_state.dataHeatBal->TotPeople; ++j) {
2542 0 : if (ZoneNum == m_state.dataHeatBal->People(j).ZonePtr && m_state.dataHeatBal->People(j).AdaptiveCEN15251) {
2543 0 : MultizoneZoneData(i).CEN15251PeopleInd = j;
2544 0 : break;
2545 : }
2546 : }
2547 0 : if (MultizoneZoneData(i).CEN15251PeopleInd == 0) {
2548 0 : ShowFatalError(m_state,
2549 0 : "CEN15251 ventilation control for zone " + MultizoneZoneData(i).ZoneName +
2550 : " requires a people object with respective model calculations.");
2551 : }
2552 : } else {
2553 : }
2554 : }
2555 : }
2556 :
2557 : // *** Read AirflowNetwork external node
2558 34 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
2559 : // Wind coefficient == Surface-Average does not need inputs of external nodes
2560 27 : AirflowNetworkNumOfExtNode =
2561 54 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:ExternalNode");
2562 27 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel) {
2563 1 : AirflowNetworkNumOfOutAirNode = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "OutdoorAir:Node");
2564 1 : AirflowNetworkNumOfExtNode += AirflowNetworkNumOfOutAirNode;
2565 : }
2566 :
2567 27 : if (AirflowNetworkNumOfExtNode > 0) {
2568 27 : MultizoneExternalNodeData.allocate(AirflowNetworkNumOfExtNode);
2569 27 : CurrentModuleObject = "AirflowNetwork:MultiZone:ExternalNode";
2570 142 : for (int i = 1; i <= AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode; ++i) {
2571 115 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2572 : CurrentModuleObject,
2573 : i,
2574 : Alphas,
2575 : NumAlphas,
2576 : Numbers,
2577 : NumNumbers,
2578 : IOStatus,
2579 : lNumericBlanks,
2580 : lAlphaBlanks,
2581 : cAlphaFields,
2582 : cNumericFields);
2583 115 : UtilityRoutines::IsNameEmpty(m_state, Alphas(1), CurrentModuleObject, ErrorsFound);
2584 115 : MultizoneExternalNodeData(i).Name = Alphas(1); // Name of external node
2585 115 : MultizoneExternalNodeData(i).height = Numbers(1); // Nodal height
2586 115 : if (UtilityRoutines::SameString(simulation_control.HeightOption, "ExternalNode") && lNumericBlanks(1)) {
2587 0 : ShowWarningError(m_state,
2588 0 : format(RoutineName) + CurrentModuleObject + " object =" + Alphas(1) + ". The input of " + cNumericFields(1) +
2589 : " is required, but a blank is found.");
2590 0 : ShowContinueError(m_state, format("The default value is assigned as {:.1R}", Numbers(1)));
2591 : }
2592 115 : MultizoneExternalNodeData(i).ExtNum = AirflowNetworkNumOfZones + i; // External node number
2593 115 : MultizoneExternalNodeData(i).curve = Curve::GetCurveIndex(m_state, Alphas(2)); // Wind pressure curve
2594 115 : if (MultizoneExternalNodeData(i).curve == 0) {
2595 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(2) + "=" + Alphas(2));
2596 0 : ShowContinueError(m_state, "Entered in " + CurrentModuleObject + '=' + Alphas(1));
2597 0 : ErrorsFound = true;
2598 : }
2599 115 : if (NumAlphas >= 3 && !lAlphaBlanks(3)) { // Symmetric curve
2600 0 : if (UtilityRoutines::SameString(Alphas(3), "Yes")) {
2601 0 : MultizoneExternalNodeData(i).symmetricCurve = true;
2602 0 : } else if (!UtilityRoutines::SameString(Alphas(3), "No")) {
2603 0 : ShowWarningError(
2604 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(3) + " = " + Alphas(3));
2605 0 : ShowContinueError(m_state, "The default value is assigned as No.");
2606 : }
2607 : }
2608 115 : if (NumAlphas == 4 && !lAlphaBlanks(4)) { // Relative or absolute wind angle
2609 0 : if (UtilityRoutines::SameString(Alphas(4), "Relative")) {
2610 0 : MultizoneExternalNodeData(i).useRelativeAngle = true;
2611 0 : } else if (!UtilityRoutines::SameString(Alphas(4), "Absolute")) {
2612 : // Code will never be executed, validation will catch invalid input
2613 0 : ShowWarningError(
2614 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(4) + " = " + Alphas(4));
2615 0 : ShowContinueError(m_state, "The default value is assigned as Absolute.");
2616 : }
2617 : }
2618 : }
2619 27 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel) {
2620 :
2621 1 : CurrentModuleObject = "OutdoorAir:Node";
2622 2 : for (int i = AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode + 1; i <= AirflowNetworkNumOfExtNode; ++i) {
2623 2 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2624 : CurrentModuleObject,
2625 1 : i - (AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode),
2626 : Alphas,
2627 : NumAlphas,
2628 : Numbers,
2629 : NumNumbers,
2630 : IOStatus,
2631 : lNumericBlanks,
2632 : lAlphaBlanks,
2633 : cAlphaFields,
2634 : cNumericFields);
2635 1 : UtilityRoutines::IsNameEmpty(m_state, Alphas(1), CurrentModuleObject, ErrorsFound);
2636 : // HACK: Need to verify name is unique between "OutdoorAir:Node" and "AirflowNetwork:MultiZone:ExternalNode"
2637 :
2638 1 : if (NumAlphas > 5 && !lAlphaBlanks(6)) { // Wind pressure curve
2639 1 : MultizoneExternalNodeData(i).curve = GetCurveIndex(m_state, Alphas(6));
2640 1 : if (MultizoneExternalNodeData(i).curve == 0) {
2641 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(6) + "=" + Alphas(6));
2642 0 : ShowContinueError(m_state, "Entered in " + CurrentModuleObject + '=' + Alphas(1));
2643 0 : ErrorsFound = true;
2644 : }
2645 : }
2646 :
2647 1 : if (NumAlphas > 6 && !lAlphaBlanks(7)) { // Symmetric curve
2648 1 : if (UtilityRoutines::SameString(Alphas(7), "Yes")) {
2649 0 : MultizoneExternalNodeData(i).symmetricCurve = true;
2650 1 : } else if (!UtilityRoutines::SameString(Alphas(7), "No")) {
2651 0 : ShowWarningError(m_state,
2652 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(7) + " = " +
2653 0 : Alphas(7));
2654 0 : ShowContinueError(m_state, "The default value is assigned as No.");
2655 : }
2656 : }
2657 :
2658 1 : if (NumAlphas > 7 && !lAlphaBlanks(8)) { // Relative or absolute wind angle
2659 1 : if (UtilityRoutines::SameString(Alphas(8), "Relative")) {
2660 0 : MultizoneExternalNodeData(i).useRelativeAngle = true;
2661 1 : } else if (!UtilityRoutines::SameString(Alphas(8), "Absolute")) {
2662 0 : ShowWarningError(m_state,
2663 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(8) + " = " +
2664 0 : Alphas(8));
2665 0 : ShowContinueError(m_state, "The default value is assigned as Absolute.");
2666 : }
2667 : }
2668 :
2669 1 : MultizoneExternalNodeData(i).Name = Alphas(1); // Name of external node
2670 2 : NodeNum = GetOnlySingleNode(m_state,
2671 1 : Alphas(1),
2672 : ErrorsFound,
2673 : DataLoopNode::ConnectionObjectType::OutdoorAirNode,
2674 : "AirflowNetwork:Multizone:Surface",
2675 : DataLoopNode::NodeFluidType::Air,
2676 : DataLoopNode::ConnectionType::Inlet,
2677 : NodeInputManager::CompFluidStream::Primary,
2678 1 : ObjectIsParent);
2679 1 : MultizoneExternalNodeData(i).OutAirNodeNum = NodeNum; // Name of outdoor air node
2680 1 : MultizoneExternalNodeData(i).height = Node(NodeNum).Height; // Nodal height
2681 1 : MultizoneExternalNodeData(i).ExtNum = AirflowNetworkNumOfZones + i; // External node number
2682 : }
2683 : }
2684 : } else {
2685 0 : ShowSevereError(m_state,
2686 0 : format(RoutineName) + "An " + CurrentModuleObject +
2687 : " object is required but not found when Wind Pressure Coefficient Type = Input.");
2688 0 : ErrorsFound = true;
2689 : }
2690 : }
2691 :
2692 : // *** Read AirflowNetwork element data
2693 34 : ErrorsFound = ErrorsFound || !get_element_input();
2694 :
2695 : // *** Read AirflowNetwork simulation surface data
2696 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
2697 34 : AirflowNetworkNumOfSurfaces = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2698 34 : if (AirflowNetworkNumOfSurfaces > 0) {
2699 34 : MultizoneSurfaceData.allocate(AirflowNetworkNumOfSurfaces);
2700 507 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
2701 473 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2702 : CurrentModuleObject,
2703 : i,
2704 : Alphas,
2705 : NumAlphas,
2706 : Numbers,
2707 : NumNumbers,
2708 : IOStatus,
2709 : lNumericBlanks,
2710 : lAlphaBlanks,
2711 : cAlphaFields,
2712 : cNumericFields);
2713 473 : UtilityRoutines::IsNameEmpty(m_state, Alphas(1), CurrentModuleObject, ErrorsFound);
2714 473 : MultizoneSurfaceData(i).SurfName = Alphas(1); // Name of Associated EnergyPlus surface
2715 473 : MultizoneSurfaceData(i).OpeningName = Alphas(2); // Name of crack or opening component,
2716 : // either simple or detailed large opening, or crack
2717 473 : MultizoneSurfaceData(i).ExternalNodeName = Alphas(3); // Name of external node, but not used at WPC="INPUT"
2718 720 : if (UtilityRoutines::FindItemInList(Alphas(3), MultizoneExternalNodeData) &&
2719 247 : m_state.afn->MultizoneExternalNodeData(UtilityRoutines::FindItemInList(Alphas(3), MultizoneExternalNodeData)).curve == 0) {
2720 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(3) + "=" + Alphas(3));
2721 0 : ShowContinueError(m_state,
2722 : "A valid wind pressure coefficient curve name is required but not found when Wind Pressure "
2723 : "Coefficient Type = Input.");
2724 0 : ErrorsFound = true;
2725 : }
2726 473 : MultizoneSurfaceData(i).Factor = Numbers(1); // Crack Actual Value or Window Open Factor for Ventilation
2727 473 : if (MultizoneSurfaceData(i).Factor > 1.0 || MultizoneSurfaceData(i).Factor <= 0.0) {
2728 0 : ShowWarningError(m_state,
2729 0 : format(RoutineName) + CurrentModuleObject + " object=" + MultizoneSurfaceData(i).SurfName + ", " +
2730 0 : cNumericFields(1) + " is out of range (0.0,1.0]");
2731 0 : ShowContinueError(m_state, format("..Input value = {:.2R}, Value will be set to 1.0", MultizoneSurfaceData(i).Factor));
2732 0 : MultizoneSurfaceData(i).Factor = 1.0;
2733 : }
2734 : // Get input of ventilation control and associated data
2735 473 : if (NumAlphas >= 4) {
2736 : // Ventilation Control Mode: "TEMPERATURE", "ENTHALPY",
2737 : // "CONSTANT", "ZONELEVEL", "NOVENT", "ADJACENTTEMPERATURE",
2738 : // or "ADJACENTENTHALPY"
2739 36 : if (!lAlphaBlanks(4)) MultizoneSurfaceData(i).VentControl = Alphas(4);
2740 : // Name of ventilation temperature control schedule
2741 36 : if (!lAlphaBlanks(5)) MultizoneSurfaceData(i).VentSchName = Alphas(5);
2742 : {
2743 : // This SELECT_CASE_var will go on input refactor, no need to fix
2744 72 : auto const SELECT_CASE_var(UtilityRoutines::MakeUPPERCase(MultizoneSurfaceData(i).VentControl));
2745 36 : if (SELECT_CASE_var == "TEMPERATURE") {
2746 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Temp;
2747 0 : MultizoneSurfaceData(i).IndVentControl = true;
2748 36 : } else if (SELECT_CASE_var == "ENTHALPY") {
2749 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Enth;
2750 0 : MultizoneSurfaceData(i).IndVentControl = true;
2751 36 : } else if (SELECT_CASE_var == "CONSTANT") {
2752 11 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Const;
2753 11 : MultizoneSurfaceData(i).IndVentControl = true;
2754 25 : } else if (SELECT_CASE_var == "ASHRAE55ADAPTIVE") {
2755 3 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::ASH55;
2756 3 : MultizoneSurfaceData(i).IndVentControl = true;
2757 22 : } else if (SELECT_CASE_var == "CEN15251ADAPTIVE") {
2758 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::CEN15251;
2759 0 : MultizoneSurfaceData(i).IndVentControl = true;
2760 22 : } else if (SELECT_CASE_var == "NOVENT") {
2761 18 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::NoVent;
2762 18 : MultizoneSurfaceData(i).IndVentControl = true;
2763 4 : } else if (SELECT_CASE_var == "ZONELEVEL") {
2764 4 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::ZoneLevel;
2765 4 : MultizoneSurfaceData(i).IndVentControl = false;
2766 0 : } else if (SELECT_CASE_var == "ADJACENTTEMPERATURE") {
2767 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::AdjTemp;
2768 0 : MultizoneSurfaceData(i).IndVentControl = true;
2769 0 : } else if (SELECT_CASE_var == "ADJACENTENTHALPY") {
2770 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::AdjEnth;
2771 0 : MultizoneSurfaceData(i).IndVentControl = true;
2772 : } else {
2773 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(4));
2774 0 : ShowContinueError(m_state,
2775 0 : ".." + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName + ", Specified " + cAlphaFields(4) +
2776 0 : " = " + Alphas(4));
2777 0 : ShowContinueError(m_state,
2778 : "..The valid choices are \"Temperature\", \"Enthalpy\", \"Constant\", \"NoVent\", \"ZoneLevel\", "
2779 : "\"AdjancentTemperature\" or \"AdjacentEnthalpy\"");
2780 0 : ErrorsFound = true;
2781 : }
2782 : }
2783 : }
2784 473 : MultizoneSurfaceData(i).ModulateFactor = Numbers(2); // Limit Value on Multiplier for Modulating Venting Open Factor
2785 473 : MultizoneSurfaceData(i).LowValueTemp = Numbers(3); // Lower temperature value for modulation of temperature control
2786 473 : MultizoneSurfaceData(i).UpValueTemp = Numbers(4); // Upper temperature value for modulation of temperature control
2787 473 : MultizoneSurfaceData(i).LowValueEnth = Numbers(5); // Lower Enthalpy value for modulation of Enthalpy control
2788 473 : MultizoneSurfaceData(i).UpValueEnth = Numbers(6); // Lower Enthalpy value for modulation of Enthalpy control
2789 498 : if (MultizoneSurfaceData(i).VentSurfCtrNum < 4 || MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjTemp ||
2790 25 : MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjEnth) {
2791 448 : if (!lAlphaBlanks(6)) {
2792 8 : MultizoneSurfaceData(i).VentingSchName = Alphas(6); // Name of ventilation availability schedule
2793 : }
2794 : }
2795 473 : if (!lAlphaBlanks(7)) {
2796 0 : MultizoneSurfaceData(i).OccupantVentilationControlName = Alphas(7);
2797 0 : MultizoneSurfaceData(i).OccupantVentilationControlNum =
2798 0 : UtilityRoutines::FindItemInList(MultizoneSurfaceData(i).OccupantVentilationControlName, OccupantVentilationControl);
2799 0 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) {
2800 0 : ShowSevereError(m_state,
2801 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(7) +
2802 0 : " not found = " + MultizoneSurfaceData(i).OccupantVentilationControlName);
2803 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
2804 0 : ErrorsFound = true;
2805 : }
2806 : }
2807 : // Get data of polygonal surface
2808 473 : if (!lAlphaBlanks(8)) {
2809 0 : if (Alphas(8) == "POLYGONHEIGHT") {
2810 0 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::Height;
2811 0 : } else if (Alphas(8) == "BASESURFACEASPECTRATIO") {
2812 0 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::BaseAspectRatio;
2813 0 : } else if (Alphas(8) == "USERDEFINEDASPECTRATIO") {
2814 0 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::UserAspectRatio;
2815 : } else {
2816 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(8));
2817 0 : ShowContinueError(m_state,
2818 0 : ".." + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName + ", Specified " + cAlphaFields(8) +
2819 0 : " = " + Alphas(8));
2820 0 : ShowContinueError(m_state,
2821 : "..The valid choices are \"PolygonHeight\", \"BaseSurfaceAspectRatio\", or \"UserDefinedAspectRatio\"");
2822 0 : ErrorsFound = true;
2823 : }
2824 : } else {
2825 473 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::Height;
2826 : }
2827 473 : if (!lNumericBlanks(7)) {
2828 0 : MultizoneSurfaceData(i).EquivRecUserAspectRatio = Numbers(7);
2829 : } else {
2830 473 : MultizoneSurfaceData(i).EquivRecUserAspectRatio = 1.0;
2831 : }
2832 : }
2833 : } else {
2834 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
2835 0 : ErrorsFound = true;
2836 : }
2837 :
2838 : // remove extra OutdoorAir:Node, not assigned to External Node Name
2839 34 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel && AirflowNetworkNumOfOutAirNode > 0) {
2840 2 : for (int i = AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode + 1; i <= AirflowNetworkNumOfExtNode; ++i) {
2841 1 : found = false;
2842 7 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
2843 6 : if (UtilityRoutines::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
2844 1 : found = true;
2845 : }
2846 : }
2847 1 : if (!found) {
2848 0 : if (i < AirflowNetworkNumOfExtNode) {
2849 0 : for (k = i; k <= AirflowNetworkNumOfExtNode - 1; ++k) {
2850 0 : MultizoneExternalNodeData(k).Name = MultizoneExternalNodeData(k + 1).Name;
2851 0 : MultizoneExternalNodeData(k).OutAirNodeNum = MultizoneExternalNodeData(k + 1).OutAirNodeNum;
2852 0 : MultizoneExternalNodeData(k).height = MultizoneExternalNodeData(k + 1).height;
2853 0 : MultizoneExternalNodeData(k).ExtNum = MultizoneExternalNodeData(k + 1).ExtNum - 1;
2854 : }
2855 0 : i -= 1;
2856 : }
2857 0 : AirflowNetworkNumOfOutAirNode -= 1;
2858 0 : AirflowNetworkNumOfExtNode -= 1;
2859 0 : MultizoneExternalNodeData.resize(AirflowNetworkNumOfExtNode);
2860 : }
2861 : }
2862 : }
2863 :
2864 : // ==> Validate AirflowNetwork simulation surface data
2865 34 : NumOfExtNodes = 0;
2866 507 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
2867 : // Check a valid surface defined earlier
2868 473 : MultizoneSurfaceData(i).SurfNum = UtilityRoutines::FindItemInList(MultizoneSurfaceData(i).SurfName, m_state.dataSurface->Surface);
2869 473 : if (MultizoneSurfaceData(i).SurfNum == 0) {
2870 0 : ShowSevereError(m_state,
2871 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(1) +
2872 0 : " given = " + MultizoneSurfaceData(i).SurfName);
2873 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
2874 : }
2875 473 : if (!m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).HeatTransSurf &&
2876 0 : !m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) {
2877 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2878 0 : ShowContinueError(m_state,
2879 0 : "..The surface specified must be a heat transfer surface. Invalid " + cAlphaFields(1) + " = " +
2880 0 : MultizoneSurfaceData(i).SurfName);
2881 0 : ErrorsFound = true;
2882 0 : continue;
2883 : }
2884 : // Ensure an interior surface does not face itself
2885 473 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1) {
2886 : // Check the surface is a subsurface or not
2887 161 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf == MultizoneSurfaceData(i).SurfNum) {
2888 134 : if (MultizoneSurfaceData(i).SurfNum == m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond) {
2889 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2890 0 : ShowContinueError(m_state,
2891 0 : "..The surface facing itself is not allowed. Invalid " + cAlphaFields(1) + " = " +
2892 0 : MultizoneSurfaceData(i).SurfName);
2893 0 : ErrorsFound = true;
2894 : }
2895 : } else {
2896 54 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf ==
2897 27 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).ExtBoundCond) {
2898 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2899 0 : ShowContinueError(m_state,
2900 0 : "..The base surface facing itself is not allowed. Invalid " + cAlphaFields(1) + " = " +
2901 0 : MultizoneSurfaceData(i).SurfName);
2902 0 : ErrorsFound = true;
2903 : }
2904 : }
2905 : }
2906 : // Ensure zones defined in inside and outside environment are used in the object of AIRFLOWNETWORK:MULTIZONE:ZONE
2907 473 : found = false;
2908 473 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone;
2909 1024 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
2910 1024 : if (MultizoneZoneData(j).ZoneNum == n) {
2911 473 : found = true;
2912 473 : break;
2913 : }
2914 : }
2915 : // find a surface geometry
2916 473 : MultizoneSurfaceData(i).Height = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Height;
2917 473 : MultizoneSurfaceData(i).Width = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Width;
2918 473 : MultizoneSurfaceData(i).CHeight = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Centroid.z;
2919 473 : if (found) {
2920 473 : MultizoneSurfaceData(i).NodeNums[0] = j;
2921 : } else {
2922 0 : ShowSevereError(m_state,
2923 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName);
2924 0 : ShowContinueError(m_state,
2925 0 : "..Zone for inside surface must be defined in a AirflowNetwork:MultiZone:Zone object. Could not find Zone = " +
2926 0 : Zone(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone).Name);
2927 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
2928 : }
2929 :
2930 : // Calculate equivalent width and height
2931 473 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides != 4) {
2932 8 : MultizoneSurfaceData(i).NonRectangular = true;
2933 8 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::Height) {
2934 16 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Tilt < 1.0 ||
2935 8 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Tilt > 179.0) { // horizontal surface
2936 : // check base surface shape
2937 0 : if (m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Sides == 4) {
2938 0 : baseratio = m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Width /
2939 0 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Height;
2940 0 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * baseratio);
2941 0 : MultizoneSurfaceData(i).Height =
2942 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2943 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2944 0 : ShowWarningError(m_state,
2945 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2946 0 : ShowContinueError(m_state,
2947 : "The entered choice of Equivalent Rectangle Method is PolygonHeight. This choice is not valid for "
2948 : "a horizontal surface.");
2949 0 : ShowContinueError(m_state, "The BaseSurfaceAspectRatio choice is used. Simulation continues.");
2950 : }
2951 : } else {
2952 0 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area *
2953 0 : MultizoneSurfaceData(i).EquivRecUserAspectRatio);
2954 0 : MultizoneSurfaceData(i).Height =
2955 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2956 : // add warning
2957 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2958 0 : ShowWarningError(m_state,
2959 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2960 0 : ShowContinueError(m_state,
2961 : "The entered choice of Equivalent Rectangle Method is PolygonHeight. This choice is not valid for "
2962 : "a horizontal surface with a polygonal base surface.");
2963 0 : ShowContinueError(m_state, "The default aspect ratio at 1 is used. Simulation continues.");
2964 : }
2965 : }
2966 : } else {
2967 8 : minHeight = min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2968 8 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2969 8 : maxHeight = max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2970 8 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2971 16 : for (j = 3; j <= m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides; ++j) {
2972 16 : minHeight = min(minHeight,
2973 8 : min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2974 8 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2975 16 : maxHeight = max(maxHeight,
2976 8 : max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2977 8 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2978 : }
2979 8 : if (maxHeight > minHeight) {
2980 8 : MultizoneSurfaceData(i).Height = maxHeight - minHeight;
2981 8 : MultizoneSurfaceData(i).Width =
2982 8 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / (maxHeight - minHeight);
2983 : }
2984 : }
2985 : }
2986 8 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::BaseAspectRatio) {
2987 0 : if (m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Sides == 4) {
2988 0 : baseratio = m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Width /
2989 0 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Height;
2990 0 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * baseratio);
2991 0 : MultizoneSurfaceData(i).Height =
2992 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2993 : } else {
2994 0 : minHeight = min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2995 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2996 0 : maxHeight = max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2997 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2998 0 : for (j = 3; j <= m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides; ++j) {
2999 0 : minHeight = min(minHeight,
3000 0 : min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
3001 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
3002 0 : maxHeight = max(maxHeight,
3003 0 : max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
3004 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
3005 : }
3006 0 : if (maxHeight > minHeight) {
3007 0 : MultizoneSurfaceData(i).Height = maxHeight - minHeight;
3008 0 : MultizoneSurfaceData(i).Width =
3009 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / (maxHeight - minHeight);
3010 : // add warning
3011 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3012 0 : ShowWarningError(m_state,
3013 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
3014 0 : ShowContinueError(m_state,
3015 : "The entered choice of Equivalent Rectangle Method is BaseSurfaceAspectRatio. This choice is not "
3016 : "valid for a polygonal base surface.");
3017 0 : ShowContinueError(m_state, "The PolygonHeight choice is used. Simulation continues.");
3018 : }
3019 : } else {
3020 0 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area *
3021 0 : MultizoneSurfaceData(i).EquivRecUserAspectRatio);
3022 0 : MultizoneSurfaceData(i).Height =
3023 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
3024 : // add warning
3025 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3026 0 : ShowWarningError(m_state,
3027 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
3028 0 : ShowContinueError(m_state,
3029 : "The entered choice of Equivalent Rectangle Method is BaseSurfaceAspectRatio. This choice is not "
3030 : "valid for a horizontal surface with a polygonal base surface.");
3031 0 : ShowContinueError(m_state, "The default aspect ratio at 1 is used. Simulation continues.");
3032 : }
3033 : }
3034 : }
3035 : }
3036 8 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::UserAspectRatio) {
3037 0 : MultizoneSurfaceData(i).Width =
3038 0 : sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * MultizoneSurfaceData(i).EquivRecUserAspectRatio);
3039 0 : MultizoneSurfaceData(i).Height =
3040 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
3041 : }
3042 : }
3043 :
3044 : // Get the number of external surfaces
3045 946 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == ExternalEnvironment ||
3046 161 : (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3047 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3048 312 : ++AirflowNetworkNumOfExtSurfaces;
3049 : }
3050 :
3051 : // Outside face environment
3052 473 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
3053 393 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond;
3054 1033 : if (n == ExternalEnvironment ||
3055 146 : (n == OtherSideCoefNoCalcExt && m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3056 247 : ++NumOfExtNodes;
3057 247 : if (AirflowNetworkNumOfExtNode > 0) {
3058 247 : found = false;
3059 720 : for (j = 1; j <= AirflowNetworkNumOfExtNode; ++j) {
3060 720 : if (UtilityRoutines::SameString(MultizoneSurfaceData(i).ExternalNodeName, MultizoneExternalNodeData(j).Name)) {
3061 247 : MultizoneSurfaceData(i).NodeNums[1] = MultizoneExternalNodeData(j).ExtNum;
3062 247 : found = true;
3063 247 : break;
3064 : }
3065 : }
3066 247 : if (!found) {
3067 0 : ShowSevereError(m_state,
3068 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(3) + " = " +
3069 0 : MultizoneSurfaceData(i).ExternalNodeName);
3070 0 : ShowContinueError(m_state, "A valid " + cAlphaFields(3) + " is required when Wind Pressure Coefficient Type = Input");
3071 0 : ErrorsFound = true;
3072 : }
3073 : } else {
3074 : // MultizoneSurfaceData(i)%NodeNums[1] =
3075 : // AirflowNetworkNumOfZones+NumOfExtNodes
3076 : }
3077 247 : continue;
3078 : } else {
3079 146 : if (n < ExternalEnvironment &&
3080 0 : !(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3081 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3082 0 : ShowSevereError(m_state,
3083 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(1) + " = " +
3084 0 : MultizoneSurfaceData(i).SurfName);
3085 0 : ShowContinueError(m_state, "This type of surface (has ground, etc exposure) cannot be used in the AiflowNetwork model.");
3086 0 : ErrorsFound = true;
3087 : }
3088 : }
3089 146 : found = false;
3090 458 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
3091 458 : if (MultizoneZoneData(j).ZoneNum == m_state.dataSurface->Surface(n).Zone) {
3092 146 : found = true;
3093 146 : break;
3094 : }
3095 : }
3096 146 : if (found) {
3097 146 : MultizoneSurfaceData(i).NodeNums[1] = j;
3098 : } else {
3099 0 : ShowSevereError(m_state,
3100 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3101 0 : MultizoneSurfaceData(i).SurfName);
3102 0 : ShowContinueError(
3103 : m_state,
3104 0 : "..Zone for outside surface must be defined in a AirflowNetwork:MultiZone:Zone object. Could not find Zone = " +
3105 0 : Zone(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone).Name);
3106 0 : ErrorsFound = true;
3107 0 : continue;
3108 : }
3109 : }
3110 226 : if (UtilityRoutines::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
3111 80 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond;
3112 80 : if (n >= 1) { // exterior boundary condition is a surface
3113 15 : found = false;
3114 43 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
3115 43 : if (MultizoneZoneData(j).ZoneNum == m_state.dataSurface->Surface(n).Zone) {
3116 15 : found = true;
3117 15 : break;
3118 : }
3119 : }
3120 15 : if (found) {
3121 15 : MultizoneSurfaceData(i).NodeNums[1] = j;
3122 : } else {
3123 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " = " + MultizoneSurfaceData(i).SurfName);
3124 0 : ShowContinueError(m_state,
3125 0 : "An adjacent zone = " + Zone(m_state.dataSurface->Surface(n).Zone).Name +
3126 : " is not described in AIRFLOWNETWORK:MULTIZONE:ZONE");
3127 0 : ErrorsFound = true;
3128 0 : continue;
3129 : }
3130 : }
3131 : }
3132 226 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == -2 &&
3133 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3134 226 : if (MultizoneSurfaceData(i).NodeNums[1] == 0 && m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond < 0) {
3135 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " = " + MultizoneSurfaceData(i).SurfName);
3136 0 : ShowContinueError(m_state,
3137 0 : "Outside boundary condition and object are " +
3138 0 : cExtBoundCondition(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond) + " and " +
3139 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCondName + ".");
3140 0 : ShowContinueError(m_state, "The outside boundary condition must be exposed to either the outside or an adjacent zone.");
3141 0 : ErrorsFound = true;
3142 0 : continue;
3143 : }
3144 : }
3145 : }
3146 :
3147 : // write outputs in eio file
3148 34 : found = true;
3149 507 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3150 473 : if (MultizoneSurfaceData(i).NonRectangular) {
3151 8 : if (found) {
3152 4 : print(m_state.files.eio,
3153 : "! <AirflowNetwork Model:Equivalent Rectangle Surface>, Name, Equivalent Height {{m}}, Equivalent Width {{m}} "
3154 : "AirflowNetwork "
3155 4 : "Model:Equivalent Rectangle\n");
3156 4 : found = false;
3157 : }
3158 32 : print(m_state.files.eio,
3159 : "AirflowNetwork Model:Equivalent Rectangle Surface, {}, {:.2R},{:.2R}\n",
3160 8 : MultizoneSurfaceData(i).SurfName,
3161 8 : MultizoneSurfaceData(i).Height,
3162 16 : MultizoneSurfaceData(i).Width);
3163 : }
3164 : }
3165 :
3166 : // Validate adjacent temperature and Enthalpy control for an interior surface only
3167 507 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3168 473 : if (MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjTemp) {
3169 0 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1)) {
3170 0 : ShowSevereError(m_state,
3171 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3172 0 : MultizoneSurfaceData(i).SurfName);
3173 0 : ShowContinueError(m_state, "..AdjacentTemperature venting control must be defined for an interzone surface.");
3174 0 : ErrorsFound = true;
3175 : }
3176 : }
3177 473 : if (MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjEnth) {
3178 0 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1)) {
3179 0 : ShowSevereError(m_state,
3180 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3181 0 : MultizoneSurfaceData(i).SurfName);
3182 0 : ShowContinueError(m_state, "..AdjacentEnthalpy venting control must be defined for an interzone surface.");
3183 0 : ErrorsFound = true;
3184 : }
3185 : }
3186 : }
3187 :
3188 : // Ensure the number of external node = the number of external surface with HeightOption choice = OpeningHeight
3189 34 : if (UtilityRoutines::SameString(simulation_control.HeightOption, "OpeningHeight") && simulation_control.iWPCCnt == iWPCCntr::Input) {
3190 0 : if (AirflowNetworkNumOfExtSurfaces != AirflowNetworkNumOfExtNode) {
3191 0 : ShowSevereError(m_state,
3192 0 : format(RoutineName) +
3193 : "When the choice of Height Selection for Local Wind Speed Calculation is OpeningHeight, the number of external "
3194 0 : "surfaces defined in " +
3195 0 : CurrentModuleObject + " objects ");
3196 0 : ShowContinueError(m_state, "has to be equal to the number of AirflowNetwork:MultiZone:ExternalNode objects.");
3197 0 : ShowContinueError(m_state,
3198 0 : format("The entered number of external nodes is {}. The entered number of external surfaces is {}.",
3199 : AirflowNetworkNumOfExtNode,
3200 0 : AirflowNetworkNumOfExtSurfaces));
3201 0 : ErrorsFound = true;
3202 : }
3203 : }
3204 :
3205 : // Read AirflowNetwork simulation detailed openings
3206 : // Moved into getAirflowElementInput
3207 :
3208 : // Validate opening component and assign opening dimension
3209 34 : if (AirflowNetworkNumOfDetOpenings > 0) {
3210 53 : for (int i = 1; i <= AirflowNetworkNumOfDetOpenings; ++i) {
3211 31 : found = false;
3212 505 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3213 474 : if (MultizoneCompDetOpeningData(i).name == MultizoneSurfaceData(j).OpeningName) {
3214 : // MultizoneCompDetOpeningData(i)%Width =
3215 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Width
3216 : // MultizoneCompDetOpeningData(i)%Height =
3217 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Height
3218 70 : found = true;
3219 : }
3220 : }
3221 : }
3222 : }
3223 :
3224 : // Read AirflowNetwork simulation simple openings
3225 : // Moved into getAirflowElementInput
3226 :
3227 : // Read AirflowNetwork simulation horizontal openings
3228 : // Moved into getAirflowElementInput
3229 :
3230 : // Check status of control level for each surface with an opening
3231 34 : j = 0;
3232 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
3233 507 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3234 473 : if (MultizoneSurfaceData(i).SurfNum == 0) continue;
3235 473 : bool has_Opening{false};
3236 : // This is terrible, should not do it this way
3237 946 : auto afe = elements.find(MultizoneSurfaceData(i).OpeningName);
3238 473 : if (afe != elements.end()) {
3239 473 : auto type = afe->second->type();
3240 473 : has_Opening = (type == ComponentType::DOP) || (type == ComponentType::SOP) || (type == ComponentType::HOP);
3241 : }
3242 : // Obtain schedule number and check surface shape
3243 473 : if (has_Opening) {
3244 88 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides == 3) {
3245 2 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName + "\".");
3246 2 : ShowContinueError(m_state,
3247 : "The opening is a Triangular subsurface. A rectangular subsurface will be used with equivalent "
3248 : "width and height.");
3249 : }
3250 : // Venting controls are not allowed for an air boundary surface
3251 88 : if ((m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) &&
3252 0 : (MultizoneSurfaceData(i).VentSurfCtrNum != VentControlType::Const)) {
3253 0 : ShowWarningError(m_state,
3254 0 : format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName +
3255 : "\" is an air boundary surface.");
3256 0 : ShowContinueError(m_state, "Ventilation Control Mode = " + Alphas(4) + " is not valid. Resetting to Constant.");
3257 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Const;
3258 0 : MultizoneSurfaceData(i).IndVentControl = true;
3259 : }
3260 88 : if (!MultizoneSurfaceData(i).VentingSchName.empty()) {
3261 0 : MultizoneSurfaceData(i).VentingSchNum = GetScheduleIndex(m_state, MultizoneSurfaceData(i).VentingSchName);
3262 0 : if (MultizoneSurfaceData(i).VentingSchNum == 0) {
3263 0 : ShowSevereError(
3264 0 : m_state, format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName + "\", invalid schedule.");
3265 0 : ShowContinueError(m_state, "Venting Schedule not found=\"" + MultizoneSurfaceData(i).VentingSchName + "\".");
3266 0 : ErrorsFound = true;
3267 0 : } else if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) {
3268 0 : ShowWarningError(m_state,
3269 0 : format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName +
3270 : "\" is an air boundary surface.");
3271 0 : ShowContinueError(m_state, "Venting Availability Schedule will be ignored, venting is always available.");
3272 0 : MultizoneSurfaceData(i).VentingSchName = "";
3273 0 : MultizoneSurfaceData(i).VentingSchNum = 0;
3274 : }
3275 : } else {
3276 88 : MultizoneSurfaceData(i).VentingSchName = "";
3277 88 : MultizoneSurfaceData(i).VentingSchNum = 0;
3278 : }
3279 88 : switch (MultizoneSurfaceData(i).VentSurfCtrNum) {
3280 0 : case VentControlType::Temp:
3281 : case VentControlType::AdjTemp: {
3282 0 : MultizoneSurfaceData(i).VentSchNum = GetScheduleIndex(m_state, MultizoneSurfaceData(i).VentSchName);
3283 0 : if (MultizoneSurfaceData(i).VentSchName == std::string()) {
3284 0 : ShowSevereError(m_state,
3285 0 : format(RoutineName) + CurrentModuleObject +
3286 : " object, No Ventilation Schedule was found, but is required when ventilation control is "
3287 : "Temperature.");
3288 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3289 0 : ErrorsFound = true;
3290 0 : } else if (MultizoneSurfaceData(i).VentSchNum == 0) {
3291 0 : ShowSevereError(m_state,
3292 0 : format(RoutineName) + CurrentModuleObject +
3293 : " object, Invalid Ventilation Schedule, required when ventilation control is Temperature.");
3294 0 : ShowContinueError(m_state, "..Schedule name in error = " + MultizoneSurfaceData(i).VentSchName);
3295 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3296 0 : ErrorsFound = true;
3297 : }
3298 0 : if (MultizoneSurfaceData(i).LowValueTemp < 0.0) {
3299 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Temperature difference value < 0.0d0");
3300 0 : ShowContinueError(m_state, format("..Input value={:.1R}, Value will be reset to 0.0.", MultizoneSurfaceData(i).LowValueTemp));
3301 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3302 0 : MultizoneSurfaceData(i).LowValueTemp = 0.0;
3303 : }
3304 0 : if (MultizoneSurfaceData(i).LowValueTemp >= 100.0) {
3305 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Temperature difference value >= 100.0d0");
3306 0 : ShowContinueError(m_state,
3307 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueTemp));
3308 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3309 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
3310 : }
3311 0 : if (MultizoneSurfaceData(i).UpValueTemp <= MultizoneSurfaceData(i).LowValueTemp) {
3312 0 : ShowWarningError(
3313 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Upper Temperature <= Lower Temperature difference value.");
3314 0 : ShowContinueError(m_state,
3315 0 : format("..Input value = {:.1R}, Value will be reset to 100.0", MultizoneSurfaceData(i).UpValueTemp));
3316 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3317 0 : MultizoneSurfaceData(i).UpValueTemp = 100.0;
3318 : }
3319 :
3320 0 : } break;
3321 0 : case VentControlType::Enth:
3322 : case VentControlType::AdjEnth: {
3323 0 : MultizoneSurfaceData(i).VentSchNum = GetScheduleIndex(m_state, MultizoneSurfaceData(i).VentSchName);
3324 0 : if (MultizoneSurfaceData(i).VentSchName == std::string()) {
3325 0 : ShowSevereError(m_state,
3326 0 : format(RoutineName) + CurrentModuleObject +
3327 : " object, No Ventilation Schedule was found, but is required when ventilation control is Enthalpy.");
3328 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3329 0 : ErrorsFound = true;
3330 0 : } else if (MultizoneSurfaceData(i).VentSchNum == 0) {
3331 0 : ShowSevereError(m_state,
3332 0 : format(RoutineName) + CurrentModuleObject +
3333 : " object, Invalid Ventilation Schedule, required when ventilation control is Enthalpy.");
3334 0 : ShowContinueError(m_state, "..Schedule name in error = " + MultizoneSurfaceData(i).VentSchName);
3335 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3336 0 : ErrorsFound = true;
3337 : }
3338 0 : if (MultizoneSurfaceData(i).LowValueEnth < 0.0) {
3339 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Enthalpy difference value < 0.0d0");
3340 0 : ShowContinueError(m_state,
3341 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueEnth));
3342 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3343 0 : MultizoneSurfaceData(i).LowValueEnth = 0.0;
3344 : }
3345 0 : if (MultizoneSurfaceData(i).LowValueEnth >= 300000.0) {
3346 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Enthalpy difference value >= 300000.0");
3347 0 : ShowContinueError(m_state,
3348 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueEnth));
3349 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3350 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
3351 : }
3352 0 : if (MultizoneSurfaceData(i).UpValueEnth <= MultizoneSurfaceData(i).LowValueEnth) {
3353 0 : ShowWarningError(m_state,
3354 0 : format(RoutineName) + CurrentModuleObject + " object, Upper Enthalpy <= Lower Enthalpy difference value.");
3355 0 : ShowContinueError(m_state,
3356 0 : format("..Input value = {:.1R}, Value will be set to 300000.0", MultizoneSurfaceData(i).UpValueEnth));
3357 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3358 0 : MultizoneSurfaceData(i).UpValueEnth = 300000.0;
3359 : }
3360 :
3361 0 : } break;
3362 7 : case VentControlType::Const:
3363 : case VentControlType::ASH55:
3364 : case VentControlType::CEN15251:
3365 : case VentControlType::NoVent:
3366 : case VentControlType::ZoneLevel: {
3367 7 : MultizoneSurfaceData(i).VentSchNum = 0;
3368 7 : MultizoneSurfaceData(i).VentSchName = "";
3369 7 : } break;
3370 81 : default:
3371 81 : break;
3372 : }
3373 : }
3374 : }
3375 :
3376 : // Validate opening component and assign opening dimension
3377 34 : if (AirflowNetworkNumOfSimOpenings > 0) {
3378 24 : for (int i = 1; i <= AirflowNetworkNumOfSimOpenings; ++i) {
3379 12 : found = false;
3380 254 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3381 242 : if (MultizoneCompSimpleOpeningData(i).name == MultizoneSurfaceData(j).OpeningName) {
3382 : // MultizoneCompSimpleOpeningData(i)%Width =
3383 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Width
3384 : // MultizoneCompSimpleOpeningData(i)%Height =
3385 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Height
3386 17 : found = true;
3387 : }
3388 : }
3389 : }
3390 : }
3391 :
3392 : // Calculate CP values
3393 34 : if (UtilityRoutines::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
3394 7 : calculate_Cps();
3395 : // Ensure automatic generation is OK
3396 7 : n = 0;
3397 42 : for (j = 1; j <= 5; ++j) {
3398 35 : found = false;
3399 167 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3400 162 : if (MultizoneExternalNodeData(i).facadeNum == j) {
3401 30 : found = true;
3402 30 : break;
3403 : }
3404 : }
3405 35 : if (found) ++n;
3406 35 : if (j == 5 && (!found)) {
3407 3 : found = true;
3408 3 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3409 0 : ShowWarningError(m_state,
3410 0 : format(RoutineName) +
3411 : "SurfaceAverageCalculation is entered for field = Wind Pressure Coefficient Type, but no roof "
3412 : "surface is defined using an AirflowNetwork:MultiZone:Surface object.");
3413 0 : ShowContinueError(m_state, "Reconsider if this is your modeling intent. Simulation continues.");
3414 : }
3415 : }
3416 : }
3417 7 : if (n < 5 && m_state.dataGlobal->DisplayExtraWarnings) {
3418 0 : ShowWarningError(m_state, format(RoutineName) + "SurfaceAverageCalculation is entered for field = Wind Pressure Coefficient Type.");
3419 0 : ShowContinueError(m_state,
3420 : "The AirflowNetwork model provides wind pressure coefficients for 4 vertical exterior orientations and "
3421 : "1 horizontal roof.");
3422 0 : ShowContinueError(m_state,
3423 0 : format(" There are only {} exterior surface orientations defined in this input file using "
3424 : "AirflowNetwork:MultiZone:Surface objects.",
3425 0 : n));
3426 0 : ShowContinueError(m_state, "Reconsider if this is your modeling intent. Simulation continues.");
3427 : }
3428 : }
3429 :
3430 : // Assign external node height
3431 95 : if (UtilityRoutines::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation") ||
3432 61 : UtilityRoutines::SameString(simulation_control.HeightOption, "OpeningHeight")) {
3433 72 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3434 459 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3435 918 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == ExternalEnvironment ||
3436 71 : (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3437 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtWind)) {
3438 388 : if (UtilityRoutines::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
3439 65 : MultizoneExternalNodeData(i).height = m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Centroid.z;
3440 65 : break;
3441 : }
3442 : }
3443 : }
3444 : }
3445 : }
3446 :
3447 : // Assign external node azimuth, should consider combining this with the above to avoid the repeated search
3448 215 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3449 1253 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3450 2492 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == ExternalEnvironment ||
3451 371 : (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3452 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtWind)) {
3453 875 : if (UtilityRoutines::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
3454 174 : MultizoneExternalNodeData(i).azimuth = m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Azimuth;
3455 174 : break;
3456 : }
3457 : }
3458 : }
3459 : }
3460 :
3461 34 : if (ErrorsFound) {
3462 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3463 : }
3464 :
3465 : // Write wind pressure coefficients in the EIO file
3466 34 : print(m_state.files.eio, "! <AirflowNetwork Model:Wind Direction>, Wind Direction #1 to n (degree)\n");
3467 34 : print(m_state.files.eio, "AirflowNetwork Model:Wind Direction, ");
3468 :
3469 34 : int numWinDirs = 11;
3470 34 : Real64 angleDelta = 30.0;
3471 34 : if (AirflowNetworkNumOfSingleSideZones > 0) {
3472 1 : numWinDirs = 35;
3473 1 : angleDelta = 10.0;
3474 : }
3475 :
3476 432 : for (int i = 0; i < numWinDirs; ++i) {
3477 398 : print(m_state.files.eio, "{:.1R},", i * angleDelta);
3478 : }
3479 34 : print(m_state.files.eio, "{:.1R}\n", numWinDirs * angleDelta);
3480 :
3481 34 : print(m_state.files.eio, "! <AirflowNetwork Model:Wind Pressure Coefficients>, Name, Wind Pressure Coefficients #1 to n (dimensionless)\n");
3482 :
3483 : // The old version used to write info with single-sided natural ventilation specific labeling, this version no longer does that.
3484 68 : std::set<int> curves;
3485 215 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3486 181 : curves.insert(MultizoneExternalNodeData(i).curve);
3487 : }
3488 183 : for (auto index : curves) {
3489 149 : print(m_state.files.eio, "AirflowNetwork Model:Wind Pressure Coefficients, {}, ", Curve::GetCurveName(m_state, index));
3490 :
3491 2028 : for (j = 0; j < numWinDirs; ++j) {
3492 1879 : print(m_state.files.eio, "{:.2R},", Curve::CurveValue(m_state, index, j * angleDelta));
3493 : }
3494 149 : print(m_state.files.eio, "{:.2R}\n", Curve::CurveValue(m_state, index, numWinDirs * angleDelta));
3495 : }
3496 :
3497 34 : if (AirflowNetworkNumOfSingleSideZones > 0) {
3498 5 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3499 4 : if (MultizoneZoneData(i).SingleSidedCpType == "ADVANCED") {
3500 3 : print(m_state.files.eio,
3501 3 : "AirflowNetwork: Advanced Single-Sided Model: Difference in Opening Wind Pressure Coefficients (DeltaCP), ");
3502 3 : print(m_state.files.eio, "{}, ", MultizoneZoneData(i).ZoneName);
3503 108 : for (unsigned j = 1; j <= EPDeltaCP(i).WindDir.size() - 1; ++j) {
3504 105 : print(m_state.files.eio, "{:.2R},", EPDeltaCP(i).WindDir(j));
3505 : }
3506 3 : print(m_state.files.eio, "{:.2R}\n", EPDeltaCP(i).WindDir(static_cast<int>(EPDeltaCP(i).WindDir.size())));
3507 : }
3508 : }
3509 : }
3510 :
3511 : // If no zone object, exit
3512 34 : if (AirflowNetworkNumOfZones == 0) {
3513 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3514 : }
3515 : // If zone node number =0, exit.
3516 507 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3517 473 : if (MultizoneSurfaceData(j).NodeNums[0] == 0 && ErrorsFound) {
3518 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3519 : }
3520 473 : if (MultizoneSurfaceData(j).NodeNums[1] == 0 && ErrorsFound) {
3521 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3522 : }
3523 : }
3524 :
3525 : // Ensure at least two surfaces are exposed to a zone
3526 34 : ZoneCheck.allocate(AirflowNetworkNumOfZones);
3527 34 : ZoneBCCheck.allocate(AirflowNetworkNumOfZones);
3528 34 : ZoneCheck = 0;
3529 34 : ZoneBCCheck = 0;
3530 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
3531 507 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3532 473 : if (MultizoneSurfaceData(j).NodeNums[0] <= AirflowNetworkNumOfZones) {
3533 473 : ++ZoneCheck(MultizoneSurfaceData(j).NodeNums[0]);
3534 473 : ZoneBCCheck(MultizoneSurfaceData(j).NodeNums[0]) = MultizoneSurfaceData(j).NodeNums[1];
3535 : }
3536 473 : if (MultizoneSurfaceData(j).NodeNums[1] <= AirflowNetworkNumOfZones) {
3537 161 : ++ZoneCheck(MultizoneSurfaceData(j).NodeNums[1]);
3538 161 : ZoneBCCheck(MultizoneSurfaceData(j).NodeNums[1]) = MultizoneSurfaceData(j).NodeNums[0];
3539 : }
3540 : }
3541 146 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3542 112 : if (ZoneCheck(i) == 0) {
3543 0 : ShowSevereError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3544 0 : ShowContinueError(m_state, " does not have any surfaces defined in " + CurrentModuleObject);
3545 0 : ShowContinueError(m_state, "Each zone should have at least two surfaces defined in " + CurrentModuleObject);
3546 0 : ErrorsFound = true;
3547 : }
3548 112 : if (ZoneCheck(i) == 1) {
3549 0 : ShowSevereError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3550 0 : ShowContinueError(m_state, " has only one surface defined in " + CurrentModuleObject);
3551 0 : ShowContinueError(m_state, " Each zone should have at least two surfaces defined in " + CurrentModuleObject);
3552 0 : ErrorsFound = true;
3553 : }
3554 112 : if (ZoneCheck(i) > 1) {
3555 112 : SurfaceFound = false;
3556 494 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3557 494 : if (MultizoneSurfaceData(j).NodeNums[0] == i) {
3558 52 : if (ZoneBCCheck(i) != MultizoneSurfaceData(j).NodeNums[1]) {
3559 50 : SurfaceFound = true;
3560 50 : break;
3561 : }
3562 : }
3563 444 : if (MultizoneSurfaceData(j).NodeNums[1] == i) {
3564 62 : if (ZoneBCCheck(i) != MultizoneSurfaceData(j).NodeNums[0]) {
3565 62 : SurfaceFound = true;
3566 62 : break;
3567 : }
3568 : }
3569 : }
3570 112 : if (!SurfaceFound) {
3571 0 : ShowWarningError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3572 0 : ShowContinueError(m_state,
3573 0 : "has more than one surface defined in " + CurrentModuleObject + ", but has the same boundary conditions");
3574 0 : ShowContinueError(m_state, "Please check inputs of " + CurrentModuleObject);
3575 : }
3576 : }
3577 : }
3578 34 : ZoneCheck.deallocate();
3579 34 : ZoneBCCheck.deallocate();
3580 :
3581 : // Validate CP Value number
3582 34 : if (simulation_control.iWPCCnt == iWPCCntr::Input) { // Surface-Average does not need inputs of external nodes
3583 : // Ensure different curve is used to avoid a single side boundary condition
3584 27 : found = false;
3585 27 : bool differentAngle = false;
3586 27 : for (j = 2; j <= AirflowNetworkNumOfExtNode; ++j) {
3587 27 : if (MultizoneExternalNodeData(j - 1).curve != MultizoneExternalNodeData(j).curve) {
3588 27 : found = true;
3589 27 : break;
3590 : } else {
3591 : // If the curves are the same, then check to see if the azimuths are different
3592 0 : if (MultizoneExternalNodeData(j - 1).azimuth != MultizoneExternalNodeData(j).azimuth) {
3593 0 : differentAngle = MultizoneExternalNodeData(j - 1).symmetricCurve || MultizoneExternalNodeData(j).symmetricCurve;
3594 : }
3595 : }
3596 : }
3597 27 : if (!found && !differentAngle) {
3598 0 : ShowSevereError(m_state,
3599 : "The same Wind Pressure Coefficient Curve name is used in all AirflowNetwork:MultiZone:ExternalNode objects.");
3600 0 : ShowContinueError(
3601 : m_state, "Please input at least two different Wind Pressure Coefficient Curve names to avoid single side boundary condition.");
3602 0 : ErrorsFound = true;
3603 : }
3604 : }
3605 :
3606 : // Assign occupant ventilation control number from zone to surface
3607 507 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3608 473 : j = MultizoneSurfaceData(i).SurfNum;
3609 1352 : if (m_state.dataSurface->SurfWinOriginalClass(j) == SurfaceClass::Window ||
3610 852 : m_state.dataSurface->SurfWinOriginalClass(j) == SurfaceClass::Door ||
3611 379 : m_state.dataSurface->SurfWinOriginalClass(j) == SurfaceClass::GlassDoor) {
3612 453 : for (n = 1; n <= AirflowNetworkNumOfZones; ++n) {
3613 359 : if (MultizoneZoneData(n).ZoneNum == m_state.dataSurface->Surface(j).Zone) {
3614 94 : if (MultizoneZoneData(n).OccupantVentilationControlNum > 0 && MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) {
3615 2 : MultizoneSurfaceData(i).OccupantVentilationControlNum = MultizoneZoneData(n).OccupantVentilationControlNum;
3616 : }
3617 : }
3618 : }
3619 : }
3620 : }
3621 :
3622 : // Read AirflowNetwork Intra zone node
3623 34 : CurrentModuleObject = "AirflowNetwork:IntraZone:Node";
3624 34 : IntraZoneNumOfNodes = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3625 34 : if (IntraZoneNumOfNodes > 0) {
3626 1 : IntraZoneNodeData.allocate(IntraZoneNumOfNodes);
3627 6 : for (int i = 1; i <= IntraZoneNumOfNodes; ++i) {
3628 5 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3629 : CurrentModuleObject,
3630 : i,
3631 : Alphas,
3632 : NumAlphas,
3633 : Numbers,
3634 : NumNumbers,
3635 : IOStatus,
3636 : lNumericBlanks,
3637 : lAlphaBlanks,
3638 : cAlphaFields,
3639 : cNumericFields);
3640 5 : UtilityRoutines::IsNameEmpty(m_state, Alphas(1), CurrentModuleObject, ErrorsFound);
3641 5 : IntraZoneNodeData(i).Name = Alphas(1); // Name of node
3642 5 : IntraZoneNodeData(i).RAFNNodeName = Alphas(2); // Name of RoomAir node
3643 5 : IntraZoneNodeData(i).Height = Numbers(1); // Nodal height
3644 : // verify RoomAir model node names(May be too early to check and move to another subroutine)
3645 15 : GetRAFNNodeNum(
3646 15 : m_state, IntraZoneNodeData(i).RAFNNodeName, IntraZoneNodeData(i).ZoneNum, IntraZoneNodeData(i).RAFNNodeNum, Errorfound1);
3647 5 : if (Errorfound1) ErrorsFound = true;
3648 5 : if (IntraZoneNodeData(i).RAFNNodeNum == 0) {
3649 0 : ShowSevereError(m_state,
3650 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "' invalid name " + cAlphaFields(2) + "='" +
3651 0 : Alphas(2));
3652 0 : ErrorsFound = true;
3653 : }
3654 5 : IntraZoneNodeData(i).AFNZoneNum =
3655 5 : UtilityRoutines::FindItemInList(Alphas(3), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3656 5 : if (MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).RAFNNodeNum == 0) {
3657 3 : GetRAFNNodeNum(m_state,
3658 1 : MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).ZoneName,
3659 1 : IntraZoneNodeData(i).ZoneNum,
3660 1 : MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).RAFNNodeNum,
3661 : Errorfound1);
3662 : }
3663 5 : if (IntraZoneNodeData(i).ZoneNum == 0) {
3664 0 : ShowSevereError(m_state,
3665 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "' the Zone is not defined for " +
3666 0 : cAlphaFields(3) + "='" + Alphas(3));
3667 0 : ErrorsFound = true;
3668 : }
3669 : }
3670 : }
3671 :
3672 : // check model compatibility
3673 34 : if (IntraZoneNumOfNodes > 0) {
3674 1 : if (!UtilityRoutines::SameString(SimAirNetworkKey, "MultizoneWithoutDistribution")) {
3675 0 : ShowSevereError(m_state,
3676 0 : format(RoutineName) + CurrentModuleObject +
3677 0 : " model requires Simulation Control = MultizoneWithoutDistribution, while the input choice is " +
3678 0 : SimAirNetworkKey + ".");
3679 0 : ErrorsFound = true;
3680 0 : ShowFatalError(
3681 : m_state,
3682 0 : format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
3683 : }
3684 : }
3685 :
3686 34 : NumOfNodesIntraZone = IntraZoneNumOfNodes;
3687 : // check zone node
3688 34 : IntraZoneNumOfZones = 0;
3689 146 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3690 112 : if (MultizoneZoneData(i).RAFNNodeNum > 0) {
3691 1 : IntraZoneNumOfZones += 1;
3692 : }
3693 : }
3694 :
3695 : // Override error check due to RoomAirNode for the time being
3696 :
3697 : // Read AirflowNetwork Intra linkage
3698 34 : CurrentModuleObject = "AirflowNetwork:IntraZone:Linkage";
3699 34 : IntraZoneNumOfLinks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3700 34 : if (IntraZoneNumOfLinks > 0) {
3701 1 : IntraZoneLinkageData.allocate(IntraZoneNumOfLinks);
3702 1 : UniqueAirflowNetworkSurfaceName.reserve(IntraZoneNumOfLinks);
3703 10 : for (int i = 1; i <= IntraZoneNumOfLinks; ++i) {
3704 9 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3705 : CurrentModuleObject,
3706 : i,
3707 : Alphas,
3708 : NumAlphas,
3709 : Numbers,
3710 : NumNumbers,
3711 : IOStatus,
3712 : lNumericBlanks,
3713 : lAlphaBlanks,
3714 : cAlphaFields,
3715 : cNumericFields);
3716 9 : UtilityRoutines::IsNameEmpty(m_state, Alphas(1), CurrentModuleObject, ErrorsFound);
3717 9 : IntraZoneLinkageData(i).Name = Alphas(1); // Name of linkage
3718 9 : IntraZoneLinkageData(i).NodeNames[0] = Alphas(2);
3719 9 : IntraZoneLinkageData(i).NodeHeights[0] = 0.0;
3720 9 : IntraZoneLinkageData(i).NodeNames[1] = Alphas(3);
3721 9 : IntraZoneLinkageData(i).NodeHeights[1] = 0.0;
3722 9 : IntraZoneLinkageData(i).CompName = Alphas(4);
3723 9 : if (!lAlphaBlanks(5)) {
3724 : // Perform simple test first.The comprehensive input validation will occur later
3725 : // Check valid surface name
3726 2 : IntraZoneLinkageData(i).SurfaceName = Alphas(5);
3727 4 : IntraZoneLinkageData(i).LinkNum = UtilityRoutines::FindItemInList(
3728 2 : Alphas(5), MultizoneSurfaceData, &MultizoneSurfaceProp::SurfName, AirflowNetworkNumOfSurfaces);
3729 2 : if (IntraZoneLinkageData(i).LinkNum == 0) {
3730 0 : ShowSevereError(m_state,
3731 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(5) +
3732 0 : " given = " + Alphas(5) + " in AirflowNetwork:MultiZone:Surface objects");
3733 0 : ErrorsFound = true;
3734 : }
3735 4 : GlobalNames::VerifyUniqueInterObjectName(
3736 4 : m_state, UniqueAirflowNetworkSurfaceName, Alphas(5), CurrentModuleObject, cAlphaFields(5), ErrorsFound);
3737 : }
3738 9 : if (UtilityRoutines::SameString(Alphas(2), Alphas(3))) {
3739 0 : ShowSevereError(m_state,
3740 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid inputs of both node name with " +
3741 0 : Alphas(2) + " = " + Alphas(3));
3742 0 : ErrorsFound = true;
3743 : }
3744 : // Check valid node names
3745 9 : IntraZoneLinkageData(i).NodeNums[0] = UtilityRoutines::FindItemInList(Alphas(2), IntraZoneNodeData, IntraZoneNumOfNodes);
3746 9 : if (IntraZoneLinkageData(i).NodeNums[0] == 0) {
3747 0 : IntraZoneLinkageData(i).NodeNums[0] =
3748 0 : UtilityRoutines::FindItemInList(Alphas(2), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3749 0 : IntraZoneLinkageData(i).NodeHeights[0] = Zone(MultizoneZoneData(IntraZoneLinkageData(i).NodeNums[0]).ZoneNum).Centroid.z;
3750 0 : if (IntraZoneLinkageData(i).NodeNums[0] == 0) {
3751 0 : ShowSevereError(m_state,
3752 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(2) +
3753 0 : " given = " + Alphas(2) + " in AirflowNetwork:IntraZone:Node and AirflowNetwork:MultiZone:Zone objects");
3754 0 : ErrorsFound = true;
3755 : }
3756 : } else {
3757 9 : IntraZoneLinkageData(i).NodeHeights[0] = IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0]).Height;
3758 9 : IntraZoneLinkageData(i).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0] + AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
3759 : }
3760 9 : IntraZoneLinkageData(i).NodeNums[1] = UtilityRoutines::FindItemInList(Alphas(3), IntraZoneNodeData, IntraZoneNumOfNodes);
3761 9 : if (IntraZoneLinkageData(i).NodeNums[1] == 0) {
3762 5 : IntraZoneLinkageData(i).NodeNums[1] =
3763 5 : UtilityRoutines::FindItemInList(Alphas(3), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3764 5 : if (IntraZoneLinkageData(i).NodeNums[1] > 0) {
3765 5 : IntraZoneLinkageData(i).NodeHeights[1] = Zone(MultizoneZoneData(IntraZoneLinkageData(i).NodeNums[1]).ZoneNum).Centroid.z;
3766 : } else {
3767 0 : if (simulation_control.iWPCCnt == iWPCCntr::Input) { // Surface-Average does not need inputs of external nodes
3768 0 : IntraZoneLinkageData(i).NodeNums[1] = MultizoneSurfaceData(IntraZoneLinkageData(i).LinkNum).NodeNums[1];
3769 0 : if (IntraZoneLinkageData(i).NodeNums[1] == 0) {
3770 0 : ShowSevereError(m_state,
3771 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(3) +
3772 0 : " given = " + Alphas(3) +
3773 : " in AirflowNetwork:IntraZone:Node or AirflowNetwork:MultiZone:Zone or "
3774 : "AirflowNetwork:MultiZone:ExternalNode objects");
3775 0 : ErrorsFound = true;
3776 : }
3777 : }
3778 0 : if (simulation_control.iWPCCnt == iWPCCntr::SurfAvg) {
3779 0 : if (!lAlphaBlanks(3)) {
3780 0 : ShowWarningError(m_state,
3781 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + " The input of " + cAlphaFields(3) +
3782 : " is not needed, ");
3783 0 : ShowContinueError(m_state,
3784 : " since AirflowNetwork Wind Pressure Coefficient Type = SURFACE-AVERAGE CALCULATION. The "
3785 : "simulation continues...");
3786 : }
3787 0 : IntraZoneLinkageData(i).NodeNums[1] = MultizoneSurfaceData(IntraZoneLinkageData(i).LinkNum).NodeNums[1];
3788 : }
3789 : }
3790 : } else {
3791 4 : IntraZoneLinkageData(i).NodeHeights[1] = IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1]).Height;
3792 4 : IntraZoneLinkageData(i).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1] + AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
3793 : }
3794 : // Ensure the both linked nodes for a surface are not zone nodes.One of nodes has to be an intrazone node
3795 14 : if (IntraZoneLinkageData(i).NodeNums[1] <= AirflowNetworkNumOfZones &&
3796 5 : IntraZoneLinkageData(i).NodeNums[0] <= AirflowNetworkNumOfZones) {
3797 0 : ShowSevereError(m_state,
3798 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid node inputs " + Alphas(2) + " and " +
3799 0 : Alphas(3) + " are zone nodes");
3800 0 : ErrorsFound = true;
3801 : }
3802 18 : if (IntraZoneLinkageData(i).NodeNums[0] <= AirflowNetworkNumOfZones &&
3803 9 : IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode && lAlphaBlanks(5)) {
3804 0 : if (IntraZoneLinkageData(i).NodeNums[0] !=
3805 0 : m_state.afn->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3806 0 : .AFNZoneNum) {
3807 0 : ShowSevereError(
3808 : m_state,
3809 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + ": Invalid zone inputs between Node and Link " +
3810 0 : Alphas(2) + " and " +
3811 0 : m_state.afn->MultizoneZoneData(IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0]).AFNZoneNum).ZoneName);
3812 0 : ErrorsFound = true;
3813 : }
3814 : }
3815 23 : if (IntraZoneLinkageData(i).NodeNums[1] <= AirflowNetworkNumOfZones &&
3816 14 : IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode && lAlphaBlanks(5)) {
3817 6 : if (IntraZoneLinkageData(i).NodeNums[1] !=
3818 3 : m_state.afn->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3819 3 : .AFNZoneNum) {
3820 0 : ShowSevereError(
3821 : m_state,
3822 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + ": Invalid zone inputs between Node and Link " +
3823 0 : Alphas(3) + " and " +
3824 0 : m_state.afn->MultizoneZoneData(IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1]).AFNZoneNum).ZoneName);
3825 0 : ErrorsFound = true;
3826 : }
3827 : }
3828 : }
3829 :
3830 : // Reset the number of intrazone links for a given surface
3831 1 : NumOfLinksIntraZone = IntraZoneNumOfLinks;
3832 10 : for (int i = 1; i <= IntraZoneNumOfLinks; ++i) {
3833 9 : j = IntraZoneLinkageData(i).LinkNum;
3834 9 : if (j > 0) {
3835 : // Revise data in multizone object
3836 2 : NumOfLinksIntraZone = NumOfLinksIntraZone - 1;
3837 2 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == 0) {
3838 : // Exterior surface NodeNums[1] should be equal
3839 0 : if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3840 0 : MultizoneSurfaceData(j).RAFNflag = true;
3841 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3842 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3843 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3844 0 : MultizoneSurfaceData(j).RAFNflag = true;
3845 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3846 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3847 : } else {
3848 0 : ShowSevereError(m_state,
3849 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3850 0 : IntraZoneLinkageData(i).Name +
3851 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3852 0 : ErrorsFound = true;
3853 : }
3854 : } else {
3855 : // Interior surface
3856 4 : if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode &&
3857 2 : IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3858 0 : MultizoneSurfaceData(j).RAFNflag = true;
3859 0 : if (MultizoneZoneData(MultizoneSurfaceData(j).NodeNums[0]).ZoneNum ==
3860 0 : m_state.afn
3861 0 : ->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3862 0 : .ZoneNum) {
3863 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3864 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3865 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1];
3866 : } else {
3867 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3868 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3869 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[0];
3870 : }
3871 2 : } else if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3872 2 : MultizoneSurfaceData(j).RAFNflag = true;
3873 2 : if (IntraZoneLinkageData(i).NodeNums[1] == MultizoneSurfaceData(j).NodeNums[0]) {
3874 2 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[0];
3875 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] == MultizoneSurfaceData(j).NodeNums[1]) {
3876 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3877 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3878 : } else {
3879 0 : ShowSevereError(m_state,
3880 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3881 0 : IntraZoneLinkageData(i).Name +
3882 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3883 0 : ErrorsFound = true;
3884 : }
3885 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3886 0 : MultizoneSurfaceData(j).RAFNflag = true;
3887 0 : if (IntraZoneLinkageData(i).NodeNums[0] == MultizoneSurfaceData(j).NodeNums[0]) {
3888 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1];
3889 0 : } else if (IntraZoneLinkageData(i).NodeNums[0] == MultizoneSurfaceData(j).NodeNums[1]) {
3890 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3891 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3892 : } else {
3893 0 : ShowSevereError(m_state,
3894 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3895 0 : IntraZoneLinkageData(i).Name +
3896 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3897 0 : ErrorsFound = true;
3898 : }
3899 : }
3900 : }
3901 : }
3902 : }
3903 : // Remove links with surface defined in Multizone : Surface objects
3904 1 : int link = 1;
3905 1 : if (NumOfLinksIntraZone < IntraZoneNumOfLinks) {
3906 15 : while (link <= NumOfLinksIntraZone) {
3907 7 : if (IntraZoneLinkageData(link).LinkNum > 0) {
3908 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3909 0 : ShowWarningError(m_state,
3910 0 : format(RoutineName) + CurrentModuleObject + "='" + IntraZoneLinkageData(link).Name +
3911 : " is reomoved from the list due to the surface conncetion from Intrazone to Interzone.");
3912 : }
3913 8 : for (j = link; j <= IntraZoneNumOfLinks - 1; ++j) {
3914 7 : IntraZoneLinkageData(j) = IntraZoneLinkageData(j + 1);
3915 : }
3916 : }
3917 7 : if (IntraZoneLinkageData(link).LinkNum == 0) link = link + 1;
3918 : }
3919 1 : if (IntraZoneLinkageData(link).LinkNum > 0) {
3920 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3921 0 : ShowWarningError(m_state,
3922 0 : format(RoutineName) + CurrentModuleObject + "='" + IntraZoneLinkageData(link).Name +
3923 : " is removed from the list due to the surface connection from Intrazone to Interzone.");
3924 : }
3925 : }
3926 : }
3927 : }
3928 :
3929 : // Read AirflowNetwork Distribution system node
3930 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Node";
3931 34 : DisSysNumOfNodes = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3932 34 : if (DisSysNumOfNodes > 0) {
3933 23 : DisSysNodeData.allocate(DisSysNumOfNodes);
3934 551 : for (int i = 1; i <= DisSysNumOfNodes; ++i) {
3935 528 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3936 : CurrentModuleObject,
3937 : i,
3938 : Alphas,
3939 : NumAlphas,
3940 : Numbers,
3941 : NumNumbers,
3942 : IOStatus,
3943 : lNumericBlanks,
3944 : lAlphaBlanks,
3945 : cAlphaFields,
3946 : cNumericFields);
3947 528 : UtilityRoutines::IsNameEmpty(m_state, Alphas(1), CurrentModuleObject, ErrorsFound);
3948 528 : DisSysNodeData(i).Name = Alphas(1); // Name of node
3949 528 : DisSysNodeData(i).EPlusName = Alphas(2); // Name of associated EnergyPlus node
3950 528 : DisSysNodeData(i).EPlusType = Alphas(3); // Name of associated EnergyPlus type
3951 528 : DisSysNodeData(i).Height = Numbers(1); // Nodal height
3952 528 : DisSysNodeData(i).EPlusNodeNum = 0; // EPlus node number
3953 : // verify EnergyPlus object type
3954 1560 : if (UtilityRoutines::SameString(Alphas(3), "AirLoopHVAC:ZoneMixer") ||
3955 1512 : UtilityRoutines::SameString(Alphas(3), "AirLoopHVAC:ZoneSplitter") ||
3956 1474 : UtilityRoutines::SameString(Alphas(3), "AirLoopHVAC:OutdoorAirSystem") ||
3957 1446 : UtilityRoutines::SameString(Alphas(3), "OAMixerOutdoorAirStreamNode") ||
3958 1884 : UtilityRoutines::SameString(Alphas(3), "OutdoorAir:NodeList") || UtilityRoutines::SameString(Alphas(3), "OutdoorAir:Node") ||
3959 980 : UtilityRoutines::SameString(Alphas(3), "Other") || lAlphaBlanks(3)) {
3960 : } else {
3961 0 : ShowSevereError(m_state,
3962 0 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" invalid " + cAlphaFields(3) + "=\"" +
3963 0 : Alphas(3) + "\" illegal key.");
3964 0 : ShowContinueError(m_state,
3965 : "Valid keys are: AirLoopHVAC:ZoneMixer, AirLoopHVAC:ZoneSplitter, AirLoopHVAC:OutdoorAirSystem, "
3966 : "OAMixerOutdoorAirStreamNode, OutdoorAir:NodeList, OutdoorAir:Node or Other.");
3967 0 : ErrorsFound = true;
3968 : }
3969 : // Avoid duplication of EPlusName
3970 7036 : for (j = 1; j < i; ++j) {
3971 6508 : if (!UtilityRoutines::SameString(Alphas(2), "")) {
3972 4531 : if (UtilityRoutines::SameString(DisSysNodeData(j).EPlusName, Alphas(2))) {
3973 0 : ShowSevereError(m_state,
3974 0 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" Duplicated " + cAlphaFields(2) +
3975 0 : "=\"" + Alphas(2) + "\". Please make a correction.");
3976 0 : ErrorsFound = true;
3977 : }
3978 : }
3979 : }
3980 : }
3981 : } else {
3982 11 : if (distribution_simulated) {
3983 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
3984 0 : ErrorsFound = true;
3985 : }
3986 : }
3987 :
3988 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Duct";
3989 34 : if (DisSysNumOfDucts == 0) {
3990 11 : if (distribution_simulated) {
3991 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
3992 0 : ErrorsFound = true;
3993 : }
3994 : }
3995 :
3996 : // Read AirflowNetwork distribution system component: DuctViewFactors
3997 34 : CurrentModuleObject = "AirflowNetwork:Distribution:DuctViewFactors";
3998 34 : DisSysNumOfDuctViewFactors = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3999 34 : if (DisSysNumOfDuctViewFactors > 0) {
4000 1 : AirflowNetworkLinkageViewFactorData.allocate(DisSysNumOfDuctViewFactors);
4001 2 : for (int i = 1; i <= DisSysNumOfDuctViewFactors; ++i) {
4002 1 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
4003 : CurrentModuleObject,
4004 : i,
4005 : Alphas,
4006 : NumAlphas,
4007 : Numbers,
4008 : NumNumbers,
4009 : IOStatus,
4010 : lNumericBlanks,
4011 : lAlphaBlanks,
4012 : cAlphaFields,
4013 : cNumericFields);
4014 1 : UtilityRoutines::IsNameEmpty(m_state, Alphas(1), CurrentModuleObject, ErrorsFound);
4015 :
4016 1 : auto &this_VF_object(AirflowNetworkLinkageViewFactorData(i));
4017 :
4018 1 : this_VF_object.LinkageName = Alphas(1); // Name of linkage
4019 :
4020 : // Surface exposure fraction
4021 1 : if (Numbers(2) > 1) {
4022 0 : ShowWarningError(m_state,
4023 0 : "Duct surface exposure fraction greater than 1. Check input in: " + CurrentModuleObject + " " +
4024 : this_VF_object.LinkageName);
4025 0 : ShowContinueError(m_state, "Using value of 1 for surface exposure fraction");
4026 0 : this_VF_object.DuctExposureFraction = 1;
4027 1 : } else if (Numbers(2) < 0) {
4028 0 : ShowWarningError(
4029 0 : m_state, "Surface exposure fraction less than 0. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4030 0 : ShowContinueError(m_state, "Using value of 0 for surface exposure fraction");
4031 0 : this_VF_object.DuctExposureFraction = 0;
4032 : } else {
4033 1 : this_VF_object.DuctExposureFraction = Numbers(1);
4034 : }
4035 :
4036 : // Duct surface emittance
4037 1 : if (Numbers(2) > 1) {
4038 0 : ShowWarningError(
4039 0 : m_state, "Duct surface emittance greater than 1. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4040 0 : ShowContinueError(m_state, "Using value of 1 for surface emittance");
4041 0 : this_VF_object.DuctEmittance = 1;
4042 1 : } else if (Numbers(2) < 0) {
4043 0 : ShowWarningError(
4044 0 : m_state, "Surface exposure fraction less than 0. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4045 0 : ShowContinueError(m_state, "Using value of 0 for surface exposure fraction");
4046 0 : this_VF_object.DuctEmittance = 0;
4047 : } else {
4048 1 : this_VF_object.DuctEmittance = Numbers(2);
4049 : }
4050 :
4051 1 : this_VF_object.ObjectNum = i;
4052 :
4053 1 : int numSurfaces = NumAlphas - 1;
4054 :
4055 1 : this_VF_object.LinkageSurfaceData.allocate(numSurfaces);
4056 :
4057 6 : for (int surfNum = 1; surfNum < NumAlphas; ++surfNum) {
4058 5 : this_VF_object.LinkageSurfaceData(surfNum).SurfaceName = Alphas(surfNum + 1); // Surface name
4059 5 : this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum =
4060 5 : UtilityRoutines::FindItemInList(Alphas(surfNum + 1), m_state.dataSurface->Surface);
4061 :
4062 5 : if (this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum == 0) {
4063 0 : ShowFatalError(
4064 0 : m_state, "Surface " + Alphas(surfNum + 1) + " not found. See: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4065 : }
4066 :
4067 : // Surface view factor
4068 5 : if (!m_state.dataSurface->Surface(this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum).HeatTransSurf) {
4069 0 : ShowWarningError(m_state,
4070 0 : "Surface=" + Alphas(surfNum + 1) + " is not a heat transfer surface. Check input in: " +
4071 0 : CurrentModuleObject + " " + this_VF_object.LinkageName);
4072 0 : ShowContinueError(m_state, "Using value of 0 for view factor");
4073 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 0;
4074 5 : } else if (Numbers(surfNum + 2) > 1) {
4075 0 : ShowWarningError(m_state,
4076 0 : "View factor for surface " + Alphas(surfNum + 1) +
4077 0 : " greater than 1. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4078 0 : ShowContinueError(m_state, "Using value of 1 for view factor");
4079 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 1;
4080 5 : } else if (Numbers(surfNum + 2) < 0) {
4081 0 : ShowWarningError(m_state,
4082 0 : "View factor for surface " + Alphas(surfNum + 1) + " less than 0. Check input in: " + CurrentModuleObject +
4083 0 : " " + this_VF_object.LinkageName);
4084 0 : ShowContinueError(m_state, "Using value of 0 for view factor");
4085 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 0;
4086 : } else {
4087 5 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = Numbers(surfNum + 2);
4088 : }
4089 : }
4090 : }
4091 : }
4092 :
4093 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Fan";
4094 34 : if (DisSysNumOfCVFs == 0) {
4095 11 : if (distribution_simulated) {
4096 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
4097 0 : ErrorsFound = true;
4098 : }
4099 : }
4100 :
4101 : // Read PressureController
4102 34 : CurrentModuleObject = "AirflowNetwork:ZoneControl:PressureController";
4103 34 : NumOfPressureControllers = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
4104 34 : if (NumOfPressureControllers > 1) {
4105 0 : ShowSevereError(m_state,
4106 0 : format(RoutineName) + "More " + CurrentModuleObject + " are found. Currently only one( \"1\") " + CurrentModuleObject +
4107 : " object per simulation is allowed when using AirflowNetwork Distribution Systems.");
4108 0 : ShowFatalError(
4109 0 : m_state, format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
4110 : }
4111 :
4112 34 : if (NumOfPressureControllers > 0) {
4113 1 : PressureControllerData.allocate(NumOfPressureControllers);
4114 2 : for (int i = 1; i <= NumOfPressureControllers; ++i) {
4115 1 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
4116 : CurrentModuleObject,
4117 : i,
4118 : Alphas,
4119 : NumAlphas,
4120 : Numbers,
4121 : NumNumbers,
4122 : IOStatus,
4123 : lNumericBlanks,
4124 : lAlphaBlanks,
4125 : cAlphaFields,
4126 : cNumericFields);
4127 1 : UtilityRoutines::IsNameEmpty(m_state, Alphas(1), CurrentModuleObject, ErrorsFound);
4128 1 : PressureControllerData(i).Name = Alphas(1); // Object Name
4129 1 : PressureControllerData(i).ZoneName = Alphas(2); // Zone name
4130 1 : PressureControllerData(i).ZoneNum = UtilityRoutines::FindItemInList(Alphas(2), Zone);
4131 1 : PressureControllerData(i).AFNNodeNum =
4132 1 : UtilityRoutines::FindItemInList(Alphas(2), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
4133 1 : if (PressureControllerData(i).ZoneNum == 0) {
4134 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(2) + " given.");
4135 0 : ShowContinueError(m_state, "..invalid " + cAlphaFields(2) + " = \"" + PressureControllerData(i).ZoneName + "\"");
4136 0 : ErrorsFound = true;
4137 : }
4138 :
4139 1 : PressureControllerData(i).ControlObjectType = Alphas(3); // Control Object Type
4140 1 : PressureControllerData(i).ControlObjectName = Alphas(4); // Control Object Name
4141 :
4142 : {
4143 : // This SELECT_CASE_var will go on input refactor, no need to fix
4144 2 : auto const SELECT_CASE_var(UtilityRoutines::MakeUPPERCase(Alphas(3)));
4145 1 : if (SELECT_CASE_var == "AIRFLOWNETWORK:MULTIZONE:COMPONENT:ZONEEXHAUSTFAN") {
4146 0 : PressureControllerData(i).ControlTypeSet = PressureCtrlExhaust;
4147 1 : } else if (SELECT_CASE_var == "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT:RELIEFAIRFLOW") {
4148 1 : PressureControllerData(i).ControlTypeSet = PressureCtrlRelief;
4149 : } else { // Error
4150 0 : ShowSevereError(m_state,
4151 0 : format(RoutineName) + CurrentModuleObject + " object, The entered choice for " + cAlphaFields(3) +
4152 0 : " is not valid = \"" + PressureControllerData(i).Name + "\"");
4153 0 : ShowContinueError(m_state,
4154 : "Valid choices are "
4155 : "\"AirflowNetwork:MultiZone:Component:ZoneExhaustFan\",\"AirflowNetwork:Distribution:Component:"
4156 : "ReliefAirFlow\"");
4157 0 : ShowContinueError(m_state, "The input choice is " + Alphas(3));
4158 0 : ErrorsFound = true;
4159 : }
4160 : }
4161 :
4162 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlExhaust) {
4163 : // This is not great
4164 0 : bool is_EXF{false};
4165 0 : auto afe = elements.find(Alphas(4));
4166 0 : if (afe != elements.end()) {
4167 0 : is_EXF = afe->second->type() == ComponentType::EXF;
4168 : }
4169 0 : if (!is_EXF) {
4170 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, an invalid name is given:");
4171 0 : ShowContinueError(m_state, ".. invalid " + cAlphaFields(4) + " = \"" + Alphas(4) + "\".");
4172 0 : ErrorsFound = true;
4173 : }
4174 : }
4175 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlRelief) {
4176 : // This is not great
4177 1 : bool is_REL{false};
4178 2 : auto afe = elements.find(Alphas(4));
4179 1 : if (afe != elements.end()) {
4180 1 : is_REL = afe->second->type() == ComponentType::REL;
4181 : }
4182 1 : if (!is_REL) {
4183 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, an invalid name is given:");
4184 0 : ShowContinueError(m_state, ".. invalid " + cAlphaFields(4) + " = \"" + Alphas(4) + "\".");
4185 0 : ErrorsFound = true;
4186 : }
4187 : }
4188 :
4189 1 : if (lAlphaBlanks(5)) {
4190 1 : PressureControllerData(i).AvailSchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
4191 : } else {
4192 0 : PressureControllerData(i).AvailSchedPtr = GetScheduleIndex(m_state, Alphas(5));
4193 0 : if (PressureControllerData(i).AvailSchedPtr == 0) {
4194 0 : ShowSevereError(m_state,
4195 0 : CurrentModuleObject + ", \"" + PressureControllerData(i).Name + "\" " + cAlphaFields(5) +
4196 0 : " not found: " + Alphas(5));
4197 0 : ErrorsFound = true;
4198 : }
4199 : }
4200 1 : PressureControllerData(i).PresSetpointSchedPtr = GetScheduleIndex(m_state, Alphas(6));
4201 1 : if (PressureControllerData(i).PresSetpointSchedPtr == 0) {
4202 0 : ShowSevereError(m_state,
4203 0 : CurrentModuleObject + ", \"" + PressureControllerData(i).Name + "\" " + cAlphaFields(6) +
4204 0 : " not found: " + Alphas(6));
4205 0 : ErrorsFound = true;
4206 : }
4207 : }
4208 : }
4209 :
4210 : // Assign numbers of nodes and linkages
4211 34 : if (simulation_control.type != ControlType::NoMultizoneOrDistribution) {
4212 34 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
4213 27 : NumOfNodesMultiZone = AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
4214 : } else {
4215 7 : NumOfNodesMultiZone = AirflowNetworkNumOfZones + NumOfExtNodes;
4216 : }
4217 34 : NumOfLinksMultiZone = AirflowNetworkNumOfSurfaces;
4218 34 : AirflowNetworkNumOfNodes = NumOfNodesMultiZone;
4219 34 : if (NumOfNodesIntraZone > 0) AirflowNetworkNumOfNodes = AirflowNetworkNumOfNodes + NumOfNodesIntraZone;
4220 34 : AirflowNetworkNumOfLinks = NumOfLinksMultiZone;
4221 34 : if (NumOfLinksIntraZone > 0) AirflowNetworkNumOfLinks = AirflowNetworkNumOfLinks + NumOfLinksIntraZone;
4222 : }
4223 34 : if (distribution_simulated) {
4224 23 : AirflowNetworkNumOfNodes = NumOfNodesMultiZone + DisSysNumOfNodes + NumOfNodesIntraZone;
4225 : }
4226 :
4227 : // Assign node data
4228 34 : AirflowNetworkNodeData.allocate(AirflowNetworkNumOfNodes);
4229 : // Zone node
4230 146 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
4231 112 : AirflowNetworkNodeData(i).Name = MultizoneZoneData(i).ZoneName;
4232 112 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4233 112 : AirflowNetworkNodeData(i).EPlusZoneNum = MultizoneZoneData(i).ZoneNum;
4234 112 : AirflowNetworkNodeData(i).NodeHeight = MultizoneZoneData(i).Height;
4235 : }
4236 : // External node
4237 34 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
4238 143 : for (int i = AirflowNetworkNumOfZones + 1; i <= NumOfNodesMultiZone; ++i) {
4239 116 : AirflowNetworkNodeData(i).Name = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).Name;
4240 116 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4241 116 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4242 116 : AirflowNetworkNodeData(i).NodeHeight = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).height;
4243 116 : AirflowNetworkNodeData(i).ExtNodeNum = i - AirflowNetworkNumOfZones;
4244 116 : AirflowNetworkNodeData(i).OutAirNodeNum = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).OutAirNodeNum;
4245 : }
4246 : } else { // Surface-Average input
4247 72 : for (int i = AirflowNetworkNumOfZones + 1; i <= NumOfNodesMultiZone; ++i) {
4248 65 : n = i - AirflowNetworkNumOfZones;
4249 65 : AirflowNetworkNodeData(i).Name = MultizoneExternalNodeData(n).Name;
4250 65 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4251 65 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4252 65 : AirflowNetworkNodeData(i).ExtNodeNum = n;
4253 : }
4254 : }
4255 :
4256 : // Intrazone node
4257 34 : if (NumOfNodesIntraZone > 0) {
4258 6 : for (int i = NumOfNodesMultiZone + 1; i <= NumOfNodesMultiZone + NumOfNodesIntraZone; ++i) {
4259 5 : n = i - NumOfNodesMultiZone;
4260 5 : AirflowNetworkNodeData(i).Name = IntraZoneNodeData(n).Name;
4261 5 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4262 5 : AirflowNetworkNodeData(i).EPlusZoneNum = IntraZoneNodeData(n).ZoneNum;
4263 5 : AirflowNetworkNodeData(i).NodeHeight = IntraZoneNodeData(n).Height;
4264 5 : AirflowNetworkNodeData(i).RAFNNodeNum = IntraZoneNodeData(n).RAFNNodeNum;
4265 : }
4266 6 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
4267 5 : if (MultizoneZoneData(i).RAFNNodeNum > 0) {
4268 1 : AirflowNetworkNodeData(i).RAFNNodeNum = MultizoneZoneData(i).RAFNNodeNum;
4269 : }
4270 : }
4271 : }
4272 34 : NumOfNodesMultiZone = NumOfNodesMultiZone + NumOfNodesIntraZone;
4273 :
4274 : // Check whether Distribution system is simulated
4275 34 : if (AirflowNetworkNumOfNodes > NumOfNodesMultiZone) {
4276 : // Search node types: OAMixerOutdoorAirStreamNode, OutdoorAir:NodeList, and OutdoorAir:Node
4277 23 : j = 0;
4278 551 : for (int i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
4279 528 : if (UtilityRoutines::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
4280 14 : ++j;
4281 : }
4282 528 : if (UtilityRoutines::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:NodeList")) {
4283 0 : ++j;
4284 : }
4285 528 : if (UtilityRoutines::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:Node")) {
4286 0 : ++j;
4287 : }
4288 : }
4289 :
4290 551 : for (int i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
4291 528 : AirflowNetworkNodeData(i).Name = DisSysNodeData(i - NumOfNodesMultiZone).Name;
4292 528 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4293 528 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4294 528 : AirflowNetworkNodeData(i).NodeHeight = DisSysNodeData(i - NumOfNodesMultiZone).Height;
4295 528 : AirflowNetworkNodeData(i).EPlusNodeNum = DisSysNodeData(i - NumOfNodesMultiZone).EPlusNodeNum;
4296 : // Get mixer information
4297 528 : if (UtilityRoutines::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:ZoneMixer")) {
4298 24 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::MIX;
4299 : }
4300 : // Get splitter information
4301 528 : if (UtilityRoutines::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:ZoneSplitter")) {
4302 24 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPL;
4303 : }
4304 : // Get outside air system information
4305 528 : if (UtilityRoutines::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
4306 14 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::OAN;
4307 : }
4308 : // Get OA system inlet information 'OAMixerOutdoorAirStreamNode' was specified as an outdoor air node implicitly
4309 528 : if (UtilityRoutines::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
4310 14 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::EXT;
4311 14 : AirflowNetworkNodeData(i).ExtNodeNum = AirflowNetworkNumOfExtNode + 1;
4312 14 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4313 : }
4314 1584 : if (UtilityRoutines::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:NodeList") ||
4315 1056 : UtilityRoutines::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:Node")) {
4316 0 : if (j > 1) {
4317 0 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::EXT;
4318 0 : AirflowNetworkNodeData(i).ExtNodeNum = AirflowNetworkNumOfExtNode + 1;
4319 0 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4320 : } else {
4321 0 : ShowSevereError(m_state,
4322 0 : format(RoutineName) + "AirflowNetwork:Distribution:Node: The outdoor air node is found at " +
4323 0 : AirflowNetworkNodeData(i).Name);
4324 0 : ShowContinueError(m_state,
4325 : "The node with Component Object Type = OAMixerOutdoorAirStreamNode is not found. Please check inputs.");
4326 0 : ErrorsFound = true;
4327 : }
4328 : }
4329 : }
4330 : }
4331 :
4332 : // Start to assembly AirflowNetwork Components
4333 102 : AirflowNetworkNumOfComps = AirflowNetworkNumOfDetOpenings + AirflowNetworkNumOfSimOpenings + AirflowNetworkNumOfSurCracks +
4334 102 : AirflowNetworkNumOfSurELA + DisSysNumOfLeaks + DisSysNumOfELRs + DisSysNumOfDucts + DisSysNumOfDampers +
4335 102 : DisSysNumOfCVFs + DisSysNumOfDetFans + DisSysNumOfCPDs + DisSysNumOfCoils + DisSysNumOfTermUnits +
4336 102 : AirflowNetworkNumOfExhFan + DisSysNumOfHXs + AirflowNetworkNumOfHorOpenings + NumOfOAFans + NumOfReliefFans +
4337 34 : AirflowNetworkNumOfSFR;
4338 34 : AirflowNetworkCompData.allocate(AirflowNetworkNumOfComps);
4339 :
4340 65 : for (int i = 1; i <= AirflowNetworkNumOfDetOpenings; ++i) { // Detailed opening component
4341 31 : AirflowNetworkCompData(i).Name = MultizoneCompDetOpeningData(i).name;
4342 31 : compnum[AirflowNetworkCompData(i).Name] = i;
4343 31 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DOP;
4344 31 : AirflowNetworkCompData(i).TypeNum = i;
4345 31 : AirflowNetworkCompData(i).EPlusName = "";
4346 31 : AirflowNetworkCompData(i).EPlusCompName = "";
4347 31 : AirflowNetworkCompData(i).EPlusType = "";
4348 31 : AirflowNetworkCompData(i).CompNum = i;
4349 : }
4350 :
4351 34 : j = AirflowNetworkNumOfDetOpenings;
4352 46 : for (int i = 1 + j; i <= AirflowNetworkNumOfSimOpenings + j; ++i) { // Simple opening component
4353 12 : n = i - j;
4354 12 : AirflowNetworkCompData(i).Name = MultizoneCompSimpleOpeningData(n).name;
4355 12 : compnum[AirflowNetworkCompData(i).Name] = i;
4356 12 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SOP;
4357 12 : AirflowNetworkCompData(i).TypeNum = n;
4358 12 : AirflowNetworkCompData(i).EPlusName = "";
4359 12 : AirflowNetworkCompData(i).EPlusCompName = "";
4360 12 : AirflowNetworkCompData(i).EPlusType = "";
4361 12 : AirflowNetworkCompData(i).CompNum = i;
4362 : }
4363 :
4364 34 : j += AirflowNetworkNumOfSimOpenings;
4365 117 : for (int i = 1 + j; i <= AirflowNetworkNumOfSurCracks + j; ++i) { // Surface crack component
4366 83 : n = i - j;
4367 83 : AirflowNetworkCompData(i).Name = MultizoneSurfaceCrackData(n).name;
4368 83 : compnum[AirflowNetworkCompData(i).Name] = i;
4369 83 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SCR;
4370 83 : AirflowNetworkCompData(i).TypeNum = n;
4371 83 : AirflowNetworkCompData(i).EPlusName = "";
4372 83 : AirflowNetworkCompData(i).EPlusCompName = "";
4373 83 : AirflowNetworkCompData(i).EPlusType = "";
4374 83 : AirflowNetworkCompData(i).CompNum = i;
4375 : }
4376 :
4377 34 : j += AirflowNetworkNumOfSurCracks;
4378 59 : for (int i = 1 + j; i <= AirflowNetworkNumOfSurELA + j; ++i) { // Surface crack component
4379 25 : n = i - j;
4380 25 : AirflowNetworkCompData(i).Name = MultizoneSurfaceELAData(n).name;
4381 25 : compnum[AirflowNetworkCompData(i).Name] = i;
4382 25 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SEL;
4383 25 : AirflowNetworkCompData(i).TypeNum = n;
4384 25 : AirflowNetworkCompData(i).EPlusName = "";
4385 25 : AirflowNetworkCompData(i).EPlusCompName = "";
4386 25 : AirflowNetworkCompData(i).EPlusType = "";
4387 25 : AirflowNetworkCompData(i).CompNum = i;
4388 : }
4389 :
4390 34 : j += AirflowNetworkNumOfSurELA;
4391 48 : for (int i = 1 + j; i <= AirflowNetworkNumOfExhFan + j; ++i) { // Zone exhaust fan component
4392 14 : n = i - j;
4393 14 : AirflowNetworkCompData(i).Name = MultizoneCompExhaustFanData(n).name;
4394 14 : compnum[AirflowNetworkCompData(i).Name] = i;
4395 14 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::EXF;
4396 14 : AirflowNetworkCompData(i).TypeNum = n;
4397 14 : AirflowNetworkCompData(i).EPlusName = "";
4398 14 : AirflowNetworkCompData(i).EPlusCompName = "";
4399 14 : AirflowNetworkCompData(i).EPlusType = "";
4400 14 : AirflowNetworkCompData(i).CompNum = i;
4401 : }
4402 :
4403 34 : j += AirflowNetworkNumOfExhFan;
4404 36 : for (int i = 1 + j; i <= AirflowNetworkNumOfHorOpenings + j; ++i) { // Distribution system crack component
4405 2 : n = i - j;
4406 2 : AirflowNetworkCompData(i).Name = MultizoneCompHorOpeningData(n).name;
4407 2 : compnum[AirflowNetworkCompData(i).Name] = i;
4408 2 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::HOP;
4409 2 : AirflowNetworkCompData(i).TypeNum = n;
4410 2 : AirflowNetworkCompData(i).EPlusName = "";
4411 2 : AirflowNetworkCompData(i).EPlusCompName = "";
4412 2 : AirflowNetworkCompData(i).EPlusType = "";
4413 2 : AirflowNetworkCompData(i).CompNum = i;
4414 : }
4415 :
4416 34 : j += AirflowNetworkNumOfHorOpenings;
4417 48 : for (int i = 1 + j; i <= DisSysNumOfLeaks + j; ++i) { // Distribution system crack component
4418 14 : n = i - j;
4419 14 : AirflowNetworkCompData(i).Name = DisSysCompLeakData(n).name;
4420 14 : compnum[AirflowNetworkCompData(i).Name] = i;
4421 14 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::PLR;
4422 14 : AirflowNetworkCompData(i).TypeNum = n;
4423 14 : AirflowNetworkCompData(i).EPlusName = "";
4424 14 : AirflowNetworkCompData(i).EPlusCompName = "";
4425 14 : AirflowNetworkCompData(i).EPlusType = "";
4426 14 : AirflowNetworkCompData(i).CompNum = i;
4427 : }
4428 :
4429 34 : j += DisSysNumOfLeaks;
4430 132 : for (int i = 1 + j; i <= DisSysNumOfELRs + j; ++i) { // Distribution system effective leakage ratio component
4431 98 : n = i - j;
4432 98 : AirflowNetworkCompData(i).Name = DisSysCompELRData(n).name;
4433 98 : compnum[AirflowNetworkCompData(i).Name] = i;
4434 98 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::ELR;
4435 98 : AirflowNetworkCompData(i).TypeNum = n;
4436 98 : AirflowNetworkCompData(i).EPlusName = "";
4437 98 : AirflowNetworkCompData(i).EPlusCompName = "";
4438 98 : AirflowNetworkCompData(i).EPlusType = "";
4439 98 : AirflowNetworkCompData(i).CompNum = i;
4440 : }
4441 :
4442 34 : j += DisSysNumOfELRs;
4443 289 : for (int i = 1 + j; i <= DisSysNumOfDucts + j; ++i) { // Distribution system effective leakage ratio component
4444 255 : n = i - j;
4445 255 : AirflowNetworkCompData(i).Name = DisSysCompDuctData(n).name;
4446 255 : compnum[AirflowNetworkCompData(i).Name] = i;
4447 255 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DWC;
4448 255 : AirflowNetworkCompData(i).TypeNum = n;
4449 255 : AirflowNetworkCompData(i).EPlusName = "";
4450 255 : AirflowNetworkCompData(i).EPlusCompName = "";
4451 255 : AirflowNetworkCompData(i).EPlusType = "";
4452 255 : AirflowNetworkCompData(i).CompNum = i;
4453 : }
4454 :
4455 34 : j += DisSysNumOfDucts;
4456 34 : for (int i = 1 + j; i <= DisSysNumOfDampers + j; ++i) { // Distribution system effective leakage ratio component
4457 0 : n = i - j;
4458 0 : AirflowNetworkCompData(i).Name = DisSysCompDamperData(n).name;
4459 0 : compnum[AirflowNetworkCompData(i).Name] = i;
4460 0 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DMP;
4461 0 : AirflowNetworkCompData(i).TypeNum = n;
4462 0 : AirflowNetworkCompData(i).EPlusName = "";
4463 0 : AirflowNetworkCompData(i).EPlusCompName = "";
4464 0 : AirflowNetworkCompData(i).EPlusType = "";
4465 0 : AirflowNetworkCompData(i).CompNum = i;
4466 : }
4467 :
4468 34 : j += DisSysNumOfDampers;
4469 58 : for (int i = 1 + j; i <= DisSysNumOfCVFs + j; ++i) { // Distribution system constant volume fan component
4470 24 : n = i - j;
4471 24 : AirflowNetworkCompData(i).Name = DisSysCompCVFData(n).name;
4472 24 : compnum[AirflowNetworkCompData(i).Name] = i;
4473 24 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::CVF;
4474 24 : AirflowNetworkCompData(i).TypeNum = n;
4475 24 : AirflowNetworkCompData(i).EPlusName = "";
4476 24 : AirflowNetworkCompData(i).EPlusCompName = "";
4477 24 : AirflowNetworkCompData(i).EPlusType = "";
4478 24 : AirflowNetworkCompData(i).CompNum = i;
4479 24 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::FAN;
4480 : }
4481 :
4482 34 : j += DisSysNumOfCVFs;
4483 34 : for (int i = 1 + j; i <= DisSysNumOfDetFans + j; ++i) { // Distribution system fan component
4484 0 : n = i - j;
4485 0 : AirflowNetworkCompData(i).Name = DisSysCompDetFanData(n).name;
4486 0 : compnum[AirflowNetworkCompData(i).Name] = i;
4487 0 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::FAN;
4488 0 : AirflowNetworkCompData(i).TypeNum = n;
4489 0 : AirflowNetworkCompData(i).EPlusName = "";
4490 0 : AirflowNetworkCompData(i).EPlusCompName = "";
4491 0 : AirflowNetworkCompData(i).EPlusType = "";
4492 0 : AirflowNetworkCompData(i).CompNum = i;
4493 0 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::FAN;
4494 : }
4495 :
4496 34 : j += DisSysNumOfDetFans;
4497 46 : for (int i = 1 + j; i <= DisSysNumOfCPDs + j; ++i) { // Distribution system constant pressure drop component
4498 12 : n = i - j;
4499 12 : AirflowNetworkCompData(i).Name = DisSysCompCPDData(n).name;
4500 12 : compnum[AirflowNetworkCompData(i).Name] = i;
4501 12 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::CPD;
4502 12 : AirflowNetworkCompData(i).TypeNum = n;
4503 12 : AirflowNetworkCompData(i).EPlusName = "";
4504 12 : AirflowNetworkCompData(i).EPlusCompName = "";
4505 12 : AirflowNetworkCompData(i).EPlusType = "";
4506 12 : AirflowNetworkCompData(i).CompNum = i;
4507 : }
4508 :
4509 34 : j += DisSysNumOfCPDs;
4510 91 : for (int i = 1 + j; i <= DisSysNumOfCoils + j; ++i) { // Distribution system coil component
4511 57 : n = i - j;
4512 57 : AirflowNetworkCompData(i).Name = DisSysCompCoilData(n).name;
4513 57 : compnum[AirflowNetworkCompData(i).Name] = i;
4514 57 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::COI;
4515 57 : AirflowNetworkCompData(i).TypeNum = n;
4516 57 : AirflowNetworkCompData(i).EPlusName = "";
4517 57 : AirflowNetworkCompData(i).EPlusCompName = "";
4518 57 : AirflowNetworkCompData(i).EPlusType = "";
4519 57 : AirflowNetworkCompData(i).CompNum = i;
4520 57 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::COI;
4521 : }
4522 :
4523 34 : j += DisSysNumOfCoils;
4524 58 : for (int i = 1 + j; i <= DisSysNumOfTermUnits + j; ++i) { // Terminal unit component
4525 24 : n = i - j;
4526 24 : AirflowNetworkCompData(i).Name = DisSysCompTermUnitData(n).name;
4527 24 : compnum[AirflowNetworkCompData(i).Name] = i;
4528 24 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::TMU;
4529 24 : AirflowNetworkCompData(i).TypeNum = n;
4530 24 : AirflowNetworkCompData(i).EPlusName = "";
4531 24 : AirflowNetworkCompData(i).EPlusCompName = "";
4532 24 : AirflowNetworkCompData(i).EPlusType = "";
4533 24 : AirflowNetworkCompData(i).CompNum = i;
4534 24 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::RHT;
4535 : }
4536 :
4537 34 : j += DisSysNumOfTermUnits;
4538 35 : for (int i = 1 + j; i <= DisSysNumOfHXs + j; ++i) { // Distribution system heat exchanger component
4539 1 : n = i - j;
4540 1 : AirflowNetworkCompData(i).Name = DisSysCompHXData(n).name;
4541 1 : compnum[AirflowNetworkCompData(i).Name] = i;
4542 1 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::HEX;
4543 1 : AirflowNetworkCompData(i).TypeNum = n;
4544 1 : AirflowNetworkCompData(i).EPlusName = "";
4545 1 : AirflowNetworkCompData(i).EPlusCompName = "";
4546 1 : AirflowNetworkCompData(i).EPlusType = "";
4547 1 : AirflowNetworkCompData(i).CompNum = i;
4548 1 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::HEX;
4549 : }
4550 :
4551 34 : j += DisSysNumOfHXs;
4552 36 : for (int i = 1 + j; i <= NumOfOAFans + j; ++i) { // OA fan component
4553 2 : n = i - j;
4554 2 : AirflowNetworkCompData(i).Name = DisSysCompOutdoorAirData(n).name;
4555 2 : compnum[AirflowNetworkCompData(i).Name] = i;
4556 2 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::OAF;
4557 2 : AirflowNetworkCompData(i).TypeNum = n;
4558 2 : AirflowNetworkCompData(i).EPlusName = "";
4559 2 : AirflowNetworkCompData(i).EPlusCompName = "";
4560 2 : AirflowNetworkCompData(i).EPlusType = "";
4561 2 : AirflowNetworkCompData(i).CompNum = i;
4562 : }
4563 :
4564 34 : j += NumOfOAFans;
4565 36 : for (int i = 1 + j; i <= NumOfReliefFans + j; ++i) { // OA fan component
4566 2 : n = i - j;
4567 2 : AirflowNetworkCompData(i).Name = DisSysCompReliefAirData(n).name;
4568 2 : compnum[AirflowNetworkCompData(i).Name] = i;
4569 2 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::REL;
4570 2 : AirflowNetworkCompData(i).TypeNum = n;
4571 2 : AirflowNetworkCompData(i).EPlusName = "";
4572 2 : AirflowNetworkCompData(i).EPlusCompName = "";
4573 2 : AirflowNetworkCompData(i).EPlusType = "";
4574 2 : AirflowNetworkCompData(i).CompNum = i;
4575 : }
4576 :
4577 : // This is also a bit of a hack to keep things working, this needs to be removed ASAP
4578 34 : j += NumOfReliefFans;
4579 34 : int ii = 1 + j;
4580 34 : int type_i = 1;
4581 35 : for (auto &el : SpecifiedMassFlowData) {
4582 1 : AirflowNetworkCompData(ii).Name = el.name;
4583 1 : compnum[el.name] = ii;
4584 1 : AirflowNetworkCompData(ii).CompTypeNum = iComponentTypeNum::SMF;
4585 1 : AirflowNetworkCompData(ii).TypeNum = type_i;
4586 1 : AirflowNetworkCompData(ii).EPlusName = "";
4587 1 : AirflowNetworkCompData(ii).EPlusCompName = "";
4588 1 : AirflowNetworkCompData(ii).EPlusType = "";
4589 1 : AirflowNetworkCompData(ii).CompNum = ii;
4590 1 : ++ii;
4591 1 : ++type_i;
4592 : }
4593 :
4594 34 : type_i = 1;
4595 34 : for (auto &el : SpecifiedVolumeFlowData) {
4596 0 : AirflowNetworkCompData(ii).Name = el.name;
4597 0 : compnum[el.name] = ii;
4598 0 : AirflowNetworkCompData(ii).CompTypeNum = iComponentTypeNum::SVF;
4599 0 : AirflowNetworkCompData(ii).TypeNum = type_i;
4600 0 : AirflowNetworkCompData(ii).EPlusName = "";
4601 0 : AirflowNetworkCompData(ii).EPlusCompName = "";
4602 0 : AirflowNetworkCompData(ii).EPlusType = "";
4603 0 : AirflowNetworkCompData(ii).CompNum = ii;
4604 0 : ++ii;
4605 0 : ++type_i;
4606 : }
4607 :
4608 : // Assign linkage data
4609 :
4610 : // Read AirflowNetwork linkage data
4611 34 : CurrentModuleObject = "AirflowNetwork:Distribution:Linkage";
4612 34 : DisSysNumOfLinks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
4613 34 : if (DisSysNumOfLinks > 0 && distribution_simulated) { // Multizone + Distribution
4614 23 : AirflowNetworkNumOfLinks = NumOfLinksMultiZone + DisSysNumOfLinks;
4615 23 : AirflowNetworkLinkageData.allocate(DisSysNumOfLinks + AirflowNetworkNumOfSurfaces);
4616 : } else { // Multizone + IntraZone only
4617 : // AirflowNetworkLinkageData.allocate( AirflowNetworkNumOfSurfaces );
4618 11 : AirflowNetworkLinkageData.allocate(AirflowNetworkNumOfLinks);
4619 : }
4620 :
4621 : // Assign Multizone linkage based on surfaces, by assuming every surface has a crack or opening
4622 34 : j = 0;
4623 507 : for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
4624 473 : if (MultizoneSurfaceData(count).SurfNum == 0) continue;
4625 473 : AirflowNetworkLinkageData(count).Name = MultizoneSurfaceData(count).SurfName;
4626 473 : AirflowNetworkLinkageData(count).NodeNums[0] = MultizoneSurfaceData(count).NodeNums[0];
4627 473 : AirflowNetworkLinkageData(count).NodeNums[1] = MultizoneSurfaceData(count).NodeNums[1];
4628 473 : AirflowNetworkLinkageData(count).CompName = MultizoneSurfaceData(count).OpeningName;
4629 473 : AirflowNetworkLinkageData(count).ZoneNum = 0;
4630 473 : AirflowNetworkLinkageData(count).LinkNum = count;
4631 473 : AirflowNetworkLinkageData(count).NodeHeights[0] = MultizoneSurfaceData(count).CHeight;
4632 473 : AirflowNetworkLinkageData(count).NodeHeights[1] = MultizoneSurfaceData(count).CHeight;
4633 473 : if (!m_state.dataSurface->WorldCoordSystem) {
4634 58 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum > 0) {
4635 58 : AirflowNetworkLinkageData(count).NodeHeights[0] -=
4636 58 : Zone(AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum).OriginZ;
4637 : }
4638 58 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum > 0) {
4639 2 : AirflowNetworkLinkageData(count).NodeHeights[1] -=
4640 2 : Zone(AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum).OriginZ;
4641 : }
4642 : }
4643 : // Find component number
4644 946 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4645 473 : if (afe != elements.end()) {
4646 : // found = false;
4647 : // for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
4648 473 : AirflowNetworkLinkageData(count).element = afe->second;
4649 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4650 946 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4651 473 : assert(compnum_iter != compnum.end());
4652 473 : int compnum = compnum_iter->second;
4653 473 : AirflowNetworkLinkageData(count).CompNum = compnum;
4654 :
4655 473 : switch (AirflowNetworkLinkageData(count).element->type()) {
4656 70 : case ComponentType::DOP: {
4657 : // if (AirflowNetworkLinkageData(count).CompName ==
4658 : // AirflowNetworkCompData(i).Name) {
4659 : // AirflowNetworkLinkageData(count).CompNum = i;
4660 : // found = true;
4661 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::DOP) {
4662 70 : ++j;
4663 70 : AirflowNetworkLinkageData(count).DetOpenNum = j;
4664 70 : MultizoneSurfaceData(count).Multiplier = m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).Multiplier;
4665 140 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).Tilt < 10.0 ||
4666 70 : m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).Tilt > 170.0) {
4667 0 : ShowWarningError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4668 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is within ");
4669 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through large horizontal openings are poorly");
4670 0 : ShowContinueError(m_state, "modeled in the AirflowNetwork model resulting in only one-way airflow.");
4671 : }
4672 77 : if (!(m_state.dataSurface->SurfWinOriginalClass(MultizoneSurfaceData(count).SurfNum) == SurfaceClass::Window ||
4673 14 : m_state.dataSurface->SurfWinOriginalClass(MultizoneSurfaceData(count).SurfNum) == SurfaceClass::GlassDoor ||
4674 7 : m_state.dataSurface->SurfWinOriginalClass(MultizoneSurfaceData(count).SurfNum) == SurfaceClass::Door ||
4675 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).IsAirBoundarySurf)) {
4676 0 : ShowSevereError(m_state,
4677 0 : format(RoutineName) +
4678 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4679 0 : AirflowNetworkLinkageData(count).Name);
4680 0 : ErrorsFound = true;
4681 : }
4682 133 : if (m_state.dataSurface->SurfWinOriginalClass(MultizoneSurfaceData(count).SurfNum) == SurfaceClass::Door ||
4683 63 : m_state.dataSurface->SurfWinOriginalClass(MultizoneSurfaceData(count).SurfNum) == SurfaceClass::GlassDoor) {
4684 7 : if (MultizoneCompDetOpeningData(AirflowNetworkCompData(compnum).TypeNum).LVOType == 2) {
4685 0 : ShowSevereError(m_state,
4686 0 : format(RoutineName) +
4687 : "AirflowNetworkComponent: The opening with horizontally pivoted type must be assigned to a "
4688 0 : "window surface at " +
4689 0 : AirflowNetworkLinkageData(count).Name);
4690 0 : ErrorsFound = true;
4691 : }
4692 : }
4693 70 : } break;
4694 17 : case ComponentType::SOP: {
4695 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SOP) {
4696 17 : MultizoneSurfaceData(count).Multiplier = m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).Multiplier;
4697 34 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).Tilt < 10.0 ||
4698 17 : m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).Tilt > 170.0) {
4699 0 : ShowSevereError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4700 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is within");
4701 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through horizontal openings are not allowed.");
4702 0 : ShowContinueError(m_state, "AirflowNetwork:Multizone:Component:SimpleOpening = " + AirflowNetworkCompData(compnum).Name);
4703 0 : ErrorsFound = true;
4704 : }
4705 :
4706 34 : if (!(m_state.dataSurface->SurfWinOriginalClass(MultizoneSurfaceData(count).SurfNum) == SurfaceClass::Window ||
4707 34 : m_state.dataSurface->SurfWinOriginalClass(MultizoneSurfaceData(count).SurfNum) == SurfaceClass::GlassDoor ||
4708 17 : m_state.dataSurface->SurfWinOriginalClass(MultizoneSurfaceData(count).SurfNum) == SurfaceClass::Door ||
4709 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).IsAirBoundarySurf)) {
4710 0 : ShowSevereError(m_state,
4711 0 : format(RoutineName) +
4712 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4713 0 : AirflowNetworkLinkageData(count).Name);
4714 0 : ErrorsFound = true;
4715 : }
4716 17 : } break;
4717 1 : case ComponentType::HOP: {
4718 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::HOP) {
4719 1 : MultizoneSurfaceData(count).Multiplier = m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).Multiplier;
4720 : // Get linkage height from upper and lower zones
4721 1 : if (MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum > 0) {
4722 1 : AirflowNetworkLinkageData(count).NodeHeights[0] =
4723 1 : Zone(MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum).Centroid.z;
4724 : }
4725 1 : if (AirflowNetworkLinkageData(count).NodeNums[1] <= AirflowNetworkNumOfZones) {
4726 1 : if (MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum > 0) {
4727 1 : AirflowNetworkLinkageData(count).NodeHeights[1] =
4728 1 : Zone(m_state.afn->MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum).Centroid.z;
4729 : }
4730 : }
4731 1 : if (AirflowNetworkLinkageData(count).NodeNums[1] > AirflowNetworkNumOfZones) {
4732 0 : ShowSevereError(m_state,
4733 0 : format(RoutineName) +
4734 0 : "AirflowNetworkComponent: The horizontal opening must be located between two thermal zones at " +
4735 0 : AirflowNetworkLinkageData(count).Name);
4736 0 : ShowContinueError(m_state, "This component is exposed to outdoors.");
4737 0 : ErrorsFound = true;
4738 : } else {
4739 2 : if (!(MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum > 0 &&
4740 1 : MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum > 0)) {
4741 0 : ShowSevereError(m_state,
4742 0 : format(RoutineName) +
4743 0 : "AirflowNetworkComponent: The horizontal opening must be located between two thermal zones at " +
4744 0 : AirflowNetworkLinkageData(count).Name);
4745 0 : ErrorsFound = true;
4746 : }
4747 : }
4748 3 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).Tilt > 170.0 &&
4749 1 : m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).Tilt < 190.0) &&
4750 0 : !(m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).Tilt > -10.0 &&
4751 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).Tilt < 10.0)) {
4752 0 : ShowWarningError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4753 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is above");
4754 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through non-horizontal openings are not modeled");
4755 0 : ShowContinueError(m_state,
4756 0 : "with the object of AirflowNetwork:Multizone:Component:HorizontalOpening = " +
4757 0 : AirflowNetworkCompData(compnum).Name);
4758 : }
4759 2 : if (!(m_state.dataSurface->SurfWinOriginalClass(MultizoneSurfaceData(count).SurfNum) == SurfaceClass::Window ||
4760 2 : m_state.dataSurface->SurfWinOriginalClass(MultizoneSurfaceData(count).SurfNum) == SurfaceClass::GlassDoor ||
4761 1 : m_state.dataSurface->SurfWinOriginalClass(MultizoneSurfaceData(count).SurfNum) == SurfaceClass::Door ||
4762 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum).IsAirBoundarySurf)) {
4763 0 : ShowSevereError(m_state,
4764 0 : format(RoutineName) +
4765 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4766 0 : AirflowNetworkLinkageData(count).Name);
4767 0 : ErrorsFound = true;
4768 : }
4769 1 : } break;
4770 385 : default:
4771 : // Nothing to do here
4772 385 : break;
4773 : }
4774 : } else {
4775 0 : ShowSevereError(m_state,
4776 0 : format(RoutineName) + CurrentModuleObject + ": The component is not defined in " +
4777 0 : AirflowNetworkLinkageData(count).Name);
4778 0 : ErrorsFound = true;
4779 : }
4780 : }
4781 :
4782 : // Assign intrazone links
4783 41 : for (count = 1 + AirflowNetworkNumOfSurfaces; count <= NumOfLinksIntraZone + AirflowNetworkNumOfSurfaces; ++count) {
4784 7 : AirflowNetworkLinkageData(count).Name = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).Name;
4785 7 : AirflowNetworkLinkageData(count).NodeNums[0] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeNums[0];
4786 7 : AirflowNetworkLinkageData(count).NodeNums[1] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeNums[1];
4787 7 : AirflowNetworkLinkageData(count).CompName = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).CompName;
4788 7 : AirflowNetworkLinkageData(count).ZoneNum = 0;
4789 7 : AirflowNetworkLinkageData(count).LinkNum = count;
4790 7 : AirflowNetworkLinkageData(count).NodeHeights[0] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeHeights[0];
4791 7 : AirflowNetworkLinkageData(count).NodeHeights[1] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeHeights[1];
4792 : // Find component number
4793 14 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4794 7 : if (afe != elements.end()) {
4795 7 : AirflowNetworkLinkageData(count).element = afe->second;
4796 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4797 14 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4798 7 : assert(compnum_iter != compnum.end());
4799 7 : int compnum = compnum_iter->second;
4800 7 : AirflowNetworkLinkageData(count).CompNum = compnum;
4801 7 : if (AirflowNetworkLinkageData(count).element->type() != ComponentType::SCR &&
4802 0 : AirflowNetworkLinkageData(count).element->type() != ComponentType::SEL) {
4803 :
4804 0 : ShowSevereError(m_state,
4805 0 : format(RoutineName) + AirflowNetworkLinkageData(count).CompName + ": The component is not allowed in " +
4806 0 : AirflowNetworkLinkageData(count).Name);
4807 0 : ShowContinueError(m_state,
4808 : "The allowed component type is either AirflowNetwork:MultiZone:Surface:Crack or "
4809 : "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea.");
4810 0 : ErrorsFound = true;
4811 : }
4812 : } else {
4813 0 : ShowSevereError(m_state,
4814 0 : format(RoutineName) + AirflowNetworkLinkageData(count).CompName + ": The component is not defined in " +
4815 0 : AirflowNetworkLinkageData(count).Name);
4816 0 : ErrorsFound = true;
4817 : }
4818 : }
4819 :
4820 : // Reset AirflowNetworkNumOfSurfaces by including NumOfLinksIntraZone
4821 34 : AirflowNetworkNumOfSurfaces = AirflowNetworkNumOfSurfaces + NumOfLinksIntraZone;
4822 34 : if (NumOfLinksIntraZone > 0) NumOfLinksMultiZone = AirflowNetworkNumOfSurfaces;
4823 :
4824 : // Assign AirflowNetwork info in RoomAirflowNetworkZoneInfo
4825 34 : if (NumOfNodesIntraZone > 0) {
4826 15 : for (int i = 1; i <= NumOfNodesMultiZone; ++i) {
4827 14 : n = AirflowNetworkNodeData(i).EPlusZoneNum;
4828 14 : AirflowNetworkNodeData(i).NumOfLinks = 0;
4829 14 : if (n > 0 && AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
4830 6 : m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(n).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirflowNetworkNodeID = i;
4831 216 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
4832 210 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i) {
4833 15 : AirflowNetworkNodeData(i).NumOfLinks = AirflowNetworkNodeData(i).NumOfLinks + 1;
4834 195 : } else if (AirflowNetworkLinkageData(j).NodeNums[1] == i) {
4835 13 : AirflowNetworkNodeData(i).NumOfLinks = AirflowNetworkNodeData(i).NumOfLinks + 1;
4836 : } else {
4837 : }
4838 : }
4839 : }
4840 14 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
4841 42 : for (j = 1; j <= m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(n).NumOfAirNodes; ++j) {
4842 36 : if (m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(n).Node(j).AirflowNetworkNodeID == i) {
4843 6 : m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(n).Node(j).NumOfAirflowLinks = AirflowNetworkNodeData(i).NumOfLinks;
4844 6 : m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(n).Node(j).Link.allocate(AirflowNetworkNodeData(i).NumOfLinks);
4845 6 : k = 1;
4846 198 : for (m = 1; m <= AirflowNetworkNumOfSurfaces; ++m) {
4847 198 : if (AirflowNetworkLinkageData(m).NodeNums[0] == i) {
4848 15 : m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(n).Node(j).Link(k).AirflowNetworkLinkSimuID = m;
4849 15 : m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(n).Node(j).Link(k).AirflowNetworkLinkageDataID = m;
4850 15 : k = k + 1;
4851 15 : if (k > AirflowNetworkNodeData(i).NumOfLinks) break;
4852 : }
4853 195 : if (AirflowNetworkLinkageData(m).NodeNums[1] == i) {
4854 13 : m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(n).Node(j).Link(k).AirflowNetworkLinkSimuID = m;
4855 13 : m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(n).Node(j).Link(k).AirflowNetworkLinkageDataID = m;
4856 13 : k = k + 1;
4857 13 : if (k > AirflowNetworkNodeData(i).NumOfLinks) break;
4858 : }
4859 : }
4860 : }
4861 : }
4862 : }
4863 : }
4864 : }
4865 :
4866 34 : if (DisSysNumOfLinks > 0 && distribution_simulated) { // Distribution
4867 :
4868 1053 : for (auto &e : AirflowNetworkLinkageData)
4869 1030 : e.ZoneNum = 0;
4870 :
4871 724 : for (count = AirflowNetworkNumOfSurfaces + 1; count <= AirflowNetworkNumOfLinks; ++count) {
4872 :
4873 1402 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
4874 : CurrentModuleObject,
4875 701 : count - AirflowNetworkNumOfSurfaces,
4876 : Alphas,
4877 : NumAlphas,
4878 : Numbers,
4879 : NumNumbers,
4880 : IOStatus,
4881 : lNumericBlanks,
4882 : lAlphaBlanks,
4883 : cAlphaFields,
4884 : cNumericFields);
4885 701 : UtilityRoutines::IsNameEmpty(m_state, Alphas(1), CurrentModuleObject, ErrorsFound);
4886 701 : AirflowNetworkLinkageData(count).Name = Alphas(1);
4887 701 : AirflowNetworkLinkageData(count).NodeNames[0] = Alphas(2);
4888 701 : AirflowNetworkLinkageData(count).NodeHeights[0] = 0.0;
4889 701 : AirflowNetworkLinkageData(count).NodeNames[1] = Alphas(3);
4890 701 : AirflowNetworkLinkageData(count).NodeHeights[1] = 0.0;
4891 701 : AirflowNetworkLinkageData(count).CompName = Alphas(4);
4892 701 : AirflowNetworkLinkageData(count).ZoneName = Alphas(5);
4893 701 : AirflowNetworkLinkageData(count).LinkNum = count;
4894 :
4895 715 : for (int i = 1; i <= DisSysNumOfDuctViewFactors; ++i) {
4896 15 : if (AirflowNetworkLinkageData(count).Name == AirflowNetworkLinkageViewFactorData(i).LinkageName) {
4897 1 : AirflowNetworkLinkageData(count).LinkageViewFactorObjectNum = AirflowNetworkLinkageViewFactorData(i).ObjectNum;
4898 1 : break;
4899 : }
4900 : }
4901 :
4902 701 : if (!lAlphaBlanks(5)) {
4903 292 : AirflowNetworkLinkageData(count).ZoneNum = UtilityRoutines::FindItemInList(AirflowNetworkLinkageData(count).ZoneName, Zone);
4904 292 : if (AirflowNetworkLinkageData(count).ZoneNum == 0) {
4905 0 : ShowSevereError(m_state,
4906 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(5) +
4907 0 : " given = " + AirflowNetworkLinkageData(count).ZoneName);
4908 0 : ErrorsFound = true;
4909 : }
4910 : }
4911 701 : if (Alphas(2) == Alphas(3)) {
4912 0 : ShowSevereError(m_state,
4913 0 : format(RoutineName) + CurrentModuleObject + ", " + cAlphaFields(2) + " = " + cAlphaFields(3) + " in " +
4914 0 : AirflowNetworkLinkageData(count).Name);
4915 0 : ErrorsFound = true;
4916 : }
4917 : // Find component number
4918 1402 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4919 701 : if (afe != elements.end()) {
4920 701 : AirflowNetworkLinkageData(count).element = afe->second;
4921 :
4922 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4923 1402 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4924 701 : assert(compnum_iter != compnum.end());
4925 701 : int compnum = compnum_iter->second;
4926 701 : AirflowNetworkLinkageData(count).CompNum = compnum;
4927 : } else {
4928 0 : ShowSevereError(m_state,
4929 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(4) + " is not defined in " +
4930 0 : AirflowNetworkLinkageData(count).Name);
4931 0 : ErrorsFound = true;
4932 : }
4933 : // Find Node number
4934 701 : found = false;
4935 14013 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4936 14013 : if (AirflowNetworkLinkageData(count).NodeNames[0] == AirflowNetworkNodeData(i).Name) {
4937 701 : AirflowNetworkLinkageData(count).NodeNums[0] = i;
4938 701 : AirflowNetworkLinkageData(count).NodeHeights[0] += AirflowNetworkNodeData(i).NodeHeight;
4939 701 : found = true;
4940 701 : break;
4941 : }
4942 : }
4943 701 : if (!found) {
4944 0 : ShowSevereError(m_state,
4945 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(2) + " is not found in the node data " +
4946 0 : AirflowNetworkLinkageData(count).Name);
4947 0 : ErrorsFound = true;
4948 : }
4949 13976 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4950 13976 : if (AirflowNetworkLinkageData(count).NodeNames[1] == AirflowNetworkNodeData(i).Name) {
4951 701 : AirflowNetworkLinkageData(count).NodeNums[1] = i;
4952 701 : AirflowNetworkLinkageData(count).NodeHeights[1] += AirflowNetworkNodeData(i).NodeHeight;
4953 701 : found = true;
4954 701 : break;
4955 : }
4956 : }
4957 701 : if (!found) {
4958 0 : ShowSevereError(m_state,
4959 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(3) + " is not found in the node data " +
4960 0 : AirflowNetworkLinkageData(count).Name);
4961 0 : ErrorsFound = true;
4962 : }
4963 23 : }
4964 : } else {
4965 :
4966 11 : if (distribution_simulated) {
4967 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
4968 0 : ErrorsFound = true;
4969 : }
4970 : }
4971 :
4972 : // Ensure no duplicated names in AirflowNetwork component objects
4973 : // for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
4974 : // for (j = i + 1; j <= AirflowNetworkNumOfComps; ++j) {
4975 : // if (UtilityRoutines::SameString(AirflowNetworkCompData(i).Name,
4976 : // AirflowNetworkCompData(j).Name)) {
4977 : // // SurfaceAirflowLeakageNames
4978 : // if (i <= 4 && j <= 4) {
4979 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::DOP)
4980 : // CompName(1) = "AirflowNetwork:MultiZone:Component:DetailedOpening";
4981 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SOP)
4982 : // CompName(1) = "AirflowNetwork:MultiZone:Component:SimpleOpening";
4983 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SCR) CompName(1) =
4984 : // "AirflowNetwork:MultiZone:Surface:Crack"; if (AirflowNetworkCompData(i).CompTypeNum ==
4985 : // iComponentTypeNum::SEL) CompName(1) = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea"; if
4986 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DOP) CompName(2) =
4987 : // "AirflowNetwork:MultiZone:Component:DetailedOpening"; if (AirflowNetworkCompData(j).CompTypeNum ==
4988 : // iComponentTypeNum::SOP) CompName(2) = "AirflowNetwork:MultiZone:Component:SimpleOpening"; if
4989 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::SCR) CompName(2) =
4990 : // "AirflowNetwork:MultiZone:Surface:Crack"; if (AirflowNetworkCompData(j).CompTypeNum ==
4991 : // iComponentTypeNum::SEL) CompName(2) = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea"; ShowSevereError(m_state, RoutineName
4992 : // + "Duplicated component names are found = " + AirflowNetworkCompData(i).Name); ShowContinueError(m_state,
4993 : // "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2)); ErrorsFound = true;
4994 : // }
4995 : // // Distribution component
4996 : // if (i > 4 && j > 4) {
4997 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::PLR) CompName(1) =
4998 : // "AirflowNetwork:Distribution:Component:Leak"; if (AirflowNetworkCompData(i).CompTypeNum ==
4999 : // iComponentTypeNum::DWC) CompName(1) = "AirflowNetwork:Distribution:Component:Duct"; if
5000 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::ELR) CompName(1) =
5001 : // "AirflowNetwork:Distribution:Component:LeakageRatio"; if (AirflowNetworkCompData(i).CompTypeNum ==
5002 : // iComponentTypeNum::DMP) CompName(1) = "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT DAMPER"; if
5003 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::CVF) CompName(1) =
5004 : // "AirflowNetwork:Distribution:Component:Fan"; if (AirflowNetworkCompData(i).CompTypeNum ==
5005 : // iComponentTypeNum::CPD) CompName(1) = "AirflowNetwork:Distribution:Component:ConstantPressureDrop"; if
5006 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::COI) CompName(1) =
5007 : // "AirflowNetwork:Distribution:Component:Coil"; if (AirflowNetworkCompData(i).CompTypeNum ==
5008 : // iComponentTypeNum::TMU) CompName(1) = "AirflowNetwork:Distribution:Component:TerminalUnit"; if
5009 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::HEX) CompName(1) =
5010 : // "AirflowNetwork:Distribution:Component:HeatExchanger"; if (AirflowNetworkCompData(j).CompTypeNum ==
5011 : // iComponentTypeNum::PLR) CompName(2) = "AirflowNetwork:Distribution:Component:Leak"; if
5012 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DWC) CompName(2) =
5013 : // "AirflowNetwork:Distribution:Component:Duct"; if (AirflowNetworkCompData(j).CompTypeNum ==
5014 : // iComponentTypeNum::ELR) CompName(2) = "AirflowNetwork:Distribution:Component:LeakageRatio"; if
5015 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DMP) CompName(2) =
5016 : // "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT DAMPER"; if (AirflowNetworkCompData(j).CompTypeNum ==
5017 : // iComponentTypeNum::CVF) CompName(2) = "AirflowNetwork:Distribution:Component:Fan"; if
5018 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::CPD) CompName(2) =
5019 : // "AirflowNetwork:Distribution:Component:ConstantPressureDrop"; if (AirflowNetworkCompData(j).CompTypeNum
5020 : // == iComponentTypeNum::COI) CompName(2) = "AirflowNetwork:Distribution:Component:Coil"; if
5021 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::TMU) CompName(2) =
5022 : // "AirflowNetwork:Distribution:Component:TerminalUnit"; if (AirflowNetworkCompData(j).CompTypeNum ==
5023 : // iComponentTypeNum::HEX) CompName(2) = "AirflowNetwork:Distribution:Component:HeatExchanger"; ShowSevereError(m_state,
5024 : // format(RoutineName) + "Duplicated component names are found = " + AirflowNetworkCompData(i).Name);
5025 : // ShowContinueError(m_state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
5026 : // ErrorsFound = true;
5027 : // }
5028 : // }
5029 : // }
5030 : // }
5031 :
5032 : // Node and component validation
5033 1215 : for (count = 1; count <= AirflowNetworkNumOfLinks; ++count) {
5034 1181 : NodeFound = false;
5035 15120 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5036 15120 : if (i == AirflowNetworkLinkageData(count).NodeNums[0]) {
5037 1181 : NodeFound = true;
5038 1181 : break;
5039 : }
5040 : }
5041 1181 : if (!NodeFound) {
5042 0 : if (count <= AirflowNetworkNumOfSurfaces) {
5043 0 : ShowSevereError(m_state,
5044 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
5045 0 : " in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name + " is not found");
5046 : } else {
5047 0 : ShowSevereError(m_state,
5048 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
5049 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
5050 : " is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE objects.");
5051 : }
5052 0 : ErrorsFound = true;
5053 : }
5054 1181 : NodeFound = false;
5055 16828 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5056 16828 : if (i == AirflowNetworkLinkageData(count).NodeNums[1]) {
5057 1181 : NodeFound = true;
5058 1181 : break;
5059 : }
5060 : }
5061 1181 : if (!NodeFound) {
5062 0 : if (count <= AirflowNetworkNumOfSurfaces) {
5063 0 : ShowSevereError(m_state,
5064 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
5065 0 : " in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name + " is not found");
5066 : } else {
5067 0 : ShowSevereError(m_state,
5068 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[1] +
5069 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
5070 : " is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE objects.");
5071 : }
5072 0 : ErrorsFound = true;
5073 : }
5074 1181 : CompFound = false;
5075 32340 : for (int i = 1; i <= AirflowNetworkNumOfComps; ++i) {
5076 31159 : if (i == AirflowNetworkLinkageData(count).CompNum) {
5077 1181 : CompFound = true;
5078 : }
5079 : }
5080 1181 : if (!CompFound) {
5081 0 : ShowSevereError(m_state,
5082 0 : format(RoutineName) + "Component = " + AirflowNetworkLinkageData(count).CompName +
5083 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
5084 : " is not found in AirflowNetwork Component Data objects.");
5085 0 : ErrorsFound = true;
5086 : }
5087 : }
5088 :
5089 : // Ensure every AirflowNetworkNode is used in AirflowNetworkLinkage
5090 860 : for (count = 1; count <= AirflowNetworkNumOfNodes; ++count) {
5091 826 : NodeFound1 = false;
5092 826 : NodeFound2 = false;
5093 38724 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
5094 37898 : if (count == AirflowNetworkLinkageData(i).NodeNums[0]) {
5095 1181 : NodeFound1 = true;
5096 : }
5097 37898 : if (count == AirflowNetworkLinkageData(i).NodeNums[1]) {
5098 1181 : NodeFound2 = true;
5099 : }
5100 : }
5101 826 : if ((!NodeFound1) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum == 0) {
5102 0 : ShowSevereError(m_state,
5103 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5104 : " is not found as Node 1 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5105 0 : ShowContinueError(m_state,
5106 : "Each non-external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined as Node 1 once in "
5107 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5108 0 : ErrorsFound = true;
5109 : }
5110 826 : if ((!NodeFound2) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum == 0) {
5111 0 : ShowSevereError(m_state,
5112 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5113 : " is not found as Node 2 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5114 0 : ShowContinueError(m_state,
5115 : "Each non-external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined as Node 2 once in "
5116 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5117 0 : ErrorsFound = true;
5118 : }
5119 826 : if ((!NodeFound1) && (!NodeFound2) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum > 0) {
5120 0 : ShowSevereError(m_state,
5121 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5122 : " is not found as Node 1 Name or Node 2 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5123 0 : ShowContinueError(m_state, "This external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5124 0 : ErrorsFound = true;
5125 : }
5126 : }
5127 :
5128 : // Ensure there is at least one node defined as EXTERNAL node
5129 34 : NodeFound = false;
5130 860 : for (count = 1; count <= AirflowNetworkNumOfNodes; ++count) {
5131 826 : if (AirflowNetworkNodeData(count).ExtNodeNum > 0) {
5132 195 : NodeFound = true;
5133 : }
5134 : }
5135 34 : if (!NodeFound) {
5136 0 : ShowSevereError(m_state,
5137 0 : format(RoutineName) +
5138 : "No External Nodes found in AirflowNetwork:Multizone:ExternalNode. There must be at least 1 external node defined.");
5139 0 : ErrorsFound = true;
5140 : }
5141 :
5142 34 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
5143 427 : for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
5144 400 : if (AirflowNetworkLinkageData(count).NodeNums[0] == 0) {
5145 0 : ShowSevereError(m_state,
5146 0 : "The surface is not found in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name);
5147 0 : ErrorsFound = true;
5148 : }
5149 400 : if (AirflowNetworkLinkageData(count).NodeNums[1] == 0) {
5150 0 : ShowSevereError(m_state,
5151 0 : "The external node is not found in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name);
5152 0 : ErrorsFound = true;
5153 : }
5154 : }
5155 : }
5156 :
5157 : // Provide a warning when a door component is assigned as envelope leakage
5158 : // if (!ErrorsFound) {
5159 : // for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
5160 : // if
5161 : // (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).ExtNodeNum
5162 : // > 0 &&
5163 : // AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum
5164 : // > 0 && AirflowNetworkLinkageData(count).CompNum > 0) { if
5165 : // (AirflowNetworkCompData(AirflowNetworkLinkageData(count).CompNum).CompTypeNum
5166 : // == iComponentTypeNum::SOP) {
5167 : // }
5168 : // }
5169 : // if
5170 : // (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).ExtNodeNum
5171 : // > 0 &&
5172 : // AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum
5173 : // > 0 && AirflowNetworkLinkageData(count).CompNum > 0) { if
5174 : // (AirflowNetworkCompData(AirflowNetworkLinkageData(count).CompNum).CompTypeNum
5175 : // == iComponentTypeNum::SOP) {
5176 : // }
5177 : // }
5178 : // }
5179 : // }
5180 :
5181 : // Ensure the name of each heat exchanger is shown either once or twice in the field of
5182 34 : if (distribution_simulated) {
5183 24 : for (int i = 1; i <= DisSysNumOfHXs; ++i) {
5184 1 : count = 0;
5185 61 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
5186 60 : if (UtilityRoutines::SameString(AirflowNetworkLinkageData(j).CompName, DisSysCompHXData(i).name)) {
5187 2 : ++count;
5188 : }
5189 : }
5190 :
5191 1 : if (DisSysCompHXData(i).CoilParentExists && count != 2) {
5192 0 : ShowSevereError(m_state,
5193 0 : format(RoutineName) + "The inputs of component name field as a heat exchanger in "
5194 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE is not correct");
5195 0 : ShowContinueError(m_state,
5196 0 : "The entered name of heat exchanger is " + DisSysCompHXData(i).name +
5197 : " in AirflowNetwork:Distribution:Component:HeatExchanger objects");
5198 0 : ShowContinueError(m_state, format("The correct appearance number is 2. The entered appearance number is {}", count));
5199 0 : ErrorsFound = true;
5200 : }
5201 1 : if ((!DisSysCompHXData(i).CoilParentExists) && count != 1) {
5202 0 : ShowSevereError(m_state,
5203 0 : format(RoutineName) + "The inputs of component name field as a heat exchanger in "
5204 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE is not correct");
5205 0 : ShowContinueError(m_state,
5206 0 : "The entered name of heat exchanger is " + DisSysCompHXData(i).name +
5207 : " in AirflowNetwork:Distribution:Component:HeatExchanger objects");
5208 0 : ShowContinueError(m_state, format("The correct appearance number is 1. The entered appearance number is {}", count));
5209 0 : ErrorsFound = true;
5210 : }
5211 : }
5212 : }
5213 :
5214 : // Check node assignments using AirflowNetwork:Distribution:Component:OutdoorAirFlow or
5215 : // AirflowNetwork:Distribution:Component:ReliefAirFlow
5216 735 : for (count = AirflowNetworkNumOfSurfaces + 1; count <= AirflowNetworkNumOfLinks; ++count) {
5217 701 : int i = AirflowNetworkLinkageData(count).CompNum;
5218 701 : j = AirflowNetworkLinkageData(count).NodeNums[0];
5219 701 : k = AirflowNetworkLinkageData(count).NodeNums[1];
5220 :
5221 701 : if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::OAF) {
5222 2 : if (!UtilityRoutines::SameString(DisSysNodeData(j - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
5223 0 : ShowSevereError(m_state,
5224 0 : format(RoutineName) +
5225 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5226 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5227 0 : AirflowNetworkNodeData(j).Name + ",");
5228 0 : ShowContinueError(
5229 0 : m_state, "the component type in the first node should be OAMixerOutdoorAirStreamNode at " + AirflowNetworkNodeData(j).Name);
5230 0 : ErrorsFound = true;
5231 : }
5232 2 : if (!UtilityRoutines::SameString(DisSysNodeData(k - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
5233 0 : ShowSevereError(m_state,
5234 0 : format(RoutineName) +
5235 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5236 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5237 0 : AirflowNetworkNodeData(k).Name + ",");
5238 0 : ShowContinueError(m_state,
5239 0 : "the component object type in the second node should be AirLoopHVAC:OutdoorAirSystem at " +
5240 0 : AirflowNetworkNodeData(k).Name);
5241 0 : ErrorsFound = true;
5242 : }
5243 : }
5244 :
5245 701 : if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::REL) {
5246 2 : if (!UtilityRoutines::SameString(DisSysNodeData(j - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
5247 0 : ShowSevereError(m_state,
5248 0 : format(RoutineName) +
5249 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5250 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5251 0 : AirflowNetworkNodeData(j).Name + ",");
5252 0 : ShowContinueError(m_state,
5253 0 : "the component object type in the first node should be AirLoopHVAC:OutdoorAirSystem at " +
5254 0 : AirflowNetworkNodeData(j).Name);
5255 0 : ErrorsFound = true;
5256 : }
5257 2 : if (!UtilityRoutines::SameString(DisSysNodeData(k - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
5258 0 : ShowSevereError(m_state,
5259 0 : format(RoutineName) +
5260 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5261 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5262 0 : AirflowNetworkNodeData(k).Name + ",");
5263 0 : ShowContinueError(
5264 0 : m_state, "the component type in the second node should be OAMixerOutdoorAirStreamNode at " + AirflowNetworkNodeData(k).Name);
5265 0 : ErrorsFound = true;
5266 : }
5267 : }
5268 : }
5269 :
5270 34 : if (ErrorsFound) {
5271 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
5272 : }
5273 :
5274 34 : Alphas.deallocate();
5275 34 : cAlphaFields.deallocate();
5276 34 : cNumericFields.deallocate();
5277 34 : Numbers.deallocate();
5278 34 : lAlphaBlanks.deallocate();
5279 34 : lNumericBlanks.deallocate();
5280 :
5281 34 : if (!ErrorsFound) {
5282 34 : allocate_and_initialize();
5283 : }
5284 : }
5285 :
5286 656873 : void Solver::initialize()
5287 : {
5288 : // SUBROUTINE INFORMATION:
5289 : // AUTHOR Lixing Gu
5290 : // DATE WRITTEN Aug. 2003
5291 : // MODIFIED na
5292 : // RE-ENGINEERED na
5293 :
5294 : // PURPOSE OF THIS SUBROUTINE:
5295 : // This subroutine initializes variables of additional zone loads caused by ADS.
5296 :
5297 : // USE STATEMENTS:
5298 656873 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
5299 :
5300 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5301 : int i;
5302 : int j;
5303 : int ZoneNum;
5304 656873 : auto &Zone(m_state.dataHeatBal->Zone);
5305 :
5306 656873 : if (initializeOneTimeFlag) {
5307 34 : exchangeData.allocate(m_state.dataGlobal->NumOfZones); // AirflowNetwork exchange data due to air-forced system
5308 49 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5309 24 : if (DisSysCompCVFData(i).FanTypeNum == AirflowNetwork::FanType_SimpleOnOff) {
5310 9 : multiExchangeData.allocate(m_state.dataGlobal->NumOfZones);
5311 9 : break;
5312 : }
5313 : }
5314 :
5315 34 : initializeOneTimeFlag = false;
5316 34 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5317 5 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5318 16 : SetupOutputVariable(m_state,
5319 : "AFN Zone Outdoor Air Mass Flow Rate",
5320 : OutputProcessor::Unit::kg_s,
5321 4 : exchangeData(i).SumMHr,
5322 : OutputProcessor::SOVTimeStepType::System,
5323 : OutputProcessor::SOVStoreType::Average,
5324 8 : Zone(i).Name);
5325 16 : SetupOutputVariable(m_state,
5326 : "AFN Zone Mixing Mass Flow Rate",
5327 : OutputProcessor::Unit::kg_s,
5328 4 : exchangeData(i).SumMMHr,
5329 : OutputProcessor::SOVTimeStepType::System,
5330 : OutputProcessor::SOVStoreType::Average,
5331 8 : Zone(i).Name);
5332 16 : SetupOutputVariable(m_state,
5333 : "AFN Zone Outdoor Air CO2 Mass Flow Rate",
5334 : OutputProcessor::Unit::kg_s,
5335 4 : exchangeData(i).SumMHrCO,
5336 : OutputProcessor::SOVTimeStepType::System,
5337 : OutputProcessor::SOVStoreType::Average,
5338 8 : Zone(i).Name);
5339 16 : SetupOutputVariable(m_state,
5340 : "AFN Zone Mixing CO2 Mass Flow Rate",
5341 : OutputProcessor::Unit::kg_s,
5342 4 : exchangeData(i).SumMMHrCO,
5343 : OutputProcessor::SOVTimeStepType::System,
5344 : OutputProcessor::SOVStoreType::Average,
5345 8 : Zone(i).Name);
5346 16 : SetupOutputVariable(m_state,
5347 : "AFN Zone Total CO2 Mass Flow Rate",
5348 : OutputProcessor::Unit::kg_s,
5349 4 : exchangeData(i).TotalCO2,
5350 : OutputProcessor::SOVTimeStepType::System,
5351 : OutputProcessor::SOVStoreType::Average,
5352 8 : Zone(i).Name);
5353 : }
5354 : }
5355 34 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5356 5 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5357 4 : if (!m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5358 16 : SetupOutputVariable(m_state,
5359 : "AFN Zone Outdoor Air Mass Flow Rate",
5360 : OutputProcessor::Unit::kg_s,
5361 4 : exchangeData(i).SumMHr,
5362 : OutputProcessor::SOVTimeStepType::System,
5363 : OutputProcessor::SOVStoreType::Average,
5364 8 : Zone(i).Name);
5365 16 : SetupOutputVariable(m_state,
5366 : "AFN Zone Mixing Mass Flow Rate",
5367 : OutputProcessor::Unit::kg_s,
5368 4 : exchangeData(i).SumMMHr,
5369 : OutputProcessor::SOVTimeStepType::System,
5370 : OutputProcessor::SOVStoreType::Average,
5371 8 : Zone(i).Name);
5372 : }
5373 16 : SetupOutputVariable(m_state,
5374 : "AFN Zone Outdoor Air Generic Air Contaminant Mass Flow Rate",
5375 : OutputProcessor::Unit::kg_s,
5376 4 : exchangeData(i).SumMHrGC,
5377 : OutputProcessor::SOVTimeStepType::System,
5378 : OutputProcessor::SOVStoreType::Average,
5379 8 : Zone(i).Name);
5380 16 : SetupOutputVariable(m_state,
5381 : "AFN Zone Mixing Generic Air Contaminant Mass Flow Rate",
5382 : OutputProcessor::Unit::kg_s,
5383 4 : exchangeData(i).SumMMHrGC,
5384 : OutputProcessor::SOVTimeStepType::System,
5385 : OutputProcessor::SOVStoreType::Average,
5386 8 : Zone(i).Name);
5387 16 : SetupOutputVariable(m_state,
5388 : "AFN Zone Total Generic Air Contaminant Mass Flow Rate",
5389 : OutputProcessor::Unit::kg_s,
5390 4 : exchangeData(i).TotalGC,
5391 : OutputProcessor::SOVTimeStepType::System,
5392 : OutputProcessor::SOVStoreType::Average,
5393 8 : Zone(i).Name);
5394 : }
5395 : }
5396 : }
5397 :
5398 656873 : if (m_state.dataGlobal->BeginEnvrnFlag && initializeMyEnvrnFlag) {
5399 : // Assign node values
5400 5447 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5401 5235 : AirflowNetworkNodeSimu(i).TZ = 23.0;
5402 5235 : AirflowNetworkNodeSimu(i).WZ = 0.00084;
5403 5235 : AirflowNetworkNodeSimu(i).PZ = 0.0;
5404 5235 : AirflowNetworkNodeSimu(i).TZlast = AirflowNetworkNodeSimu(i).TZ;
5405 5235 : AirflowNetworkNodeSimu(i).WZlast = AirflowNetworkNodeSimu(i).WZ;
5406 5235 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5407 222 : AirflowNetworkNodeSimu(i).CO2Z = m_state.dataContaminantBalance->OutdoorCO2;
5408 222 : AirflowNetworkNodeSimu(i).CO2Zlast = AirflowNetworkNodeSimu(i).CO2Z;
5409 : }
5410 5235 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5411 222 : AirflowNetworkNodeSimu(i).GCZ = m_state.dataContaminantBalance->OutdoorGC;
5412 222 : AirflowNetworkNodeSimu(i).GCZlast = AirflowNetworkNodeSimu(i).GCZ;
5413 : }
5414 5235 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
5415 54 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
5416 54 : m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp = 23.0;
5417 54 : m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat = 0.0;
5418 : }
5419 : }
5420 :
5421 7713 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
5422 7501 : AirflowNetworkLinkSimu(i).FLOW = 0.0;
5423 7501 : AirflowNetworkLinkSimu(i).FLOW2 = 0.0;
5424 : }
5425 :
5426 915 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5427 703 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT;
5428 703 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).ZoneAirHumRat;
5429 703 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5430 24 : ANCO(i) = m_state.dataContaminantBalance->ZoneAirCO2(i);
5431 : }
5432 703 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5433 24 : ANGC(i) = m_state.dataContaminantBalance->ZoneAirGC(i);
5434 : }
5435 : }
5436 212 : if (AirflowNetworkNumOfOccuVentCtrls > 0) {
5437 70 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5438 65 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5439 10 : MultizoneSurfaceData(i).PrevOpeningstatus = AirflowNetwork::OpenStatus::FreeOperation;
5440 10 : MultizoneSurfaceData(i).CloseElapsedTime = 0.0;
5441 10 : MultizoneSurfaceData(i).OpenElapsedTime = 0.0;
5442 10 : MultizoneSurfaceData(i).OpeningStatus = AirflowNetwork::OpenStatus::FreeOperation;
5443 10 : MultizoneSurfaceData(i).OpeningProbStatus = AirflowNetwork::ProbabilityCheck::NoAction;
5444 10 : MultizoneSurfaceData(i).ClosingProbStatus = 0;
5445 : }
5446 : }
5447 : }
5448 :
5449 212 : initializeMyEnvrnFlag = false;
5450 : }
5451 656873 : if (!m_state.dataGlobal->BeginEnvrnFlag) {
5452 654645 : initializeMyEnvrnFlag = true;
5453 654645 : if (simulation_control.type != ControlType::NoMultizoneOrDistribution) {
5454 654645 : if (RollBackFlag) {
5455 0 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5456 0 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).XMAT[0];
5457 0 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).WPrevZoneTS[0];
5458 0 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) ANCO(i) = m_state.dataContaminantBalance->CO2ZoneTimeMinus1(i);
5459 0 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5460 0 : ANGC(i) = m_state.dataContaminantBalance->GCZoneTimeMinus1(i);
5461 : }
5462 : } else {
5463 2606239 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5464 1951594 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT;
5465 1951594 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).ZoneAirHumRat;
5466 1951594 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) ANCO(i) = m_state.dataContaminantBalance->ZoneAirCO2(i);
5467 1951594 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5468 36048 : ANGC(i) = m_state.dataContaminantBalance->ZoneAirGC(i);
5469 : }
5470 : }
5471 :
5472 18461897 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5473 17807252 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0) {
5474 2029039 : AirflowNetworkNodeSimu(i).TZ = ANZT(AirflowNetworkNodeData(i).EPlusZoneNum);
5475 2029039 : AirflowNetworkNodeSimu(i).WZ = ANZW(AirflowNetworkNodeData(i).EPlusZoneNum);
5476 2029039 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5477 45744 : AirflowNetworkNodeSimu(i).CO2Z = ANCO(AirflowNetworkNodeData(i).EPlusZoneNum);
5478 2029039 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5479 36048 : AirflowNetworkNodeSimu(i).GCZ = ANGC(AirflowNetworkNodeData(i).EPlusZoneNum);
5480 : }
5481 17807252 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
5482 5098341 : if (AirflowNetworkNodeData(i).OutAirNodeNum > 0 &&
5483 16958 : m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).IsLocalNode) {
5484 16958 : AirflowNetworkNodeSimu(i).TZ = m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).OutAirDryBulb;
5485 16958 : AirflowNetworkNodeSimu(i).WZ = m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).HumRat;
5486 : } else {
5487 5064425 : AirflowNetworkNodeSimu(i).TZ = AirflowNetwork::OutDryBulbTempAt(m_state, AirflowNetworkNodeData(i).NodeHeight);
5488 5064425 : AirflowNetworkNodeSimu(i).WZ = m_state.dataEnvrn->OutHumRat;
5489 : }
5490 :
5491 5081383 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5492 68616 : AirflowNetworkNodeSimu(i).CO2Z = m_state.dataContaminantBalance->OutdoorCO2;
5493 5081383 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5494 54072 : AirflowNetworkNodeSimu(i).GCZ = m_state.dataContaminantBalance->OutdoorGC;
5495 : }
5496 :
5497 17807252 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
5498 92934 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
5499 185868 : if (m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum)
5500 92934 : .Node(AirflowNetworkNodeData(i).RAFNNodeNum)
5501 92934 : .AirflowNetworkNodeID == i) {
5502 92934 : AirflowNetworkNodeSimu(i).TZ =
5503 92934 : m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp;
5504 92934 : AirflowNetworkNodeSimu(i).WZ =
5505 92934 : m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat;
5506 : }
5507 : }
5508 : }
5509 : }
5510 : }
5511 :
5512 2615440 : for (auto &e : exchangeData) {
5513 1958567 : e.TotalSen = 0.0;
5514 1958567 : e.TotalLat = 0.0;
5515 1958567 : e.MultiZoneSen = 0.0;
5516 1958567 : e.MultiZoneLat = 0.0;
5517 1958567 : e.LeakSen = 0.0;
5518 1958567 : e.LeakLat = 0.0;
5519 1958567 : e.CondSen = 0.0;
5520 1958567 : e.DiffLat = 0.0;
5521 1958567 : e.RadGain = 0.0;
5522 : }
5523 656873 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5524 57420 : for (auto &e : exchangeData)
5525 45936 : e.TotalCO2 = 0.0;
5526 656873 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5527 45300 : for (auto &e : exchangeData)
5528 36240 : e.TotalGC = 0.0;
5529 :
5530 : // Occupant ventilation control
5531 656873 : Real64 CurrentEndTime = m_state.dataGlobal->CurrentTime + m_state.dataHVACGlobal->SysTimeElapsed;
5532 656873 : if (CurrentEndTime > CurrentEndTimeLast && TimeStepSys >= TimeStepSysLast) {
5533 2202914 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5534 2065591 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) continue;
5535 2015772 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5536 5192 : MultizoneSurfaceData(i).PrevOpeningstatus = MultizoneSurfaceData(i).OpeningStatus;
5537 5192 : MultizoneSurfaceData(i).OpenFactorLast = MultizoneSurfaceData(i).OpenFactor;
5538 5192 : if (MultizoneSurfaceData(i).OpenFactor > 0.0) {
5539 1832 : MultizoneSurfaceData(i).OpenElapsedTime += (CurrentEndTime - CurrentEndTimeLast) * 60.0;
5540 1832 : MultizoneSurfaceData(i).CloseElapsedTime = 0.0;
5541 : } else {
5542 3360 : MultizoneSurfaceData(i).OpenElapsedTime = 0.0;
5543 3360 : MultizoneSurfaceData(i).CloseElapsedTime += (CurrentEndTime - CurrentEndTimeLast) * 60.0;
5544 : }
5545 5192 : j = MultizoneSurfaceData(i).SurfNum;
5546 5192 : OccupantVentilationControl(MultizoneSurfaceData(i).OccupantVentilationControlNum)
5547 31152 : .calc(m_state,
5548 5192 : m_state.dataSurface->Surface(j).Zone,
5549 5192 : MultizoneSurfaceData(i).OpenElapsedTime,
5550 5192 : MultizoneSurfaceData(i).CloseElapsedTime,
5551 5192 : MultizoneSurfaceData(i).OpeningStatus,
5552 5192 : MultizoneSurfaceData(i).OpeningProbStatus,
5553 5192 : MultizoneSurfaceData(i).ClosingProbStatus);
5554 5192 : if (MultizoneSurfaceData(i).OpeningStatus == AirflowNetwork::OpenStatus::MinCheckForceOpen) {
5555 210 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).OpenFactorLast;
5556 : }
5557 5192 : if (MultizoneSurfaceData(i).OpeningStatus == AirflowNetwork::OpenStatus::MinCheckForceClose) {
5558 236 : MultizoneSurfaceData(i).OpenFactor = 0.0;
5559 : }
5560 : }
5561 : }
5562 : }
5563 656873 : TimeStepSysLast = TimeStepSys;
5564 656873 : CurrentEndTimeLast = CurrentEndTime;
5565 656873 : }
5566 :
5567 34 : void Solver::allocate_and_initialize()
5568 : {
5569 :
5570 : // SUBROUTINE INFORMATION:
5571 : // AUTHOR Lixing Gu
5572 : // DATE WRITTEN Aug. 2003
5573 : // MODIFIED na
5574 : // RE-ENGINEERED na
5575 :
5576 : // PURPOSE OF THIS SUBROUTINE:
5577 : // This subroutine initializes variables and allocates dynamic arrays.
5578 :
5579 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5580 : int i;
5581 : int ZoneNum;
5582 : int n;
5583 : int SurfNum;
5584 34 : auto &Zone(m_state.dataHeatBal->Zone);
5585 :
5586 34 : AirflowNetworkNodeSimu.allocate(AirflowNetworkNumOfNodes); // Node simulation variable in air distribution system
5587 34 : AirflowNetworkLinkSimu.allocate(AirflowNetworkNumOfLinks); // Link simulation variable in air distribution system
5588 34 : linkReport.allocate(AirflowNetworkNumOfLinks); // Report link simulation variable in air distribution system
5589 :
5590 49 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5591 24 : if (DisSysCompCVFData(i).FanTypeNum == FanType_SimpleOnOff) {
5592 9 : nodeReport.allocate(AirflowNetworkNumOfZones);
5593 9 : linkReport1.allocate(AirflowNetworkNumOfSurfaces);
5594 9 : break;
5595 : }
5596 : }
5597 :
5598 34 : MA.allocate(AirflowNetworkNumOfNodes * AirflowNetworkNumOfNodes);
5599 34 : MV.allocate(AirflowNetworkNumOfNodes);
5600 34 : IVEC.allocate(AirflowNetworkNumOfNodes + 20);
5601 :
5602 34 : AirflowNetworkReportData.allocate(m_state.dataGlobal->NumOfZones); // Report variables
5603 34 : AirflowNetworkZnRpt.allocate(m_state.dataGlobal->NumOfZones); // Report variables
5604 :
5605 34 : ANZT.allocate(m_state.dataGlobal->NumOfZones); // Local zone air temperature for rollback use
5606 34 : ANZW.allocate(m_state.dataGlobal->NumOfZones); // Local zone humidity ratio for rollback use
5607 34 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5608 1 : ANCO.allocate(m_state.dataGlobal->NumOfZones); // Local zone CO2 for rollback use
5609 34 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5610 1 : ANGC.allocate(m_state.dataGlobal->NumOfZones); // Local zone generic contaminant for rollback use
5611 34 : allocate();
5612 :
5613 34 : bool OnOffFanFlag = false;
5614 58 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5615 24 : if (DisSysCompCVFData(i).FanTypeNum == FanType_SimpleOnOff) {
5616 9 : OnOffFanFlag = true;
5617 : }
5618 : }
5619 :
5620 : // CurrentModuleObject='AirflowNetwork Simulations'
5621 860 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5622 3304 : SetupOutputVariable(m_state,
5623 : "AFN Node Temperature",
5624 : OutputProcessor::Unit::C,
5625 826 : AirflowNetworkNodeSimu(i).TZ,
5626 : OutputProcessor::SOVTimeStepType::System,
5627 : OutputProcessor::SOVStoreType::Average,
5628 1652 : AirflowNetworkNodeData(i).Name);
5629 3304 : SetupOutputVariable(m_state,
5630 : "AFN Node Humidity Ratio",
5631 : OutputProcessor::Unit::kgWater_kgDryAir,
5632 826 : AirflowNetworkNodeSimu(i).WZ,
5633 : OutputProcessor::SOVTimeStepType::System,
5634 : OutputProcessor::SOVStoreType::Average,
5635 1652 : AirflowNetworkNodeData(i).Name);
5636 826 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5637 148 : SetupOutputVariable(m_state,
5638 : "AFN Node CO2 Concentration",
5639 : OutputProcessor::Unit::ppm,
5640 37 : AirflowNetworkNodeSimu(i).CO2Z,
5641 : OutputProcessor::SOVTimeStepType::System,
5642 : OutputProcessor::SOVStoreType::Average,
5643 74 : AirflowNetworkNodeData(i).Name);
5644 : }
5645 826 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5646 148 : SetupOutputVariable(m_state,
5647 : "AFN Node Generic Air Contaminant Concentration",
5648 : OutputProcessor::Unit::ppm,
5649 37 : AirflowNetworkNodeSimu(i).GCZ,
5650 : OutputProcessor::SOVTimeStepType::System,
5651 : OutputProcessor::SOVStoreType::Average,
5652 74 : AirflowNetworkNodeData(i).Name);
5653 : }
5654 826 : if (!(SupplyFanType == FanType_SimpleOnOff && i <= AirflowNetworkNumOfZones)) {
5655 3196 : SetupOutputVariable(m_state,
5656 : "AFN Node Total Pressure",
5657 : OutputProcessor::Unit::Pa,
5658 799 : AirflowNetworkNodeSimu(i).PZ,
5659 : OutputProcessor::SOVTimeStepType::System,
5660 : OutputProcessor::SOVStoreType::Average,
5661 1598 : AirflowNetworkNodeData(i).Name);
5662 : }
5663 826 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
5664 780 : SetupOutputVariable(m_state,
5665 : "AFN Node Wind Pressure",
5666 : OutputProcessor::Unit::Pa,
5667 195 : AirflowNetworkNodeSimu(i).PZ,
5668 : OutputProcessor::SOVTimeStepType::System,
5669 : OutputProcessor::SOVStoreType::Average,
5670 390 : AirflowNetworkNodeData(i).Name);
5671 : }
5672 : }
5673 :
5674 1215 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
5675 1181 : if (!(SupplyFanType == FanType_SimpleOnOff && i <= AirflowNetworkNumOfSurfaces)) {
5676 4384 : SetupOutputVariable(m_state,
5677 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
5678 : OutputProcessor::Unit::kg_s,
5679 1096 : linkReport(i).FLOW,
5680 : OutputProcessor::SOVTimeStepType::System,
5681 : OutputProcessor::SOVStoreType::Average,
5682 2192 : AirflowNetworkLinkageData(i).Name);
5683 4384 : SetupOutputVariable(m_state,
5684 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
5685 : OutputProcessor::Unit::kg_s,
5686 1096 : linkReport(i).FLOW2,
5687 : OutputProcessor::SOVTimeStepType::System,
5688 : OutputProcessor::SOVStoreType::Average,
5689 2192 : AirflowNetworkLinkageData(i).Name);
5690 4384 : SetupOutputVariable(m_state,
5691 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
5692 : OutputProcessor::Unit::m3_s,
5693 1096 : linkReport(i).VolFLOW,
5694 : OutputProcessor::SOVTimeStepType::System,
5695 : OutputProcessor::SOVStoreType::Average,
5696 2192 : AirflowNetworkLinkageData(i).Name);
5697 4384 : SetupOutputVariable(m_state,
5698 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
5699 : OutputProcessor::Unit::m3_s,
5700 1096 : linkReport(i).VolFLOW2,
5701 : OutputProcessor::SOVTimeStepType::System,
5702 : OutputProcessor::SOVStoreType::Average,
5703 2192 : AirflowNetworkLinkageData(i).Name);
5704 4384 : SetupOutputVariable(m_state,
5705 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
5706 : OutputProcessor::Unit::Pa,
5707 1096 : AirflowNetworkLinkSimu(i).DP,
5708 : OutputProcessor::SOVTimeStepType::System,
5709 : OutputProcessor::SOVStoreType::Average,
5710 2192 : AirflowNetworkLinkageData(i).Name);
5711 : }
5712 : }
5713 :
5714 514 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5715 480 : if (AirflowNetworkLinkageData(i).element == nullptr) {
5716 : // This is not great
5717 0 : continue;
5718 : }
5719 480 : n = AirflowNetworkLinkageData(i).CompNum;
5720 1370 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::DOP ||
5721 873 : AirflowNetworkLinkageData(i).element->type() == ComponentType::SOP ||
5722 393 : AirflowNetworkLinkageData(i).element->type() == ComponentType::HOP) {
5723 88 : SurfNum = MultizoneSurfaceData(i).SurfNum;
5724 352 : SetupOutputVariable(m_state,
5725 : "AFN Surface Venting Window or Door Opening Factor",
5726 : OutputProcessor::Unit::None,
5727 88 : MultizoneSurfaceData(i).OpenFactor,
5728 : OutputProcessor::SOVTimeStepType::System,
5729 : OutputProcessor::SOVStoreType::Average,
5730 176 : MultizoneSurfaceData(i).SurfName);
5731 88 : if (m_state.dataGlobal->AnyEnergyManagementSystemInModel) {
5732 40 : SetupEMSActuator(m_state,
5733 : "AirFlow Network Window/Door Opening",
5734 10 : MultizoneSurfaceData(i).SurfName,
5735 : "Venting Opening Factor",
5736 : "[Fraction]",
5737 10 : MultizoneSurfaceData(i).EMSOpenFactorActuated,
5738 30 : MultizoneSurfaceData(i).EMSOpenFactor);
5739 : }
5740 264 : SetupOutputVariable(m_state,
5741 : "AFN Surface Venting Window or Door Opening Modulation Multiplier",
5742 : OutputProcessor::Unit::None,
5743 88 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum),
5744 : OutputProcessor::SOVTimeStepType::System,
5745 : OutputProcessor::SOVStoreType::Average,
5746 176 : m_state.dataSurface->Surface(SurfNum).Name);
5747 264 : SetupOutputVariable(m_state,
5748 : "AFN Surface Venting Inside Setpoint Temperature",
5749 : OutputProcessor::Unit::C,
5750 88 : m_state.dataSurface->SurfWinInsideTempForVentingRep(SurfNum),
5751 : OutputProcessor::SOVTimeStepType::System,
5752 : OutputProcessor::SOVStoreType::Average,
5753 176 : m_state.dataSurface->Surface(SurfNum).Name);
5754 264 : SetupOutputVariable(m_state,
5755 : "AFN Surface Venting Availability Status",
5756 : OutputProcessor::Unit::None,
5757 88 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum),
5758 : OutputProcessor::SOVTimeStepType::System,
5759 : OutputProcessor::SOVStoreType::Average,
5760 176 : m_state.dataSurface->Surface(SurfNum).Name);
5761 88 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5762 8 : SetupOutputVariable(m_state,
5763 : "AFN Surface Venting Window or Door Opening Factor at Previous Time Step",
5764 : OutputProcessor::Unit::None,
5765 2 : MultizoneSurfaceData(i).OpenFactorLast,
5766 : OutputProcessor::SOVTimeStepType::System,
5767 : OutputProcessor::SOVStoreType::Average,
5768 4 : MultizoneSurfaceData(i).SurfName);
5769 8 : SetupOutputVariable(m_state,
5770 : "AFN Surface Opening Elapsed Time",
5771 : OutputProcessor::Unit::min,
5772 2 : MultizoneSurfaceData(i).OpenElapsedTime,
5773 : OutputProcessor::SOVTimeStepType::System,
5774 : OutputProcessor::SOVStoreType::Average,
5775 4 : MultizoneSurfaceData(i).SurfName);
5776 8 : SetupOutputVariable(m_state,
5777 : "AFN Surface Closing Elapsed Time",
5778 : OutputProcessor::Unit::min,
5779 2 : MultizoneSurfaceData(i).CloseElapsedTime,
5780 : OutputProcessor::SOVTimeStepType::System,
5781 : OutputProcessor::SOVStoreType::Average,
5782 4 : MultizoneSurfaceData(i).SurfName);
5783 8 : SetupOutputVariable(m_state,
5784 : "AFN Surface Opening Status at Previous Time Step",
5785 : OutputProcessor::Unit::None,
5786 2 : MultizoneSurfaceData(i).PrevOpeningstatus,
5787 : OutputProcessor::SOVTimeStepType::System,
5788 : OutputProcessor::SOVStoreType::Average,
5789 4 : MultizoneSurfaceData(i).SurfName);
5790 8 : SetupOutputVariable(m_state,
5791 : "AFN Surface Opening Status",
5792 : OutputProcessor::Unit::None,
5793 2 : MultizoneSurfaceData(i).OpeningStatus,
5794 : OutputProcessor::SOVTimeStepType::System,
5795 : OutputProcessor::SOVStoreType::Average,
5796 4 : MultizoneSurfaceData(i).SurfName);
5797 8 : SetupOutputVariable(m_state,
5798 : "AFN Surface Opening Probability Status",
5799 : OutputProcessor::Unit::None,
5800 2 : MultizoneSurfaceData(i).OpeningProbStatus,
5801 : OutputProcessor::SOVTimeStepType::System,
5802 : OutputProcessor::SOVStoreType::Average,
5803 4 : MultizoneSurfaceData(i).SurfName);
5804 8 : SetupOutputVariable(m_state,
5805 : "AFN Surface Closing Probability Status",
5806 : OutputProcessor::Unit::None,
5807 2 : MultizoneSurfaceData(i).ClosingProbStatus,
5808 : OutputProcessor::SOVTimeStepType::System,
5809 : OutputProcessor::SOVStoreType::Average,
5810 4 : MultizoneSurfaceData(i).SurfName);
5811 : }
5812 : }
5813 : }
5814 :
5815 146 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5816 : // Multizone losses due to force air systems
5817 448 : SetupOutputVariable(m_state,
5818 : "AFN Zone Infiltration Sensible Heat Gain Rate",
5819 : OutputProcessor::Unit::W,
5820 112 : AirflowNetworkReportData(i).MultiZoneInfiSenGainW,
5821 : OutputProcessor::SOVTimeStepType::System,
5822 : OutputProcessor::SOVStoreType::Average,
5823 224 : Zone(i).Name);
5824 448 : SetupOutputVariable(m_state,
5825 : "AFN Zone Infiltration Sensible Heat Gain Energy",
5826 : OutputProcessor::Unit::J,
5827 112 : AirflowNetworkReportData(i).MultiZoneInfiSenGainJ,
5828 : OutputProcessor::SOVTimeStepType::System,
5829 : OutputProcessor::SOVStoreType::Summed,
5830 224 : Zone(i).Name);
5831 448 : SetupOutputVariable(m_state,
5832 : "AFN Zone Ventilation Sensible Heat Gain Rate",
5833 : OutputProcessor::Unit::W,
5834 112 : AirflowNetworkReportData(i).MultiZoneVentSenGainW,
5835 : OutputProcessor::SOVTimeStepType::System,
5836 : OutputProcessor::SOVStoreType::Average,
5837 224 : Zone(i).Name);
5838 448 : SetupOutputVariable(m_state,
5839 : "AFN Zone Ventilation Sensible Heat Gain Energy",
5840 : OutputProcessor::Unit::J,
5841 112 : AirflowNetworkReportData(i).MultiZoneVentSenGainJ,
5842 : OutputProcessor::SOVTimeStepType::System,
5843 : OutputProcessor::SOVStoreType::Summed,
5844 224 : Zone(i).Name);
5845 448 : SetupOutputVariable(m_state,
5846 : "AFN Zone Mixing Sensible Heat Gain Rate",
5847 : OutputProcessor::Unit::W,
5848 112 : AirflowNetworkReportData(i).MultiZoneMixSenGainW,
5849 : OutputProcessor::SOVTimeStepType::System,
5850 : OutputProcessor::SOVStoreType::Average,
5851 224 : Zone(i).Name);
5852 448 : SetupOutputVariable(m_state,
5853 : "AFN Zone Mixing Sensible Heat Gain Energy",
5854 : OutputProcessor::Unit::J,
5855 112 : AirflowNetworkReportData(i).MultiZoneMixSenGainJ,
5856 : OutputProcessor::SOVTimeStepType::System,
5857 : OutputProcessor::SOVStoreType::Summed,
5858 224 : Zone(i).Name);
5859 448 : SetupOutputVariable(m_state,
5860 : "AFN Zone Infiltration Sensible Heat Loss Rate",
5861 : OutputProcessor::Unit::W,
5862 112 : AirflowNetworkReportData(i).MultiZoneInfiSenLossW,
5863 : OutputProcessor::SOVTimeStepType::System,
5864 : OutputProcessor::SOVStoreType::Average,
5865 224 : Zone(i).Name);
5866 448 : SetupOutputVariable(m_state,
5867 : "AFN Zone Infiltration Sensible Heat Loss Energy",
5868 : OutputProcessor::Unit::J,
5869 112 : AirflowNetworkReportData(i).MultiZoneInfiSenLossJ,
5870 : OutputProcessor::SOVTimeStepType::System,
5871 : OutputProcessor::SOVStoreType::Summed,
5872 224 : Zone(i).Name);
5873 448 : SetupOutputVariable(m_state,
5874 : "AFN Zone Ventilation Sensible Heat Loss Rate",
5875 : OutputProcessor::Unit::W,
5876 112 : AirflowNetworkReportData(i).MultiZoneVentSenLossW,
5877 : OutputProcessor::SOVTimeStepType::System,
5878 : OutputProcessor::SOVStoreType::Average,
5879 224 : Zone(i).Name);
5880 448 : SetupOutputVariable(m_state,
5881 : "AFN Zone Ventilation Sensible Heat Loss Energy",
5882 : OutputProcessor::Unit::J,
5883 112 : AirflowNetworkReportData(i).MultiZoneVentSenLossJ,
5884 : OutputProcessor::SOVTimeStepType::System,
5885 : OutputProcessor::SOVStoreType::Summed,
5886 224 : Zone(i).Name);
5887 448 : SetupOutputVariable(m_state,
5888 : "AFN Zone Mixing Sensible Heat Loss Rate",
5889 : OutputProcessor::Unit::W,
5890 112 : AirflowNetworkReportData(i).MultiZoneMixSenLossW,
5891 : OutputProcessor::SOVTimeStepType::System,
5892 : OutputProcessor::SOVStoreType::Average,
5893 224 : Zone(i).Name);
5894 448 : SetupOutputVariable(m_state,
5895 : "AFN Zone Mixing Sensible Heat Loss Energy",
5896 : OutputProcessor::Unit::J,
5897 112 : AirflowNetworkReportData(i).MultiZoneMixSenLossJ,
5898 : OutputProcessor::SOVTimeStepType::System,
5899 : OutputProcessor::SOVStoreType::Summed,
5900 224 : Zone(i).Name);
5901 448 : SetupOutputVariable(m_state,
5902 : "AFN Zone Infiltration Latent Heat Gain Rate",
5903 : OutputProcessor::Unit::W,
5904 112 : AirflowNetworkReportData(i).MultiZoneInfiLatGainW,
5905 : OutputProcessor::SOVTimeStepType::System,
5906 : OutputProcessor::SOVStoreType::Average,
5907 224 : Zone(i).Name);
5908 448 : SetupOutputVariable(m_state,
5909 : "AFN Zone Infiltration Latent Heat Gain Energy",
5910 : OutputProcessor::Unit::J,
5911 112 : AirflowNetworkReportData(i).MultiZoneInfiLatGainJ,
5912 : OutputProcessor::SOVTimeStepType::System,
5913 : OutputProcessor::SOVStoreType::Summed,
5914 224 : Zone(i).Name);
5915 448 : SetupOutputVariable(m_state,
5916 : "AFN Zone Infiltration Latent Heat Loss Rate",
5917 : OutputProcessor::Unit::W,
5918 112 : AirflowNetworkReportData(i).MultiZoneInfiLatLossW,
5919 : OutputProcessor::SOVTimeStepType::System,
5920 : OutputProcessor::SOVStoreType::Average,
5921 224 : Zone(i).Name);
5922 448 : SetupOutputVariable(m_state,
5923 : "AFN Zone Infiltration Latent Heat Loss Energy",
5924 : OutputProcessor::Unit::J,
5925 112 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ,
5926 : OutputProcessor::SOVTimeStepType::System,
5927 : OutputProcessor::SOVStoreType::Summed,
5928 224 : Zone(i).Name);
5929 448 : SetupOutputVariable(m_state,
5930 : "AFN Zone Ventilation Latent Heat Gain Rate",
5931 : OutputProcessor::Unit::W,
5932 112 : AirflowNetworkReportData(i).MultiZoneVentLatGainW,
5933 : OutputProcessor::SOVTimeStepType::System,
5934 : OutputProcessor::SOVStoreType::Average,
5935 224 : Zone(i).Name);
5936 448 : SetupOutputVariable(m_state,
5937 : "AFN Zone Ventilation Latent Heat Gain Energy",
5938 : OutputProcessor::Unit::J,
5939 112 : AirflowNetworkReportData(i).MultiZoneVentLatGainJ,
5940 : OutputProcessor::SOVTimeStepType::System,
5941 : OutputProcessor::SOVStoreType::Summed,
5942 224 : Zone(i).Name);
5943 448 : SetupOutputVariable(m_state,
5944 : "AFN Zone Ventilation Latent Heat Loss Rate",
5945 : OutputProcessor::Unit::W,
5946 112 : AirflowNetworkReportData(i).MultiZoneVentLatLossW,
5947 : OutputProcessor::SOVTimeStepType::System,
5948 : OutputProcessor::SOVStoreType::Average,
5949 224 : Zone(i).Name);
5950 448 : SetupOutputVariable(m_state,
5951 : "AFN Zone Ventilation Latent Heat Loss Energy",
5952 : OutputProcessor::Unit::J,
5953 112 : AirflowNetworkReportData(i).MultiZoneVentLatLossJ,
5954 : OutputProcessor::SOVTimeStepType::System,
5955 : OutputProcessor::SOVStoreType::Summed,
5956 224 : Zone(i).Name);
5957 448 : SetupOutputVariable(m_state,
5958 : "AFN Zone Mixing Latent Heat Gain Rate",
5959 : OutputProcessor::Unit::W,
5960 112 : AirflowNetworkReportData(i).MultiZoneMixLatGainW,
5961 : OutputProcessor::SOVTimeStepType::System,
5962 : OutputProcessor::SOVStoreType::Average,
5963 224 : Zone(i).Name);
5964 448 : SetupOutputVariable(m_state,
5965 : "AFN Zone Mixing Latent Heat Gain Energy",
5966 : OutputProcessor::Unit::J,
5967 112 : AirflowNetworkReportData(i).MultiZoneMixLatGainJ,
5968 : OutputProcessor::SOVTimeStepType::System,
5969 : OutputProcessor::SOVStoreType::Summed,
5970 224 : Zone(i).Name);
5971 448 : SetupOutputVariable(m_state,
5972 : "AFN Zone Mixing Latent Heat Loss Rate",
5973 : OutputProcessor::Unit::W,
5974 112 : AirflowNetworkReportData(i).MultiZoneMixLatLossW,
5975 : OutputProcessor::SOVTimeStepType::System,
5976 : OutputProcessor::SOVStoreType::Average,
5977 224 : Zone(i).Name);
5978 448 : SetupOutputVariable(m_state,
5979 : "AFN Zone Mixing Latent Heat Loss Energy",
5980 : OutputProcessor::Unit::J,
5981 112 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ,
5982 : OutputProcessor::SOVTimeStepType::System,
5983 : OutputProcessor::SOVStoreType::Summed,
5984 224 : Zone(i).Name);
5985 : // Supply leak losses due to force air systems
5986 448 : SetupOutputVariable(m_state,
5987 : "AFN Zone Duct Leaked Air Sensible Heat Gain Rate",
5988 : OutputProcessor::Unit::W,
5989 112 : AirflowNetworkReportData(i).LeakSenGainW,
5990 : OutputProcessor::SOVTimeStepType::System,
5991 : OutputProcessor::SOVStoreType::Average,
5992 224 : Zone(i).Name);
5993 448 : SetupOutputVariable(m_state,
5994 : "AFN Zone Duct Leaked Air Sensible Heat Gain Energy",
5995 : OutputProcessor::Unit::J,
5996 112 : AirflowNetworkReportData(i).LeakSenGainJ,
5997 : OutputProcessor::SOVTimeStepType::System,
5998 : OutputProcessor::SOVStoreType::Summed,
5999 224 : Zone(i).Name);
6000 448 : SetupOutputVariable(m_state,
6001 : "AFN Zone Duct Leaked Air Sensible Heat Loss Rate",
6002 : OutputProcessor::Unit::W,
6003 112 : AirflowNetworkReportData(i).LeakSenLossW,
6004 : OutputProcessor::SOVTimeStepType::System,
6005 : OutputProcessor::SOVStoreType::Average,
6006 224 : Zone(i).Name);
6007 448 : SetupOutputVariable(m_state,
6008 : "AFN Zone Duct Leaked Air Sensible Heat Loss Energy",
6009 : OutputProcessor::Unit::J,
6010 112 : AirflowNetworkReportData(i).LeakSenLossJ,
6011 : OutputProcessor::SOVTimeStepType::System,
6012 : OutputProcessor::SOVStoreType::Summed,
6013 224 : Zone(i).Name);
6014 448 : SetupOutputVariable(m_state,
6015 : "AFN Zone Duct Leaked Air Latent Heat Gain Rate",
6016 : OutputProcessor::Unit::W,
6017 112 : AirflowNetworkReportData(i).LeakLatGainW,
6018 : OutputProcessor::SOVTimeStepType::System,
6019 : OutputProcessor::SOVStoreType::Average,
6020 224 : Zone(i).Name);
6021 448 : SetupOutputVariable(m_state,
6022 : "AFN Zone Duct Leaked Air Latent Heat Gain Energy",
6023 : OutputProcessor::Unit::J,
6024 112 : AirflowNetworkReportData(i).LeakLatGainJ,
6025 : OutputProcessor::SOVTimeStepType::System,
6026 : OutputProcessor::SOVStoreType::Summed,
6027 224 : Zone(i).Name);
6028 448 : SetupOutputVariable(m_state,
6029 : "AFN Zone Duct Leaked Air Latent Heat Loss Rate",
6030 : OutputProcessor::Unit::W,
6031 112 : AirflowNetworkReportData(i).LeakLatLossW,
6032 : OutputProcessor::SOVTimeStepType::System,
6033 : OutputProcessor::SOVStoreType::Average,
6034 224 : Zone(i).Name);
6035 448 : SetupOutputVariable(m_state,
6036 : "AFN Zone Duct Leaked Air Latent Heat Loss Energy",
6037 : OutputProcessor::Unit::J,
6038 112 : AirflowNetworkReportData(i).LeakLatLossJ,
6039 : OutputProcessor::SOVTimeStepType::System,
6040 : OutputProcessor::SOVStoreType::Summed,
6041 224 : Zone(i).Name);
6042 : // Conduction losses due to force air systems
6043 448 : SetupOutputVariable(m_state,
6044 : "AFN Zone Duct Conduction Sensible Heat Gain Rate",
6045 : OutputProcessor::Unit::W,
6046 112 : AirflowNetworkReportData(i).CondSenGainW,
6047 : OutputProcessor::SOVTimeStepType::System,
6048 : OutputProcessor::SOVStoreType::Average,
6049 224 : Zone(i).Name);
6050 448 : SetupOutputVariable(m_state,
6051 : "AFN Zone Duct Conduction Sensible Heat Gain Energy",
6052 : OutputProcessor::Unit::J,
6053 112 : AirflowNetworkReportData(i).CondSenGainJ,
6054 : OutputProcessor::SOVTimeStepType::System,
6055 : OutputProcessor::SOVStoreType::Summed,
6056 224 : Zone(i).Name);
6057 448 : SetupOutputVariable(m_state,
6058 : "AFN Zone Duct Conduction Sensible Heat Loss Rate",
6059 : OutputProcessor::Unit::W,
6060 112 : AirflowNetworkReportData(i).CondSenLossW,
6061 : OutputProcessor::SOVTimeStepType::System,
6062 : OutputProcessor::SOVStoreType::Average,
6063 224 : Zone(i).Name);
6064 448 : SetupOutputVariable(m_state,
6065 : "AFN Zone Duct Conduction Sensible Heat Loss Energy",
6066 : OutputProcessor::Unit::J,
6067 112 : AirflowNetworkReportData(i).CondSenLossJ,
6068 : OutputProcessor::SOVTimeStepType::System,
6069 : OutputProcessor::SOVStoreType::Summed,
6070 224 : Zone(i).Name);
6071 448 : SetupOutputVariable(m_state,
6072 : "AFN Zone Duct Diffusion Latent Heat Gain Rate",
6073 : OutputProcessor::Unit::W,
6074 112 : AirflowNetworkReportData(i).DiffLatGainW,
6075 : OutputProcessor::SOVTimeStepType::System,
6076 : OutputProcessor::SOVStoreType::Average,
6077 224 : Zone(i).Name);
6078 448 : SetupOutputVariable(m_state,
6079 : "AFN Zone Duct Diffusion Latent Heat Gain Energy",
6080 : OutputProcessor::Unit::J,
6081 112 : AirflowNetworkReportData(i).DiffLatGainJ,
6082 : OutputProcessor::SOVTimeStepType::System,
6083 : OutputProcessor::SOVStoreType::Summed,
6084 224 : Zone(i).Name);
6085 448 : SetupOutputVariable(m_state,
6086 : "AFN Zone Duct Diffusion Latent Heat Loss Rate",
6087 : OutputProcessor::Unit::W,
6088 112 : AirflowNetworkReportData(i).DiffLatLossW,
6089 : OutputProcessor::SOVTimeStepType::System,
6090 : OutputProcessor::SOVStoreType::Average,
6091 224 : Zone(i).Name);
6092 448 : SetupOutputVariable(m_state,
6093 : "AFN Zone Duct Diffusion Latent Heat Loss Energy",
6094 : OutputProcessor::Unit::J,
6095 112 : AirflowNetworkReportData(i).DiffLatLossJ,
6096 : OutputProcessor::SOVTimeStepType::System,
6097 : OutputProcessor::SOVStoreType::Summed,
6098 224 : Zone(i).Name);
6099 : // Radiation losses due to forced air systems
6100 448 : SetupOutputVariable(m_state,
6101 : "AFN Zone Duct Radiation Heat Gain Rate",
6102 : OutputProcessor::Unit::W,
6103 112 : AirflowNetworkReportData(i).RadGainW,
6104 : OutputProcessor::SOVTimeStepType::System,
6105 : OutputProcessor::SOVStoreType::Average,
6106 224 : Zone(i).Name);
6107 448 : SetupOutputVariable(m_state,
6108 : "AFN Zone Duct Radiation Sensible Heat Gain Energy",
6109 : OutputProcessor::Unit::J,
6110 112 : AirflowNetworkReportData(i).RadGainJ,
6111 : OutputProcessor::SOVTimeStepType::System,
6112 : OutputProcessor::SOVStoreType::Summed,
6113 224 : Zone(i).Name);
6114 448 : SetupOutputVariable(m_state,
6115 : "AFN Zone Duct Radiation Heat Loss Rate",
6116 : OutputProcessor::Unit::W,
6117 112 : AirflowNetworkReportData(i).RadLossW,
6118 : OutputProcessor::SOVTimeStepType::System,
6119 : OutputProcessor::SOVStoreType::Average,
6120 224 : Zone(i).Name);
6121 448 : SetupOutputVariable(m_state,
6122 : "AFN Zone Duct Radiation Sensible Heat Loss Energy",
6123 : OutputProcessor::Unit::J,
6124 112 : AirflowNetworkReportData(i).RadLossJ,
6125 : OutputProcessor::SOVTimeStepType::System,
6126 : OutputProcessor::SOVStoreType::Summed,
6127 224 : Zone(i).Name);
6128 : // Total losses due to force air systems
6129 448 : SetupOutputVariable(m_state,
6130 : "AFN Distribution Sensible Heat Gain Rate",
6131 : OutputProcessor::Unit::W,
6132 112 : AirflowNetworkReportData(i).TotalSenGainW,
6133 : OutputProcessor::SOVTimeStepType::System,
6134 : OutputProcessor::SOVStoreType::Average,
6135 224 : Zone(i).Name);
6136 448 : SetupOutputVariable(m_state,
6137 : "AFN Distribution Sensible Heat Gain Energy",
6138 : OutputProcessor::Unit::J,
6139 112 : AirflowNetworkReportData(i).TotalSenGainJ,
6140 : OutputProcessor::SOVTimeStepType::System,
6141 : OutputProcessor::SOVStoreType::Summed,
6142 224 : Zone(i).Name);
6143 448 : SetupOutputVariable(m_state,
6144 : "AFN Distribution Sensible Heat Loss Rate",
6145 : OutputProcessor::Unit::W,
6146 112 : AirflowNetworkReportData(i).TotalSenLossW,
6147 : OutputProcessor::SOVTimeStepType::System,
6148 : OutputProcessor::SOVStoreType::Average,
6149 224 : Zone(i).Name);
6150 448 : SetupOutputVariable(m_state,
6151 : "AFN Distribution Sensible Heat Loss Energy",
6152 : OutputProcessor::Unit::J,
6153 112 : AirflowNetworkReportData(i).TotalSenLossJ,
6154 : OutputProcessor::SOVTimeStepType::System,
6155 : OutputProcessor::SOVStoreType::Summed,
6156 224 : Zone(i).Name);
6157 448 : SetupOutputVariable(m_state,
6158 : "AFN Distribution Latent Heat Gain Rate",
6159 : OutputProcessor::Unit::W,
6160 112 : AirflowNetworkReportData(i).TotalLatGainW,
6161 : OutputProcessor::SOVTimeStepType::System,
6162 : OutputProcessor::SOVStoreType::Average,
6163 224 : Zone(i).Name);
6164 448 : SetupOutputVariable(m_state,
6165 : "AFN Distribution Latent Heat Gain Energy",
6166 : OutputProcessor::Unit::J,
6167 112 : AirflowNetworkReportData(i).TotalLatGainJ,
6168 : OutputProcessor::SOVTimeStepType::System,
6169 : OutputProcessor::SOVStoreType::Summed,
6170 224 : Zone(i).Name);
6171 448 : SetupOutputVariable(m_state,
6172 : "AFN Distribution Latent Heat Loss Rate",
6173 : OutputProcessor::Unit::W,
6174 112 : AirflowNetworkReportData(i).TotalLatLossW,
6175 : OutputProcessor::SOVTimeStepType::System,
6176 : OutputProcessor::SOVStoreType::Average,
6177 224 : Zone(i).Name);
6178 448 : SetupOutputVariable(m_state,
6179 : "AFN Distribution Latent Heat Loss Energy",
6180 : OutputProcessor::Unit::J,
6181 112 : AirflowNetworkReportData(i).TotalLatLossJ,
6182 : OutputProcessor::SOVTimeStepType::System,
6183 : OutputProcessor::SOVStoreType::Summed,
6184 224 : Zone(i).Name);
6185 : }
6186 :
6187 146 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
6188 448 : SetupOutputVariable(m_state,
6189 : "AFN Zone Infiltration Volume",
6190 : OutputProcessor::Unit::m3,
6191 112 : AirflowNetworkZnRpt(i).InfilVolume,
6192 : OutputProcessor::SOVTimeStepType::System,
6193 : OutputProcessor::SOVStoreType::Summed,
6194 224 : Zone(i).Name);
6195 448 : SetupOutputVariable(m_state,
6196 : "AFN Zone Infiltration Mass",
6197 : OutputProcessor::Unit::kg,
6198 112 : AirflowNetworkZnRpt(i).InfilMass,
6199 : OutputProcessor::SOVTimeStepType::System,
6200 : OutputProcessor::SOVStoreType::Summed,
6201 224 : Zone(i).Name);
6202 448 : SetupOutputVariable(m_state,
6203 : "AFN Zone Infiltration Air Change Rate",
6204 : OutputProcessor::Unit::ach,
6205 112 : AirflowNetworkZnRpt(i).InfilAirChangeRate,
6206 : OutputProcessor::SOVTimeStepType::System,
6207 : OutputProcessor::SOVStoreType::Average,
6208 224 : Zone(i).Name);
6209 448 : SetupOutputVariable(m_state,
6210 : "AFN Zone Ventilation Volume",
6211 : OutputProcessor::Unit::m3,
6212 112 : AirflowNetworkZnRpt(i).VentilVolume,
6213 : OutputProcessor::SOVTimeStepType::System,
6214 : OutputProcessor::SOVStoreType::Summed,
6215 224 : Zone(i).Name);
6216 448 : SetupOutputVariable(m_state,
6217 : "AFN Zone Ventilation Mass",
6218 : OutputProcessor::Unit::kg,
6219 112 : AirflowNetworkZnRpt(i).VentilMass,
6220 : OutputProcessor::SOVTimeStepType::System,
6221 : OutputProcessor::SOVStoreType::Summed,
6222 224 : Zone(i).Name);
6223 448 : SetupOutputVariable(m_state,
6224 : "AFN Zone Ventilation Air Change Rate",
6225 : OutputProcessor::Unit::ach,
6226 112 : AirflowNetworkZnRpt(i).VentilAirChangeRate,
6227 : OutputProcessor::SOVTimeStepType::System,
6228 : OutputProcessor::SOVStoreType::Average,
6229 224 : Zone(i).Name);
6230 448 : SetupOutputVariable(m_state,
6231 : "AFN Zone Mixing Volume",
6232 : OutputProcessor::Unit::m3,
6233 112 : AirflowNetworkZnRpt(i).MixVolume,
6234 : OutputProcessor::SOVTimeStepType::System,
6235 : OutputProcessor::SOVStoreType::Summed,
6236 224 : Zone(i).Name);
6237 448 : SetupOutputVariable(m_state,
6238 : "AFN Zone Mixing Mass",
6239 : OutputProcessor::Unit::kg,
6240 112 : AirflowNetworkZnRpt(i).MixMass,
6241 : OutputProcessor::SOVTimeStepType::System,
6242 : OutputProcessor::SOVStoreType::Summed,
6243 224 : Zone(i).Name);
6244 :
6245 448 : SetupOutputVariable(m_state,
6246 : "AFN Zone Exfiltration Heat Transfer Rate",
6247 : OutputProcessor::Unit::W,
6248 112 : AirflowNetworkZnRpt(i).ExfilTotalLoss,
6249 : OutputProcessor::SOVTimeStepType::System,
6250 : OutputProcessor::SOVStoreType::Average,
6251 224 : Zone(i).Name);
6252 448 : SetupOutputVariable(m_state,
6253 : "AFN Zone Exfiltration Sensible Heat Transfer Rate",
6254 : OutputProcessor::Unit::W,
6255 112 : AirflowNetworkZnRpt(i).ExfilSensiLoss,
6256 : OutputProcessor::SOVTimeStepType::System,
6257 : OutputProcessor::SOVStoreType::Average,
6258 224 : Zone(i).Name);
6259 448 : SetupOutputVariable(m_state,
6260 : "AFN Zone Exfiltration Latent Heat Transfer Rate",
6261 : OutputProcessor::Unit::W,
6262 112 : AirflowNetworkZnRpt(i).ExfilLatentLoss,
6263 : OutputProcessor::SOVTimeStepType::System,
6264 : OutputProcessor::SOVStoreType::Average,
6265 224 : Zone(i).Name);
6266 : }
6267 :
6268 34 : if (OnOffFanFlag) {
6269 36 : for (i = 1; i <= AirflowNetworkNumOfZones; ++i) {
6270 108 : SetupOutputVariable(m_state,
6271 : "AFN Zone Average Pressure",
6272 : OutputProcessor::Unit::Pa,
6273 27 : nodeReport(i).PZ,
6274 : OutputProcessor::SOVTimeStepType::System,
6275 : OutputProcessor::SOVStoreType::Average,
6276 54 : Zone(i).Name);
6277 108 : SetupOutputVariable(m_state,
6278 : "AFN Zone On Cycle Pressure",
6279 : OutputProcessor::Unit::Pa,
6280 27 : nodeReport(i).PZON,
6281 : OutputProcessor::SOVTimeStepType::System,
6282 : OutputProcessor::SOVStoreType::Average,
6283 54 : Zone(i).Name);
6284 108 : SetupOutputVariable(m_state,
6285 : "AFN Zone Off Cycle Pressure",
6286 : OutputProcessor::Unit::Pa,
6287 27 : nodeReport(i).PZOFF,
6288 : OutputProcessor::SOVTimeStepType::System,
6289 : OutputProcessor::SOVStoreType::Average,
6290 54 : Zone(i).Name);
6291 : }
6292 94 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6293 340 : SetupOutputVariable(m_state,
6294 : "AFN Linkage Node 1 to 2 Average Mass Flow Rate",
6295 : OutputProcessor::Unit::kg_s,
6296 85 : linkReport1(i).FLOW,
6297 : OutputProcessor::SOVTimeStepType::System,
6298 : OutputProcessor::SOVStoreType::Average,
6299 170 : MultizoneSurfaceData(i).SurfName);
6300 340 : SetupOutputVariable(m_state,
6301 : "AFN Linkage Node 2 to 1 Average Mass Flow Rate",
6302 : OutputProcessor::Unit::kg_s,
6303 85 : linkReport1(i).FLOW2,
6304 : OutputProcessor::SOVTimeStepType::System,
6305 : OutputProcessor::SOVStoreType::Average,
6306 170 : MultizoneSurfaceData(i).SurfName);
6307 340 : SetupOutputVariable(m_state,
6308 : "AFN Linkage Node 1 to 2 Average Volume Flow Rate",
6309 : OutputProcessor::Unit::m3_s,
6310 85 : linkReport1(i).VolFLOW,
6311 : OutputProcessor::SOVTimeStepType::System,
6312 : OutputProcessor::SOVStoreType::Average,
6313 170 : MultizoneSurfaceData(i).SurfName);
6314 340 : SetupOutputVariable(m_state,
6315 : "AFN Linkage Node 2 to 1 Average Volume Flow Rate",
6316 : OutputProcessor::Unit::m3_s,
6317 85 : linkReport1(i).VolFLOW2,
6318 : OutputProcessor::SOVTimeStepType::System,
6319 : OutputProcessor::SOVStoreType::Average,
6320 170 : MultizoneSurfaceData(i).SurfName);
6321 340 : SetupOutputVariable(m_state,
6322 : "AFN Surface Average Pressure Difference",
6323 : OutputProcessor::Unit::Pa,
6324 85 : linkReport1(i).DP,
6325 : OutputProcessor::SOVTimeStepType::System,
6326 : OutputProcessor::SOVStoreType::Average,
6327 170 : MultizoneSurfaceData(i).SurfName);
6328 340 : SetupOutputVariable(m_state,
6329 : "AFN Surface On Cycle Pressure Difference",
6330 : OutputProcessor::Unit::Pa,
6331 85 : linkReport1(i).DPON,
6332 : OutputProcessor::SOVTimeStepType::System,
6333 : OutputProcessor::SOVStoreType::Average,
6334 170 : MultizoneSurfaceData(i).SurfName);
6335 340 : SetupOutputVariable(m_state,
6336 : "AFN Surface Off Cycle Pressure Difference",
6337 : OutputProcessor::Unit::Pa,
6338 85 : linkReport1(i).DPOFF,
6339 : OutputProcessor::SOVTimeStepType::System,
6340 : OutputProcessor::SOVStoreType::Average,
6341 170 : MultizoneSurfaceData(i).SurfName);
6342 : }
6343 : }
6344 :
6345 : // Assign node reference height
6346 860 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
6347 826 : if (!simulation_control.temperature_height_dependence) AirflowNetworkNodeData(i).NodeHeight = 0.0;
6348 826 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
6349 826 : if (ZoneNum > 0) {
6350 117 : if (m_state.dataSurface->WorldCoordSystem) {
6351 103 : AirflowNetworkNodeData(i).NodeHeight = 0.0;
6352 : } else {
6353 14 : AirflowNetworkNodeData(i).NodeHeight = Zone(ZoneNum).OriginZ;
6354 : }
6355 : }
6356 : }
6357 34 : }
6358 :
6359 656873 : void Solver::calculate_balance()
6360 : {
6361 : // SUBROUTINE INFORMATION:
6362 : // AUTHOR Lixing Gu
6363 : // DATE WRITTEN Oct. 2005
6364 : // MODIFIED na
6365 : // RE-ENGINEERED na
6366 :
6367 : // PURPOSE OF THIS SUBROUTINE:
6368 : // This subroutine performs simulations of nodal pressures and linkage airflows.
6369 :
6370 : // Using/Aliasing
6371 : using DataHVACGlobals::VerySmallMassFlow;
6372 : using General::SolveRoot;
6373 :
6374 : // SUBROUTINE PARAMETER DEFINITIONS:
6375 656873 : int constexpr CycFanCycComp(1); // fan cycles with compressor operation
6376 :
6377 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6378 : int i;
6379 : int j;
6380 : int n;
6381 : int NodeNum;
6382 : Real64 GlobalOpenFactor;
6383 : Real64 ZonePressure1;
6384 : Real64 ZonePressure2;
6385 : Real64 PressureSet;
6386 : Real64 LocalAzimuth;
6387 : Real64 LocalWindSpeed;
6388 : Real64 LocalWindDir;
6389 : Real64 LocalHumRat;
6390 : Real64 LocalDryBulb;
6391 1313746 : Array1D<Real64> Par; // Pressure setpoint
6392 656873 : Real64 constexpr ErrorToler(0.00001);
6393 656873 : int constexpr MaxIte(20);
6394 : int SolFla;
6395 : Real64 MinExhaustMassFlowrate;
6396 : Real64 MaxExhaustMassFlowrate;
6397 : Real64 MinReliefMassFlowrate;
6398 : Real64 MaxReliefMassFlowrate;
6399 : int AirLoopNum;
6400 :
6401 656873 : auto &Node(m_state.dataLoopNodes->Node);
6402 :
6403 : // Validate supply and return connections
6404 656873 : if (CalcAirflowNetworkAirBalanceOneTimeFlag) {
6405 34 : CalcAirflowNetworkAirBalanceOneTimeFlag = false;
6406 34 : if (CalcAirflowNetworkAirBalanceErrorsFound) {
6407 0 : ShowFatalError(m_state, "GetAirflowNetworkInput: Program terminates for preceding reason(s).");
6408 : }
6409 : }
6410 :
6411 14359964 : for (n = 1; n <= ActualNumOfNodes; ++n) {
6412 13703091 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
6413 8719037 : AirflowNetworkNodeSimu(n).PZ = 0.0;
6414 : } else {
6415 : // Assigning ambient conditions to external nodes
6416 4984054 : i = AirflowNetworkNodeData(n).ExtNodeNum;
6417 4984054 : if (i > 0) {
6418 4984054 : AirflowNetworkNodeSimu(n).TZ = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(n).NodeHeight);
6419 4984054 : AirflowNetworkNodeSimu(n).WZ = m_state.dataEnvrn->OutHumRat;
6420 4984054 : if (i <= AirflowNetworkNumOfExtNode) {
6421 4891440 : if (MultizoneExternalNodeData(i).OutAirNodeNum == 0) {
6422 4874425 : LocalWindSpeed = DataEnvironment::WindSpeedAt(m_state, MultizoneExternalNodeData(i).height);
6423 4874425 : LocalDryBulb = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(n).NodeHeight);
6424 4874425 : LocalAzimuth = MultizoneExternalNodeData(i).azimuth;
6425 19497700 : AirflowNetworkNodeSimu(n).PZ = calculate_wind_pressure(MultizoneExternalNodeData(i).curve,
6426 4874425 : MultizoneExternalNodeData(i).symmetricCurve,
6427 4874425 : MultizoneExternalNodeData(i).useRelativeAngle,
6428 : LocalAzimuth,
6429 : LocalWindSpeed,
6430 4874425 : m_state.dataEnvrn->WindDir,
6431 : LocalDryBulb,
6432 4874425 : m_state.dataEnvrn->OutHumRat);
6433 : } else {
6434 : // If and outdoor air node object is defined as the External Node Name in AirflowNetwork:MultiZone:Surface,
6435 : // the node object requires to define the Wind Pressure Coefficient Curve Name.
6436 17015 : NodeNum = MultizoneExternalNodeData(i).OutAirNodeNum;
6437 17015 : LocalWindSpeed = Node((NodeNum)).OutAirWindSpeed;
6438 17015 : LocalWindDir = Node((NodeNum)).OutAirWindDir;
6439 17015 : LocalHumRat = Node((NodeNum)).HumRat;
6440 17015 : LocalDryBulb = Node((NodeNum)).OutAirDryBulb;
6441 17015 : LocalAzimuth = MultizoneExternalNodeData(i).azimuth;
6442 34030 : AirflowNetworkNodeSimu(n).PZ = calculate_wind_pressure(MultizoneExternalNodeData(i).curve,
6443 17015 : MultizoneExternalNodeData(i).symmetricCurve,
6444 17015 : MultizoneExternalNodeData(i).useRelativeAngle,
6445 : LocalAzimuth,
6446 : LocalWindSpeed,
6447 : LocalWindDir,
6448 : LocalDryBulb,
6449 : LocalHumRat);
6450 17015 : AirflowNetworkNodeSimu(n).TZ = LocalDryBulb;
6451 17015 : AirflowNetworkNodeSimu(n).WZ = LocalHumRat;
6452 : }
6453 : }
6454 :
6455 : } else {
6456 0 : ShowSevereError(m_state,
6457 0 : "GetAirflowNetworkInput: AIRFLOWNETWORK:DISTRIBUTION:NODE: Invalid external node = " +
6458 0 : AirflowNetworkNodeData(n).Name);
6459 0 : CalcAirflowNetworkAirBalanceErrorsFound = true;
6460 : }
6461 : }
6462 : }
6463 :
6464 9898997 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6465 9242124 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) {
6466 108899 : continue;
6467 : }
6468 9133225 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::SCR) {
6469 4683314 : AirflowNetworkLinkageData(i).control = MultizoneSurfaceData(i).Factor;
6470 : }
6471 9133225 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) MultizoneSurfaceData(i).OpenFactor = 0.0;
6472 9133225 : j = MultizoneSurfaceData(i).SurfNum;
6473 26660408 : if (m_state.dataSurface->SurfWinOriginalClass(j) == SurfaceClass::Window ||
6474 16444700 : m_state.dataSurface->SurfWinOriginalClass(j) == SurfaceClass::Door ||
6475 25234709 : m_state.dataSurface->SurfWinOriginalClass(j) == SurfaceClass::GlassDoor || m_state.dataSurface->Surface(j).IsAirBoundarySurf) {
6476 1082483 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
6477 16182 : if (MultizoneSurfaceData(i).OpeningStatus == OpenStatus::FreeOperation) {
6478 14712 : if (MultizoneSurfaceData(i).OpeningProbStatus == ProbabilityCheck::ForceChange) {
6479 54 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).Factor;
6480 14658 : } else if (MultizoneSurfaceData(i).ClosingProbStatus == ProbabilityCheck::ForceChange) {
6481 336 : MultizoneSurfaceData(i).OpenFactor = 0.0;
6482 20400 : } else if (MultizoneSurfaceData(i).ClosingProbStatus == ProbabilityCheck::KeepStatus ||
6483 6078 : MultizoneSurfaceData(i).OpeningProbStatus == ProbabilityCheck::KeepStatus) {
6484 10536 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).OpenFactorLast;
6485 : } else {
6486 3786 : venting_control(i, MultizoneSurfaceData(i).OpenFactor);
6487 : }
6488 : }
6489 : } else {
6490 1066301 : venting_control(i, MultizoneSurfaceData(i).OpenFactor);
6491 : }
6492 1082483 : MultizoneSurfaceData(i).OpenFactor *= MultizoneSurfaceData(i).WindModifier;
6493 1082483 : if (MultizoneSurfaceData(i).HybridVentClose) {
6494 181388 : MultizoneSurfaceData(i).OpenFactor = 0.0;
6495 181388 : if (m_state.dataSurface->SurfWinVentingOpenFactorMultRep(j) > 0.0) m_state.dataSurface->SurfWinVentingOpenFactorMultRep(j) = 0.0;
6496 : }
6497 2497722 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DOP ||
6498 1177049 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SOP ||
6499 94566 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
6500 2216359 : if (AirflowNetworkFanActivated && distribution_simulated && MultizoneSurfaceData(i).OpenFactor > 0.0 &&
6501 915 : (m_state.dataSurface->Surface(j).ExtBoundCond == ExternalEnvironment ||
6502 18 : (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
6503 996131 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) &&
6504 879 : !m_state.dataGlobal->WarmupFlag) {
6505 : // Exterior Large opening only
6506 462 : ++MultizoneSurfaceData(i).ExtLargeOpeningErrCount;
6507 462 : if (MultizoneSurfaceData(i).ExtLargeOpeningErrCount < 2) {
6508 12 : ShowWarningError(m_state,
6509 8 : "AirflowNetwork: The window or door is open during HVAC system operation " +
6510 4 : MultizoneSurfaceData(i).SurfName);
6511 4 : ShowContinueError(m_state, format("The window or door opening factor is {:.2R}", MultizoneSurfaceData(i).OpenFactor));
6512 4 : ShowContinueErrorTimeStamp(m_state, "");
6513 : } else {
6514 2748 : ShowRecurringWarningErrorAtEnd(m_state,
6515 916 : "AirFlowNetwork: " + MultizoneSurfaceData(i).SurfName +
6516 : " The window or door is open during HVAC system operation error continues...",
6517 458 : MultizoneSurfaceData(i).ExtLargeOpeningErrIndex,
6518 458 : MultizoneSurfaceData(i).OpenFactor,
6519 458 : MultizoneSurfaceData(i).OpenFactor);
6520 : }
6521 : }
6522 : }
6523 1082483 : if (MultizoneSurfaceData(i).OpenFactor > 1.0) {
6524 0 : ++MultizoneSurfaceData(i).OpenFactorErrCount;
6525 0 : if (MultizoneSurfaceData(i).OpenFactorErrCount < 2) {
6526 0 : ShowWarningError(m_state,
6527 0 : "AirflowNetwork: The window or door opening factor is greater than 1.0 " + MultizoneSurfaceData(i).SurfName);
6528 0 : ShowContinueErrorTimeStamp(m_state, "");
6529 : } else {
6530 0 : ShowRecurringWarningErrorAtEnd(m_state,
6531 0 : "AirFlowNetwork: " + MultizoneSurfaceData(i).SurfName +
6532 : " The window or door opening factor is greater than 1.0 error continues...",
6533 0 : MultizoneSurfaceData(i).OpenFactorErrIndex,
6534 0 : MultizoneSurfaceData(i).OpenFactor,
6535 0 : MultizoneSurfaceData(i).OpenFactor);
6536 : }
6537 : }
6538 : }
6539 : }
6540 :
6541 : // Check if the global ventilation control is applied or not
6542 656873 : GlobalOpenFactor = -1.0;
6543 9748945 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6544 9101221 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) continue;
6545 8992322 : if (MultizoneSurfaceData(i).HybridCtrlMaster) {
6546 9149 : GlobalOpenFactor = MultizoneSurfaceData(i).OpenFactor;
6547 9149 : break;
6548 : }
6549 : }
6550 656873 : if (GlobalOpenFactor >= 0.0) {
6551 201278 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6552 192129 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) continue;
6553 192129 : j = MultizoneSurfaceData(i).SurfNum;
6554 548940 : if (m_state.dataSurface->SurfWinOriginalClass(j) == SurfaceClass::Window ||
6555 338513 : m_state.dataSurface->SurfWinOriginalClass(j) == SurfaceClass::Door ||
6556 146384 : m_state.dataSurface->SurfWinOriginalClass(j) == SurfaceClass::GlassDoor) {
6557 45745 : if (MultizoneSurfaceData(i).HybridCtrlGlobal) {
6558 35675 : MultizoneSurfaceData(i).OpenFactor = GlobalOpenFactor;
6559 : }
6560 : }
6561 : }
6562 : }
6563 :
6564 656873 : if (!Par.allocated()) {
6565 656873 : Par.allocate(1);
6566 656873 : Par = 0.0;
6567 : }
6568 :
6569 656873 : PressureSetFlag = 0;
6570 :
6571 656873 : if (NumOfPressureControllers == 1) {
6572 12387 : if (PressureControllerData(1).AvailSchedPtr == DataGlobalConstants::ScheduleAlwaysOn) {
6573 12387 : PressureSetFlag = PressureControllerData(1).ControlTypeSet;
6574 : } else {
6575 0 : if (GetCurrentScheduleValue(m_state, PressureControllerData(1).AvailSchedPtr) > 0.0) {
6576 0 : PressureSetFlag = PressureControllerData(1).ControlTypeSet;
6577 : }
6578 : }
6579 12387 : if (PressureSetFlag > 0) {
6580 12387 : PressureSet = GetCurrentScheduleValue(m_state, PressureControllerData(1).PresSetpointSchedPtr);
6581 : }
6582 : }
6583 :
6584 656873 : initialize_calculation();
6585 :
6586 656873 : if (!(PressureSetFlag > 0 && AirflowNetworkFanActivated)) {
6587 651098 : airmov();
6588 5775 : } else if (PressureSetFlag == PressureCtrlExhaust) {
6589 0 : AirLoopNum = AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).AirLoopNum;
6590 0 : MinExhaustMassFlowrate = 2.0 * VerySmallMassFlow;
6591 0 : MaxExhaustMassFlowrate = Node(PressureControllerData(1).OANodeNum).MassFlowRate;
6592 0 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == CycFanCycComp &&
6593 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio > 0.0) {
6594 0 : MaxExhaustMassFlowrate = MaxExhaustMassFlowrate / m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
6595 : }
6596 0 : ExhaustFanMassFlowRate = MinExhaustMassFlowrate;
6597 0 : airmov();
6598 0 : ZonePressure1 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6599 0 : if (ZonePressure1 <= PressureSet) {
6600 : // The highest pressure due to minimum flow rate could not reach Pressure set, bypass pressure set calculation
6601 0 : if (!m_state.dataGlobal->WarmupFlag) {
6602 0 : if (ErrCountLowPre == 0) {
6603 0 : ++ErrCountLowPre;
6604 0 : ShowWarningError(m_state,
6605 : "The calculated pressure with minimum exhaust fan rate is lower than the pressure setpoint. The pressure "
6606 : "control is unable to perform.");
6607 0 : ShowContinueErrorTimeStamp(m_state,
6608 0 : format("Calculated pressure = {:.2R}[Pa], Pressure setpoint ={:.2R}", ZonePressure1, PressureSet));
6609 : } else {
6610 0 : ++ErrCountLowPre;
6611 0 : ShowRecurringWarningErrorAtEnd(m_state,
6612 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6613 : ": The AFN model continues not to perform pressure control due to lower zone pressure...",
6614 : ErrIndexLowPre,
6615 : ZonePressure1,
6616 : ZonePressure1);
6617 : }
6618 : }
6619 : } else {
6620 0 : ExhaustFanMassFlowRate = MaxExhaustMassFlowrate;
6621 0 : airmov();
6622 0 : ZonePressure2 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6623 0 : if (ZonePressure2 >= PressureSet) {
6624 : // The lowest pressure due to maximum flow rate is still higher than Pressure set, bypass pressure set calculation
6625 0 : if (!m_state.dataGlobal->WarmupFlag) {
6626 0 : if (ErrCountHighPre == 0) {
6627 0 : ++ErrCountHighPre;
6628 0 : ShowWarningError(m_state,
6629 : "The calculated pressure with maximum exhaust fan rate is higher than the pressure setpoint. The "
6630 : "pressure control is unable to perform.");
6631 0 : ShowContinueErrorTimeStamp(
6632 0 : m_state, format("Calculated pressure = {:.2R}[Pa], Pressure setpoint = {:.2R}", ZonePressure2, PressureSet));
6633 : } else {
6634 0 : ++ErrCountHighPre;
6635 0 : ShowRecurringWarningErrorAtEnd(
6636 : m_state,
6637 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6638 : ": The AFN model continues not to perform pressure control due to higher zone pressure...",
6639 : ErrIndexHighPre,
6640 : ZonePressure2,
6641 : ZonePressure2);
6642 : }
6643 : }
6644 : } else {
6645 : // if ( ZonePressure1 > PressureSet && ZonePressure2 < PressureSet ) {
6646 0 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
6647 0 : auto f = [&thisState, PressureSet](Real64 const ControllerMassFlowRate) {
6648 : return AFNPressureResidual(thisState, ControllerMassFlowRate, PressureSet);
6649 0 : };
6650 0 : General::SolveRoot(
6651 : m_state, ErrorToler, MaxIte, SolFla, ExhaustFanMassFlowRate, f, MinExhaustMassFlowrate, MaxExhaustMassFlowrate);
6652 0 : if (SolFla == -1) {
6653 0 : if (!m_state.dataGlobal->WarmupFlag) {
6654 0 : if (ErrCountVar == 0) {
6655 0 : ++ErrCountVar;
6656 0 : ShowWarningError(m_state, "Iteration limit exceeded pressure setpoint using an exhaust fan. Simulation continues.");
6657 0 : ShowContinueErrorTimeStamp(m_state, format("Exhaust fan flow rate = {:.4R}", ExhaustFanMassFlowRate));
6658 : } else {
6659 0 : ++ErrCountVar;
6660 0 : ShowRecurringWarningErrorAtEnd(m_state,
6661 0 : PressureControllerData(1).Name +
6662 : "\": Iteration limit warning exceeding pressure setpoint continues...",
6663 : ErrIndexVar,
6664 : ExhaustFanMassFlowRate,
6665 : ExhaustFanMassFlowRate);
6666 : }
6667 : }
6668 0 : } else if (SolFla == -2) {
6669 0 : ShowFatalError(m_state,
6670 0 : "Zone pressure control failed using an exhaust fan: no solution is reached, for " +
6671 0 : PressureControllerData(1).Name);
6672 : }
6673 : }
6674 : }
6675 : } else { // PressureCtrlRelief - Pressure control type is Relief Flow
6676 5775 : AirLoopNum = AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).AirLoopNum;
6677 5775 : MinReliefMassFlowrate = 2.0 * VerySmallMassFlow;
6678 5775 : MaxReliefMassFlowrate = Node(PressureControllerData(1).OANodeNum).MassFlowRate;
6679 5775 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == CycFanCycComp &&
6680 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio > 0.0) {
6681 0 : MaxReliefMassFlowrate = MaxReliefMassFlowrate / m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
6682 : }
6683 5775 : ReliefMassFlowRate = MinReliefMassFlowrate;
6684 5775 : initialize_calculation();
6685 5775 : airmov();
6686 5775 : ZonePressure1 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6687 :
6688 5775 : if (ZonePressure1 <= PressureSet) {
6689 : // The highest pressure due to minimum flow rate could not reach Pressure set, bypass pressure set calculation
6690 0 : if (!m_state.dataGlobal->WarmupFlag) {
6691 0 : if (ErrCountLowPre == 0) {
6692 0 : ++ErrCountLowPre;
6693 0 : ShowWarningError(m_state,
6694 : "The calculated pressure with minimum relief air rate is lower than the pressure setpoint. The pressure "
6695 : "control is unable to perform.");
6696 0 : ShowContinueErrorTimeStamp(m_state,
6697 0 : format("Calculated pressure = {:.2R}[Pa], Pressure setpoint ={:.2R}", ZonePressure1, PressureSet));
6698 : } else {
6699 0 : ++ErrCountLowPre;
6700 0 : ShowRecurringWarningErrorAtEnd(m_state,
6701 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6702 : ": The AFN model continues not to perform pressure control due to lower zone pressure...",
6703 : ErrIndexLowPre,
6704 : ZonePressure1,
6705 : ZonePressure1);
6706 : }
6707 : }
6708 : } else {
6709 5775 : ReliefMassFlowRate = MaxReliefMassFlowrate;
6710 5775 : initialize_calculation();
6711 5775 : airmov();
6712 5775 : ZonePressure2 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6713 5775 : if (ZonePressure2 >= PressureSet) {
6714 : // The lowest pressure due to maximum flow rate is still higher than Pressure set, bypass pressure set calculation
6715 0 : if (!m_state.dataGlobal->WarmupFlag) {
6716 0 : if (ErrCountHighPre == 0) {
6717 0 : ++ErrCountHighPre;
6718 0 : ShowWarningError(m_state,
6719 : "The calculated pressure with maximum relief air rate is higher than the pressure setpoint. The "
6720 : "pressure control is unable to perform.");
6721 0 : ShowContinueErrorTimeStamp(
6722 0 : m_state, format("Calculated pressure = {:.2R}[Pa], Pressure setpoint = {:.2R}", ZonePressure2, PressureSet));
6723 : } else {
6724 0 : ++ErrCountHighPre;
6725 0 : ShowRecurringWarningErrorAtEnd(
6726 : m_state,
6727 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6728 : ": The AFN model continues not to perform pressure control due to higher zone pressure...",
6729 : ErrIndexHighPre,
6730 : ZonePressure2,
6731 : ZonePressure2);
6732 : }
6733 : }
6734 : } else {
6735 : // if ( ZonePressure1 > PressureSet && ZonePressure2 < PressureSet ) {
6736 5775 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
6737 30452 : auto f = [&thisState, PressureSet](Real64 const ControllerMassFlowRate) {
6738 : return AFNPressureResidual(thisState, ControllerMassFlowRate, PressureSet);
6739 36227 : };
6740 5775 : General::SolveRoot(m_state, ErrorToler, MaxIte, SolFla, ReliefMassFlowRate, f, MinReliefMassFlowrate, MaxReliefMassFlowrate);
6741 5775 : if (SolFla == -1) {
6742 0 : if (!m_state.dataGlobal->WarmupFlag) {
6743 0 : if (ErrCountVar == 0) {
6744 0 : ++ErrCountVar;
6745 0 : ShowWarningError(m_state, "Iteration limit exceeded pressure setpoint using relief air. Simulation continues.");
6746 0 : ShowContinueErrorTimeStamp(m_state, format("Relief air flow rate = {:.4R}", ReliefMassFlowRate));
6747 : } else {
6748 0 : ++ErrCountVar;
6749 0 : ShowRecurringWarningErrorAtEnd(m_state,
6750 0 : PressureControllerData(1).Name +
6751 : "\": Iteration limit warning exceeding pressure setpoint continues...",
6752 : ErrIndexVar,
6753 : ReliefMassFlowRate,
6754 : ReliefMassFlowRate);
6755 : }
6756 : }
6757 5775 : } else if (SolFla == -2) {
6758 0 : ShowFatalError(
6759 0 : m_state, "Zone pressure control failed using relief air: no solution is reached, for " + PressureControllerData(1).Name);
6760 : }
6761 : }
6762 : }
6763 : }
6764 656873 : }
6765 :
6766 30452 : Real64 AFNPressureResidual(EnergyPlusData &state,
6767 : Real64 const ControllerMassFlowRate, // Pressure setpoint
6768 : Real64 PressureSet)
6769 : {
6770 : // FUNCTION INFORMATION:
6771 : // AUTHOR Lixing Gu
6772 : // DATE WRITTEN April 2016
6773 : // MODIFIED NA
6774 : // RE-ENGINEERED NA
6775 :
6776 : // PURPOSE OF THIS FUNCTION:
6777 : // Calculates residual function ((ZonePressure - PressureSet)/PressureSet)
6778 :
6779 : // METHODOLOGY EMPLOYED:
6780 : // Calls AIRMOV to get the pressure in the controlled zone and calculates the residual as defined above
6781 :
6782 : // Return value
6783 : Real64 AFNPressureResidual;
6784 :
6785 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
6786 : Real64 ZonePressure;
6787 :
6788 30452 : if (state.afn->PressureSetFlag == PressureCtrlExhaust) {
6789 0 : state.afn->ExhaustFanMassFlowRate = ControllerMassFlowRate;
6790 : }
6791 :
6792 30452 : if (state.afn->PressureSetFlag == PressureCtrlRelief) {
6793 30452 : state.afn->ReliefMassFlowRate = ControllerMassFlowRate;
6794 : }
6795 30452 : auto &solver = state.afn;
6796 30452 : solver->initialize_calculation();
6797 30452 : solver->airmov();
6798 :
6799 30452 : ZonePressure = state.afn->AirflowNetworkNodeSimu(state.afn->PressureControllerData(1).AFNNodeNum).PZ;
6800 :
6801 30452 : if (PressureSet != 0.0) {
6802 30452 : AFNPressureResidual = (ZonePressure - PressureSet) / PressureSet;
6803 : } else {
6804 0 : AFNPressureResidual = (ZonePressure - PressureSet);
6805 : }
6806 30452 : return AFNPressureResidual;
6807 : }
6808 :
6809 41 : static int makeTable(EnergyPlusData &state, const std::string &name, const int gridIndex, const std::vector<Real64> &y)
6810 : {
6811 : // Add a new table and performance curve
6812 82 : std::string contextString = "CalcWindPressureCoeffs: Creating table \"" + name + "\"";
6813 82 : std::pair<EnergyPlusData *, std::string> callbackPair{&state, contextString};
6814 41 : Btwxt::setMessageCallback(Curve::BtwxtMessageCallback, &callbackPair);
6815 :
6816 41 : int CurveNum = static_cast<int>(state.dataCurveManager->PerfCurve.size()) + 1;
6817 41 : state.dataCurveManager->PerfCurve.push_back(Curve::PerformanceCurveData());
6818 :
6819 41 : state.dataCurveManager->PerfCurve(CurveNum).Name = name;
6820 41 : state.dataCurveManager->PerfCurve(CurveNum).numDims = 1;
6821 :
6822 41 : state.dataCurveManager->PerfCurve(CurveNum).interpolationType = Curve::InterpType::BtwxtMethod;
6823 :
6824 41 : state.dataCurveManager->PerfCurve(CurveNum).inputLimits[0].min = 0.0;
6825 41 : state.dataCurveManager->PerfCurve(CurveNum).inputLimits[0].minPresent = true;
6826 41 : state.dataCurveManager->PerfCurve(CurveNum).inputLimits[0].max = 360.0;
6827 41 : state.dataCurveManager->PerfCurve(CurveNum).inputLimits[0].maxPresent = true;
6828 :
6829 41 : state.dataCurveManager->PerfCurve(CurveNum).TableIndex = gridIndex;
6830 41 : state.dataCurveManager->PerfCurve(CurveNum).GridValueIndex = state.dataCurveManager->btwxtManager.addOutputValues(gridIndex, y);
6831 :
6832 41 : state.dataCurveManager->NumCurves += 1;
6833 82 : return CurveNum;
6834 : }
6835 :
6836 7 : void Solver::calculate_Cps()
6837 : {
6838 :
6839 : // SUBROUTINE INFORMATION:
6840 : // AUTHOR Fred Winkelmann
6841 : // DATE WRITTEN May 2003
6842 : // MODIFIED Revised by L. Gu, Nov. 2005, to meet requirements of AirflowNetwork
6843 : // MODIFIED Revised by L. Gu, Dec. 2008, to set the number of external nodes based on
6844 : // the number of external surfaces
6845 : // MODIFIED Revised by J. DeGraw, Feb. 2017, to use tables
6846 : // RE-ENGINEERED na
6847 :
6848 : // PURPOSE OF THIS SUBROUTINE:
6849 : // Calculates surface-average wind pressure coefficients for
6850 : // the walls and roof of a rectangular building.
6851 :
6852 : // METHODOLOGY EMPLOYED:
6853 : // Interpolates correlations between surface-average wind pressure coefficient and wind direction based on
6854 : // measurements (see REFERENCES). Applicable only to rectangular buildings.
6855 :
6856 : // REFERENCES:
6857 : // For low-rise buildings: M.V. Swami and S. Chandra, Correlations for Pressure Distribution
6858 : // on Buildings and Calculation of Natural-Ventilation Airflow. ASHRAE Transactions 94 (1): 243-266.
6859 : // For high-rise buildings: 2001 ASHRAE Fundamentals Handbook, p. 16.5, Fig. 7, "Surface Averaged
6860 : // Wall Pressure Coefficients for Tall Buildings" and p.16.6, Fig. 9, "Surface Averaged Roof Pressure
6861 : // Coefficients for Tall Buildings; from R.E. Akins, J.A. Peterka, and J.E. Cermak. 1979.
6862 : // Averaged Pressure Coefficients for Rectangular Buildings. Wind Engineering. Proc. Fifth
6863 : // International Conference 7:369-80, Fort Collins, CO. Pergamon Press, NY.
6864 :
6865 : // Using/Aliasing
6866 : using namespace DataSurfaces;
6867 :
6868 : // index 1 is wind incidence angle (0,30,60,...,300,330 deg)
6869 : // index 2 is side ratio (0.25,1.0,4.0)
6870 : // Surface-averaged wind-pressure coefficient array for walls
6871 : static constexpr std::array<std::array<Real64, 12>, 3> CPHighRiseWall = {{
6872 : {0.60, 0.54, 0.23, -0.25, -0.61, -0.55, -0.51, -0.55, -0.61, -0.25, 0.23, 0.54},
6873 : {0.60, 0.48, 0.04, -0.56, -0.56, -0.42, -0.37, -0.42, -0.56, -0.56, 0.04, 0.48},
6874 : {0.60, 0.44, -0.26, -0.70, -0.53, -0.32, -0.22, -0.32, -0.53, -0.70, -0.26, 0.44},
6875 : }};
6876 :
6877 : // index 1 is wind incidence angle (0,30,60,...,300,330 deg)
6878 : // index 2 is side ratio (0.25,0.5,1.0)
6879 : // Surface-averaged wind-pressure coefficient array for roof
6880 : static constexpr std::array<std::array<Real64, 12>, 3> CPHighRiseRoof = {{
6881 : {-0.28, -0.69, -0.72, -0.76, -0.72, -0.69, -0.28, -0.69, -0.72, -0.76, -0.72, -0.69},
6882 : {-0.47, -0.52, -0.70, -0.76, -0.70, -0.52, -0.47, -0.52, -0.70, -0.76, -0.70, -0.52},
6883 : {-0.70, -0.55, -0.55, -0.70, -0.55, -0.55, -0.70, -0.55, -0.55, -0.70, -0.55, -0.55},
6884 : }};
6885 :
6886 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6887 : int FacadeNum; // Facade number
6888 : int ExtNum; // External number
6889 : int AFNZnNum; // Zone number
6890 : Real64 SideRatio; // For vertical facades, width of facade / width of adjacent facade
6891 : Real64 SR; // SideRatio restricted to 0.25 to 4.0 range
6892 : Real64 SideRatioFac; // LOG(SideRatio)
6893 : Real64 IncRad; // IncAng in radians
6894 : int IAng; // Incidence angle index; used in interpolation
6895 : Real64 DelAng; // Incidence angle difference; used in interpolation
6896 : Real64 WtAng; // Incidence angle weighting factor; used in interpolation
6897 : int ISR; // Side ratio index, for interpolation
6898 : Real64 WtSR; // Side ratio weighting factor; used in interpolation
6899 : int SurfNum; // Surface number
6900 : int SurfDatNum; // Surface data number
6901 : Real64 SurfAng; // Azimuth angle of surface normal (degrees clockwise from North)
6902 : int FacadeNumThisSurf; // Facade number for a particular surface
6903 : Real64 AngDiff; // Angle difference between wind and surface direction (deg)
6904 : Real64 AngDiffMin; // Minimum angle difference between wind and surface direction (deg)
6905 14 : std::string Name; // External node name
6906 14 : std::vector<int> curveIndex = {0, 0, 0, 0, 0};
6907 :
6908 : // Facade azimuth angle
6909 35 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
6910 28 : FacadeAng(FacadeNum) = m_state.afn->simulation_control.azimuth + (FacadeNum - 1) * 90.0;
6911 28 : if (FacadeAng(FacadeNum) >= 360.0) {
6912 1 : FacadeAng(FacadeNum) -= 360.0;
6913 : }
6914 : }
6915 :
6916 7 : FacadeAng(5) = simulation_control.azimuth + 90.0;
6917 :
6918 : // Create AirflowNetwork external node objects -- one for each of the external surfaces
6919 :
6920 7 : MultizoneExternalNodeData.allocate(AirflowNetworkNumOfExtSurfaces);
6921 7 : AirflowNetworkNumOfExtNode = AirflowNetworkNumOfExtSurfaces;
6922 7 : NumOfExtNodes = AirflowNetworkNumOfExtSurfaces;
6923 72 : for (ExtNum = 1; ExtNum <= NumOfExtNodes; ++ExtNum) {
6924 65 : MultizoneExternalNodeData(ExtNum).ExtNum = AirflowNetworkNumOfZones + ExtNum;
6925 65 : MultizoneExternalNodeData(ExtNum).Name = format("ExtNode{:4}", ExtNum);
6926 : }
6927 :
6928 : // Associate each external node with SurfaceData
6929 :
6930 7 : ExtNum = 0;
6931 87 : for (SurfDatNum = 1; SurfDatNum <= AirflowNetworkNumOfSurfaces; ++SurfDatNum) {
6932 80 : if (SurfDatNum > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) {
6933 0 : continue;
6934 : }
6935 80 : SurfNum = MultizoneSurfaceData(SurfDatNum).SurfNum;
6936 80 : if (SurfNum == 0) {
6937 0 : continue; // Error caught earlier
6938 : }
6939 160 : if (m_state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment ||
6940 15 : (m_state.dataSurface->Surface(SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt && m_state.dataSurface->Surface(SurfNum).ExtWind)) {
6941 65 : ++ExtNum;
6942 65 : if (m_state.dataSurface->Surface(SurfNum).Tilt >= 45.0) { // "Vertical" surface
6943 59 : SurfAng = m_state.dataSurface->Surface(SurfNum).Azimuth;
6944 59 : FacadeNumThisSurf = 1;
6945 59 : AngDiffMin = std::abs(SurfAng - FacadeAng(1));
6946 59 : if (AngDiffMin > 359.0) {
6947 0 : AngDiffMin = std::abs(AngDiffMin - 360.0);
6948 : }
6949 236 : for (FacadeNum = 2; FacadeNum <= 4; ++FacadeNum) {
6950 177 : AngDiff = std::abs(SurfAng - FacadeAng(FacadeNum));
6951 177 : if (AngDiff > 359.0) {
6952 0 : AngDiff = std::abs(AngDiff - 360.0);
6953 : }
6954 177 : if (AngDiff < AngDiffMin) {
6955 82 : AngDiffMin = AngDiff;
6956 82 : FacadeNumThisSurf = FacadeNum;
6957 : }
6958 : }
6959 59 : MultizoneExternalNodeData(ExtNum).facadeNum = FacadeNumThisSurf;
6960 : } else { // "Roof" surface
6961 6 : MultizoneExternalNodeData(ExtNum).facadeNum = 5;
6962 : }
6963 65 : MultizoneSurfaceData(SurfDatNum).NodeNums[1] = MultizoneExternalNodeData(ExtNum).ExtNum;
6964 65 : MultizoneSurfaceData(SurfDatNum).ExternalNodeName = MultizoneExternalNodeData(ExtNum).Name;
6965 : }
6966 : }
6967 :
6968 : // Check if using the advanced single sided model
6969 27 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
6970 20 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
6971 3 : ++AirflowNetworkNumOfSingleSideZones;
6972 : }
6973 : }
6974 :
6975 14 : std::vector<Real64> dirs30 = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360};
6976 14 : std::vector<Btwxt::GridAxis> dirs30Axes;
6977 7 : dirs30Axes.emplace_back(dirs30, Btwxt::Method::LINEAR, Btwxt::Method::LINEAR, std::pair<double, double>{0.0, 360.0});
6978 :
6979 7 : auto dirs30GridIndex = m_state.dataCurveManager->btwxtManager.addGrid("30 Degree Increments", Btwxt::GriddedData(dirs30Axes));
6980 :
6981 7 : if (AirflowNetworkNumOfSingleSideZones == 0) { // do the standard surface average coefficient calculation
6982 : // Create the array of wind directions
6983 :
6984 : // Create a curve for each facade
6985 36 : for (FacadeNum = 1; FacadeNum <= 5; ++FacadeNum) {
6986 30 : if (FacadeNum == 1 || FacadeNum == 3 || FacadeNum == 5) {
6987 18 : SideRatio = simulation_control.aspect_ratio;
6988 : } else { // FacadeNum = 2 or 4
6989 12 : SideRatio = 1.0 / simulation_control.aspect_ratio;
6990 : }
6991 30 : if (UtilityRoutines::SameString(simulation_control.BldgType, "HighRise") && FacadeNum != 5) {
6992 0 : SideRatio = 1.0 / SideRatio;
6993 : }
6994 30 : SideRatioFac = std::log(SideRatio);
6995 60 : std::vector<Real64> vals(13);
6996 390 : for (int windDirNum = 1; windDirNum <= 12; ++windDirNum) {
6997 360 : Real64 WindAng = (windDirNum - 1) * 30.0;
6998 360 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
6999 360 : if (IncAng > 180.0) IncAng = 360.0 - IncAng;
7000 360 : IAng = int(IncAng / 30.0) + 1;
7001 360 : DelAng = mod(IncAng, 30.0);
7002 360 : WtAng = 1.0 - DelAng / 30.0;
7003 :
7004 : // Wind-pressure coefficients for vertical facades, low-rise building
7005 :
7006 360 : if (UtilityRoutines::SameString(simulation_control.BldgType, "LowRise") && FacadeNum <= 4) {
7007 288 : IncRad = IncAng * DataGlobalConstants::DegToRadians;
7008 288 : Real64 const cos_IncRad_over_2(std::cos(IncRad / 2.0));
7009 864 : vals[windDirNum - 1] = 0.6 * std::log(1.248 - 0.703 * std::sin(IncRad / 2.0) - 1.175 * pow_2(std::sin(IncRad)) +
7010 864 : 0.131 * pow_3(std::sin(2.0 * IncRad * SideRatioFac)) + 0.769 * cos_IncRad_over_2 +
7011 576 : 0.07 * pow_2(SideRatioFac * std::sin(IncRad / 2.0)) + 0.717 * pow_2(cos_IncRad_over_2));
7012 : }
7013 :
7014 : // Wind-pressure coefficients for vertical facades, high-rise building
7015 :
7016 72 : else if (UtilityRoutines::SameString(simulation_control.BldgType, "HighRise") && FacadeNum <= 4) {
7017 0 : SR = min(max(SideRatio, 0.25), 4.0);
7018 0 : if (SR >= 0.25 && SR < 1.0) {
7019 0 : ISR = 1;
7020 0 : WtSR = (1.0 - SR) / 0.75;
7021 : } else { // 1.0 <= SR <= 4.0
7022 0 : ISR = 2;
7023 0 : WtSR = (4.0 - SR) / 3.0;
7024 : }
7025 0 : vals[windDirNum - 1] = WtSR * (WtAng * CPHighRiseWall[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseWall[ISR - 1][IAng]) +
7026 0 : (1.0 - WtSR) * (WtAng * CPHighRiseWall[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseWall[ISR][IAng]);
7027 : }
7028 :
7029 : // Wind-pressure coefficients for roof (assumed same for low-rise and high-rise buildings)
7030 :
7031 216 : else if ((UtilityRoutines::SameString(simulation_control.BldgType, "HighRise") ||
7032 144 : UtilityRoutines::SameString(simulation_control.BldgType, "LowRise")) &&
7033 72 : FacadeNum == 5) {
7034 72 : SR = min(max(SideRatio, 0.25), 1.0);
7035 72 : if (SR >= 0.25 && SR < 0.5) {
7036 0 : ISR = 1;
7037 0 : WtSR = (0.5 - SR) / 0.25;
7038 : } else { // 0.5 <= SR <= 1.0
7039 72 : ISR = 2;
7040 72 : WtSR = (1.0 - SR) / 0.5;
7041 : }
7042 144 : vals[windDirNum - 1] = WtSR * (WtAng * CPHighRiseRoof[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR - 1][IAng]) +
7043 72 : (1.0 - WtSR) * (WtAng * CPHighRiseRoof[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR][IAng]);
7044 : }
7045 :
7046 : } // End of wind direction loop
7047 : // Add new table
7048 30 : vals[12] = vals[0]; // Enforce periodicity
7049 30 : curveIndex[FacadeNum - 1] = AirflowNetwork::makeTable(m_state, format("!WPCTABLE{}", FacadeNum), dirs30GridIndex, vals);
7050 : } // End of facade number loop
7051 :
7052 : } else { //-calculate the advanced single sided wind pressure coefficients
7053 :
7054 : // Calculate the wind pressure coefficients vs. wind direction for each external node
7055 : // The wind pressure coeffients are stored temporarily in the "valsByFacade" vector and then
7056 : // converted into a table near the end of this else. There will be at least seven profiles
7057 : // (four sides plus one roof plus two for each pair of windows). The name is thus a little
7058 : // misleading, as it isn't really the values by facade once you get beyond the first five.
7059 2 : std::vector<std::vector<Real64>> valsByFacade(5);
7060 5 : for (FacadeNum = 0; FacadeNum < 4; ++FacadeNum) {
7061 4 : valsByFacade[FacadeNum] = std::vector<Real64>(36);
7062 : }
7063 1 : FacadeNum = 4;
7064 1 : valsByFacade[FacadeNum] = std::vector<Real64>(12);
7065 5 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
7066 4 : if (FacadeNum == 1 || FacadeNum == 3) {
7067 2 : SideRatio = simulation_control.aspect_ratio;
7068 : } else { // FacadeNum = 2 or 4
7069 2 : SideRatio = 1.0 / simulation_control.aspect_ratio;
7070 : }
7071 4 : if (UtilityRoutines::SameString(simulation_control.BldgType, "HighRise") && FacadeNum != 5) {
7072 0 : SideRatio = 1.0 / SideRatio;
7073 : }
7074 4 : SideRatioFac = std::log(SideRatio);
7075 148 : for (int windDirNum = 1; windDirNum <= 36; ++windDirNum) {
7076 144 : Real64 WindAng = (windDirNum - 1) * 10.0;
7077 144 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
7078 144 : if (IncAng > 180.0) IncAng = 360.0 - IncAng;
7079 144 : IAng = int(IncAng / 10.0) + 1;
7080 144 : DelAng = mod(IncAng, 10.0);
7081 144 : WtAng = 1.0 - DelAng / 10.0;
7082 : // Wind-pressure coefficients for vertical facades, low-rise building
7083 144 : IncRad = IncAng * DataGlobalConstants::DegToRadians;
7084 144 : valsByFacade[FacadeNum - 1][windDirNum - 1] =
7085 432 : 0.6 * std::log(1.248 - 0.703 * std::sin(IncRad / 2.0) - 1.175 * pow_2(std::sin(IncRad)) +
7086 432 : 0.131 * pow_3(std::sin(2.0 * IncRad * SideRatioFac)) + 0.769 * std::cos(IncRad / 2.0) +
7087 288 : 0.07 * pow_2(SideRatioFac * std::sin(IncRad / 2.0)) + 0.717 * pow_2(std::cos(IncRad / 2.0)));
7088 : } // End of wind direction loop
7089 : } // End of facade number loop
7090 : // Add a roof
7091 1 : FacadeNum = 5;
7092 1 : SR = min(max(SideRatio, 0.25), 1.0);
7093 1 : if (SR >= 0.25 && SR < 0.5) {
7094 0 : ISR = 1;
7095 0 : WtSR = (0.5 - SR) / 0.25;
7096 : } else { // 0.5 <= SR <= 1.0
7097 1 : ISR = 2;
7098 1 : WtSR = (1.0 - SR) / 0.5;
7099 : }
7100 13 : for (int windDirNum = 1; windDirNum <= 12; ++windDirNum) {
7101 12 : Real64 WindAng = (windDirNum - 1) * 30.0;
7102 12 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
7103 12 : if (IncAng > 180.0) IncAng = 360.0 - IncAng;
7104 12 : IAng = int(IncAng / 30.0) + 1;
7105 12 : DelAng = mod(IncAng, 30.0);
7106 12 : WtAng = 1.0 - DelAng / 30.0;
7107 : // Wind-pressure coefficients for roof (assumed same for low-rise and high-rise buildings)
7108 12 : valsByFacade[FacadeNum - 1][windDirNum - 1] =
7109 24 : WtSR * (WtAng * CPHighRiseRoof[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR - 1][IAng]) +
7110 12 : (1.0 - WtSR) * (WtAng * CPHighRiseRoof[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR][IAng]);
7111 : }
7112 1 : single_sided_Cps(valsByFacade); // run the advanced single sided subroutine if at least one zone calls for it
7113 : // Resize the curve index array
7114 1 : curveIndex.resize(valsByFacade.size());
7115 : // Create the curves
7116 :
7117 : std::vector<Real64> dirs10 = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180,
7118 2 : 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360};
7119 :
7120 2 : std::vector<Btwxt::GridAxis> dirs10Axes;
7121 1 : dirs10Axes.emplace_back(dirs10, Btwxt::Method::LINEAR, Btwxt::Method::LINEAR, std::pair<double, double>{0.0, 360.0});
7122 :
7123 1 : auto dirs10GridIndex = m_state.dataCurveManager->btwxtManager.addGrid("10 Degree Increments", Btwxt::GriddedData(dirs10Axes));
7124 :
7125 5 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
7126 4 : valsByFacade[FacadeNum - 1].push_back(valsByFacade[FacadeNum - 1][0]); // Enforce periodicity
7127 4 : curveIndex[FacadeNum - 1] =
7128 8 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLEFACADE{}", FacadeNum), dirs10GridIndex, valsByFacade[FacadeNum - 1]);
7129 : }
7130 1 : FacadeNum = 5;
7131 1 : valsByFacade[FacadeNum - 1].push_back(valsByFacade[FacadeNum - 1][0]); // Enforce periodicity
7132 1 : curveIndex[FacadeNum - 1] =
7133 2 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLEFACADE{}", FacadeNum), dirs30GridIndex, valsByFacade[FacadeNum - 1]);
7134 7 : for (unsigned facadeNum = 6; facadeNum <= valsByFacade.size(); ++facadeNum) {
7135 6 : valsByFacade[facadeNum - 1].push_back(valsByFacade[facadeNum - 1][0]); // Enforce periodicity
7136 6 : curveIndex[facadeNum - 1] =
7137 12 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLE{}", facadeNum), dirs10GridIndex, valsByFacade[facadeNum - 1]);
7138 : }
7139 : }
7140 : // Connect the external nodes to the new curves
7141 72 : for (ExtNum = 1; ExtNum <= NumOfExtNodes; ++ExtNum) {
7142 65 : MultizoneExternalNodeData(ExtNum).curve = curveIndex[MultizoneExternalNodeData(ExtNum).facadeNum - 1];
7143 : }
7144 7 : }
7145 :
7146 4891440 : Real64 Solver::calculate_wind_pressure(int const curve, // Curve index, change this to pointer after curve refactor
7147 : bool const symmetricCurve, // True if the curve is symmetric (0 to 180)
7148 : bool const relativeAngle, // True if the Cp curve angle is measured relative to the surface
7149 : Real64 const azimuth, // Azimuthal angle of surface
7150 : Real64 const windSpeed, // Wind velocity
7151 : Real64 const windDir, // Wind direction
7152 : Real64 const dryBulbTemp, // Air node dry bulb temperature
7153 : Real64 const humRat // Air node humidity ratio
7154 : )
7155 : {
7156 :
7157 : // SUBROUTINE INFORMATION:
7158 : // AUTHOR Lixing Gu
7159 : // DATE WRITTEN Oct. 2005
7160 : // MODIFIED Jason DeGraw, Feb. 2017, modify to use curves
7161 : // MODIFIED Xuan Luo, Aug. 2017, modify to use local air condition
7162 : // RE-ENGINEERED na
7163 :
7164 : // PURPOSE OF THIS SUBROUTINE:
7165 : // Calculates surface wind pressure based on given CP values
7166 :
7167 : // REFERENCES:
7168 : // COMIS Fundamentals
7169 :
7170 : // Return value is wind pressure[Pa]
7171 :
7172 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
7173 4891440 : Real64 angle(windDir);
7174 : Real64 rho; // Outdoor air density
7175 : Real64 Cp; // Cp value at given wind direction
7176 :
7177 : // Calculate outdoor density
7178 4891440 : rho = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, dryBulbTemp, humRat);
7179 :
7180 : // Calculate pressure coefficient
7181 4891440 : if (relativeAngle) {
7182 0 : angle = angle - azimuth;
7183 0 : if (angle < 0.0) {
7184 0 : angle += 360.0;
7185 : }
7186 : }
7187 4891440 : if (symmetricCurve) {
7188 0 : if (angle > 180.0) {
7189 0 : angle = 360.0 - angle;
7190 : }
7191 : }
7192 4891440 : Cp = Curve::CurveValue(m_state, curve, angle);
7193 :
7194 4891440 : return Cp * 0.5 * rho * windSpeed * windSpeed;
7195 : }
7196 :
7197 11095434 : Real64 Solver::duct_inside_convection_resistance(Real64 const Tair, // Average air temperature
7198 : Real64 const mdot, // Mass flow rate
7199 : Real64 const Dh, // Hydraulic diameter
7200 : Real64 const hIn // User defined convection coefficient
7201 : )
7202 : {
7203 : // SUBROUTINE INFORMATION:
7204 : // AUTHOR Matt Mitchell, Tony Fontanini
7205 : // DATE WRITTEN Feb. 2017
7206 : // MODIFIED na
7207 : // RE-ENGINEERED na
7208 :
7209 : // PURPOSE OF THIS SUBROUTINE:
7210 : // Calculates duct inside convection coefficients
7211 :
7212 : // REFERENCES:
7213 : // ASTM C1340
7214 : // Jakob, F.E., Fischer, R.D., Flanigan, L.J. 1987. "Experimental Validation of the Duct Submodel for the SP43 Simulation Model."
7215 : // ASHRAE Trans. pp 1499-1514.
7216 :
7217 11095434 : Real64 hIn_final = 0;
7218 :
7219 11095434 : if (hIn == 0) {
7220 :
7221 7732463 : Real64 Tair_IP = Tair * 1.8 + 32.0; // Convert C to F
7222 7732463 : Real64 mdot_IP = mdot * 2.20462 * 3600; // Convert kg/s to lb/hr
7223 7732463 : Real64 Dh_IP = Dh * 3.28084; // Convert m to ft
7224 7732463 : Real64 Ai_IP = pow_2(Dh_IP) * DataGlobalConstants::Pi / 4;
7225 :
7226 7732463 : Real64 CorrelationCoeff = 0.00368 + 1.5e-6 * (Tair_IP - 80);
7227 7732463 : Real64 MassFlux = mdot_IP / Ai_IP; // lb/hr-ft2
7228 :
7229 7732463 : Real64 DuctInsideConvCoeff_IP = CorrelationCoeff * pow(MassFlux, 0.8) / pow(Dh_IP, 0.2); // BTU/hr-ft2-F
7230 :
7231 7732463 : hIn_final = DuctInsideConvCoeff_IP * pow_2(3.28084) * 1.8 * 1055.06 / 3600; // Convert BTU/hr-ft2-F to W/m2-K
7232 :
7233 : } else {
7234 3362971 : hIn_final = hIn;
7235 : }
7236 :
7237 11095434 : if (hIn_final == 0) {
7238 0 : return 0;
7239 : } else {
7240 11095434 : return 1 / hIn_final;
7241 : }
7242 : }
7243 :
7244 11095434 : Real64 Solver::duct_outside_convection_resistance(Real64 const Ts, // Surface temperature
7245 : Real64 const Tamb, // Free air temperature
7246 : Real64 const Wamb, // Free air humidity ratio
7247 : Real64 const Pamb, // Free air barometric pressure
7248 : Real64 const Dh, // Hydraulic diameter
7249 : int const ZoneNum, // Zone number
7250 : Real64 const hOut // User defined convection coefficient
7251 : )
7252 : {
7253 : // SUBROUTINE INFORMATION:
7254 : // AUTHOR Matt Mitchell, Tony Fontanini
7255 : // DATE WRITTEN Feb. 2017
7256 : // MODIFIED na
7257 : // RE-ENGINEERED na
7258 :
7259 : // PURPOSE OF THIS SUBROUTINE:
7260 : // Calculates duct outside convection coefficients
7261 :
7262 : // REFERENCES:
7263 : // ASTM C1340
7264 :
7265 11095434 : Real64 k = properties.thermal_conductivity(Ts);
7266 11095434 : auto &Zone(m_state.dataHeatBal->Zone);
7267 :
7268 11095434 : Real64 hOut_final = 0;
7269 :
7270 11095434 : if (hOut == 0) {
7271 :
7272 : // Free convection
7273 7732463 : Real64 Pr = properties.prandtl_number(Pamb, (Ts + Tamb) / 2, Wamb);
7274 7732463 : Real64 KinVisc = properties.kinematic_viscosity(Pamb, (Ts + Tamb) / 2, Wamb);
7275 7732463 : Real64 Beta = 2.0 / ((Tamb + DataGlobalConstants::KelvinConv) + (Ts + DataGlobalConstants::KelvinConv));
7276 7732463 : Real64 Gr = DataGlobalConstants::GravityConstant * Beta * std::abs(Ts - Tamb) * pow_3(Dh) / pow_2(KinVisc);
7277 7732463 : Real64 Ra = Gr * Pr;
7278 7732463 : Real64 Nu_free(0);
7279 :
7280 7732463 : if (Ra < 10e9) {
7281 7732463 : Nu_free = 0.53 * pow(Ra, 0.25);
7282 : } else {
7283 0 : Nu_free = 0.13 * pow(Ra, 0.333);
7284 : }
7285 :
7286 7732463 : Real64 V = 0;
7287 : // Forced convection
7288 7732463 : if (ZoneNum > 0) {
7289 6008207 : Real64 ACH = zone_OA_change_rate(ZoneNum); // Zone air change rate [1/hr]
7290 6008207 : Real64 Vol = Zone(ZoneNum).Volume; // Zone volume [m3]
7291 6008207 : V = pow(Vol, 0.333) * ACH / 3600; // Average air speed in zone [m/s]
7292 : } else {
7293 1724256 : V = m_state.dataEnvrn->WindSpeed;
7294 : }
7295 :
7296 7732463 : Real64 Re = V * Dh / KinVisc; // Reynolds number
7297 7732463 : Real64 c = 0;
7298 7732463 : Real64 n = 0;
7299 :
7300 7732463 : if (Re <= 4) {
7301 366499 : c = 0.989;
7302 366499 : n = 0.33;
7303 7365964 : } else if (4 < Re && Re <= 40) {
7304 84 : c = 0.911;
7305 84 : n = 0.385;
7306 7365880 : } else if (40 < Re && Re <= 4000) {
7307 5641624 : c = 0.683;
7308 5641624 : n = 0.466;
7309 1724256 : } else if (4000 < Re && Re <= 40000) {
7310 243340 : c = 0.193;
7311 243340 : n = 0.618;
7312 1480916 : } else if (40000 < Re) {
7313 1480916 : c = 0.0266;
7314 1480916 : n = 0.805;
7315 : }
7316 :
7317 7732463 : Real64 Nu_forced = c * pow(Re, n) * pow(Pr, 0.333);
7318 :
7319 7732463 : Real64 Nu_combined = pow(pow_3(Nu_free) + pow_3(Nu_forced), 0.333);
7320 7732463 : hOut_final = Nu_combined * k / Dh;
7321 :
7322 : } else {
7323 3362971 : hOut_final = hOut;
7324 : }
7325 :
7326 11095434 : if (hOut_final == 0) {
7327 97 : return 0;
7328 : } else {
7329 11095337 : return 1 / hOut_final;
7330 : }
7331 : }
7332 :
7333 380734 : void Solver::calculate_heat_balance()
7334 : {
7335 : // SUBROUTINE INFORMATION:
7336 : // AUTHOR Lixing Gu
7337 : // DATE WRITTEN Oct. 2005
7338 : // MODIFIED na
7339 : // RE-ENGINEERED Revised based on Subroutine CalcADSHeatBalance
7340 :
7341 : // PURPOSE OF THIS SUBROUTINE:
7342 : // This subroutine performs AirflowNetwork thermal simulations.
7343 :
7344 : // USE STATEMENTS:
7345 380734 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
7346 :
7347 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7348 : int i;
7349 : int j;
7350 : int LF;
7351 : int LT;
7352 : int CompNum;
7353 : int NF;
7354 : int NT;
7355 : iComponentTypeNum CompTypeNum;
7356 : int TypeNum;
7357 : int ExtNodeNum;
7358 761468 : std::string CompName;
7359 : Real64 Ei;
7360 : Real64 DirSign;
7361 : Real64 Tamb;
7362 : Real64 Wamb;
7363 : Real64 Pamb;
7364 : Real64 CpAir;
7365 : Real64 TZON;
7366 : Real64 load;
7367 : int ZoneNum;
7368 : bool found;
7369 : bool OANode;
7370 :
7371 380734 : auto &Node(m_state.dataLoopNodes->Node);
7372 :
7373 380734 : MA = 0.0;
7374 380734 : MV = 0.0;
7375 :
7376 13859032 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
7377 13478298 : CompNum = AirflowNetworkLinkageData(i).CompNum;
7378 13478298 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
7379 13478298 : CompName = AirflowNetworkCompData(CompNum).EPlusName;
7380 26956596 : CpAir = PsyCpAirFnW((AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i).NodeNums[0]).WZ +
7381 13478298 : AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i).NodeNums[1]).WZ) /
7382 : 2.0);
7383 : // Calculate duct conduction loss
7384 13478298 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct element only
7385 5671808 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7386 5671808 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7387 5664527 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7388 5664527 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7389 5664527 : DirSign = 1.0;
7390 : } else { // flow direction is the opposite as input from node 2 to node 1
7391 7281 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7392 7281 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7393 7281 : DirSign = -1.0;
7394 : }
7395 : // Fatal error when return flow is opposite to the desired direction
7396 5671808 : if (AirflowNetworkLinkSimu(i).FLOW == 0.0 && AirflowNetworkLinkSimu(i).FLOW2 > 0.0) {
7397 7281 : if (LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
7398 0 : ShowSevereError(m_state,
7399 : "AirflowNetwork: The airflow direction is opposite to the intended direction (from node 1 to node 2) in "
7400 0 : "AirflowNetwork:Distribution:Linkage = " +
7401 0 : AirflowNetworkLinkageData(i).Name);
7402 0 : ShowContinueErrorTimeStamp(m_state, "");
7403 0 : ShowContinueError(m_state,
7404 : "The sum of the airflows entering the zone is greater than the airflows leaving the zone (e.g., wind "
7405 : "and stack effect).");
7406 0 : ShowContinueError(m_state,
7407 : "Please check wind speed or reduce values of \"Window/Door Opening Factor, or Crack Factor\" defined in "
7408 : "AirflowNetwork:MultiZone:Surface objects.");
7409 : // ShowFatalError(state, "AirflowNetwork: The previous error causes termination." );
7410 : }
7411 : }
7412 :
7413 5671808 : if (AirflowNetworkLinkageData(i).ZoneNum < 0) {
7414 0 : ExtNodeNum = AirflowNetworkLinkageData(i).NodeNums[1];
7415 0 : if (AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum > 0 && Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).IsLocalNode) {
7416 0 : Tamb = Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).OutAirDryBulb;
7417 0 : Wamb = Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).HumRat;
7418 : } else {
7419 0 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(ExtNodeNum).NodeHeight);
7420 0 : Wamb = m_state.dataEnvrn->OutHumRat;
7421 : }
7422 5671808 : } else if (AirflowNetworkLinkageData(i).ZoneNum == 0) {
7423 2057286 : Tamb = AirflowNetworkNodeSimu(LT).TZ;
7424 2057286 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7425 : } else {
7426 3614522 : Tamb = ANZT(AirflowNetworkLinkageData(i).ZoneNum);
7427 3614522 : Wamb = ANZW(AirflowNetworkLinkageData(i).ZoneNum);
7428 : }
7429 :
7430 5671808 : Pamb = m_state.dataEnvrn->OutBaroPress;
7431 :
7432 5671808 : Real64 constexpr tolerance = 0.001;
7433 5671808 : Real64 UThermal(10); // Initialize. This will get updated.
7434 5671808 : Real64 UThermal_iter = 0;
7435 5671808 : Real64 Tsurr = Tamb;
7436 5671808 : Real64 Tsurr_K = Tsurr + DataGlobalConstants::KelvinConv;
7437 5671808 : Real64 Tin = AirflowNetworkNodeSimu(LF).TZ;
7438 5671808 : Real64 TDuctSurf = (Tamb + Tin) / 2.0;
7439 5671808 : Real64 TDuctSurf_K = TDuctSurf + DataGlobalConstants::KelvinConv;
7440 5671808 : Real64 DuctSurfArea = DisSysCompDuctData(TypeNum).L * DisSysCompDuctData(TypeNum).hydraulicDiameter * DataGlobalConstants::Pi;
7441 :
7442 : // If user defined view factors not present, calculate air-to-air heat transfer
7443 5671808 : if (AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum == 0) {
7444 :
7445 : // Calculate convection coefficient if one or both not present
7446 5663489 : if (DisSysCompDuctData(TypeNum).InsideConvCoeff == 0 && DisSysCompDuctData(TypeNum).OutsideConvCoeff == 0) {
7447 17700232 : while (std::abs(UThermal - UThermal_iter) > tolerance) {
7448 7699857 : UThermal_iter = UThermal;
7449 :
7450 23099571 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin,
7451 7699857 : AirflowNetworkLinkSimu(i).FLOW,
7452 7699857 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7453 15399714 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7454 23099571 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7455 : Tamb,
7456 : Wamb,
7457 : Pamb,
7458 7699857 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7459 7699857 : AirflowNetworkLinkageData(i).ZoneNum,
7460 15399714 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7461 7699857 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7462 7699857 : Real64 RThermTotal = RThermConvIn + RThermConvOut + RThermConduct;
7463 7699857 : UThermal = pow(RThermTotal, -1);
7464 :
7465 : // Duct conduction, assuming effectiveness = 1 - exp(-NTU)
7466 7699857 : Ei = General::epexp(-UThermal * DuctSurfArea, (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7467 7699857 : Real64 QCondDuct = std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * (Tamb - Tin) * (1 - Ei);
7468 :
7469 7699857 : TDuctSurf = Tamb - QCondDuct * RThermConvOut / DuctSurfArea;
7470 : }
7471 : } else { // Air-to-air only. U and h values are all known
7472 10088913 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin,
7473 3362971 : AirflowNetworkLinkSimu(i).FLOW,
7474 3362971 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7475 6725942 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7476 10088913 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7477 : Tamb,
7478 : Wamb,
7479 : Pamb,
7480 3362971 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7481 3362971 : AirflowNetworkLinkageData(i).ZoneNum,
7482 6725942 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7483 3362971 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7484 3362971 : Real64 RThermTotal = RThermConvIn + RThermConvOut + RThermConduct;
7485 3362971 : UThermal = pow(RThermTotal, -1);
7486 : }
7487 :
7488 5663489 : Tsurr = Tamb;
7489 :
7490 : } else { // Air-to-air + radiation heat transfer
7491 :
7492 8319 : auto &VFObj(AirflowNetworkLinkageViewFactorData(AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum));
7493 8319 : VFObj.QRad = 0;
7494 8319 : VFObj.QConv = 0;
7495 :
7496 8319 : Real64 Tin_ave = Tin;
7497 8319 : Real64 hOut = 0;
7498 :
7499 73531 : while (std::abs(UThermal - UThermal_iter) > tolerance) {
7500 32606 : UThermal_iter = UThermal;
7501 :
7502 97818 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin_ave,
7503 32606 : AirflowNetworkLinkSimu(i).FLOW,
7504 32606 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7505 65212 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7506 97818 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7507 : Tamb,
7508 : Wamb,
7509 : Pamb,
7510 32606 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7511 32606 : AirflowNetworkLinkageData(i).ZoneNum,
7512 65212 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7513 :
7514 32606 : if (RThermConvOut > 0.0) {
7515 32605 : hOut = 1 / RThermConvOut;
7516 : }
7517 :
7518 32606 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7519 :
7520 32606 : Real64 hrjTj_sum = 0;
7521 32606 : Real64 hrj_sum = 0;
7522 :
7523 195636 : for (int j = 1; j <= VFObj.LinkageSurfaceData.u(); ++j) {
7524 :
7525 163030 : int ZoneSurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7526 :
7527 163030 : Real64 TSurfj = m_state.dataHeatBalSurf->SurfOutsideTempHist(1)(ZoneSurfNum);
7528 163030 : Real64 TSurfj_K = TSurfj + DataGlobalConstants::KelvinConv;
7529 :
7530 : Real64 ZoneSurfEmissivity =
7531 163030 : m_state.dataConstruction->Construct(m_state.dataSurface->Surface(ZoneSurfNum).Construction).InsideAbsorpThermal;
7532 163030 : Real64 ZoneSurfArea = m_state.dataSurface->Surface(ZoneSurfNum).Area;
7533 :
7534 163030 : Real64 DuctEmissivity = VFObj.DuctEmittance;
7535 163030 : Real64 DuctExposureFrac = VFObj.DuctExposureFraction;
7536 163030 : Real64 DuctToZoneSurfViewFactor = VFObj.LinkageSurfaceData(j).ViewFactor;
7537 :
7538 163030 : Real64 DuctSurfResistance = (1 - DuctEmissivity) / (DuctExposureFrac * DuctSurfArea * DuctEmissivity);
7539 163030 : Real64 SpaceResistance = 1 / (DuctExposureFrac * DuctSurfArea * DuctToZoneSurfViewFactor);
7540 163030 : Real64 ZoneSurfResistance = (1 - ZoneSurfEmissivity) / (ZoneSurfArea * ZoneSurfEmissivity);
7541 :
7542 163030 : VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor =
7543 163030 : DataGlobalConstants::StefanBoltzmann / (DuctSurfResistance + SpaceResistance + ZoneSurfResistance);
7544 :
7545 326060 : Real64 hrj = VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor * (TDuctSurf_K + TSurfj_K) *
7546 326060 : (pow_2(TDuctSurf_K) + pow_2(TSurfj_K)) / DuctSurfArea;
7547 :
7548 163030 : hrjTj_sum += hrj * TSurfj;
7549 163030 : hrj_sum += hrj;
7550 : }
7551 :
7552 32606 : Tsurr = (hOut * Tamb + hrjTj_sum) / (hOut + hrj_sum); // Surroundings temperature [C]
7553 32606 : Tsurr_K = Tsurr + DataGlobalConstants::KelvinConv;
7554 :
7555 32606 : Real64 RThermTotal = RThermConvIn + RThermConduct + 1 / (hOut + hrj_sum);
7556 32606 : UThermal = pow(RThermTotal, -1);
7557 :
7558 32606 : Real64 NTU = UThermal * DuctSurfArea / (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir);
7559 32606 : Tin_ave = Tsurr + (Tin - Tsurr) * (1 / NTU) * (1 - exp(-NTU));
7560 :
7561 32606 : TDuctSurf = Tin_ave - UThermal * (RThermConvIn + RThermConduct) * (Tin_ave - Tsurr);
7562 32606 : TDuctSurf_K = TDuctSurf + DataGlobalConstants::KelvinConv;
7563 : }
7564 :
7565 49914 : for (int j = 1; j <= VFObj.LinkageSurfaceData.u(); ++j) {
7566 41595 : int ZoneSurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7567 41595 : Real64 TSurfj = m_state.dataHeatBalSurf->SurfOutsideTempHist(1)(ZoneSurfNum);
7568 41595 : Real64 TSurfj_K = TSurfj + DataGlobalConstants::KelvinConv;
7569 83190 : VFObj.LinkageSurfaceData(j).SurfaceRadLoad = VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor *
7570 41595 : (pow_4(TDuctSurf_K) - pow_4(TSurfj_K)); // Radiant load for this surface [W]
7571 41595 : int SurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7572 41595 : Real64 ZoneSurfaceArea = m_state.dataSurface->Surface(SurfNum).Area;
7573 83190 : m_state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) += VFObj.LinkageSurfaceData(j).SurfaceRadLoad * TimeStepSys *
7574 41595 : DataGlobalConstants::SecInHour /
7575 : ZoneSurfaceArea; // Energy to each surface per unit area [J/m2]
7576 41595 : VFObj.QRad += VFObj.LinkageSurfaceData(j).SurfaceRadLoad; // Total radiant load from all surfaces for this system timestep [W]
7577 : }
7578 :
7579 8319 : VFObj.QConv = hOut * DuctSurfArea * (TDuctSurf - Tamb);
7580 8319 : UThermal = (VFObj.QRad + VFObj.QConv) / (DuctSurfArea * std::abs(Tsurr - Tin));
7581 : }
7582 :
7583 5671808 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7584 7281 : Ei = General::epexp(-UThermal * DuctSurfArea, (AirflowNetworkLinkSimu(i).FLOW2 * CpAir));
7585 7281 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7586 7281 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * Ei;
7587 7281 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Tsurr * (1.0 - Ei) * CpAir;
7588 : } else {
7589 5664527 : Ei = General::epexp(-UThermal * DuctSurfArea, (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7590 5664527 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7591 5664527 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * Ei;
7592 5664527 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Tsurr * (1.0 - Ei) * CpAir;
7593 : }
7594 : }
7595 13478298 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
7596 109129 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7597 109129 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7598 109129 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7599 109129 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7600 109129 : DirSign = 1.0;
7601 : } else { // flow direction is the opposite as input from node 2 to node 1
7602 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7603 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7604 0 : DirSign = -1.0;
7605 : }
7606 109129 : Ei = General::epexp(-0.001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter *
7607 : DataGlobalConstants::Pi,
7608 109129 : (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7609 109129 : Tamb = AirflowNetworkNodeSimu(LT).TZ;
7610 109129 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7611 0 : Ei = General::epexp(-0.001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter *
7612 : DataGlobalConstants::Pi,
7613 0 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir));
7614 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7615 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * Ei;
7616 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Tamb * (1.0 - Ei) * CpAir;
7617 : } else {
7618 109129 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7619 109129 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * Ei;
7620 109129 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Tamb * (1.0 - Ei) * CpAir;
7621 : }
7622 : }
7623 13478298 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
7624 1077244 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7625 1077244 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7626 1075376 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7627 1075376 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7628 1075376 : DirSign = 1.0;
7629 : } else { // flow direction is the opposite as input from node 2 to node 1
7630 1868 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7631 1868 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7632 1868 : DirSign = -1.0;
7633 : }
7634 : }
7635 : // Calculate temp in a constant pressure drop element
7636 13478298 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
7637 77844 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7638 77844 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7639 77844 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7640 : } else { // flow direction is the opposite as input from node 2 to node 1
7641 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7642 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7643 : }
7644 77844 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7645 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7646 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7647 : } else {
7648 77844 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7649 77844 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7650 : }
7651 77844 : MV(LT) = 0.0;
7652 : }
7653 : // Calculate return leak
7654 13478298 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
7655 : // Return leak element only
7656 2599598 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
7657 1445033 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7658 286424 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7659 286424 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7660 286424 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7661 286424 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7662 : }
7663 2315892 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
7664 1161327 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7665 6003 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7666 6003 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7667 6003 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7668 6003 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7669 : }
7670 2927386 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
7671 1772821 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7672 121 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7673 121 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7674 121 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7675 121 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7676 : }
7677 2548209 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
7678 1393644 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7679 238355 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7680 238355 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7681 238355 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7682 238355 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7683 : }
7684 : }
7685 : // Check reheat unit or coil
7686 13478298 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(i).VAVTermDamper)) {
7687 102367 : NF = 0;
7688 102367 : NT = 0;
7689 102367 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
7690 102367 : NF = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum;
7691 : }
7692 102367 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
7693 102367 : NT = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum;
7694 : }
7695 102367 : if ((NF == 0) || (NT == 0)) {
7696 0 : ShowFatalError(m_state,
7697 0 : "Node number in the primary air loop is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " +
7698 0 : AirflowNetworkLinkageData(i).Name);
7699 : }
7700 102367 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) {
7701 102367 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7702 102367 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7703 102367 : load = Node(NT).Temp - Node(NF).Temp;
7704 : } else {
7705 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7706 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7707 0 : load = Node(NF).Temp - Node(NT).Temp;
7708 : }
7709 102367 : CpAir = PsyCpAirFnW(Node(NT).HumRat);
7710 102367 : MV(LT) += AirflowNetworkLinkSimu(i).FLOW * CpAir * load;
7711 : }
7712 : }
7713 :
7714 : // Prescribe temperature for EPlus nodes
7715 11541555 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7716 11160821 : found = false;
7717 11160821 : OANode = false;
7718 420016719 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
7719 410519960 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7720 26069154 : CompNum = AirflowNetworkLinkageData(j).CompNum;
7721 26069154 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
7722 204734 : found = true;
7723 204734 : break;
7724 : }
7725 : // Overwrite fan outlet node
7726 25864420 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7727 391401 : found = false;
7728 391401 : break;
7729 : }
7730 : // Overwrite return connection outlet
7731 25473019 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
7732 567470 : found = true;
7733 567470 : break;
7734 : }
7735 25688351 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
7736 782802 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
7737 391401 : found = true;
7738 391401 : break;
7739 : }
7740 : }
7741 421257023 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
7742 12292069 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
7743 109056 : OANode = true;
7744 109056 : break;
7745 : }
7746 : }
7747 11160821 : if (found) continue;
7748 9997216 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
7749 9554955 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
7750 :
7751 15081940 : if (j > 0 &&
7752 8901137 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
7753 3971894 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
7754 2066387 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7755 2066387 : MV(i) = Node(j).Temp * 1.0e10;
7756 : }
7757 9554955 : if (j > 0 && OANode) {
7758 109056 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7759 109056 : MV(i) = Node(j).Temp * 1.0e10;
7760 : }
7761 9554955 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7762 490748 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
7763 490748 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7764 490748 : MV(i) = ANZT(ZoneNum) * 1.0e10;
7765 : }
7766 9554955 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7767 3426318 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7768 3426318 : if (AirflowNetworkNodeData(i).OutAirNodeNum > 0) {
7769 12865 : MV(i) = Node(AirflowNetworkNodeData(i).OutAirNodeNum).OutAirDryBulb * 1.0e10;
7770 : } else {
7771 3413453 : MV(i) = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(i).NodeHeight) * 1.0e10;
7772 : }
7773 : }
7774 9554955 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7775 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7776 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
7777 0 : if (m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirflowNetworkNodeID ==
7778 : i) {
7779 0 : MV(i) = m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp * 1.0e10;
7780 : }
7781 : }
7782 : }
7783 :
7784 : // Assign node value to distribution nodes with fan off
7785 7156033 : for (i = 1 + NumOfNodesMultiZone; i <= AirflowNetworkNumOfNodes; ++i) {
7786 6775299 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
7787 6775299 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
7788 4344 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7789 4344 : MV(i) = Node(j).Temp * 1.0e10;
7790 : }
7791 6775299 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
7792 5068 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7793 5068 : MV(i) = AirflowNetworkNodeSimu(i).TZlast * 1.0e10;
7794 : }
7795 : }
7796 :
7797 : // Check singularity
7798 11541555 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7799 11160821 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
7800 0 : if (i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
7801 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7802 0 : MV(i) = AirflowNetworkNodeSimu(i).TZlast * 1.0e10;
7803 : } else {
7804 0 : ShowFatalError(m_state,
7805 0 : "CalcAirflowNetworkHeatBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
7806 0 : AirflowNetworkNodeData(i).Name);
7807 : }
7808 : }
7809 : }
7810 :
7811 : // Get an inverse matrix
7812 380734 : mrxinv(AirflowNetworkNumOfNodes);
7813 :
7814 : // Calculate node temperatures
7815 11541555 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7816 11160821 : TZON = 0.0;
7817 355203138 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
7818 344042317 : TZON += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
7819 : }
7820 11160821 : AirflowNetworkNodeSimu(i).TZ = TZON;
7821 : }
7822 380734 : }
7823 :
7824 380734 : void Solver::calculate_moisture_balance()
7825 : {
7826 : // SUBROUTINE INFORMATION:
7827 : // AUTHOR Lixing Gu
7828 : // DATE WRITTEN Oct. 2005
7829 : // MODIFIED na
7830 : // RE-ENGINEERED Revised based on Subroutine CalcADSMoistureBalance
7831 :
7832 : // PURPOSE OF THIS SUBROUTINE:
7833 : // This subroutine performs AirflowNetwork moisture simulations.
7834 :
7835 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7836 : int i;
7837 : int j;
7838 : int LF;
7839 : int LT;
7840 : int CompNum;
7841 : int NF;
7842 : int NT;
7843 : iComponentTypeNum CompTypeNum;
7844 : int TypeNum;
7845 761468 : std::string CompName;
7846 : Real64 Ei;
7847 : Real64 DirSign;
7848 : Real64 Wamb;
7849 : Real64 WZON;
7850 : Real64 load;
7851 : int ZoneNum;
7852 : bool found;
7853 : bool OANode;
7854 :
7855 380734 : auto &Node(m_state.dataLoopNodes->Node);
7856 :
7857 380734 : MA = 0.0;
7858 380734 : MV = 0.0;
7859 13859032 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
7860 13478298 : CompNum = AirflowNetworkLinkageData(i).CompNum;
7861 13478298 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
7862 13478298 : CompName = AirflowNetworkCompData(CompNum).EPlusName;
7863 : // Calculate duct moisture diffusion loss
7864 13478298 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct component only
7865 5671808 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7866 5671808 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7867 5664527 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7868 5664527 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7869 5664527 : DirSign = 1.0;
7870 : } else { // flow direction is the opposite as input from node 2 to node 1
7871 7281 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7872 7281 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7873 7281 : DirSign = -1.0;
7874 : }
7875 11343616 : Ei = General::epexp(-DisSysCompDuctData(TypeNum).UMoisture * DisSysCompDuctData(TypeNum).L *
7876 5671808 : DisSysCompDuctData(TypeNum).hydraulicDiameter * DataGlobalConstants::Pi,
7877 5671808 : (DirSign * AirflowNetworkLinkSimu(i).FLOW));
7878 5671808 : if (AirflowNetworkLinkageData(i).ZoneNum < 0) {
7879 0 : Wamb = m_state.dataEnvrn->OutHumRat;
7880 5671808 : } else if (AirflowNetworkLinkageData(i).ZoneNum == 0) {
7881 2057286 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7882 : } else {
7883 3614522 : Wamb = ANZW(AirflowNetworkLinkageData(i).ZoneNum);
7884 : }
7885 5671808 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7886 14562 : Ei = General::epexp(-DisSysCompDuctData(TypeNum).UMoisture * DisSysCompDuctData(TypeNum).L *
7887 7281 : DisSysCompDuctData(TypeNum).hydraulicDiameter * DataGlobalConstants::Pi,
7888 7281 : (AirflowNetworkLinkSimu(i).FLOW2));
7889 7281 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7890 7281 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Ei;
7891 7281 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Wamb * (1.0 - Ei);
7892 : } else {
7893 5664527 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7894 5664527 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * Ei;
7895 5664527 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Wamb * (1.0 - Ei);
7896 : }
7897 : }
7898 13478298 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
7899 109129 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7900 109129 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7901 109129 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7902 109129 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7903 109129 : DirSign = 1.0;
7904 : } else { // flow direction is the opposite as input from node 2 to node 1
7905 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7906 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7907 0 : DirSign = -1.0;
7908 : }
7909 109129 : Ei = General::epexp(-0.0001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter *
7910 : DataGlobalConstants::Pi,
7911 109129 : (DirSign * AirflowNetworkLinkSimu(i).FLOW));
7912 109129 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7913 109129 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7914 :
7915 0 : Ei = General::epexp(-0.0001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter *
7916 : DataGlobalConstants::Pi,
7917 0 : (AirflowNetworkLinkSimu(i).FLOW2));
7918 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7919 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Ei;
7920 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Wamb * (1.0 - Ei);
7921 : } else {
7922 109129 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7923 109129 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * Ei;
7924 109129 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Wamb * (1.0 - Ei);
7925 : }
7926 : }
7927 13478298 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
7928 1077244 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7929 1077244 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7930 1075376 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7931 1075376 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7932 1075376 : DirSign = 1.0;
7933 : } else { // flow direction is the opposite as input from node 2 to node 1
7934 1868 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7935 1868 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7936 1868 : DirSign = -1.0;
7937 : }
7938 : }
7939 : // Calculate temp in a constant pressure drop component
7940 13478298 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
7941 77844 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7942 77844 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7943 77844 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7944 : } else { // flow direction is the opposite as input from node 2 to node 1
7945 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7946 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7947 : }
7948 77844 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7949 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7950 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7951 : } else {
7952 77844 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7953 77844 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7954 : }
7955 77844 : MV(LT) = 0.0;
7956 : }
7957 : // Calculate return leak
7958 13478298 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
7959 : // Return leak component only
7960 2599598 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
7961 1445033 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7962 286424 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7963 286424 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7964 286424 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7965 286424 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7966 : }
7967 2315892 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
7968 1161327 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7969 6003 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7970 6003 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7971 6003 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7972 6003 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7973 : }
7974 2927386 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
7975 1772821 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7976 121 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7977 121 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7978 121 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7979 121 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7980 : }
7981 2548209 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
7982 1393644 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7983 238355 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7984 238355 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7985 238355 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7986 238355 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7987 : }
7988 : }
7989 : // Check reheat unit
7990 13478298 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(i).VAVTermDamper)) {
7991 102367 : NF = 0;
7992 102367 : NT = 0;
7993 102367 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
7994 102367 : NF = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum;
7995 : }
7996 102367 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
7997 102367 : NT = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum;
7998 : }
7999 102367 : if ((NF == 0) || (NT == 0)) {
8000 0 : ShowFatalError(m_state,
8001 0 : "Node number in the primary air loop is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " +
8002 0 : AirflowNetworkLinkageData(i).Name);
8003 : }
8004 102367 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) {
8005 102367 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8006 102367 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8007 102367 : load = Node(NT).HumRat - Node(NF).HumRat;
8008 : } else {
8009 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8010 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8011 0 : load = Node(NF).HumRat - Node(NT).HumRat;
8012 : }
8013 102367 : MV(LT) += AirflowNetworkLinkSimu(i).FLOW * load;
8014 : }
8015 : }
8016 :
8017 : // Prescribe temperature for EPlus nodes
8018 11541555 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8019 11160821 : found = false;
8020 11160821 : OANode = false;
8021 420016719 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
8022 410519960 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8023 26069154 : CompNum = AirflowNetworkLinkageData(j).CompNum;
8024 26069154 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
8025 204734 : found = true;
8026 204734 : break;
8027 : }
8028 : // Overwrite fan outlet node
8029 25864420 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8030 391401 : found = false;
8031 391401 : break;
8032 : }
8033 : // Overwrite return connection outlet
8034 25473019 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
8035 567470 : found = true;
8036 567470 : break;
8037 : }
8038 25688351 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
8039 782802 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
8040 391401 : found = true;
8041 391401 : break;
8042 : }
8043 : }
8044 421257023 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
8045 12292069 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
8046 109056 : OANode = true;
8047 109056 : break;
8048 : }
8049 : }
8050 11160821 : if (found) continue;
8051 9997216 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
8052 9554955 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8053 15081940 : if (j > 0 &&
8054 8901137 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
8055 3971894 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
8056 2066387 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8057 2066387 : MV(i) = Node(j).HumRat * 1.0e10;
8058 : }
8059 9554955 : if (j > 0 && OANode) {
8060 109056 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8061 109056 : MV(i) = Node(j).HumRat * 1.0e10;
8062 : }
8063 9554955 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8064 490748 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8065 490748 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8066 490748 : MV(i) = ANZW(ZoneNum) * 1.0e10;
8067 : }
8068 9554955 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
8069 3442760 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8070 3442760 : MV(i) = m_state.dataEnvrn->OutHumRat * 1.0e10;
8071 : }
8072 9554955 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8073 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8074 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8075 0 : if (m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirflowNetworkNodeID ==
8076 : i) {
8077 0 : MV(i) = m_state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat * 1.0e10;
8078 : }
8079 : }
8080 : }
8081 :
8082 : // Assign node value to distribution nodes with fan off
8083 11541555 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8084 11160821 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8085 11160821 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
8086 4344 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8087 4344 : MV(i) = Node(j).HumRat * 1.0e10;
8088 : }
8089 11160821 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
8090 5068 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8091 5068 : MV(i) = AirflowNetworkNodeSimu(i).WZlast * 1.0e10;
8092 : }
8093 : }
8094 :
8095 : // Check singularity
8096 11541555 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8097 11160821 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-8) {
8098 0 : ShowFatalError(m_state,
8099 0 : "CalcAirflowNetworkMoisBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
8100 0 : AirflowNetworkNodeData(i).Name);
8101 : }
8102 : }
8103 :
8104 : // Get an inverse matrix
8105 380734 : mrxinv(AirflowNetworkNumOfNodes);
8106 :
8107 : // Calculate node temperatures
8108 11541555 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8109 11160821 : WZON = 0.0;
8110 355203138 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
8111 344042317 : WZON += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
8112 : }
8113 11160821 : AirflowNetworkNodeSimu(i).WZ = WZON;
8114 : }
8115 380734 : }
8116 :
8117 4178 : void Solver::calculate_CO2_balance()
8118 : {
8119 : // SUBROUTINE INFORMATION:
8120 : // AUTHOR Lixing Gu
8121 : // DATE WRITTEN June. 2010
8122 : // MODIFIED na
8123 : // RE-ENGINEERED Revised based on Subroutine CalcAirflowNetworkMoisBalance
8124 :
8125 : // PURPOSE OF THIS SUBROUTINE:
8126 : // This subroutine performs AirflowNetwork CO2 simulations.
8127 :
8128 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8129 : int i;
8130 : int j;
8131 : int LF;
8132 : int LT;
8133 : int CompNum;
8134 : iComponentTypeNum CompTypeNum;
8135 : int TypeNum;
8136 8356 : std::string CompName;
8137 : Real64 DirSign;
8138 : Real64 COZN;
8139 : int ZoneNum;
8140 : bool found;
8141 : bool OANode;
8142 :
8143 4178 : MA = 0.0;
8144 4178 : MV = 0.0;
8145 254858 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
8146 250680 : CompNum = AirflowNetworkLinkageData(i).CompNum;
8147 250680 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
8148 250680 : CompName = AirflowNetworkCompData(CompNum).EPlusName;
8149 : // Calculate duct moisture diffusion loss
8150 250680 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct component only
8151 108628 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8152 108628 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8153 108628 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8154 108628 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8155 108628 : DirSign = 1.0;
8156 : } else { // flow direction is the opposite as input from node 2 to node 1
8157 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8158 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8159 0 : DirSign = -1.0;
8160 : }
8161 108628 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8162 108628 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8163 : }
8164 250680 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
8165 8356 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8166 8356 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8167 8356 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8168 8356 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8169 8356 : DirSign = 1.0;
8170 : } else { // flow direction is the opposite as input from node 2 to node 1
8171 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8172 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8173 0 : DirSign = -1.0;
8174 : }
8175 8356 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8176 8356 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8177 : }
8178 250680 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
8179 8356 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8180 8356 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8181 8356 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8182 8356 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8183 8356 : DirSign = 1.0;
8184 : } else { // flow direction is the opposite as input from node 2 to node 1
8185 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8186 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8187 0 : DirSign = -1.0;
8188 : }
8189 : }
8190 : // Calculate temp in a constant pressure drop component
8191 250680 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
8192 4178 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8193 4178 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8194 4178 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8195 : } else { // flow direction is the opposite as input from node 2 to node 1
8196 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8197 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8198 : }
8199 4178 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8200 4178 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8201 4178 : MV(LT) = 0.0;
8202 : }
8203 : // Calculate return leak
8204 250680 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
8205 : // Return leak component only
8206 58492 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
8207 29246 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8208 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8209 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8210 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8211 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8212 : }
8213 58492 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
8214 29246 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8215 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8216 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8217 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8218 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8219 : }
8220 75204 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
8221 45958 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8222 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8223 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8224 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8225 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8226 : }
8227 71026 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
8228 41780 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8229 12534 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8230 12534 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8231 12534 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8232 12534 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8233 : }
8234 : }
8235 : }
8236 :
8237 : // Prescribe temperature for EPlus nodes
8238 158764 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8239 154586 : found = false;
8240 154586 : OANode = false;
8241 8656816 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
8242 8539832 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8243 480470 : CompNum = AirflowNetworkLinkageData(j).CompNum;
8244 480470 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
8245 16712 : found = true;
8246 16712 : break;
8247 : }
8248 : // Overwrite fan outlet node
8249 463758 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8250 4178 : found = false;
8251 4178 : break;
8252 : }
8253 : // Overwrite return connection outlet
8254 459580 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
8255 8356 : found = true;
8256 8356 : break;
8257 : }
8258 459580 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
8259 8356 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
8260 4178 : found = true;
8261 4178 : break;
8262 : }
8263 : }
8264 8736198 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
8265 229790 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
8266 4178 : OANode = true;
8267 4178 : break;
8268 : }
8269 : }
8270 154586 : if (found) continue;
8271 125340 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
8272 121162 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8273 196366 : if (j > 0 &&
8274 121162 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
8275 58492 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
8276 25068 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8277 25068 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8278 : }
8279 121162 : if (j > 0 && OANode) {
8280 4178 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8281 4178 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8282 : }
8283 121162 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8284 4178 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8285 4178 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8286 4178 : MV(i) = ANCO(ZoneNum) * 1.0e10;
8287 : }
8288 121162 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
8289 25068 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8290 25068 : MV(i) = m_state.dataContaminantBalance->OutdoorCO2 * 1.0e10;
8291 : }
8292 : }
8293 :
8294 : // Assign node value to distribution nodes with fan off
8295 158764 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8296 154586 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8297 154586 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
8298 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8299 0 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8300 : }
8301 154586 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
8302 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8303 0 : MV(i) = AirflowNetworkNodeSimu(i).CO2Zlast * 1.0e10;
8304 : }
8305 : }
8306 :
8307 : // Check singularity
8308 158764 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8309 154586 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
8310 0 : ShowFatalError(m_state,
8311 0 : "CalcAirflowNetworkCO2Balance: A diagonal entity is zero in AirflowNetwork matrix at node " +
8312 0 : AirflowNetworkNodeData(i).Name);
8313 : }
8314 : }
8315 :
8316 : // Get an inverse matrix
8317 4178 : mrxinv(AirflowNetworkNumOfNodes);
8318 :
8319 : // Calculate node temperatures
8320 158764 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8321 154586 : COZN = 0.0;
8322 5874268 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
8323 5719682 : COZN += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
8324 : }
8325 154586 : AirflowNetworkNodeSimu(i).CO2Z = COZN;
8326 : }
8327 4178 : }
8328 :
8329 4077 : void Solver::calculate_GC_balance()
8330 : {
8331 : // SUBROUTINE INFORMATION:
8332 : // AUTHOR Lixing Gu
8333 : // DATE WRITTEN Jan. 2012
8334 : // MODIFIED na
8335 : // RE-ENGINEERED Revised based on Subroutine CalcAirflowNetworkCO2Balance
8336 :
8337 : // PURPOSE OF THIS SUBROUTINE:
8338 : // This subroutine performs AirflowNetwork generic contaminant simulations.
8339 :
8340 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8341 : int i;
8342 : int j;
8343 : int LF;
8344 : int LT;
8345 : int CompNum;
8346 : iComponentTypeNum CompTypeNum;
8347 : int TypeNum;
8348 8154 : std::string CompName;
8349 : Real64 DirSign;
8350 : Real64 COZN;
8351 : int ZoneNum;
8352 : bool found;
8353 : bool OANode;
8354 :
8355 4077 : MA = 0.0;
8356 4077 : MV = 0.0;
8357 240543 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
8358 236466 : CompNum = AirflowNetworkLinkageData(i).CompNum;
8359 236466 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
8360 236466 : CompName = AirflowNetworkCompData(CompNum).EPlusName;
8361 : // Calculate duct moisture diffusion loss
8362 236466 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct component only
8363 106002 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8364 106002 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8365 106002 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8366 106002 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8367 106002 : DirSign = 1.0;
8368 : } else { // flow direction is the opposite as input from node 2 to node 1
8369 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8370 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8371 0 : DirSign = -1.0;
8372 : }
8373 106002 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8374 106002 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8375 : }
8376 236466 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
8377 8154 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8378 8154 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8379 8154 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8380 8154 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8381 8154 : DirSign = 1.0;
8382 : } else { // flow direction is the opposite as input from node 2 to node 1
8383 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8384 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8385 0 : DirSign = -1.0;
8386 : }
8387 8154 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8388 8154 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8389 : }
8390 236466 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
8391 8154 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8392 8154 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8393 8154 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8394 8154 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8395 8154 : DirSign = 1.0;
8396 : } else { // flow direction is the opposite as input from node 2 to node 1
8397 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8398 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8399 0 : DirSign = -1.0;
8400 : }
8401 : }
8402 : // Calculate temp in a constant pressure drop component
8403 236466 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
8404 4077 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8405 4077 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8406 4077 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8407 : } else { // flow direction is the opposite as input from node 2 to node 1
8408 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8409 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8410 : }
8411 4077 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8412 4077 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8413 4077 : MV(LT) = 0.0;
8414 : }
8415 : // Calculate return leak
8416 236466 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
8417 : // Return leak component only
8418 57078 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
8419 28539 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8420 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8421 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8422 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8423 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8424 : }
8425 57078 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
8426 28539 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8427 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8428 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8429 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8430 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8431 : }
8432 73386 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
8433 44847 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8434 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8435 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8436 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8437 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8438 : }
8439 69309 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
8440 40770 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8441 12231 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8442 12231 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8443 12231 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8444 12231 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8445 : }
8446 : }
8447 : }
8448 :
8449 : // Prescribe temperature for EPlus nodes
8450 154926 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8451 150849 : found = false;
8452 150849 : OANode = false;
8453 8145846 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
8454 8031690 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8455 452547 : CompNum = AirflowNetworkLinkageData(j).CompNum;
8456 452547 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
8457 16308 : found = true;
8458 16308 : break;
8459 : }
8460 : // Overwrite fan outlet node
8461 436239 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8462 4077 : found = false;
8463 4077 : break;
8464 : }
8465 : // Overwrite return connection outlet
8466 432162 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
8467 8154 : found = true;
8468 8154 : break;
8469 : }
8470 432162 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
8471 8154 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
8472 4077 : found = true;
8473 4077 : break;
8474 : }
8475 : }
8476 8215155 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
8477 216081 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
8478 4077 : OANode = true;
8479 4077 : break;
8480 : }
8481 : }
8482 150849 : if (found) continue;
8483 122310 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
8484 118233 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8485 191619 : if (j > 0 &&
8486 118233 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
8487 57078 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
8488 24462 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8489 24462 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8490 : }
8491 118233 : if (j > 0 && OANode) {
8492 4077 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8493 4077 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8494 : }
8495 118233 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8496 4077 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8497 4077 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8498 4077 : MV(i) = ANGC(ZoneNum) * 1.0e10;
8499 : }
8500 118233 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
8501 24462 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8502 24462 : MV(i) = m_state.dataContaminantBalance->OutdoorGC * 1.0e10;
8503 : }
8504 : }
8505 :
8506 : // Assign node value to distribution nodes with fan off
8507 154926 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8508 150849 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8509 150849 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
8510 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8511 0 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8512 : }
8513 150849 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
8514 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8515 0 : MV(i) = AirflowNetworkNodeSimu(i).GCZlast * 1.0e10;
8516 : }
8517 : }
8518 :
8519 : // Check singularity
8520 154926 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8521 150849 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
8522 0 : ShowFatalError(m_state,
8523 0 : "CalcAirflowNetworkGCBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
8524 0 : AirflowNetworkNodeData(i).Name);
8525 : }
8526 : }
8527 :
8528 : // Get an inverse matrix
8529 4077 : mrxinv(AirflowNetworkNumOfNodes);
8530 :
8531 : // Calculate node temperatures
8532 154926 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8533 150849 : COZN = 0.0;
8534 5732262 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
8535 5581413 : COZN += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
8536 : }
8537 150849 : AirflowNetworkNodeSimu(i).GCZ = COZN;
8538 : }
8539 4077 : }
8540 :
8541 769723 : void Solver::mrxinv(int const NORDER)
8542 : {
8543 :
8544 : // SUBROUTINE INFORMATION:
8545 : // AUTHOR Lixing Gu
8546 : // DATE WRITTEN Oct. 2005
8547 : // MODIFIED na
8548 : // RE-ENGINEERED Revised based on Subroutine ADSINV
8549 :
8550 : // PURPOSE OF THIS SUBROUTINE:
8551 : // This subroutine inverses a matrix
8552 :
8553 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8554 : int i;
8555 : int j;
8556 : int K;
8557 : int M;
8558 : Real64 R1;
8559 : Real64 S;
8560 :
8561 769723 : IVEC = 0;
8562 23396800 : for (i = 1; i <= NORDER; ++i) {
8563 22627077 : IVEC(i + 20) = i;
8564 : }
8565 23396800 : for (i = 1; i <= NORDER; ++i) {
8566 22627077 : R1 = 0.0;
8567 22627077 : M = i;
8568 383633480 : for (j = i; j <= NORDER; ++j) {
8569 361006403 : if (std::abs(R1) < std::abs(MA((i - 1) * NORDER + j))) {
8570 22632702 : M = j;
8571 22632702 : R1 = MA((i - 1) * NORDER + j);
8572 : }
8573 : }
8574 22627077 : if (i != M) {
8575 5625 : K = IVEC(M + 20);
8576 5625 : IVEC(M + 20) = IVEC(i + 20);
8577 5625 : IVEC(i + 20) = K;
8578 118125 : for (j = 1; j <= NORDER; ++j) {
8579 112500 : S = MA((j - 1) * NORDER + i);
8580 112500 : MA((j - 1) * NORDER + i) = MA((j - 1) * NORDER + M);
8581 112500 : MA((j - 1) * NORDER + M) = S;
8582 : }
8583 : }
8584 22627077 : MA((i - 1) * NORDER + i) = 1.0;
8585 722012806 : for (j = 1; j <= NORDER; ++j) {
8586 699385729 : MA((i - 1) * NORDER + j) /= R1;
8587 : }
8588 722012806 : for (j = 1; j <= NORDER; ++j) {
8589 699385729 : if (i == j) continue;
8590 676758652 : R1 = MA((j - 1) * NORDER + i);
8591 676758652 : if (std::abs(R1) <= 1.0E-20) continue;
8592 25911950 : MA((j - 1) * NORDER + i) = 0.0;
8593 869331866 : for (K = 1; K <= NORDER; ++K) {
8594 843419916 : MA((j - 1) * NORDER + K) -= R1 * MA((i - 1) * NORDER + K);
8595 : }
8596 : }
8597 : }
8598 23396800 : for (i = 1; i <= NORDER; ++i) {
8599 22627077 : if (IVEC(i + 20) == i) continue;
8600 5625 : M = i;
8601 129375 : while (NORDER > M) {
8602 67500 : ++M;
8603 67500 : if (IVEC(M + 20) == i) break;
8604 : }
8605 5625 : IVEC(M + 20) = IVEC(i + 20);
8606 118125 : for (j = 1; j <= NORDER; ++j) {
8607 112500 : R1 = MA((i - 1) * NORDER + j);
8608 112500 : MA((i - 1) * NORDER + j) = MA((M - 1) * NORDER + j);
8609 112500 : MA((M - 1) * NORDER + j) = R1;
8610 : }
8611 5625 : IVEC(i + 20) = i;
8612 : }
8613 769723 : }
8614 :
8615 13012 : void Solver::report()
8616 : {
8617 :
8618 : // SUBROUTINE INFORMATION:
8619 : // AUTHOR Lixing Gu
8620 : // DATE WRITTEN 2/1/04
8621 : // MODIFIED na
8622 : // RE-ENGINEERED na
8623 :
8624 : // PURPOSE OF THIS SUBROUTINE:
8625 : // This subroutine reports outputs of air distribution systems
8626 :
8627 : // Using/Aliasing
8628 13012 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
8629 13012 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
8630 :
8631 13012 : auto &Zone(m_state.dataHeatBal->Zone);
8632 :
8633 : // SUBROUTINE PARAMETER DEFINITIONS:
8634 13012 : constexpr Real64 Lam(2.5e6); // Heat of vaporization (J/kg)
8635 :
8636 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8637 : int i;
8638 : int n;
8639 : int M;
8640 : int ZN1;
8641 : int ZN2;
8642 : Real64 AirDensity;
8643 : Real64 CpAir;
8644 : Real64 Tamb;
8645 : Real64 hg; // latent heat of vaporization
8646 : Real64 ReportingConstant;
8647 : Real64 ReportingFraction;
8648 : int AirLoopNum;
8649 : int FanNum;
8650 : Real64 RepOnOffFanRunTimeFraction;
8651 :
8652 13012 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) return;
8653 :
8654 13012 : if (!onetime) {
8655 34 : onceZoneFlag.dimension(m_state.dataGlobal->NumOfZones, false);
8656 34 : onceSurfFlag.dimension(AirflowNetworkNumOfLinks, false);
8657 34 : onetime = true;
8658 : }
8659 13012 : ReportingConstant = TimeStepSys * DataGlobalConstants::SecInHour;
8660 :
8661 13012 : m_state.dataHeatBal->ZoneTotalExfiltrationHeatLoss = 0.0;
8662 :
8663 56596 : for (auto &e : AirflowNetworkReportData) {
8664 43584 : e.MultiZoneInfiSenGainW = 0.0;
8665 43584 : e.MultiZoneInfiSenGainJ = 0.0;
8666 43584 : e.MultiZoneInfiSenLossW = 0.0;
8667 43584 : e.MultiZoneInfiSenLossJ = 0.0;
8668 43584 : e.MultiZoneInfiLatGainW = 0.0;
8669 43584 : e.MultiZoneInfiLatGainJ = 0.0;
8670 43584 : e.MultiZoneInfiLatLossW = 0.0;
8671 43584 : e.MultiZoneInfiLatLossJ = 0.0;
8672 43584 : e.MultiZoneVentSenGainW = 0.0;
8673 43584 : e.MultiZoneVentSenGainJ = 0.0;
8674 43584 : e.MultiZoneVentSenLossW = 0.0;
8675 43584 : e.MultiZoneVentSenLossJ = 0.0;
8676 43584 : e.MultiZoneVentLatGainW = 0.0;
8677 43584 : e.MultiZoneVentLatGainJ = 0.0;
8678 43584 : e.MultiZoneVentLatLossW = 0.0;
8679 43584 : e.MultiZoneVentLatLossJ = 0.0;
8680 43584 : e.MultiZoneMixSenGainW = 0.0;
8681 43584 : e.MultiZoneMixSenGainJ = 0.0;
8682 43584 : e.MultiZoneMixSenLossW = 0.0;
8683 43584 : e.MultiZoneMixSenLossJ = 0.0;
8684 43584 : e.MultiZoneMixLatGainW = 0.0;
8685 43584 : e.MultiZoneMixLatGainJ = 0.0;
8686 43584 : e.MultiZoneMixLatLossW = 0.0;
8687 43584 : e.MultiZoneMixLatLossJ = 0.0;
8688 43584 : e.LeakSenGainW = 0.0;
8689 43584 : e.LeakSenGainJ = 0.0;
8690 43584 : e.LeakSenLossW = 0.0;
8691 43584 : e.LeakSenLossJ = 0.0;
8692 43584 : e.LeakLatGainW = 0.0;
8693 43584 : e.LeakLatGainJ = 0.0;
8694 43584 : e.LeakLatLossW = 0.0;
8695 43584 : e.LeakLatLossJ = 0.0;
8696 43584 : e.CondSenGainW = 0.0;
8697 43584 : e.CondSenGainJ = 0.0;
8698 43584 : e.CondSenLossW = 0.0;
8699 43584 : e.CondSenLossJ = 0.0;
8700 43584 : e.DiffLatGainW = 0.0;
8701 43584 : e.DiffLatGainJ = 0.0;
8702 43584 : e.DiffLatLossW = 0.0;
8703 43584 : e.DiffLatLossJ = 0.0;
8704 43584 : e.RadGainW = 0.0;
8705 43584 : e.RadGainJ = 0.0;
8706 43584 : e.RadLossW = 0.0;
8707 43584 : e.RadLossJ = 0.0;
8708 43584 : e.TotalSenGainW = 0.0;
8709 43584 : e.TotalSenGainJ = 0.0;
8710 43584 : e.TotalSenLossW = 0.0;
8711 43584 : e.TotalSenLossJ = 0.0;
8712 43584 : e.TotalLatGainW = 0.0;
8713 43584 : e.TotalLatGainJ = 0.0;
8714 43584 : e.TotalLatLossW = 0.0;
8715 43584 : e.TotalLatLossJ = 0.0;
8716 : }
8717 :
8718 : // Calculate sensible and latent loads in each zone from multizone airflows
8719 13785 : if (multizone_always_simulated ||
8720 1546 : (simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation && AirflowNetworkFanActivated)) {
8721 196758 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
8722 183877 : n = AirflowNetworkLinkageData(i).NodeNums[0];
8723 183877 : M = AirflowNetworkLinkageData(i).NodeNums[1];
8724 183877 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
8725 183877 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
8726 : // Find a linkage from a zone to outdoors
8727 183877 : if (ZN1 > 0 && ZN2 == 0) {
8728 118002 : auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
8729 118002 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfLinkedOutAirNode > 0) {
8730 0 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(MultizoneSurfaceData(i).SurfNum);
8731 0 : CpAir = PsyCpAirFnW(Psychrometrics::PsyWFnTdbTwbPb(m_state,
8732 : Tamb,
8733 0 : m_state.dataSurface->SurfOutWetBulbTemp(MultizoneSurfaceData(i).SurfNum),
8734 0 : m_state.dataEnvrn->OutBaroPress));
8735 : } else {
8736 118002 : Tamb = Zone(ZN1).OutDryBulbTemp;
8737 118002 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
8738 : }
8739 118002 : hg = Psychrometrics::PsyHgAirFnWTdb(zn1HB.ZoneAirHumRat, zn1HB.MAT);
8740 :
8741 160031 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
8742 42029 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
8743 90205 : if (Tamb > zn1HB.MAT) {
8744 17774 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT));
8745 17774 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainJ +=
8746 17774 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant;
8747 : } else {
8748 72431 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb));
8749 72431 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossJ +=
8750 72431 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant;
8751 : }
8752 90205 : if (m_state.dataEnvrn->OutHumRat > zn1HB.ZoneAirHumRat) {
8753 44217 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainW +=
8754 44217 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * hg;
8755 44217 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainJ +=
8756 44217 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * hg * ReportingConstant;
8757 : } else {
8758 45988 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossW +=
8759 45988 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8760 45988 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossJ +=
8761 45988 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8762 : }
8763 : } else {
8764 27797 : if (Tamb > zn1HB.MAT) {
8765 6407 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT));
8766 6407 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainJ +=
8767 6407 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant;
8768 : } else {
8769 21390 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb));
8770 21390 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossJ +=
8771 21390 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant;
8772 : }
8773 27797 : if (m_state.dataEnvrn->OutHumRat > zn1HB.ZoneAirHumRat) {
8774 12785 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainW +=
8775 12785 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * hg;
8776 12785 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainJ +=
8777 12785 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * hg * ReportingConstant;
8778 : } else {
8779 15012 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossW +=
8780 15012 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8781 15012 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossJ +=
8782 15012 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8783 : }
8784 : }
8785 : }
8786 183877 : if (ZN1 == 0 && ZN2 > 0) {
8787 0 : auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
8788 0 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfLinkedOutAirNode > 0) {
8789 0 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(MultizoneSurfaceData(i).SurfNum);
8790 0 : CpAir = PsyCpAirFnW(Psychrometrics::PsyWFnTdbTwbPb(m_state,
8791 : Tamb,
8792 0 : m_state.dataSurface->SurfOutWetBulbTemp(MultizoneSurfaceData(i).SurfNum),
8793 0 : m_state.dataEnvrn->OutBaroPress));
8794 : } else {
8795 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
8796 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
8797 : }
8798 0 : hg = Psychrometrics::PsyHgAirFnWTdb(zn2HB.ZoneAirHumRat, zn2HB.MAT);
8799 :
8800 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
8801 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
8802 0 : if (Tamb > zn2HB.MAT) {
8803 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT));
8804 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainJ +=
8805 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant;
8806 : } else {
8807 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb));
8808 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossJ +=
8809 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant;
8810 : }
8811 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.ZoneAirHumRat) {
8812 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainW +=
8813 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * hg;
8814 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainJ +=
8815 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * hg * ReportingConstant;
8816 : } else {
8817 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossW +=
8818 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8819 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossJ +=
8820 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8821 : }
8822 : } else {
8823 0 : if (Tamb > zn2HB.MAT) {
8824 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT));
8825 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainJ +=
8826 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant;
8827 : } else {
8828 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb));
8829 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossJ +=
8830 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant;
8831 : }
8832 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.ZoneAirHumRat) {
8833 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainW +=
8834 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * hg;
8835 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainJ +=
8836 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * hg * ReportingConstant;
8837 : } else {
8838 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossW +=
8839 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8840 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossJ +=
8841 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8842 : }
8843 : }
8844 : }
8845 :
8846 183877 : if (ZN1 > 0 && ZN2 > 0) {
8847 65875 : auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
8848 65875 : auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
8849 65875 : CpAir = PsyCpAirFnW((zn1HB.ZoneAirHumRat + zn2HB.ZoneAirHumRat) / 2.0);
8850 65875 : hg = Psychrometrics::PsyHgAirFnWTdb((zn1HB.ZoneAirHumRat + zn2HB.ZoneAirHumRat) / 2.0, (zn1HB.MAT + zn2HB.MAT) / 2.0);
8851 65875 : if (zn1HB.MAT > zn2HB.MAT) {
8852 29301 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn1HB.MAT - zn2HB.MAT));
8853 29301 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainJ +=
8854 29301 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant;
8855 : } else {
8856 36574 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - zn1HB.MAT));
8857 36574 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossJ +=
8858 36574 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant;
8859 : }
8860 65875 : if (zn1HB.ZoneAirHumRat > zn2HB.ZoneAirHumRat) {
8861 29720 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainW +=
8862 29720 : (AirflowNetworkLinkSimu(i).FLOW * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * hg;
8863 29720 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainJ +=
8864 29720 : (AirflowNetworkLinkSimu(i).FLOW * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * hg * ReportingConstant;
8865 : } else {
8866 36155 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossW +=
8867 36155 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * hg;
8868 36155 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossJ +=
8869 36155 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * hg * ReportingConstant;
8870 : }
8871 65875 : if (zn2HB.MAT > zn1HB.MAT) {
8872 34082 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn2HB.MAT - zn1HB.MAT));
8873 34082 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainJ +=
8874 34082 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant;
8875 : } else {
8876 31793 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - zn2HB.MAT));
8877 31793 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossJ +=
8878 31793 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant;
8879 : }
8880 65875 : if (zn2HB.ZoneAirHumRat > zn1HB.ZoneAirHumRat) {
8881 33108 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainW +=
8882 33108 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * hg;
8883 33108 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainJ +=
8884 33108 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * hg * ReportingConstant;
8885 : } else {
8886 32767 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossW +=
8887 32767 : std::abs(AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * hg;
8888 32767 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossJ +=
8889 32767 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * hg * ReportingConstant;
8890 : }
8891 : }
8892 : }
8893 : }
8894 :
8895 : // Assign data for report
8896 13012 : if (distribution_simulated) {
8897 43122 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
8898 33502 : if (exchangeData(i).LeakSen > 0.0) {
8899 4123 : AirflowNetworkReportData(i).LeakSenGainW = exchangeData(i).LeakSen;
8900 4123 : AirflowNetworkReportData(i).LeakSenGainJ = exchangeData(i).LeakSen * ReportingConstant;
8901 : } else {
8902 29379 : AirflowNetworkReportData(i).LeakSenLossW = -exchangeData(i).LeakSen;
8903 29379 : AirflowNetworkReportData(i).LeakSenLossJ = -exchangeData(i).LeakSen * ReportingConstant;
8904 : }
8905 33502 : if (exchangeData(i).LeakLat > 0.0) {
8906 2610 : AirflowNetworkReportData(i).LeakLatGainW = exchangeData(i).LeakLat * Lam;
8907 2610 : AirflowNetworkReportData(i).LeakLatGainJ = exchangeData(i).LeakLat * Lam * ReportingConstant;
8908 : } else {
8909 30892 : AirflowNetworkReportData(i).LeakLatLossW = -exchangeData(i).LeakLat * Lam;
8910 30892 : AirflowNetworkReportData(i).LeakLatLossJ = -exchangeData(i).LeakLat * Lam * ReportingConstant;
8911 : }
8912 33502 : if (exchangeData(i).CondSen > 0.0) {
8913 5893 : AirflowNetworkReportData(i).CondSenGainW = exchangeData(i).CondSen;
8914 5893 : AirflowNetworkReportData(i).CondSenGainJ = exchangeData(i).CondSen * ReportingConstant;
8915 : } else {
8916 27609 : AirflowNetworkReportData(i).CondSenLossW = -exchangeData(i).CondSen;
8917 27609 : AirflowNetworkReportData(i).CondSenLossJ = -exchangeData(i).CondSen * ReportingConstant;
8918 : }
8919 33502 : if (exchangeData(i).DiffLat > 0.0) {
8920 6052 : AirflowNetworkReportData(i).DiffLatGainW = exchangeData(i).DiffLat * Lam;
8921 6052 : AirflowNetworkReportData(i).DiffLatGainJ = exchangeData(i).DiffLat * Lam * ReportingConstant;
8922 : } else {
8923 27450 : AirflowNetworkReportData(i).DiffLatLossW = -exchangeData(i).DiffLat * Lam;
8924 27450 : AirflowNetworkReportData(i).DiffLatLossJ = -exchangeData(i).DiffLat * Lam * ReportingConstant;
8925 : }
8926 33502 : if (exchangeData(i).RadGain < 0.0) {
8927 235 : AirflowNetworkReportData(i).RadGainW = -exchangeData(i).RadGain;
8928 235 : AirflowNetworkReportData(i).RadGainJ = -exchangeData(i).RadGain * ReportingConstant;
8929 : } else {
8930 33267 : AirflowNetworkReportData(i).RadLossW = exchangeData(i).RadGain;
8931 33267 : AirflowNetworkReportData(i).RadLossJ = exchangeData(i).RadGain * ReportingConstant;
8932 : }
8933 33502 : if (exchangeData(i).TotalSen > 0.0) {
8934 5878 : AirflowNetworkReportData(i).TotalSenGainW = exchangeData(i).TotalSen;
8935 5878 : AirflowNetworkReportData(i).TotalSenGainJ = exchangeData(i).TotalSen * ReportingConstant;
8936 : } else {
8937 27624 : AirflowNetworkReportData(i).TotalSenLossW = -exchangeData(i).TotalSen;
8938 27624 : AirflowNetworkReportData(i).TotalSenLossJ = -exchangeData(i).TotalSen * ReportingConstant;
8939 : }
8940 33502 : if (exchangeData(i).TotalLat > 0.0) {
8941 5482 : AirflowNetworkReportData(i).TotalLatGainW = exchangeData(i).TotalLat * Lam;
8942 5482 : AirflowNetworkReportData(i).TotalLatGainJ = exchangeData(i).TotalLat * Lam * ReportingConstant;
8943 : } else {
8944 28020 : AirflowNetworkReportData(i).TotalLatLossW = -exchangeData(i).TotalLat * Lam;
8945 28020 : AirflowNetworkReportData(i).TotalLatLossJ = -exchangeData(i).TotalLat * Lam * ReportingConstant;
8946 : }
8947 : }
8948 : }
8949 :
8950 : // Zone report
8951 :
8952 56596 : for (auto &e : AirflowNetworkZnRpt) {
8953 43584 : e.InfilVolume = 0.0;
8954 43584 : e.InfilMass = 0.0;
8955 43584 : e.InfilAirChangeRate = 0.0;
8956 43584 : e.VentilVolume = 0.0;
8957 43584 : e.VentilMass = 0.0;
8958 43584 : e.VentilAirChangeRate = 0.0;
8959 43584 : e.MixVolume = 0.0;
8960 43584 : e.MixMass = 0.0;
8961 : }
8962 :
8963 23490 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
8964 10478 : if (DisSysNumOfCVFs == 0) continue;
8965 10428 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
8966 10428 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
8967 : }
8968 12141 : if (DisSysCompCVFData(FanNum).FanTypeNum == FanType_SimpleOnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
8969 2117 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
8970 : // ON Cycle calculation
8971 2117 : onceZoneFlag = false;
8972 8468 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
8973 6351 : if (AirflowNetworkNodeData(i).AirLoopNum > 0 && AirflowNetworkNodeData(i).AirLoopNum != AirLoopNum) continue;
8974 5694 : if (AirflowNetworkNodeData(i).AirLoopNum == AirLoopNum) {
8975 5694 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
8976 : }
8977 5694 : if (AirflowNetworkNodeData(i).AirLoopNum == 0) {
8978 0 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
8979 : }
8980 5694 : if (AirflowNetworkNodeData(i).AirLoopNum == 0 && onceZoneFlag(i)) continue;
8981 5694 : AirflowNetworkReportData(i).MultiZoneInfiSenGainW *= RepOnOffFanRunTimeFraction;
8982 5694 : AirflowNetworkReportData(i).MultiZoneInfiSenGainJ *= RepOnOffFanRunTimeFraction;
8983 5694 : AirflowNetworkReportData(i).MultiZoneInfiSenLossW *= RepOnOffFanRunTimeFraction;
8984 5694 : AirflowNetworkReportData(i).MultiZoneInfiSenLossJ *= RepOnOffFanRunTimeFraction;
8985 5694 : AirflowNetworkReportData(i).MultiZoneInfiLatGainW *= RepOnOffFanRunTimeFraction;
8986 5694 : AirflowNetworkReportData(i).MultiZoneInfiLatGainJ *= RepOnOffFanRunTimeFraction;
8987 5694 : AirflowNetworkReportData(i).MultiZoneInfiLatLossW *= RepOnOffFanRunTimeFraction;
8988 5694 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ *= RepOnOffFanRunTimeFraction;
8989 5694 : AirflowNetworkReportData(i).MultiZoneVentSenGainW *= RepOnOffFanRunTimeFraction;
8990 5694 : AirflowNetworkReportData(i).MultiZoneVentSenGainJ *= RepOnOffFanRunTimeFraction;
8991 5694 : AirflowNetworkReportData(i).MultiZoneVentSenLossW *= RepOnOffFanRunTimeFraction;
8992 5694 : AirflowNetworkReportData(i).MultiZoneVentSenLossJ *= RepOnOffFanRunTimeFraction;
8993 5694 : AirflowNetworkReportData(i).MultiZoneVentLatGainW *= RepOnOffFanRunTimeFraction;
8994 5694 : AirflowNetworkReportData(i).MultiZoneVentLatGainJ *= RepOnOffFanRunTimeFraction;
8995 5694 : AirflowNetworkReportData(i).MultiZoneVentLatLossW *= RepOnOffFanRunTimeFraction;
8996 5694 : AirflowNetworkReportData(i).MultiZoneVentLatLossJ *= RepOnOffFanRunTimeFraction;
8997 5694 : AirflowNetworkReportData(i).MultiZoneMixSenGainW *= RepOnOffFanRunTimeFraction;
8998 5694 : AirflowNetworkReportData(i).MultiZoneMixSenGainJ *= RepOnOffFanRunTimeFraction;
8999 5694 : AirflowNetworkReportData(i).MultiZoneMixSenLossW *= RepOnOffFanRunTimeFraction;
9000 5694 : AirflowNetworkReportData(i).MultiZoneMixSenLossJ *= RepOnOffFanRunTimeFraction;
9001 5694 : AirflowNetworkReportData(i).MultiZoneMixLatGainW *= RepOnOffFanRunTimeFraction;
9002 5694 : AirflowNetworkReportData(i).MultiZoneMixLatGainJ *= RepOnOffFanRunTimeFraction;
9003 5694 : AirflowNetworkReportData(i).MultiZoneMixLatLossW *= RepOnOffFanRunTimeFraction;
9004 5694 : AirflowNetworkReportData(i).MultiZoneMixLatLossJ *= RepOnOffFanRunTimeFraction;
9005 5694 : if (AirflowNetworkNodeData(i).AirLoopNum == 0) {
9006 0 : onceZoneFlag(i) = true;
9007 : }
9008 : }
9009 : // Off Cycle addon
9010 2117 : onceSurfFlag = false;
9011 21608 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
9012 19491 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9013 19491 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9014 19491 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
9015 19491 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
9016 : // Find a linkage from a zone to outdoors
9017 19491 : if (ZN1 > 0 && ZN2 == 0) {
9018 12702 : auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
9019 12702 : if (AirflowNetworkNodeData(n).AirLoopNum > 0 && AirflowNetworkNodeData(n).AirLoopNum != AirLoopNum) continue;
9020 11169 : if (AirflowNetworkNodeData(n).AirLoopNum == AirLoopNum) {
9021 11169 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
9022 : }
9023 11169 : if (AirflowNetworkNodeData(n).AirLoopNum == 0) {
9024 0 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
9025 : }
9026 11169 : if (AirflowNetworkNodeData(n).AirLoopNum == 0 && onceSurfFlag(i)) continue;
9027 11169 : ReportingFraction = (1.0 - RepOnOffFanRunTimeFraction);
9028 11169 : Tamb = Zone(ZN1).OutDryBulbTemp;
9029 11169 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9030 16863 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9031 5694 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9032 10731 : if (Tamb > zn1HB.MAT) {
9033 3322 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainW +=
9034 3322 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * (1.0 - RepOnOffFanRunTimeFraction);
9035 3322 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainJ +=
9036 3322 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9037 : } else {
9038 7409 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossW +=
9039 7409 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * (1.0 - RepOnOffFanRunTimeFraction);
9040 7409 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossJ +=
9041 7409 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
9042 : }
9043 10731 : if (m_state.dataEnvrn->OutHumRat > zn1HB.ZoneAirHumRat) {
9044 5475 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainW +=
9045 5475 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * ReportingFraction;
9046 5475 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainJ +=
9047 5475 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * ReportingConstant *
9048 : ReportingFraction;
9049 : } else {
9050 5256 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossW +=
9051 5256 : (linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
9052 5256 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossJ +=
9053 5256 : (linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9054 : ReportingFraction;
9055 : }
9056 : } else {
9057 438 : if (Tamb > zn1HB.MAT) {
9058 152 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainW +=
9059 152 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * (1.0 - RepOnOffFanRunTimeFraction);
9060 152 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainJ +=
9061 152 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9062 : } else {
9063 286 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossW +=
9064 286 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * (1.0 - RepOnOffFanRunTimeFraction);
9065 286 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossJ +=
9066 286 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
9067 : }
9068 438 : if (m_state.dataEnvrn->OutHumRat > zn1HB.ZoneAirHumRat) {
9069 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainW +=
9070 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * ReportingFraction;
9071 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainJ +=
9072 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * ReportingConstant *
9073 : ReportingFraction;
9074 : } else {
9075 438 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossW +=
9076 438 : (linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
9077 438 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossJ +=
9078 438 : (linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9079 : ReportingFraction;
9080 : }
9081 : }
9082 11169 : if (AirflowNetworkNodeData(n).AirLoopNum == 0) {
9083 0 : onceSurfFlag(i) = true;
9084 : }
9085 : }
9086 17958 : if (ZN1 == 0 && ZN2 > 0) {
9087 0 : auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
9088 0 : if (AirflowNetworkNodeData(M).AirLoopNum > 0 && AirflowNetworkNodeData(M).AirLoopNum != AirLoopNum) continue;
9089 0 : if (AirflowNetworkNodeData(M).AirLoopNum == AirLoopNum) {
9090 0 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
9091 : }
9092 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0) {
9093 0 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
9094 : }
9095 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0 && onceSurfFlag(i)) continue;
9096 0 : ReportingFraction = (1.0 - RepOnOffFanRunTimeFraction);
9097 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
9098 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9099 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9100 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9101 0 : if (Tamb > zn2HB.MAT) {
9102 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainW +=
9103 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingFraction;
9104 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainJ +=
9105 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9106 : } else {
9107 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossW +=
9108 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingFraction;
9109 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossJ +=
9110 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
9111 : }
9112 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.ZoneAirHumRat) {
9113 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainW +=
9114 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * ReportingFraction;
9115 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainJ +=
9116 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * ReportingConstant *
9117 : ReportingFraction;
9118 : } else {
9119 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossW +=
9120 0 : (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
9121 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossJ +=
9122 0 : (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9123 : ReportingFraction;
9124 : }
9125 : } else {
9126 0 : if (Tamb > zn2HB.MAT) {
9127 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainW +=
9128 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingFraction;
9129 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainJ +=
9130 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9131 : } else {
9132 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossW +=
9133 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingFraction;
9134 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossJ +=
9135 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
9136 : }
9137 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.ZoneAirHumRat) {
9138 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainW +=
9139 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * ReportingFraction;
9140 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainJ +=
9141 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * ReportingConstant *
9142 : ReportingFraction;
9143 : } else {
9144 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossW +=
9145 0 : (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
9146 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossJ +=
9147 0 : (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9148 : ReportingFraction;
9149 : }
9150 : }
9151 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0) {
9152 0 : onceSurfFlag(i) = true;
9153 : }
9154 : }
9155 :
9156 17958 : if (ZN1 > 0 && ZN2 > 0) {
9157 6789 : auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
9158 6789 : auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
9159 6789 : ReportingFraction = (1.0 - MaxOnOffFanRunTimeFraction);
9160 6789 : CpAir = PsyCpAirFnW(zn1HB.ZoneAirHumRat);
9161 6789 : if (zn1HB.MAT > zn2HB.MAT) {
9162 2181 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainW +=
9163 2181 : (linkReport1(i).FLOWOFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingFraction;
9164 2181 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainJ +=
9165 2181 : (linkReport1(i).FLOWOFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9166 : } else {
9167 4608 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossW +=
9168 4608 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingFraction;
9169 4608 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossJ +=
9170 4608 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9171 : }
9172 6789 : if (zn1HB.ZoneAirHumRat > zn2HB.ZoneAirHumRat) {
9173 2242 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainW +=
9174 2242 : (linkReport1(i).FLOWOFF * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * ReportingFraction;
9175 2242 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainJ +=
9176 2242 : (linkReport1(i).FLOWOFF * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * ReportingConstant * ReportingFraction;
9177 : } else {
9178 4547 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossW +=
9179 4547 : (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * ReportingFraction;
9180 4547 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossJ +=
9181 4547 : (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * ReportingConstant * ReportingFraction;
9182 : }
9183 6789 : CpAir = PsyCpAirFnW(zn2HB.ZoneAirHumRat);
9184 6789 : if (zn2HB.MAT > zn1HB.MAT) {
9185 4608 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainW +=
9186 4608 : (linkReport1(i).FLOW2OFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingFraction;
9187 4608 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainJ +=
9188 4608 : (linkReport1(i).FLOW2OFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9189 : } else {
9190 2181 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossW +=
9191 2181 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingFraction;
9192 2181 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossJ +=
9193 2181 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9194 : }
9195 :
9196 6789 : if (zn2HB.ZoneAirHumRat > zn1HB.ZoneAirHumRat) {
9197 4547 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainW +=
9198 4547 : (linkReport1(i).FLOW2OFF * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * ReportingFraction;
9199 4547 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainJ +=
9200 4547 : (linkReport1(i).FLOW2OFF * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * ReportingConstant * ReportingFraction;
9201 : } else {
9202 2242 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossW +=
9203 2242 : std::abs(linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * ReportingFraction;
9204 2242 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossJ +=
9205 2242 : (linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * ReportingConstant * ReportingFraction;
9206 : }
9207 : }
9208 : }
9209 : }
9210 : }
9211 :
9212 13012 : if (!multizone_always_simulated) {
9213 773 : return;
9214 : }
9215 :
9216 53127 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) { // Start of zone loads report variable update loop ...
9217 40888 : auto &thisZoneHB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i);
9218 40888 : Tamb = Zone(i).OutDryBulbTemp;
9219 40888 : CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRatAvg);
9220 40888 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRatAvg);
9221 :
9222 40888 : AirflowNetworkZnRpt(i).InfilMass = (exchangeData(i).SumMCp / CpAir) * ReportingConstant;
9223 40888 : AirflowNetworkZnRpt(i).InfilVolume = AirflowNetworkZnRpt(i).InfilMass / AirDensity;
9224 40888 : AirflowNetworkZnRpt(i).InfilAirChangeRate = AirflowNetworkZnRpt(i).InfilVolume / (TimeStepSys * Zone(i).Volume);
9225 40888 : AirflowNetworkZnRpt(i).VentilMass = (exchangeData(i).SumMVCp / CpAir) * ReportingConstant;
9226 40888 : AirflowNetworkZnRpt(i).VentilVolume = AirflowNetworkZnRpt(i).VentilMass / AirDensity;
9227 40888 : AirflowNetworkZnRpt(i).VentilAirChangeRate = AirflowNetworkZnRpt(i).VentilVolume / (TimeStepSys * Zone(i).Volume);
9228 40888 : AirflowNetworkZnRpt(i).MixMass = (exchangeData(i).SumMMCp / CpAir) * ReportingConstant;
9229 40888 : AirflowNetworkZnRpt(i).MixVolume = AirflowNetworkZnRpt(i).MixMass / AirDensity;
9230 : // save values for predefined report
9231 40888 : Real64 stdDensAFNInfilVolume = AirflowNetworkZnRpt(i).InfilMass / m_state.dataEnvrn->StdRhoAir;
9232 40888 : Real64 stdDensAFNNatVentVolume = AirflowNetworkZnRpt(i).VentilMass / m_state.dataEnvrn->StdRhoAir;
9233 40888 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolStdDen = stdDensAFNNatVentVolume;
9234 40888 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolTotalStdDen += stdDensAFNNatVentVolume;
9235 40888 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalStdDen += stdDensAFNInfilVolume;
9236 40888 : if (m_state.dataHeatBal->ZonePreDefRep(i).isOccupied) {
9237 3396 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolTotalOccStdDen += stdDensAFNNatVentVolume;
9238 3396 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalOccStdDen += stdDensAFNInfilVolume;
9239 3396 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalOcc +=
9240 3396 : (AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) * Zone(i).Multiplier * Zone(i).ListMultiplier;
9241 6792 : if ((AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) <
9242 3396 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolMin) {
9243 685 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolMin =
9244 685 : (AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) * Zone(i).Multiplier * Zone(i).ListMultiplier;
9245 : }
9246 : }
9247 :
9248 40888 : Real64 H2OHtOfVap = Psychrometrics::PsyHgAirFnWTdb(m_state.dataEnvrn->OutHumRat, Zone(i).OutDryBulbTemp);
9249 40888 : AirflowNetworkZnRpt(i).InletMass = 0;
9250 40888 : AirflowNetworkZnRpt(i).OutletMass = 0;
9251 40888 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).IsControlled) {
9252 43209 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumInletNodes; ++j) {
9253 22512 : AirflowNetworkZnRpt(i).InletMass +=
9254 22512 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).InletNode(j)).MassFlowRate * ReportingConstant;
9255 : }
9256 28438 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumExhaustNodes; ++j) {
9257 7741 : AirflowNetworkZnRpt(i).OutletMass +=
9258 7741 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).ExhaustNode(j)).MassFlowRate * ReportingConstant;
9259 : }
9260 41394 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumReturnNodes; ++j) {
9261 20697 : AirflowNetworkZnRpt(i).OutletMass +=
9262 20697 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).ReturnNode(j)).MassFlowRate * ReportingConstant;
9263 : }
9264 : }
9265 122664 : AirflowNetworkZnRpt(i).ExfilMass = AirflowNetworkZnRpt(i).InfilMass + AirflowNetworkZnRpt(i).VentilMass + AirflowNetworkZnRpt(i).MixMass +
9266 81776 : AirflowNetworkZnRpt(i).InletMass - AirflowNetworkZnRpt(i).OutletMass;
9267 40888 : AirflowNetworkZnRpt(i).ExfilSensiLoss = AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * (thisZoneHB.MAT - Tamb) * CpAir;
9268 40888 : AirflowNetworkZnRpt(i).ExfilLatentLoss =
9269 40888 : AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * (thisZoneHB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat) * H2OHtOfVap;
9270 40888 : AirflowNetworkZnRpt(i).ExfilTotalLoss = AirflowNetworkZnRpt(i).ExfilSensiLoss + AirflowNetworkZnRpt(i).ExfilLatentLoss;
9271 :
9272 40888 : m_state.dataHeatBal->ZoneTotalExfiltrationHeatLoss += AirflowNetworkZnRpt(i).ExfilTotalLoss * ReportingConstant;
9273 : } // ... end of zone loads report variable update loop.
9274 :
9275 : // Rewrite AirflowNetwork airflow rate
9276 21944 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9277 9705 : if (DisSysNumOfCVFs == 0) continue;
9278 9655 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9279 9655 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9280 : }
9281 9251 : onceSurfFlag = false;
9282 :
9283 146289 : for (i = 1; i <= NumOfLinksMultiZone; ++i) {
9284 137038 : if (onceSurfFlag(i)) continue;
9285 137038 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9286 137038 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkLinkageData(i).NodeHeights[0]);
9287 137038 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, Tamb, m_state.dataEnvrn->OutHumRat);
9288 156529 : if (DisSysCompCVFData(FanNum).FanTypeNum == FanType_SimpleOnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
9289 19491 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
9290 19491 : linkReport(i).VolFLOW = linkReport1(i).FLOW / AirDensity;
9291 19491 : linkReport(i).VolFLOW2 = linkReport1(i).FLOW2 / AirDensity;
9292 : } else {
9293 117547 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity;
9294 117547 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity;
9295 : }
9296 137038 : onceSurfFlag(i) = true;
9297 : }
9298 : }
9299 :
9300 9251 : if (AirflowNetworkNumOfLinks > NumOfLinksMultiZone) {
9301 303342 : for (i = NumOfLinksMultiZone + 1; i <= AirflowNetworkNumOfLinks; ++i) {
9302 294091 : if (onceSurfFlag(i)) continue;
9303 294091 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9304 294091 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9305 294091 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9306 294091 : AirDensity =
9307 1176364 : PsyRhoAirFnPbTdbW(m_state,
9308 294091 : (AirflowNetworkNodeSimu(n).PZ + AirflowNetworkNodeSimu(M).PZ) / 2.0 + m_state.dataEnvrn->OutBaroPress,
9309 294091 : (AirflowNetworkNodeSimu(n).TZ + AirflowNetworkNodeSimu(M).TZ) / 2.0,
9310 294091 : (AirflowNetworkNodeSimu(n).WZ + AirflowNetworkNodeSimu(M).WZ) / 2.0);
9311 339424 : if (DisSysCompCVFData(FanNum).FanTypeNum == FanType_SimpleOnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
9312 45333 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
9313 45333 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity * (1.0 - LoopOnOffFanRunTimeFraction(AirLoopNum));
9314 45333 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity * (1.0 - LoopOnOffFanRunTimeFraction(AirLoopNum));
9315 45333 : onceSurfFlag(i) = true;
9316 : } else {
9317 248758 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity;
9318 248758 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity;
9319 : }
9320 : }
9321 : }
9322 : }
9323 : }
9324 : }
9325 :
9326 656873 : void Solver::update(Optional_bool_const FirstHVACIteration) // True when solution technique on first iteration
9327 : {
9328 :
9329 : // SUBROUTINE INFORMATION:
9330 : // AUTHOR Lixing Gu
9331 : // DATE WRITTEN 12/10/05
9332 : // MODIFIED na
9333 : // RE-ENGINEERED na
9334 :
9335 : // PURPOSE OF THIS SUBROUTINE:
9336 : // This subroutine update variables used in the AirflowNetwork model.
9337 :
9338 : // Using/Aliasing
9339 656873 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
9340 : using DataHVACGlobals::VerySmallMassFlow;
9341 :
9342 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9343 : int i;
9344 : int j;
9345 : int n;
9346 : int M;
9347 : int ZN1;
9348 : int ZN2;
9349 : int Node1;
9350 : int Node2;
9351 : int Node3;
9352 : Real64 CpAir;
9353 : Real64 Qsen;
9354 : Real64 Qlat;
9355 : Real64 AirDensity;
9356 : Real64 Tamb;
9357 : Real64 PartLoadRatio;
9358 : Real64 OnOffRatio;
9359 : Real64 NodeMass;
9360 : Real64 AFNMass;
9361 : bool WriteFlag;
9362 :
9363 656873 : auto &Zone(m_state.dataHeatBal->Zone);
9364 656873 : auto &Node(m_state.dataLoopNodes->Node);
9365 :
9366 2615440 : for (auto &e : exchangeData) {
9367 1958567 : e.SumMCp = 0.0;
9368 1958567 : e.SumMCpT = 0.0;
9369 1958567 : e.SumMVCp = 0.0;
9370 1958567 : e.SumMVCpT = 0.0;
9371 1958567 : e.SumMHr = 0.0;
9372 1958567 : e.SumMHrW = 0.0;
9373 1958567 : e.SumMMCp = 0.0;
9374 1958567 : e.SumMMCpT = 0.0;
9375 1958567 : e.SumMMHr = 0.0;
9376 1958567 : e.SumMMHrW = 0.0;
9377 : }
9378 656873 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9379 57420 : for (auto &e : exchangeData) {
9380 45936 : e.SumMHrCO = 0.0;
9381 45936 : e.SumMMHrCO = 0.0;
9382 : }
9383 : }
9384 656873 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9385 45300 : for (auto &e : exchangeData) {
9386 36240 : e.SumMHrGC = 0.0;
9387 36240 : e.SumMMHrGC = 0.0;
9388 : }
9389 : }
9390 :
9391 : // Calculate sensible and latent loads in each zone from multizone airflows
9392 676859 : if (multizone_always_simulated ||
9393 39972 : (simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation && AirflowNetworkFanActivated)) {
9394 9784604 : for (i = 1; i <= NumOfLinksMultiZone; ++i) { // Multizone airflow energy
9395 9136921 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9396 9136921 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9397 9136921 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
9398 9136921 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
9399 9136921 : if (ZN1 > 0 && ZN2 == 0) {
9400 : // Find a linkage from outdoors to this zone
9401 6572842 : Tamb = Zone(ZN1).OutDryBulbTemp;
9402 6572842 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9403 10489644 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9404 3916802 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9405 5482090 : exchangeData(ZN1).SumMCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9406 5482090 : exchangeData(ZN1).SumMCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * Tamb;
9407 : } else {
9408 1090752 : exchangeData(ZN1).SumMVCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9409 1090752 : exchangeData(ZN1).SumMVCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * Tamb;
9410 : }
9411 6572842 : exchangeData(ZN1).SumMHr += AirflowNetworkLinkSimu(i).FLOW2;
9412 6572842 : exchangeData(ZN1).SumMHrW += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataEnvrn->OutHumRat;
9413 6572842 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9414 149292 : exchangeData(ZN1).SumMHrCO += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataContaminantBalance->OutdoorCO2;
9415 : }
9416 6572842 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9417 108720 : exchangeData(ZN1).SumMHrGC += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataContaminantBalance->OutdoorGC;
9418 : }
9419 : }
9420 9136921 : if (ZN1 == 0 && ZN2 > 0) {
9421 : // Find a linkage from outdoors to this zone
9422 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
9423 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9424 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9425 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9426 0 : exchangeData(ZN2).SumMCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9427 0 : exchangeData(ZN2).SumMCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * Tamb;
9428 : } else {
9429 0 : exchangeData(ZN2).SumMVCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9430 0 : exchangeData(ZN2).SumMVCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * Tamb;
9431 : }
9432 0 : exchangeData(ZN2).SumMHr += AirflowNetworkLinkSimu(i).FLOW;
9433 0 : exchangeData(ZN2).SumMHrW += AirflowNetworkLinkSimu(i).FLOW * m_state.dataEnvrn->OutHumRat;
9434 0 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9435 0 : exchangeData(ZN2).SumMHrCO += AirflowNetworkLinkSimu(i).FLOW * m_state.dataContaminantBalance->OutdoorCO2;
9436 : }
9437 0 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9438 0 : exchangeData(ZN2).SumMHrGC += AirflowNetworkLinkSimu(i).FLOW * m_state.dataContaminantBalance->OutdoorGC;
9439 : }
9440 : }
9441 9136921 : if (ZN1 > 0 && ZN2 > 0) {
9442 : // Find a linkage from outdoors to this zone
9443 2564079 : CpAir = PsyCpAirFnW(ANZW(ZN1));
9444 2564079 : exchangeData(ZN2).SumMMCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9445 2564079 : exchangeData(ZN2).SumMMCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * ANZT(ZN1);
9446 2564079 : exchangeData(ZN2).SumMMHr += AirflowNetworkLinkSimu(i).FLOW;
9447 2564079 : exchangeData(ZN2).SumMMHrW += AirflowNetworkLinkSimu(i).FLOW * ANZW(ZN1);
9448 2564079 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9449 91872 : exchangeData(ZN2).SumMMHrCO += AirflowNetworkLinkSimu(i).FLOW * ANCO(ZN1);
9450 : }
9451 2564079 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9452 63420 : exchangeData(ZN2).SumMMHrGC += AirflowNetworkLinkSimu(i).FLOW * ANGC(ZN1);
9453 : }
9454 2564079 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9455 2564079 : exchangeData(ZN1).SumMMCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9456 2564079 : exchangeData(ZN1).SumMMCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * ANZT(ZN2);
9457 2564079 : exchangeData(ZN1).SumMMHr += AirflowNetworkLinkSimu(i).FLOW2;
9458 2564079 : exchangeData(ZN1).SumMMHrW += AirflowNetworkLinkSimu(i).FLOW2 * ANZW(ZN2);
9459 2564079 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9460 91872 : exchangeData(ZN1).SumMMHrCO += AirflowNetworkLinkSimu(i).FLOW2 * ANCO(ZN2);
9461 : }
9462 2564079 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9463 63420 : exchangeData(ZN1).SumMMHrGC += AirflowNetworkLinkSimu(i).FLOW2 * ANGC(ZN2);
9464 : }
9465 : }
9466 : }
9467 : }
9468 : // End of update of multizone airflow calculations
9469 :
9470 : // Initialize these values
9471 2615440 : for (auto &e : exchangeData) {
9472 1958567 : e.LeakSen = 0.0;
9473 1958567 : e.CondSen = 0.0;
9474 1958567 : e.LeakLat = 0.0;
9475 1958567 : e.DiffLat = 0.0;
9476 1958567 : e.MultiZoneSen = 0.0;
9477 1958567 : e.MultiZoneLat = 0.0;
9478 1958567 : e.RadGain = 0.0;
9479 : }
9480 :
9481 : // Rewrite AirflowNetwork airflow rate
9482 9898997 : for (i = 1; i <= NumOfLinksMultiZone; ++i) {
9483 9242124 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkLinkageData(i).NodeHeights[0]);
9484 9242124 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, Tamb, m_state.dataEnvrn->OutHumRat);
9485 9242124 : AirflowNetworkLinkSimu(i).VolFLOW = AirflowNetworkLinkSimu(i).FLOW / AirDensity;
9486 9242124 : AirflowNetworkLinkSimu(i).VolFLOW2 = AirflowNetworkLinkSimu(i).FLOW2 / AirDensity;
9487 : }
9488 :
9489 24012877 : for (std::size_t i = 0; i < linkReport.size(); ++i) {
9490 23356004 : auto &r(linkReport[i]);
9491 23356004 : auto &s(AirflowNetworkLinkSimu[i]);
9492 23356004 : r.FLOW = s.FLOW;
9493 23356004 : r.FLOW2 = s.FLOW2;
9494 23356004 : r.VolFLOW = s.VolFLOW;
9495 23356004 : r.VolFLOW2 = s.VolFLOW2;
9496 : }
9497 :
9498 : // Save zone loads from multizone calculation for later summation
9499 656873 : bool OnOffFanFlag = false;
9500 868655 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
9501 571719 : if (DisSysCompCVFData(i).FanTypeNum == FanType_SimpleOnOff) {
9502 359937 : OnOffFanFlag = true;
9503 359937 : break;
9504 : }
9505 : }
9506 656873 : if (present(FirstHVACIteration)) {
9507 656873 : if (FirstHVACIteration && OnOffFanFlag) {
9508 44520 : multiExchangeData = exchangeData;
9509 168684 : for (i = 1; i <= AirflowNetworkNumOfZones; ++i) {
9510 124164 : nodeReport(i).PZ = AirflowNetworkNodeSimu(i).PZ;
9511 124164 : nodeReport(i).PZOFF = AirflowNetworkNodeSimu(i).PZ;
9512 124164 : nodeReport(i).PZON = 0.0;
9513 : }
9514 499276 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
9515 454756 : linkReport1(i).FLOW = AirflowNetworkLinkSimu(i).FLOW;
9516 454756 : linkReport1(i).FLOW2 = AirflowNetworkLinkSimu(i).FLOW2;
9517 454756 : linkReport1(i).VolFLOW = AirflowNetworkLinkSimu(i).VolFLOW;
9518 454756 : linkReport1(i).VolFLOW2 = AirflowNetworkLinkSimu(i).VolFLOW2;
9519 454756 : linkReport1(i).FLOWOFF = AirflowNetworkLinkSimu(i).FLOW;
9520 454756 : linkReport1(i).FLOW2OFF = AirflowNetworkLinkSimu(i).FLOW2;
9521 454756 : linkReport1(i).VolFLOWOFF = AirflowNetworkLinkSimu(i).VolFLOW;
9522 454756 : linkReport1(i).VolFLOW2OFF = AirflowNetworkLinkSimu(i).VolFLOW2;
9523 454756 : linkReport1(i).DP = AirflowNetworkLinkSimu(i).DP;
9524 454756 : linkReport1(i).DPOFF = AirflowNetworkLinkSimu(i).DP;
9525 454756 : linkReport1(i).DPON = 0.0;
9526 : }
9527 : }
9528 : }
9529 :
9530 656873 : if (!AirflowNetworkFanActivated && distribution_simulated) {
9531 4333931 : for (i = NumOfNodesMultiZone + NumOfNodesIntraZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
9532 4159636 : AirflowNetworkNodeSimu(i).PZ = 0.0;
9533 : }
9534 5720186 : for (i = AirflowNetworkNumOfSurfaces + 1; i <= AirflowNetworkNumOfLinks; ++i) {
9535 5545891 : AirflowNetworkLinkSimu(i).DP = 0.0;
9536 5545891 : linkReport(i).FLOW = 0.0;
9537 5545891 : linkReport(i).FLOW2 = 0.0;
9538 5545891 : linkReport(i).VolFLOW = 0.0;
9539 5545891 : linkReport(i).VolFLOW2 = 0.0;
9540 : }
9541 : }
9542 :
9543 656873 : if (!(AirflowNetworkFanActivated && distribution_simulated)) return;
9544 :
9545 380734 : if (distribution_simulated) {
9546 5291043 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
9547 4910309 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9548 4910309 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9549 4910309 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
9550 4910309 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
9551 : // Find a linkage from a zone to outdoors
9552 4910309 : if (ZN1 > 0 && ZN2 == 0) {
9553 3809911 : Tamb = Zone(ZN1).OutDryBulbTemp;
9554 3809911 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9555 3809911 : exchangeData(ZN1).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - ANZT(ZN1));
9556 3809911 : exchangeData(ZN1).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - ANZW(ZN1));
9557 : }
9558 4910309 : if (ZN1 == 0 && ZN2 > 0) {
9559 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
9560 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9561 0 : exchangeData(ZN2).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - ANZT(ZN2));
9562 0 : exchangeData(ZN2).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - ANZW(ZN2));
9563 : }
9564 :
9565 4910309 : if (ZN1 > 0 && ZN2 > 0) {
9566 1100398 : if (AirflowNetworkLinkSimu(i).FLOW > 0) { // Flow from ZN1 to ZN2
9567 438802 : CpAir = PsyCpAirFnW(ANZW(ZN1));
9568 438802 : exchangeData(ZN2).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW * CpAir * (ANZT(ZN1) - ANZT(ZN2));
9569 438802 : exchangeData(ZN2).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW * (ANZW(ZN1) - ANZW(ZN2));
9570 438802 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9571 438802 : exchangeData(ZN1).MultiZoneSen += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * (ANZT(ZN2) - ANZT(ZN1));
9572 438802 : exchangeData(ZN1).MultiZoneLat += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * (ANZW(ZN2) - ANZW(ZN1));
9573 : } else {
9574 661596 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9575 661596 : exchangeData(ZN1).MultiZoneSen += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * (ANZT(ZN2) - ANZT(ZN1));
9576 661596 : exchangeData(ZN1).MultiZoneLat += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * (ANZW(ZN2) - ANZW(ZN1));
9577 : }
9578 : }
9579 : }
9580 : }
9581 :
9582 : int AirLoopNum;
9583 : int FanNum;
9584 380734 : Real64 MaxPartLoadRatio = 0.0;
9585 380734 : Real64 OnOffFanRunTimeFraction = 0.0;
9586 380734 : MaxOnOffFanRunTimeFraction = 0.0;
9587 772135 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9588 391401 : MaxPartLoadRatio = max(MaxPartLoadRatio, m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio);
9589 391401 : MaxOnOffFanRunTimeFraction = max(MaxOnOffFanRunTimeFraction, LoopOnOffFanRunTimeFraction(AirLoopNum));
9590 : }
9591 772135 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9592 402068 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9593 402068 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9594 : }
9595 391401 : PartLoadRatio = 1.0;
9596 391401 : LoopPartLoadRatio(AirLoopNum) = 1.0;
9597 391401 : OnOffFanRunTimeFraction = 1.0;
9598 391401 : LoopOnOffFanRunTimeFraction(AirLoopNum) = 1.0;
9599 : // Calculate the part load ratio, can't be greater than 1 for a simple ONOFF fan
9600 1077244 : if (DisSysCompCVFData(FanNum).FanTypeNum == FanType_SimpleOnOff &&
9601 685119 : Node(DisSysCompCVFData(FanNum).InletNode).MassFlowRate > VerySmallMassFlow &&
9602 293718 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == CycFanCycCoil) {
9603 : // Hard code here
9604 280369 : PartLoadRatio = m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
9605 280369 : LoopPartLoadRatio(AirLoopNum) = m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
9606 560738 : OnOffFanRunTimeFraction = max(m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF,
9607 280369 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopOnOffFanRTF,
9608 280369 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF);
9609 560738 : LoopOnOffFanRunTimeFraction(AirLoopNum) = max(m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF,
9610 280369 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopOnOffFanRTF,
9611 280369 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF);
9612 : }
9613 391401 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0;
9614 :
9615 391401 : if (DisSysCompCVFData(FanNum).FanTypeNum == FanType_SimpleOnOff && LoopPartLoadRatio(AirLoopNum) < 1.0) {
9616 6378580 : for (std::size_t i = 0; i < linkReport.size(); ++i) {
9617 6173770 : auto &r(linkReport[i]);
9618 6173770 : auto &s(AirflowNetworkLinkSimu[i]);
9619 6173770 : auto &t(AirflowNetworkLinkageData[i]);
9620 6173770 : if (t.AirLoopNum == AirLoopNum) {
9621 3545118 : r.FLOW = s.FLOW * LoopPartLoadRatio(AirLoopNum);
9622 3545118 : r.FLOW2 = s.FLOW2 * LoopPartLoadRatio(AirLoopNum);
9623 3545118 : r.VolFLOW = s.VolFLOW * LoopPartLoadRatio(AirLoopNum);
9624 3545118 : r.VolFLOW2 = s.VolFLOW2 * LoopPartLoadRatio(AirLoopNum);
9625 : }
9626 6173770 : if (t.AirLoopNum == 0) {
9627 2507820 : r.FLOW = s.FLOW * MaxPartLoadRatio;
9628 2507820 : r.FLOW2 = s.FLOW2 * MaxPartLoadRatio;
9629 2507820 : r.VolFLOW = s.VolFLOW * MaxPartLoadRatio;
9630 2507820 : r.VolFLOW2 = s.VolFLOW2 * MaxPartLoadRatio;
9631 : }
9632 : }
9633 : }
9634 : }
9635 :
9636 : // One time warning
9637 380734 : if (UpdateAirflowNetworkMyOneTimeFlag) {
9638 772135 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9639 402068 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9640 402068 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9641 : }
9642 685843 : if (DisSysCompCVFData(FanNum).FanTypeNum == FanType_SimpleOnOff &&
9643 294442 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == ContFanCycCoil) {
9644 40047 : OnOffRatio = std::abs((m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate -
9645 13349 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate) /
9646 13349 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate);
9647 13349 : if (OnOffRatio > 0.1) {
9648 0 : ShowWarningError(m_state,
9649 : "The absolute percent difference of supply air mass flow rate between HVAC operation and No HVAC operation "
9650 : "is above 10% with fan operation mode = ContFanCycCoil.");
9651 0 : ShowContinueError(m_state,
9652 : "The added zone loads using the AirflowNetwork model may not be accurate because the zone loads are "
9653 : "calculated based on the mass flow rate during HVAC operation.");
9654 0 : ShowContinueError(
9655 : m_state,
9656 0 : format("The mass flow rate during HVAC operation = {:.2R} The mass flow rate during no HVAC operation = {:.2R}",
9657 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate,
9658 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate));
9659 0 : UpdateAirflowNetworkMyOneTimeFlag = false;
9660 : }
9661 : }
9662 : }
9663 : }
9664 :
9665 : // Check mass flow differences in the zone inlet zones and splitter nodes between node and AFN links
9666 380734 : if (UpdateAirflowNetworkMyOneTimeFlag1) {
9667 23 : if ((!VAVSystem) && m_state.dataGlobal->DisplayExtraWarnings) {
9668 1 : WriteFlag = false;
9669 75 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9670 74 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9671 74 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9672 221 : if (AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::SPI ||
9673 145 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::SPO ||
9674 71 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::ZIN) {
9675 6 : if (AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::SPI) {
9676 1 : Node3 = Node1;
9677 : } else {
9678 5 : Node3 = Node2;
9679 : }
9680 6 : if (AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::ZIN) {
9681 3 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::Invalid) continue;
9682 : }
9683 4 : NodeMass = Node(AirflowNetworkNodeData(Node3).EPlusNodeNum).MassFlowRate;
9684 4 : AFNMass = AirflowNetworkLinkSimu(i).FLOW;
9685 4 : if (NodeMass > 0.0 && AFNMass > NodeMass + 0.01) {
9686 3 : ShowWarningError(m_state,
9687 2 : "The mass flow rate difference is found between System Node = '" +
9688 3 : m_state.dataLoopNodes->NodeID(AirflowNetworkNodeData(Node3).EPlusNodeNum) + "' and AFN Link = '" +
9689 3 : AirflowNetworkLinkageData(i).Name + "'.");
9690 3 : ShowContinueError(m_state,
9691 2 : format("The system node max mass flow rate = {:.3R} kg/s. The AFN node mass flow rate = {:.3R} kg.s.",
9692 : NodeMass,
9693 1 : AFNMass));
9694 1 : WriteFlag = true;
9695 : }
9696 : }
9697 : }
9698 1 : UpdateAirflowNetworkMyOneTimeFlag1 = false;
9699 1 : if (WriteFlag) {
9700 1 : ShowWarningError(m_state,
9701 : "Please adjust the rate of Maximum Air Flow Rate field in the terminal objects or duct pressure resistance.");
9702 : }
9703 : } else {
9704 22 : UpdateAirflowNetworkMyOneTimeFlag1 = false;
9705 : }
9706 : }
9707 :
9708 : // Assign airflows to EPLus nodes
9709 13859032 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9710 21284788 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC ||
9711 7806490 : AirflowNetworkLinkageData(i).VAVTermDamper) {
9712 : // Exclude envelope leakage Crack element
9713 5678570 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9714 5678570 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9715 :
9716 5678570 : j = AirflowNetworkNodeData(Node1).EPlusNodeNum;
9717 5678570 : if (j > 0 && AirflowNetworkNodeData(Node1).EPlusZoneNum == 0) {
9718 2805096 : Node(j).MassFlowRate = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node1).AirLoopNum);
9719 2805096 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Node(j).MassFlowRate = 0.0;
9720 5603430 : if (!(AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::DIN ||
9721 2798334 : AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::DOU)) {
9722 2798334 : Node(j).MassFlowRateMaxAvail = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node1).AirLoopNum);
9723 2798334 : Node(j).MassFlowRateMax = AirflowNetworkLinkSimu(i).FLOW;
9724 : }
9725 : }
9726 :
9727 5678570 : j = AirflowNetworkNodeData(Node2).EPlusNodeNum;
9728 5678570 : if (j > 0) {
9729 3349724 : Node(j).MassFlowRate = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node2).AirLoopNum);
9730 3349724 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Node(j).MassFlowRate = 0.0;
9731 6692686 : if (!(AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::DIN ||
9732 3342962 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::DOU)) {
9733 3336200 : Node(j).MassFlowRateMaxAvail = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node2).AirLoopNum);
9734 3336200 : Node(j).MassFlowRateMax = AirflowNetworkLinkSimu(i).FLOW;
9735 : }
9736 : }
9737 : }
9738 : }
9739 :
9740 : // Assign AirflowNetwork nodal values to Node array
9741 11541555 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
9742 11160821 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
9743 11160821 : if (j > 0) {
9744 5066464 : Node(j).Enthalpy = PsyHFnTdbW(AirflowNetworkNodeSimu(i).TZ, AirflowNetworkNodeSimu(i).WZ);
9745 5066464 : Node(j).Temp = AirflowNetworkNodeSimu(i).TZ;
9746 5066464 : Node(j).HumRat = AirflowNetworkNodeSimu(i).WZ;
9747 5066464 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9748 83560 : Node(j).CO2 = AirflowNetworkNodeSimu(i).CO2Z;
9749 : }
9750 5066464 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9751 81540 : Node(j).GenContam = AirflowNetworkNodeSimu(i).GCZ;
9752 : }
9753 : }
9754 : }
9755 :
9756 : // Calculate sensible loads from forced air flow
9757 13859032 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9758 13478298 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9759 13478298 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9760 13478298 : CpAir = PsyCpAirFnW((AirflowNetworkNodeSimu(Node1).WZ + AirflowNetworkNodeSimu(Node2).WZ) / 2.0);
9761 : // Calculate sensible loads from duct conduction losses and loads from duct radiation
9762 17092820 : if (AirflowNetworkLinkageData(i).ZoneNum > 0 &&
9763 3614522 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC) {
9764 3614522 : Qsen = AirflowNetworkLinkSimu(i).FLOW * CpAir * (AirflowNetworkNodeSimu(Node2).TZ - AirflowNetworkNodeSimu(Node1).TZ);
9765 3614522 : if (AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum != 0) {
9766 8319 : auto &DuctRadObj(AirflowNetworkLinkageViewFactorData(AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum));
9767 8319 : Qsen -= DuctRadObj.QRad;
9768 8319 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).RadGain -= DuctRadObj.QRad;
9769 : }
9770 : // When the Airloop is shut off, no duct sensible losses
9771 3614522 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qsen = 0.0;
9772 3614522 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).CondSen -= Qsen;
9773 : }
9774 : // Calculate sensible leakage losses
9775 26870339 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::PLR ||
9776 13392041 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::ELR) {
9777 : // Calculate supply leak sensible losses
9778 1772821 : if ((AirflowNetworkNodeData(Node2).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node1).EPlusNodeNum == 0) &&
9779 618256 : (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
9780 618135 : ZN2 = AirflowNetworkNodeData(Node2).EPlusZoneNum;
9781 618135 : Qsen = AirflowNetworkLinkSimu(i).FLOW * CpAir * (AirflowNetworkNodeSimu(Node1).TZ - AirflowNetworkNodeSimu(Node2).TZ);
9782 618135 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qsen = 0.0;
9783 618135 : exchangeData(ZN2).LeakSen += Qsen;
9784 : }
9785 1445033 : if ((AirflowNetworkNodeData(Node1).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node2).EPlusNodeNum == 0) &&
9786 290468 : (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
9787 4044 : ZN1 = AirflowNetworkNodeData(Node1).EPlusZoneNum;
9788 4044 : Qsen = AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (AirflowNetworkNodeSimu(Node2).TZ - AirflowNetworkNodeSimu(Node1).TZ);
9789 4044 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qsen = 0.0;
9790 4044 : exchangeData(ZN1).LeakSen += Qsen;
9791 : }
9792 : }
9793 : }
9794 :
9795 : // Calculate latent loads from forced air flow
9796 13859032 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9797 13478298 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9798 13478298 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9799 : // Calculate latent loads from duct conduction losses
9800 17092820 : if (AirflowNetworkLinkageData(i).ZoneNum > 0 &&
9801 3614522 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC) {
9802 3614522 : Qlat = AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node2).WZ - AirflowNetworkNodeSimu(Node1).WZ);
9803 3614522 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qlat = 0.0;
9804 3614522 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).DiffLat -= Qlat;
9805 : }
9806 : // Calculate latent leakage losses
9807 26870339 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::PLR ||
9808 13392041 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::ELR) {
9809 : // Calculate supply leak latent losses
9810 1772821 : if ((AirflowNetworkNodeData(Node2).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node1).EPlusNodeNum == 0) &&
9811 618256 : (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
9812 618135 : ZN2 = AirflowNetworkNodeData(Node2).EPlusZoneNum;
9813 618135 : Qlat = AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).WZ - AirflowNetworkNodeSimu(Node2).WZ);
9814 618135 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qlat = 0.0;
9815 618135 : exchangeData(ZN2).LeakLat += Qlat;
9816 618135 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9817 16712 : exchangeData(ZN2).TotalCO2 +=
9818 16712 : AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).CO2Z - AirflowNetworkNodeSimu(Node2).CO2Z);
9819 : }
9820 618135 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9821 16308 : exchangeData(ZN2).TotalGC +=
9822 16308 : AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).GCZ - AirflowNetworkNodeSimu(Node2).GCZ);
9823 : }
9824 : }
9825 1445033 : if ((AirflowNetworkNodeData(Node1).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node2).EPlusNodeNum == 0) &&
9826 290468 : (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
9827 4044 : ZN1 = AirflowNetworkNodeData(Node1).EPlusZoneNum;
9828 4044 : Qlat = AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).WZ - AirflowNetworkNodeSimu(Node1).WZ);
9829 4044 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qlat = 0.0;
9830 4044 : exchangeData(ZN1).LeakLat += Qlat;
9831 4044 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9832 0 : exchangeData(ZN1).TotalCO2 +=
9833 0 : AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).CO2Z - AirflowNetworkNodeSimu(Node1).CO2Z);
9834 : }
9835 4044 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9836 0 : exchangeData(ZN1).TotalGC +=
9837 0 : AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).GCZ - AirflowNetworkNodeSimu(Node1).GCZ);
9838 : }
9839 : }
9840 : }
9841 : }
9842 :
9843 : // Sum all the loads
9844 1416110 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9845 1035376 : exchangeData(i).TotalSen = exchangeData(i).LeakSen + exchangeData(i).CondSen + exchangeData(i).RadGain;
9846 1035376 : exchangeData(i).TotalLat = exchangeData(i).LeakLat + exchangeData(i).DiffLat;
9847 : }
9848 :
9849 : // Simple ONOFF fan
9850 772135 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9851 402068 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9852 402068 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9853 : }
9854 391401 : if (DisSysCompCVFData(FanNum).FanTypeNum == FanType_SimpleOnOff && OnOffFanRunTimeFraction < 1.0) {
9855 651804 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9856 452543 : exchangeData(i).MultiZoneSen *= OnOffFanRunTimeFraction;
9857 452543 : exchangeData(i).MultiZoneLat *= OnOffFanRunTimeFraction;
9858 452543 : exchangeData(i).LeakSen *= OnOffFanRunTimeFraction;
9859 452543 : exchangeData(i).LeakLat *= OnOffFanRunTimeFraction;
9860 452543 : exchangeData(i).CondSen *= OnOffFanRunTimeFraction;
9861 452543 : exchangeData(i).DiffLat *= OnOffFanRunTimeFraction;
9862 452543 : exchangeData(i).RadGain *= OnOffFanRunTimeFraction;
9863 452543 : exchangeData(i).TotalSen *= OnOffFanRunTimeFraction;
9864 452543 : exchangeData(i).TotalLat *= OnOffFanRunTimeFraction;
9865 452543 : exchangeData(i).SumMCp *= OnOffFanRunTimeFraction;
9866 452543 : exchangeData(i).SumMCpT *= OnOffFanRunTimeFraction;
9867 452543 : exchangeData(i).SumMVCp *= OnOffFanRunTimeFraction;
9868 452543 : exchangeData(i).SumMVCpT *= OnOffFanRunTimeFraction;
9869 452543 : exchangeData(i).SumMHr *= OnOffFanRunTimeFraction;
9870 452543 : exchangeData(i).SumMHrW *= OnOffFanRunTimeFraction;
9871 452543 : exchangeData(i).SumMMCp *= OnOffFanRunTimeFraction;
9872 452543 : exchangeData(i).SumMMCpT *= OnOffFanRunTimeFraction;
9873 452543 : exchangeData(i).SumMMHr *= OnOffFanRunTimeFraction;
9874 452543 : exchangeData(i).SumMMHrW *= OnOffFanRunTimeFraction;
9875 452543 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9876 0 : exchangeData(i).SumMHrCO *= OnOffFanRunTimeFraction;
9877 0 : exchangeData(i).SumMMHrCO *= OnOffFanRunTimeFraction;
9878 : }
9879 452543 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9880 0 : exchangeData(i).SumMHrGC *= OnOffFanRunTimeFraction;
9881 0 : exchangeData(i).SumMMHrGC *= OnOffFanRunTimeFraction;
9882 : }
9883 : }
9884 199261 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == CycFanCycCoil) {
9885 651804 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9886 452543 : exchangeData(i).SumMCp += multiExchangeData(i).SumMCp * (1.0 - OnOffFanRunTimeFraction);
9887 452543 : exchangeData(i).SumMCpT += multiExchangeData(i).SumMCpT * (1.0 - OnOffFanRunTimeFraction);
9888 452543 : exchangeData(i).SumMVCp += multiExchangeData(i).SumMVCp * (1.0 - OnOffFanRunTimeFraction);
9889 452543 : exchangeData(i).SumMVCpT += multiExchangeData(i).SumMVCpT * (1.0 - OnOffFanRunTimeFraction);
9890 452543 : exchangeData(i).SumMHr += multiExchangeData(i).SumMHr * (1.0 - OnOffFanRunTimeFraction);
9891 452543 : exchangeData(i).SumMHrW += multiExchangeData(i).SumMHrW * (1.0 - OnOffFanRunTimeFraction);
9892 452543 : exchangeData(i).SumMMCp += multiExchangeData(i).SumMMCp * (1.0 - OnOffFanRunTimeFraction);
9893 452543 : exchangeData(i).SumMMCpT += multiExchangeData(i).SumMMCpT * (1.0 - OnOffFanRunTimeFraction);
9894 452543 : exchangeData(i).SumMMHr += multiExchangeData(i).SumMMHr * (1.0 - OnOffFanRunTimeFraction);
9895 452543 : exchangeData(i).SumMMHrW += multiExchangeData(i).SumMMHrW * (1.0 - OnOffFanRunTimeFraction);
9896 452543 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9897 0 : exchangeData(i).SumMHrCO += multiExchangeData(i).SumMHrCO * (1.0 - OnOffFanRunTimeFraction);
9898 0 : exchangeData(i).SumMMHrCO += multiExchangeData(i).SumMMHrCO * (1.0 - OnOffFanRunTimeFraction);
9899 : }
9900 452543 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9901 0 : exchangeData(i).SumMHrGC += multiExchangeData(i).SumMHrGC * (1.0 - OnOffFanRunTimeFraction);
9902 0 : exchangeData(i).SumMMHrGC += multiExchangeData(i).SumMMHrGC * (1.0 - OnOffFanRunTimeFraction);
9903 : }
9904 : }
9905 : }
9906 : }
9907 :
9908 391401 : if (DisSysCompCVFData(FanNum).FanTypeNum == FanType_SimpleOnOff) {
9909 1007981 : for (i = 1; i <= AirflowNetworkNumOfZones; ++i) {
9910 713539 : if (AirflowNetworkNodeData(i).AirLoopNum == AirLoopNum) {
9911 1363076 : nodeReport(i).PZ = AirflowNetworkNodeSimu(i).PZ * LoopPartLoadRatio(AirLoopNum) +
9912 681538 : nodeReport(i).PZOFF * (1.0 - LoopPartLoadRatio(AirLoopNum));
9913 681538 : nodeReport(i).PZON = AirflowNetworkNodeSimu(i).PZ;
9914 : }
9915 : }
9916 3750067 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
9917 3455625 : PartLoadRatio = MaxPartLoadRatio;
9918 11594820 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
9919 8139195 : if (MultizoneZoneData(j).ZoneNum == MultizoneSurfaceData(i).ZonePtr) {
9920 0 : if (AirflowNetworkNodeData(j).AirLoopNum == AirLoopNum) {
9921 0 : PartLoadRatio = LoopPartLoadRatio(AirLoopNum);
9922 0 : break;
9923 : }
9924 : }
9925 : }
9926 3455625 : linkReport1(i).FLOW = AirflowNetworkLinkSimu(i).FLOW * PartLoadRatio + linkReport1(i).FLOWOFF * (1.0 - PartLoadRatio);
9927 3455625 : linkReport1(i).FLOW2 = AirflowNetworkLinkSimu(i).FLOW2 * PartLoadRatio + linkReport1(i).FLOW2OFF * (1.0 - PartLoadRatio);
9928 3455625 : linkReport1(i).VolFLOW = AirflowNetworkLinkSimu(i).VolFLOW * PartLoadRatio + linkReport1(i).VolFLOWOFF * (1.0 - PartLoadRatio);
9929 3455625 : linkReport1(i).VolFLOW2 = AirflowNetworkLinkSimu(i).VolFLOW2 * PartLoadRatio + linkReport1(i).VolFLOW2OFF * (1.0 - PartLoadRatio);
9930 3455625 : linkReport1(i).DP = AirflowNetworkLinkSimu(i).DP * PartLoadRatio + linkReport1(i).DPOFF * (1.0 - PartLoadRatio);
9931 3455625 : linkReport1(i).DPON = AirflowNetworkLinkSimu(i).DP;
9932 : }
9933 : }
9934 : }
9935 :
9936 : // Save values
9937 11541555 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
9938 11160821 : AirflowNetworkNodeSimu(i).TZlast = AirflowNetworkNodeSimu(i).TZ;
9939 11160821 : AirflowNetworkNodeSimu(i).WZlast = AirflowNetworkNodeSimu(i).WZ;
9940 11160821 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9941 154586 : AirflowNetworkNodeSimu(i).CO2Zlast = AirflowNetworkNodeSimu(i).CO2Z;
9942 : }
9943 11160821 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9944 150849 : AirflowNetworkNodeSimu(i).GCZlast = AirflowNetworkNodeSimu(i).GCZ;
9945 : }
9946 : }
9947 : }
9948 :
9949 1070087 : void Solver::venting_control(int const i, // AirflowNetwork surface number
9950 : Real64 &OpenFactor // Window or door opening factor (used to calculate airflow)
9951 : )
9952 : {
9953 : // SUBROUTINE INFORMATION:
9954 : // AUTHOR Fred Winkelmann
9955 : // DATE WRITTEN April 2003
9956 : // MODIFIED Feb 2004, FCW: allow venting control of interior window/door
9957 : // MODIFIED Nov. 2005, LG: to fit the requirement for AirflowNetwork Model
9958 : // RE-ENGINEERED
9959 :
9960 : // PURPOSE OF THIS SUBROUTINE:
9961 : // Determines the venting opening factor for an exterior or interior window or door
9962 : // as determined by the venting control method.
9963 :
9964 : // Using/Aliasing
9965 : using ScheduleManager::GetCurrentScheduleValue;
9966 :
9967 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9968 : Real64 VentTemp; // Venting temperature (C)
9969 : Real64 ZoneAirEnthalpy; // Enthalpy of zone air (J/kg)
9970 : Real64 OpenFactorMult; // Window/door opening modulation multiplier on venting open factor
9971 : Real64 DelTemp; // Inside-outside air temperature difference (K)
9972 : Real64 DelEnthal; // Inside-outside air enthalpy difference (J/kg)
9973 : int IZ; // AirflowNetwork zone number
9974 : int ZoneNum; // EnergyPlus zone number
9975 : int SurfNum; // Heat transfer surface number
9976 : Real64 LimValVentOpenFacMult; // Limiting value of venting opening factor multiplier
9977 : Real64 LowerValInOutTempDiff; // Lower value of inside/outside temperature difference for opening factor modulation
9978 : Real64 UpperValInOutTempDiff; // Upper value of inside/outside temperature difference for opening factor modulation
9979 : Real64 LowerValInOutEnthalDiff; // Lower value of inside/outside enthalpy difference for opening factor modulation
9980 : Real64 UpperValInOutEnthalDiff; // Upper value of inside/outside enthalpy difference for opening factor modulation
9981 : bool VentingAllowed; // True if venting schedule allows venting
9982 : int VentCtrlNum; // Venting control strategy 1: Temperature control; 2: Enthalpy control
9983 : Real64 VentingSchVal; // Current time step value of venting schedule
9984 : Real64 Tamb; // Outdoor dry bulb temperature at surface centroid height
9985 : int PeopleInd;
9986 :
9987 1070087 : if (MultizoneSurfaceData(i).EMSOpenFactorActuated) { // EMS sets value to use
9988 18363 : OpenFactor = MultizoneSurfaceData(i).EMSOpenFactor;
9989 18363 : SurfNum = MultizoneSurfaceData(i).SurfNum;
9990 18363 : if (MultizoneSurfaceData(i).Factor > 0.0) {
9991 18363 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactor / MultizoneSurfaceData(i).Factor;
9992 : } else {
9993 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactor;
9994 : }
9995 18363 : return;
9996 : }
9997 :
9998 1051724 : SurfNum = MultizoneSurfaceData(i).SurfNum;
9999 :
10000 1051724 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10001 :
10002 : // Get venting temperature and venting strategy for exterior window or door
10003 : // and determine whether venting is allowed
10004 :
10005 1051724 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 1.0;
10006 1051724 : VentingAllowed = true;
10007 1051724 : IZ = MultizoneSurfaceData(i).NodeNums[0];
10008 : // Revise for RoomAirflowNetwork model
10009 1051724 : if (MultizoneSurfaceData(i).RAFNflag) IZ = MultizoneSurfaceData(i).ZonePtr;
10010 1051724 : ZoneNum = MultizoneZoneData(IZ).ZoneNum;
10011 :
10012 : // Note in the following that individual venting control for a window/door takes
10013 : // precedence over zone-level control
10014 1051724 : if (MultizoneSurfaceData(i).IndVentControl) {
10015 32487 : VentTemp = GetCurrentScheduleValue(m_state, MultizoneSurfaceData(i).VentSchNum);
10016 32487 : VentCtrlNum = MultizoneSurfaceData(i).VentSurfCtrNum;
10017 32487 : if (MultizoneSurfaceData(i).VentingSchNum > 0) {
10018 0 : VentingSchVal = GetCurrentScheduleValue(m_state, MultizoneSurfaceData(i).VentingSchNum);
10019 0 : if (VentingSchVal <= 0.0) {
10020 0 : VentingAllowed = false;
10021 0 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 0.0;
10022 : }
10023 : }
10024 : } else {
10025 : // Zone level only by Gu on Nov. 8, 2005
10026 1019237 : VentTemp = GetCurrentScheduleValue(m_state, MultizoneZoneData(IZ).VentSchNum);
10027 1019237 : VentCtrlNum = MultizoneZoneData(IZ).VentCtrNum;
10028 1019237 : if (MultizoneZoneData(IZ).VentingSchNum > 0) {
10029 684082 : VentingSchVal = GetCurrentScheduleValue(m_state, MultizoneZoneData(IZ).VentingSchNum);
10030 684082 : if (VentingSchVal <= 0.0) {
10031 371109 : VentingAllowed = false;
10032 371109 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 0.0;
10033 : }
10034 : }
10035 : }
10036 :
10037 1051724 : m_state.dataSurface->SurfWinInsideTempForVentingRep(SurfNum) = VentTemp;
10038 1051724 : OpenFactor = 0.0;
10039 :
10040 : // Venting based on inside-outside air temperature difference
10041 :
10042 1051724 : if ((VentCtrlNum == VentControlType::Temp || VentCtrlNum == VentControlType::AdjTemp) && VentingAllowed) {
10043 558656 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(SurfNum);
10044 : // Check whether this surface is an interior wall or not. If Yes, use adjacent zone conditions
10045 558656 : if (VentCtrlNum == VentControlType::AdjTemp && MultizoneSurfaceData(i).IndVentControl) {
10046 0 : Tamb = ANZT(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum);
10047 : }
10048 558656 : if (ANZT(ZoneNum) > Tamb && ANZT(ZoneNum) > VentTemp) {
10049 246447 : OpenFactor = MultizoneSurfaceData(i).Factor;
10050 246447 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10051 : // Modulation of OpenFactor
10052 246447 : if (MultizoneSurfaceData(i).IndVentControl) {
10053 0 : LimValVentOpenFacMult = MultizoneSurfaceData(i).ModulateFactor;
10054 0 : LowerValInOutTempDiff = MultizoneSurfaceData(i).LowValueTemp;
10055 0 : UpperValInOutTempDiff = MultizoneSurfaceData(i).UpValueTemp;
10056 : } else {
10057 246447 : LimValVentOpenFacMult = MultizoneZoneData(IZ).OpenFactor;
10058 246447 : LowerValInOutTempDiff = MultizoneZoneData(IZ).LowValueTemp;
10059 246447 : UpperValInOutTempDiff = MultizoneZoneData(IZ).UpValueTemp;
10060 : }
10061 246447 : if (LimValVentOpenFacMult != 1.0) {
10062 154645 : DelTemp = ANZT(ZoneNum) - Tamb;
10063 154645 : if (DelTemp <= LowerValInOutTempDiff) {
10064 135339 : OpenFactorMult = 1.0;
10065 19306 : } else if (DelTemp >= UpperValInOutTempDiff) {
10066 0 : OpenFactorMult = LimValVentOpenFacMult;
10067 : } else {
10068 19306 : OpenFactorMult =
10069 : LimValVentOpenFacMult +
10070 19306 : ((UpperValInOutTempDiff - DelTemp) / (UpperValInOutTempDiff - LowerValInOutTempDiff)) * (1 - LimValVentOpenFacMult);
10071 : }
10072 154645 : OpenFactor *= OpenFactorMult;
10073 154645 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactorMult;
10074 : }
10075 : } else {
10076 312209 : OpenFactor = 0.0;
10077 312209 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10078 : }
10079 : }
10080 :
10081 : // Venting based on inside-outside air enthalpy difference
10082 :
10083 1051724 : if ((VentCtrlNum == VentControlType::Enth || VentCtrlNum == VentControlType::AdjEnth) && VentingAllowed) {
10084 0 : ZoneAirEnthalpy = PsyHFnTdbW(ANZT(ZoneNum), ANZW(ZoneNum));
10085 : // Check whether this surface is an interior wall or not. If Yes, use adjacent zone conditions
10086 0 : if (VentCtrlNum == VentControlType::AdjEnth && MultizoneSurfaceData(i).IndVentControl) {
10087 0 : m_state.dataEnvrn->OutEnthalpy = PsyHFnTdbW(ANZT(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum),
10088 0 : ANZW(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum));
10089 : }
10090 0 : if (ZoneAirEnthalpy > m_state.dataEnvrn->OutEnthalpy && ANZT(ZoneNum) > VentTemp) {
10091 0 : OpenFactor = MultizoneSurfaceData(i).Factor;
10092 : // Modulation of OpenFactor
10093 0 : if (MultizoneSurfaceData(i).IndVentControl) {
10094 0 : LimValVentOpenFacMult = MultizoneSurfaceData(i).ModulateFactor;
10095 0 : LowerValInOutEnthalDiff = MultizoneSurfaceData(i).LowValueEnth;
10096 0 : UpperValInOutEnthalDiff = MultizoneSurfaceData(i).UpValueEnth;
10097 : } else {
10098 0 : LimValVentOpenFacMult = MultizoneZoneData(IZ).OpenFactor;
10099 0 : LowerValInOutEnthalDiff = MultizoneZoneData(IZ).LowValueEnth;
10100 0 : UpperValInOutEnthalDiff = MultizoneZoneData(IZ).UpValueEnth;
10101 : }
10102 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10103 :
10104 0 : if (LimValVentOpenFacMult != 1.0) {
10105 0 : DelEnthal = ZoneAirEnthalpy - m_state.dataEnvrn->OutEnthalpy;
10106 0 : if (DelEnthal <= LowerValInOutEnthalDiff) {
10107 0 : OpenFactorMult = 1.0;
10108 0 : } else if (DelEnthal >= UpperValInOutEnthalDiff) {
10109 0 : OpenFactorMult = LimValVentOpenFacMult;
10110 : } else {
10111 0 : OpenFactorMult =
10112 0 : LimValVentOpenFacMult + ((UpperValInOutEnthalDiff - DelEnthal) / (UpperValInOutEnthalDiff - LowerValInOutEnthalDiff)) *
10113 0 : (1 - LimValVentOpenFacMult);
10114 : }
10115 0 : OpenFactor *= OpenFactorMult;
10116 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactorMult;
10117 : }
10118 : } else {
10119 0 : OpenFactor = 0.0;
10120 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10121 : }
10122 : }
10123 :
10124 : // Constant venting (opening factor as specified in IDF) - C-PH - added by Philip Haves 3/8/01
10125 : // subject to venting availability
10126 :
10127 1051724 : if (VentCtrlNum == VentControlType::Const && VentingAllowed) { // Constant
10128 96807 : OpenFactor = MultizoneSurfaceData(i).Factor;
10129 96807 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10130 : }
10131 :
10132 1051724 : if (VentCtrlNum == VentControlType::ASH55) {
10133 25152 : if (VentingAllowed && (!m_state.dataGlobal->BeginEnvrnFlag) && (!m_state.dataGlobal->WarmupFlag)) {
10134 2196 : PeopleInd = MultizoneZoneData(IZ).ASH55PeopleInd;
10135 2196 : if (PeopleInd > 0 && m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortAdaptiveASH5590 != -1) {
10136 1452 : if (m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortOpTemp >
10137 726 : m_state.dataThermalComforts->ThermalComfortData(PeopleInd).TComfASH55) {
10138 654 : OpenFactor = MultizoneSurfaceData(i).Factor;
10139 654 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10140 : } else {
10141 72 : OpenFactor = 0.0;
10142 : }
10143 : } else {
10144 1470 : OpenFactor = 0.0;
10145 : }
10146 : } else {
10147 22956 : OpenFactor = 0.0;
10148 : }
10149 : }
10150 :
10151 1051724 : if (VentCtrlNum == VentControlType::CEN15251) {
10152 0 : if (VentingAllowed && (!m_state.dataGlobal->BeginEnvrnFlag) && (!m_state.dataGlobal->WarmupFlag)) {
10153 0 : PeopleInd = MultizoneZoneData(IZ).CEN15251PeopleInd;
10154 0 : if (PeopleInd > 0 && m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortAdaptiveCEN15251CatI != -1) {
10155 0 : if (m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortOpTemp >
10156 0 : m_state.dataThermalComforts->ThermalComfortData(PeopleInd).TComfCEN15251) {
10157 0 : OpenFactor = MultizoneSurfaceData(i).Factor;
10158 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10159 : } else {
10160 0 : OpenFactor = 0.0;
10161 : }
10162 : } else {
10163 0 : OpenFactor = 0.0;
10164 : }
10165 : } else {
10166 0 : OpenFactor = 0.0;
10167 : }
10168 : }
10169 :
10170 : // No venting, i.e, window/door always closed - added YJH 8 Aug 02
10171 :
10172 1051724 : if (VentCtrlNum == VentControlType::NoVent) { // Novent
10173 0 : OpenFactor = 0.0;
10174 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10175 : }
10176 : }
10177 :
10178 34 : void Solver::assign_fan_airloop()
10179 : {
10180 : // Assign the system Fan AirLoop Number based on the zone inlet node
10181 :
10182 146 : for (int i = 1; i <= AirflowNetworkNumOfZones; i++) {
10183 528 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; j++) {
10184 416 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) continue;
10185 203 : if ((MultizoneZoneData(i).ZoneNum == j) && (m_state.dataZoneEquip->ZoneEquipConfig(j).NumInletNodes > 0)) {
10186 105 : for (int k = 1; k <= DisSysNumOfCVFs; k++) {
10187 52 : if (DisSysCompCVFData(k).AirLoopNum == 0) {
10188 50 : DisSysCompCVFData(k).AirLoopNum = m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(1);
10189 : }
10190 : }
10191 : }
10192 : }
10193 : }
10194 34 : }
10195 :
10196 23 : void Solver::validate_distribution()
10197 : {
10198 :
10199 : // SUBROUTINE INFORMATION:
10200 : // AUTHOR Lixing Gu
10201 : // DATE WRITTEN Oct. 2005
10202 : // MODIFIED L. Gu, Jan. 2009: allow a desuperheater coil and three heat exchangers
10203 : // RE-ENGINEERED na
10204 :
10205 : // PURPOSE OF THIS SUBROUTINE:
10206 : // This subroutine validates the inputs of distribution system, since node data from a primary airloop
10207 : // are not available in the first call during reading input data of airflownetwork objects.
10208 : // Note: this routine shouldn't be called more than once
10209 :
10210 : // Using/Aliasing
10211 : using BranchNodeConnections::GetNodeConnectionType;
10212 : using MixedAir::GetNumOAMixers;
10213 : using MixedAir::GetOAMixerInletNodeNumber;
10214 : using MixedAir::GetOAMixerReliefNodeNumber;
10215 : using SingleDuct::GetHVACSingleDuctSysIndex;
10216 : using namespace DataLoopNode;
10217 23 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
10218 : using DXCoils::SetDXCoilAirLoopNumber;
10219 : using Fans::SetFanAirLoopNumber;
10220 : using HeatingCoils::SetHeatingCoilAirLoopNumber;
10221 : using HVACStandAloneERV::GetStandAloneERVNodeNumber;
10222 : using SplitterComponent::GetSplitterNodeNumbers;
10223 : using SplitterComponent::GetSplitterOutletNumber;
10224 : using WaterThermalTanks::GetHeatPumpWaterHeaterNodeNumber;
10225 : using ZoneDehumidifier::GetZoneDehumidifierNodeNumber;
10226 :
10227 : // SUBROUTINE PARAMETER DEFINITIONS:
10228 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::validate_distribution: "); // include trailing blank space
10229 :
10230 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10231 : int i;
10232 : int j;
10233 : int k;
10234 : int n;
10235 : int S1;
10236 : int S2;
10237 : int R1;
10238 : int R2;
10239 : bool LocalError;
10240 46 : Array1D_bool NodeFound;
10241 :
10242 23 : bool ErrorsFound(false);
10243 23 : bool IsNotOK(false);
10244 23 : bool errFlag(false);
10245 46 : EPVector<DataLoopNode::ConnectionType> NodeConnectionType; // Specifies the type of node connection
10246 46 : std::string CurrentModuleObject;
10247 :
10248 23 : bool HPWHFound(false); // Flag for HPWH identification
10249 23 : bool StandaloneERVFound(false); // Flag for Standalone ERV (ZoneHVAC:EnergyRecoveryVentilator) identification
10250 :
10251 : // Validate supply and return connections
10252 23 : NodeFound.dimension(m_state.dataLoopNodes->NumOfNodes, false);
10253 : // Validate inlet and outlet nodes for zone exhaust fans
10254 36 : for (i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
10255 13 : NodeFound(MultizoneCompExhaustFanData(i).InletNode) = true;
10256 13 : NodeFound(MultizoneCompExhaustFanData(i).OutletNode) = true;
10257 : }
10258 : // Validate EPlus Node names and types
10259 551 : for (i = 1; i <= DisSysNumOfNodes; ++i) {
10260 528 : if (UtilityRoutines::SameString(DisSysNodeData(i).EPlusName, "") || UtilityRoutines::SameString(DisSysNodeData(i).EPlusName, "Other"))
10261 195 : continue;
10262 333 : LocalError = false;
10263 3717 : for (j = 1; j <= m_state.dataLoopNodes->NumOfNodes; ++j) { // NodeID
10264 3717 : if (DisSysNodeData(i).EPlusName == m_state.dataLoopNodes->NodeID(j)) {
10265 333 : DisSysNodeData(i).AirLoopNum = get_airloop_number(j);
10266 333 : if (DisSysNodeData(i).AirLoopNum == 0) {
10267 0 : ShowSevereError(m_state,
10268 0 : format(RoutineName) + "The Node or Component Name defined in " + DisSysNodeData(i).Name +
10269 : " is not found in the AirLoopHVAC.");
10270 0 : ShowContinueError(m_state,
10271 0 : "The entered name is " + DisSysNodeData(i).EPlusName + " in an AirflowNetwork:Distribution:Node object.");
10272 0 : ErrorsFound = true;
10273 : }
10274 333 : DisSysNodeData(i).EPlusNodeNum = j;
10275 333 : AirflowNetworkNodeData(NumOfNodesMultiZone + i).EPlusNodeNum = j;
10276 333 : AirflowNetworkNodeData(NumOfNodesMultiZone + i).AirLoopNum = DisSysNodeData(i).AirLoopNum;
10277 333 : NodeFound(j) = true;
10278 333 : LocalError = true;
10279 333 : break;
10280 : }
10281 : }
10282 : // Check outdoor air node
10283 999 : if (UtilityRoutines::SameString(DisSysNodeData(i).EPlusType, "OutdoorAir:NodeList") ||
10284 666 : UtilityRoutines::SameString(DisSysNodeData(i).EPlusType, "OutdoorAir:Node")) {
10285 0 : if (!LocalError) {
10286 0 : ShowSevereError(m_state,
10287 0 : format(RoutineName) + "The Node or Component Name defined in " + DisSysNodeData(i).Name +
10288 0 : " is not found in the " + DisSysNodeData(i).EPlusType);
10289 0 : ShowContinueError(m_state,
10290 0 : "The entered name is " + DisSysNodeData(i).EPlusName + " in an AirflowNetwork:Distribution:Node object.");
10291 0 : ErrorsFound = true;
10292 : }
10293 : }
10294 333 : if (DisSysNodeData(i).EPlusNodeNum == 0) {
10295 0 : ShowSevereError(m_state,
10296 0 : format(RoutineName) +
10297 0 : "Primary Air Loop Node is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " + DisSysNodeData(i).Name);
10298 0 : ErrorsFound = true;
10299 : }
10300 : }
10301 :
10302 : // Determine node numbers for zone inlets and outlets
10303 103 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
10304 80 : if (!m_state.dataZoneEquip->ZoneEquipConfig(i).IsControlled) continue;
10305 103 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumInletNodes; ++j) {
10306 1096 : for (int k = 1; k <= AirflowNetworkNumOfNodes; ++k) {
10307 1091 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).InletNode(j) == AirflowNetworkNodeData(k).EPlusNodeNum) {
10308 49 : AirflowNetworkNodeData(k).EPlusTypeNum = iEPlusNodeType::ZIN;
10309 49 : break;
10310 : }
10311 : }
10312 : }
10313 98 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumReturnNodes; ++j) {
10314 995 : for (int k = 1; k <= AirflowNetworkNumOfNodes; ++k) {
10315 995 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).ReturnNode(j) == AirflowNetworkNodeData(k).EPlusNodeNum) {
10316 49 : AirflowNetworkNodeData(k).EPlusTypeNum = iEPlusNodeType::ZOU;
10317 49 : break;
10318 : }
10319 : }
10320 : }
10321 : }
10322 :
10323 : // Eliminate node not related to AirLoopHVAC
10324 1426 : for (k = 1; k <= m_state.dataBranchNodeConnections->NumOfNodeConnections; ++k) {
10325 1403 : if (NodeFound(m_state.dataBranchNodeConnections->NodeConnections(k).NodeNumber)) continue;
10326 281 : if (m_state.dataBranchNodeConnections->NodeConnections(k).FluidStream == NodeInputManager::CompFluidStream::Secondary) {
10327 12 : NodeFound(m_state.dataBranchNodeConnections->NodeConnections(k).NodeNumber) = true;
10328 : }
10329 : }
10330 :
10331 : // Eliminate nodes with fluidtype = water
10332 514 : for (k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
10333 491 : if (NodeFound(k)) continue;
10334 120 : if (m_state.dataLoopNodes->Node(k).FluidType == DataLoopNode::NodeFluidType::Water) {
10335 40 : NodeFound(k) = true;
10336 : }
10337 : }
10338 :
10339 : // Eliminate local external air node for network
10340 514 : for (k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
10341 491 : if (NodeFound(k)) continue;
10342 80 : if (m_state.dataLoopNodes->Node(k).IsLocalNode) NodeFound(k) = true;
10343 : }
10344 :
10345 : // Ensure all the nodes used in Eplus are a subset of AirflowNetwork Nodes
10346 514 : for (i = 1; i <= m_state.dataLoopNodes->NumOfNodes; ++i) {
10347 491 : if (NodeFound(i)) continue;
10348 : // Skip the inlet and outlet nodes of zone dehumidifiers
10349 79 : if (GetZoneDehumidifierNodeNumber(m_state, i)) NodeFound(i) = true;
10350 :
10351 79 : if (simulation_control.allow_unsupported_zone_equipment) {
10352 : // Skip HPWH nodes that don't have to be included in the AFN
10353 16 : if (GetHeatPumpWaterHeaterNodeNumber(m_state, i)) {
10354 6 : NodeFound(i) = true;
10355 6 : HPWHFound = true;
10356 : }
10357 :
10358 : // Skip Standalone ERV nodes that don't have to be included in the AFN
10359 16 : if (GetStandAloneERVNodeNumber(m_state, i)) {
10360 6 : NodeFound(i) = true;
10361 6 : StandaloneERVFound = true;
10362 : }
10363 : }
10364 :
10365 213 : for (int zoneNum = 1; zoneNum <= m_state.dataGlobal->NumOfZones; ++zoneNum) {
10366 183 : if (!m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).IsControlled) continue;
10367 148 : if (m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneNode == i) {
10368 49 : if (zoneNum > AirflowNetworkNumOfNodes) {
10369 0 : ShowSevereError(m_state,
10370 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10371 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10372 0 : ShowContinueError(
10373 0 : m_state, "This Node is the zone air node for Zone '" + m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneName + "'.");
10374 0 : ErrorsFound = true;
10375 : } else {
10376 49 : NodeFound(i) = true;
10377 49 : AirflowNetworkNodeData(zoneNum).EPlusNodeNum = i;
10378 : }
10379 49 : break;
10380 : }
10381 : }
10382 :
10383 : // skip nodes that are not part of an airflow network
10384 :
10385 : // DX COIL CONDENSER NODE TEST:
10386 : // Outside air nodes are used for DX coil condenser inlet nodes, these are specified in an outside air node or
10387 : // OutdoorAir:NodeList object (and classified with NodeConnectionType as OutsideAir). In addition,
10388 : // this same node is specified in a Coil:DX:CoolingBypassFactorEmpirical object (and classified with
10389 : // NodeConnectionType as OutsideAirReference). In the NodeConnectionType structure, both of these nodes have a
10390 : // unique index but have the same node number. The Outside Air Node will usually be listed first. Search for all
10391 : // indexes with the same node number and check if it is classified as NodeConnectionType = OutsideAirReference.
10392 : // Mark this node as found since it is not used in an airflownetwork simulation.
10393 : // Example (using AirflowNetwork_MultiZone_SmallOffice.idf with a single OA Mixer):
10394 : // (the example shown below is identical to AirflowNetwork_SimpleHouse.idf with no OA Mixer except
10395 : // that the NodeConnections indexes are (7) and (31), respectively and the NodeNumber = 6)
10396 : // The GetNodeConnectionType CALL below returns DataLoopNode::NodeConnectionType::OutsideAir = 7 and
10397 : // DataLoopNode::NodeConnectionType::OutsideAirReference = 14.
10398 : // NodeConnections info from OUTSIDE AIR NODE object read:
10399 : // NodeConnections(9)NodeNumber = 10
10400 : // NodeConnections(9)NodeName = ACDXCOIL 1 CONDENSER NODE
10401 : // NodeConnections(9)ObjectType = OUTSIDE AIR NODE
10402 : // NodeConnections(9)ObjectName = OUTSIDE AIR NODE
10403 : // NodeConnections(9)ConnectionType = OutsideAir
10404 : // NodeConnections info from Coil:DX:CoolingBypassFactorEmpirical object read:
10405 : // NodeConnections(64)NodeNumber = 10
10406 : // NodeConnections(64)NodeName = ACDXCOIL 1 CONDENSER NODE
10407 : // NodeConnections(64)ObjectType = COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
10408 : // NodeConnections(64)ObjectName = ACDXCOIL 1
10409 : // NodeConnections(64)ConnectionType = OutsideAirReference
10410 :
10411 79 : errFlag = false;
10412 79 : GetNodeConnectionType(m_state, i, NodeConnectionType, errFlag); // Gets all connection types for a given node number
10413 79 : if (errFlag) {
10414 0 : ShowContinueError(m_state, "...occurs in Airflow Network simulation.");
10415 : } else {
10416 : // skip nodes for air cooled condensers
10417 212 : for (j = 1; j <= isize(NodeConnectionType); ++j) {
10418 133 : if (NodeConnectionType(j) == DataLoopNode::ConnectionType::OutsideAirReference) {
10419 2 : NodeFound(i) = true;
10420 : }
10421 : }
10422 : }
10423 :
10424 79 : if (!NodeFound(i)) {
10425 : // Check if this node is the OA relief node. For the time being, OA relief node is not used
10426 14 : if (GetNumOAMixers(m_state) > 1) {
10427 : // ShowSevereError(m_state, format(RoutineName) + "Only one OutdoorAir:Mixer is allowed in the
10428 : // AirflowNetwork model." ); ErrorsFound = true;
10429 : int OAFanNum;
10430 : int OARelNum;
10431 : int OAMixerNum;
10432 :
10433 4 : for (OAFanNum = 1; OAFanNum <= NumOfOAFans; ++OAFanNum) {
10434 2 : DisSysCompOutdoorAirData(OAFanNum).InletNode =
10435 2 : GetOAMixerInletNodeNumber(m_state, DisSysCompOutdoorAirData(OAFanNum).OAMixerNum);
10436 : // NodeFound( DisSysCompOutdoorAirData( OAFanNum ).InletNode
10437 : // ) = true;
10438 : }
10439 4 : for (OARelNum = 1; OARelNum <= NumOfReliefFans; ++OARelNum) {
10440 2 : DisSysCompReliefAirData(OARelNum).OutletNode =
10441 2 : GetOAMixerInletNodeNumber(m_state, DisSysCompReliefAirData(OARelNum).OAMixerNum);
10442 : // NodeFound( DisSysCompOutdoorAirData( OAFanNum ).InletNode
10443 : // ) = true;
10444 : }
10445 : // Check NodeFound status
10446 3 : for (OAMixerNum = 1; OAMixerNum <= GetNumOAMixers(m_state); ++OAMixerNum) {
10447 3 : if (i == GetOAMixerReliefNodeNumber(m_state, OAMixerNum)) {
10448 2 : NodeFound(i) = true;
10449 2 : break;
10450 1 : } else if (i == GetOAMixerInletNodeNumber(m_state, OAMixerNum)) {
10451 0 : NodeFound(i) = true;
10452 0 : break;
10453 : } else {
10454 1 : if (OAMixerNum == GetNumOAMixers(m_state)) {
10455 0 : ShowSevereError(m_state,
10456 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10457 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10458 0 : ErrorsFound = true;
10459 : }
10460 : }
10461 : }
10462 12 : } else if (GetNumOAMixers(m_state) == 0) {
10463 0 : ShowSevereError(m_state,
10464 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10465 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10466 0 : ErrorsFound = true;
10467 : } else {
10468 : // TODO: I fail to see how you could enter this block given than NumOAMixers (returned by GetNumOAMixers())
10469 : // is initialized to zero, and we check above if '> 0' or '== 0'
10470 12 : if (NumOfOAFans == 1 && DisSysCompOutdoorAirData(1).InletNode == 0) {
10471 1 : DisSysCompOutdoorAirData(1).InletNode = GetOAMixerInletNodeNumber(m_state, 1);
10472 : }
10473 12 : if (NumOfReliefFans == 1 && DisSysCompReliefAirData(1).OutletNode == 0) {
10474 1 : DisSysCompReliefAirData(1).OutletNode = GetOAMixerInletNodeNumber(m_state, 1);
10475 : }
10476 12 : if (i == GetOAMixerReliefNodeNumber(m_state, 1)) {
10477 11 : NodeFound(i) = true;
10478 1 : } else if (i == GetOAMixerInletNodeNumber(m_state, 1)) {
10479 1 : NodeFound(i) = true;
10480 : } else {
10481 0 : ShowSevereError(m_state,
10482 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10483 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10484 0 : ErrorsFound = true;
10485 : }
10486 : }
10487 : }
10488 : }
10489 23 : if (HPWHFound) {
10490 6 : ShowWarningError(m_state,
10491 4 : format(RoutineName) + "Heat pump water heater is simulated along with an AirflowNetwork but is not included in "
10492 : "the AirflowNetwork.");
10493 : }
10494 23 : if (StandaloneERVFound) {
10495 6 : ShowWarningError(m_state,
10496 4 : format(RoutineName) + "A ZoneHVAC:EnergyRecoveryVentilator is simulated along with an AirflowNetwork but is not "
10497 : "included in the AirflowNetwork.");
10498 : }
10499 23 : NodeFound.deallocate();
10500 :
10501 : // Assign AirLoop Number to every node and linkage
10502 : // Zone first
10503 103 : for (i = 1; i <= AirflowNetworkNumOfZones; i++) {
10504 372 : for (j = 1; j <= m_state.dataGlobal->NumOfZones; j++) {
10505 292 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) continue;
10506 186 : if ((MultizoneZoneData(i).ZoneNum == j) && (m_state.dataZoneEquip->ZoneEquipConfig(j).NumInletNodes > 0)) {
10507 : // No multiple Airloop
10508 49 : AirflowNetworkNodeData(i).AirLoopNum = m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(1);
10509 : }
10510 : }
10511 : }
10512 : // Air Distribution system
10513 724 : for (i = AirflowNetworkNumOfSurfaces + 1; i <= AirflowNetworkNumOfLinks; ++i) {
10514 701 : j = AirflowNetworkLinkageData(i).NodeNums[0];
10515 701 : k = AirflowNetworkLinkageData(i).NodeNums[1];
10516 701 : if (AirflowNetworkNodeData(j).AirLoopNum == 0 && AirflowNetworkNodeData(k).AirLoopNum == 0) {
10517 : // Error messaage
10518 0 : ShowSevereError(m_state,
10519 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(i).Name +
10520 : " is not valid for AirLoopNum assignment");
10521 0 : ShowContinueError(m_state,
10522 0 : "AirLoopNum is not found in both nodes for the linkage: " + AirflowNetworkLinkageData(i).NodeNames[0] + " and " +
10523 0 : AirflowNetworkLinkageData(i).NodeNames[1]);
10524 0 : ShowContinueError(m_state,
10525 : "Please ensure one of two AIRFLOWNETWORK:DISTRIBUTION:NODEs in the first AIRFLOWNETWORK:DISTRIBUTION:LINKAGE "
10526 : "object should be defined as EnergyPlus NodeID.");
10527 0 : ErrorsFound = true;
10528 : }
10529 701 : if (AirflowNetworkNodeData(j).AirLoopNum > 0 && AirflowNetworkNodeData(k).AirLoopNum == 0) {
10530 218 : AirflowNetworkNodeData(k).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10531 : }
10532 701 : if (AirflowNetworkNodeData(j).AirLoopNum == 0 && AirflowNetworkNodeData(k).AirLoopNum > 0) {
10533 7 : AirflowNetworkNodeData(j).AirLoopNum = AirflowNetworkNodeData(k).AirLoopNum;
10534 : }
10535 701 : if (AirflowNetworkNodeData(j).AirLoopNum == AirflowNetworkNodeData(k).AirLoopNum) {
10536 701 : AirflowNetworkLinkageData(i).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10537 : }
10538 701 : if (AirflowNetworkNodeData(j).AirLoopNum != AirflowNetworkNodeData(k).AirLoopNum && AirflowNetworkNodeData(j).AirLoopNum > 0 &&
10539 0 : AirflowNetworkNodeData(k).AirLoopNum > 0) {
10540 0 : AirflowNetworkLinkageData(i).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10541 0 : ShowSevereError(m_state,
10542 0 : "The AirLoopNum defined in both AIRFLOWNETWORK:DISTRIBUTION:NODE objects in " + AirflowNetworkLinkageData(i).Name +
10543 : " are not the same. Please make sure both nodes should be listed in the same AirLoop as a valid linkage.");
10544 0 : ShowContinueError(m_state,
10545 0 : "AirLoop defined in " + AirflowNetworkNodeData(j).Name + " is " +
10546 0 : m_state.dataAirSystemsData->PrimaryAirSystems(AirflowNetworkNodeData(j).AirLoopNum).Name +
10547 0 : ", and AirLoop defined in " + AirflowNetworkNodeData(k).Name + " is " +
10548 0 : m_state.dataAirSystemsData->PrimaryAirSystems(AirflowNetworkNodeData(k).AirLoopNum).Name);
10549 0 : ErrorsFound = true;
10550 : }
10551 : // Set AirLoopNum to fans and coils
10552 701 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::FAN) {
10553 24 : n = m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).FanIndex;
10554 24 : m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).AirLoopNum =
10555 24 : AirflowNetworkLinkageData(i).AirLoopNum;
10556 24 : if (m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).FanModelFlag) {
10557 1 : m_state.dataHVACFan
10558 2 : ->fanObjs[m_state.afn->DisSysCompCVFData(m_state.afn->AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum)
10559 2 : .FanIndex]
10560 2 : ->AirLoopNum = AirflowNetworkLinkageData(i).AirLoopNum;
10561 : } else {
10562 23 : SetFanAirLoopNumber(m_state, n, AirflowNetworkLinkageData(i).AirLoopNum);
10563 : }
10564 : }
10565 701 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::COI) {
10566 57 : m_state.afn->DisSysCompCoilData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).AirLoopNum =
10567 57 : AirflowNetworkLinkageData(i).AirLoopNum;
10568 : }
10569 : }
10570 :
10571 : // Validate coil name and type
10572 23 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Coil";
10573 23 : MultiSpeedHPIndicator = 0;
10574 80 : for (i = 1; i <= DisSysNumOfCoils; ++i) {
10575 : {
10576 114 : auto const SELECT_CASE_var(UtilityRoutines::MakeUPPERCase(DisSysCompCoilData(i).EPlusType));
10577 :
10578 57 : if (SELECT_CASE_var == "COIL:COOLING:DX") {
10579 0 : ValidateComponent(m_state, "Coil:Cooling:DX", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10580 0 : if (IsNotOK) {
10581 0 : ErrorsFound = true;
10582 : } else {
10583 : // Replace the convenience function with in-place code
10584 0 : std::string mycoil = DisSysCompCoilData(i).name;
10585 0 : auto it = std::find_if(m_state.dataCoilCooingDX->coilCoolingDXs.begin(),
10586 0 : m_state.dataCoilCooingDX->coilCoolingDXs.end(),
10587 0 : [&mycoil](const CoilCoolingDX &coil) { return coil.name == mycoil; });
10588 0 : if (it != m_state.dataCoilCooingDX->coilCoolingDXs.end()) {
10589 : // Set the airloop number on the CoilCoolingDX object, which is used to collect the runtime fraction
10590 0 : it->airLoopNum = DisSysCompCoilData(i).AirLoopNum;
10591 : } else {
10592 0 : ShowSevereError(m_state, "SetDXCoilAirLoopNumber: Could not find Coil \"Name=\"" + DisSysCompCoilData(i).name + "\"");
10593 : }
10594 : // SetDXCoilAirLoopNumber(DisSysCompCoilData(i).name,
10595 : // DisSysCompCoilData(i).AirLoopNum);
10596 : }
10597 57 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:SINGLESPEED") {
10598 44 : ValidateComponent(
10599 66 : m_state, "Coil:Cooling:DX:SingleSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10600 22 : if (IsNotOK) {
10601 0 : ErrorsFound = true;
10602 : } else {
10603 22 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10604 : }
10605 :
10606 35 : } else if (SELECT_CASE_var == "COIL:HEATING:DX:SINGLESPEED") {
10607 14 : ValidateComponent(
10608 21 : m_state, "Coil:Heating:DX:SingleSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10609 7 : if (IsNotOK) {
10610 0 : ErrorsFound = true;
10611 : } else {
10612 7 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10613 : }
10614 :
10615 28 : } else if (SELECT_CASE_var == "COIL:HEATING:FUEL") {
10616 22 : ValidateComponent(m_state, "Coil:Heating:Fuel", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10617 22 : if (IsNotOK) {
10618 0 : ErrorsFound = true;
10619 : } else {
10620 22 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10621 : }
10622 :
10623 6 : } else if (SELECT_CASE_var == "COIL:HEATING:ELECTRIC") {
10624 6 : ValidateComponent(
10625 9 : m_state, "Coil:Heating:Electric", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10626 3 : if (IsNotOK) {
10627 0 : ErrorsFound = true;
10628 : } else {
10629 3 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10630 : }
10631 :
10632 3 : } else if (SELECT_CASE_var == "COIL:COOLING:WATER") {
10633 0 : ValidateComponent(m_state, "Coil:Cooling:Water", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10634 0 : if (IsNotOK) {
10635 0 : ErrorsFound = true;
10636 : }
10637 :
10638 3 : } else if (SELECT_CASE_var == "COIL:HEATING:WATER") {
10639 0 : ValidateComponent(m_state, "Coil:Heating:Water", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10640 0 : if (IsNotOK) {
10641 0 : ErrorsFound = true;
10642 : }
10643 :
10644 3 : } else if (SELECT_CASE_var == "COIL:COOLING:WATER:DETAILEDGEOMETRY") {
10645 0 : ValidateComponent(m_state,
10646 : "Coil:Cooling:Water:DetailedGeometry",
10647 0 : DisSysCompCoilData(i).name,
10648 : IsNotOK,
10649 0 : format(RoutineName) + CurrentModuleObject);
10650 0 : if (IsNotOK) {
10651 0 : ErrorsFound = true;
10652 : }
10653 :
10654 3 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:TWOSTAGEWITHHUMIDITYCONTROLMODE") {
10655 0 : ValidateComponent(m_state,
10656 : "Coil:Cooling:DX:TwoStageWithHumidityControlMode",
10657 0 : DisSysCompCoilData(i).name,
10658 : IsNotOK,
10659 0 : format(RoutineName) + CurrentModuleObject);
10660 0 : if (IsNotOK) {
10661 0 : ErrorsFound = true;
10662 : } else {
10663 0 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10664 : }
10665 :
10666 3 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:MULTISPEED") {
10667 2 : ValidateComponent(
10668 3 : m_state, "Coil:Cooling:DX:MultiSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10669 1 : ++MultiSpeedHPIndicator;
10670 1 : if (IsNotOK) {
10671 0 : ErrorsFound = true;
10672 : } else {
10673 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10674 : }
10675 :
10676 2 : } else if (SELECT_CASE_var == "COIL:HEATING:DX:MULTISPEED") {
10677 2 : ValidateComponent(
10678 3 : m_state, "Coil:Heating:DX:MultiSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10679 1 : ++MultiSpeedHPIndicator;
10680 1 : if (IsNotOK) {
10681 0 : ErrorsFound = true;
10682 : } else {
10683 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10684 : }
10685 :
10686 1 : } else if (SELECT_CASE_var == "COIL:HEATING:DESUPERHEATER") {
10687 0 : ValidateComponent(
10688 0 : m_state, "Coil:Heating:Desuperheater", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10689 0 : if (IsNotOK) {
10690 0 : ErrorsFound = true;
10691 : }
10692 :
10693 1 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:TWOSPEED") {
10694 2 : ValidateComponent(
10695 3 : m_state, "Coil:Cooling:DX:TwoSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10696 1 : if (IsNotOK) {
10697 0 : ErrorsFound = true;
10698 : } else {
10699 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10700 : }
10701 :
10702 : } else {
10703 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " Invalid coil type = " + DisSysCompCoilData(i).name);
10704 0 : ErrorsFound = true;
10705 : }
10706 : }
10707 : }
10708 :
10709 : // Validate terminal unit name and type
10710 47 : for (i = 1; i <= DisSysNumOfTermUnits; ++i) {
10711 51 : if (UtilityRoutines::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:ConstantVolume:Reheat") ||
10712 27 : UtilityRoutines::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
10713 24 : LocalError = false;
10714 24 : if (UtilityRoutines::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:ConstantVolume:Reheat"))
10715 42 : GetHVACSingleDuctSysIndex(
10716 21 : m_state, DisSysCompTermUnitData(i).name, n, LocalError, "AirflowNetwork:Distribution:Component:TerminalUnit");
10717 24 : if (UtilityRoutines::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat"))
10718 9 : GetHVACSingleDuctSysIndex(m_state,
10719 3 : DisSysCompTermUnitData(i).name,
10720 : n,
10721 : LocalError,
10722 : "AirflowNetwork:Distribution:Component:TerminalUnit",
10723 3 : DisSysCompTermUnitData(i).DamperInletNode,
10724 6 : DisSysCompTermUnitData(i).DamperOutletNode);
10725 24 : if (LocalError) ErrorsFound = true;
10726 24 : if (VAVSystem) {
10727 6 : for (j = 1; j <= DisSysNumOfCVFs; j++) {
10728 3 : if (DisSysCompCVFData(j).FanTypeNum == FanType_SimpleVAV) {
10729 9 : if (DisSysCompCVFData(j).AirLoopNum == DisSysCompTermUnitData(i).AirLoopNum &&
10730 6 : !UtilityRoutines::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
10731 0 : ShowSevereError(m_state,
10732 0 : format(RoutineName) + CurrentModuleObject +
10733 0 : " Invalid terminal type for a VAV system = " + DisSysCompTermUnitData(i).name);
10734 0 : ShowContinueError(m_state, "The input type = " + DisSysCompTermUnitData(i).EPlusType);
10735 0 : ShowContinueError(m_state, "A VAV system requires all terminal units with type = AirTerminal:SingleDuct:VAV:Reheat");
10736 0 : ErrorsFound = true;
10737 : }
10738 : }
10739 : }
10740 : }
10741 : } else {
10742 0 : ShowSevereError(m_state,
10743 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT TERMINAL UNIT: Invalid Terminal unit type = " +
10744 0 : DisSysCompTermUnitData(i).name);
10745 0 : ErrorsFound = true;
10746 : }
10747 : }
10748 :
10749 : // Validate heat exchanger name and type
10750 23 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:HeatExchanger";
10751 24 : for (i = 1; i <= DisSysNumOfHXs; ++i) {
10752 : {
10753 2 : auto const SELECT_CASE_var(UtilityRoutines::MakeUPPERCase(DisSysCompHXData(i).EPlusType));
10754 :
10755 1 : if (SELECT_CASE_var == "HEATEXCHANGER:AIRTOAIR:FLATPLATE") {
10756 0 : ValidateComponent(
10757 0 : m_state, "HeatExchanger:AirToAir:FlatPlate", DisSysCompHXData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10758 0 : if (IsNotOK) {
10759 0 : ErrorsFound = true;
10760 : }
10761 :
10762 1 : } else if (SELECT_CASE_var == "HEATEXCHANGER:AIRTOAIR:SENSIBLEANDLATENT") {
10763 0 : ValidateComponent(m_state,
10764 : "HeatExchanger:AirToAir:SensibleAndLatent",
10765 0 : DisSysCompHXData(i).name,
10766 : IsNotOK,
10767 0 : format(RoutineName) + CurrentModuleObject);
10768 0 : if (IsNotOK) {
10769 0 : ErrorsFound = true;
10770 : }
10771 :
10772 1 : } else if (SELECT_CASE_var == "HEATEXCHANGER:DESICCANT:BALANCEDFLOW") {
10773 2 : ValidateComponent(m_state,
10774 : "HeatExchanger:Desiccant:BalancedFlow",
10775 1 : DisSysCompHXData(i).name,
10776 : IsNotOK,
10777 3 : format(RoutineName) + CurrentModuleObject);
10778 1 : if (IsNotOK) {
10779 0 : ErrorsFound = true;
10780 : }
10781 :
10782 : } else {
10783 0 : ShowSevereError(m_state,
10784 0 : format(RoutineName) + CurrentModuleObject + " Invalid heat exchanger type = " + DisSysCompHXData(i).EPlusType);
10785 0 : ErrorsFound = true;
10786 : }
10787 : }
10788 : }
10789 :
10790 : // Assign supply and return connection
10791 47 : for (j = 1; j <= NumPrimaryAirSys; ++j) {
10792 24 : S1 = 0;
10793 24 : S2 = 0;
10794 24 : R1 = 0;
10795 24 : R2 = 0;
10796 811 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
10797 787 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).AirLoopSupplyNodeNum(1)) S1 = i;
10798 787 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).ZoneEquipSupplyNodeNum(1)) S2 = i;
10799 787 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).ZoneEquipReturnNodeNum(1)) R1 = i;
10800 787 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).AirLoopReturnNodeNum(1)) R2 = i;
10801 : }
10802 1128 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
10803 1104 : if (AirflowNetworkLinkageData(i).NodeNums[0] == R1 && AirflowNetworkLinkageData(i).NodeNums[1] == R2) {
10804 16 : AirflowNetworkLinkageData(i).ConnectionFlag = iEPlusComponentType::RCN;
10805 : }
10806 1104 : if (AirflowNetworkLinkageData(i).NodeNums[0] == S1 && AirflowNetworkLinkageData(i).NodeNums[1] == S2) {
10807 24 : AirflowNetworkLinkageData(i).ConnectionFlag = iEPlusComponentType::SCN;
10808 : }
10809 : }
10810 : }
10811 :
10812 : // Assign fan inlet and outlet node, and coil outlet
10813 1053 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
10814 1030 : j = AirflowNetworkLinkageData(i).CompNum;
10815 1030 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::CVF) {
10816 24 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::Invalid)
10817 24 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum = iEPlusNodeType::FIN;
10818 24 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::FOU;
10819 : }
10820 1030 : if (AirflowNetworkCompData(j).EPlusTypeNum == iEPlusComponentType::COI) {
10821 57 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::COU;
10822 : }
10823 1030 : if (AirflowNetworkCompData(j).EPlusTypeNum == iEPlusComponentType::HEX) {
10824 2 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::HXO;
10825 : }
10826 1030 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::TMU) {
10827 27 : if (DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperInletNode > 0) {
10828 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum ==
10829 9 : DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperInletNode &&
10830 3 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum ==
10831 3 : DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperOutletNode) {
10832 3 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum = iEPlusNodeType::DIN;
10833 3 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::DOU;
10834 3 : AirflowNetworkLinkageData(i).VAVTermDamper = true;
10835 : }
10836 : }
10837 : }
10838 : }
10839 :
10840 : // Validate the position of constant pressure drop component
10841 23 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ConstantPressureDrop";
10842 1053 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
10843 1030 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::CPD) {
10844 741 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
10845 729 : if (AirflowNetworkLinkageData(i).NodeNums[0] == AirflowNetworkLinkageData(j).NodeNums[1]) {
10846 12 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(j).CompNum).CompTypeNum != iComponentTypeNum::DWC) {
10847 0 : ShowSevereError(m_state,
10848 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName +
10849 : ')');
10850 0 : ShowContinueError(m_state, "must connect a duct component upstream and not " + AirflowNetworkLinkageData(j).Name);
10851 0 : ErrorsFound = true;
10852 : }
10853 : }
10854 : }
10855 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::SPL) {
10856 0 : ShowSevereError(m_state,
10857 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10858 0 : ShowContinueError(m_state,
10859 0 : "does not allow a AirLoopHVAC:ZoneSplitter node = " +
10860 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10861 0 : ErrorsFound = true;
10862 : }
10863 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum == iEPlusNodeType::SPL) {
10864 0 : ShowSevereError(m_state,
10865 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10866 0 : ShowContinueError(m_state,
10867 0 : "does not allow a AirLoopHVAC:ZoneSplitter node = " +
10868 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10869 0 : ErrorsFound = true;
10870 : }
10871 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::MIX) {
10872 0 : ShowSevereError(m_state,
10873 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10874 0 : ShowContinueError(m_state,
10875 0 : "does not allow a AirLoopHVAC:ZoneMixer node = " +
10876 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10877 0 : ErrorsFound = true;
10878 : }
10879 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum == iEPlusNodeType::MIX) {
10880 0 : ShowSevereError(m_state,
10881 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10882 0 : ShowContinueError(m_state,
10883 0 : "does not allow a AirLoopHVAC:ZoneMixer node = " +
10884 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10885 0 : ErrorsFound = true;
10886 : }
10887 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
10888 0 : ShowSevereError(m_state,
10889 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10890 0 : ShowContinueError(m_state,
10891 0 : "does not allow to connect an EnergyPlus node = " +
10892 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10893 0 : ErrorsFound = true;
10894 : }
10895 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
10896 0 : ShowSevereError(m_state,
10897 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10898 0 : ShowContinueError(m_state,
10899 0 : "does not allow to connect an EnergyPlus node = " +
10900 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10901 0 : ErrorsFound = true;
10902 : }
10903 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) {
10904 0 : ShowSevereError(m_state,
10905 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10906 0 : ShowContinueError(m_state,
10907 0 : "does not allow to connect an EnergyPlus zone = " +
10908 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10909 0 : ErrorsFound = true;
10910 : }
10911 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) {
10912 0 : ShowSevereError(m_state,
10913 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10914 0 : ShowContinueError(m_state,
10915 0 : "does not allow to connect an EnergyPlus zone = " +
10916 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10917 0 : ErrorsFound = true;
10918 : }
10919 : }
10920 : }
10921 :
10922 551 : for (i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
10923 528 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::SPL) {
10924 24 : LocalError = false;
10925 24 : j = GetSplitterOutletNumber(m_state, "", 1, LocalError);
10926 24 : SplitterNodeNumbers.allocate(j + 2);
10927 24 : SplitterNodeNumbers = GetSplitterNodeNumbers(m_state, "", 1, LocalError);
10928 24 : if (LocalError) ErrorsFound = true;
10929 : }
10930 : }
10931 :
10932 : // Assigning inlet and outlet nodes for a splitter
10933 758 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
10934 735 : if (AirflowNetworkNodeData(i).EPlusNodeNum == SplitterNodeNumbers(1)) {
10935 23 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::Invalid) AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPI;
10936 : }
10937 2424 : for (j = 1; j <= SplitterNodeNumbers(2); ++j) {
10938 1689 : if (AirflowNetworkNodeData(i).EPlusNodeNum == SplitterNodeNumbers(j + 2)) {
10939 48 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::Invalid)
10940 45 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPO;
10941 : }
10942 : }
10943 : }
10944 :
10945 : // Add additional output variables
10946 23 : if (DisSysNumOfCVFs > 1) {
10947 1 : bool OnOffFanFlag = false;
10948 2 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
10949 2 : if (DisSysCompCVFData(i).FanTypeNum == FanType_SimpleOnOff && !DisSysCompCVFData(i).FanModelFlag) {
10950 1 : OnOffFanFlag = true;
10951 1 : break;
10952 : }
10953 1 : if (DisSysCompCVFData(i).FanModelFlag && DisSysCompCVFData(i).FanTypeNum == FanType_SimpleOnOff) {
10954 0 : int fanIndex = HVACFan::getFanObjectVectorIndex(m_state, DisSysCompCVFData(i).name);
10955 0 : if (m_state.dataHVACFan->fanObjs[fanIndex]->AirPathFlag) {
10956 0 : DisSysCompCVFData(i).FanTypeNum = FanType_SimpleConstVolume;
10957 : } else {
10958 0 : OnOffFanFlag = true;
10959 0 : break;
10960 : }
10961 : }
10962 : }
10963 1 : if (OnOffFanFlag) {
10964 6 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
10965 5 : if (!m_state.dataZoneEquip->ZoneEquipConfig(AirflowNetworkNodeData(j).EPlusZoneNum).IsControlled) continue;
10966 9 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
10967 9 : if (DisSysCompCVFData(i).AirLoopNum == AirflowNetworkNodeData(j).AirLoopNum &&
10968 3 : DisSysCompCVFData(i).FanTypeNum != FanType_SimpleOnOff) {
10969 8 : SetupOutputVariable(m_state,
10970 : "AFN Node Total Pressure",
10971 : OutputProcessor::Unit::Pa,
10972 2 : AirflowNetworkNodeSimu(j).PZ,
10973 : OutputProcessor::SOVTimeStepType::System,
10974 : OutputProcessor::SOVStoreType::Average,
10975 4 : AirflowNetworkNodeData(j).Name);
10976 : }
10977 : }
10978 : }
10979 22 : for (i = 1; i <= NumOfLinksMultiZone; ++i) {
10980 42 : if (!m_state.dataZoneEquip->ZoneEquipConfig(AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum)
10981 21 : .IsControlled)
10982 5 : continue;
10983 48 : for (j = 1; j <= DisSysNumOfCVFs; j++) {
10984 48 : if (DisSysCompCVFData(j).AirLoopNum == AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).AirLoopNum &&
10985 16 : DisSysCompCVFData(j).FanTypeNum != FanType_SimpleOnOff) {
10986 44 : SetupOutputVariable(m_state,
10987 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
10988 : OutputProcessor::Unit::kg_s,
10989 11 : linkReport(i).FLOW,
10990 : OutputProcessor::SOVTimeStepType::System,
10991 : OutputProcessor::SOVStoreType::Average,
10992 22 : AirflowNetworkLinkageData(i).Name);
10993 44 : SetupOutputVariable(m_state,
10994 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
10995 : OutputProcessor::Unit::kg_s,
10996 11 : linkReport(i).FLOW2,
10997 : OutputProcessor::SOVTimeStepType::System,
10998 : OutputProcessor::SOVStoreType::Average,
10999 22 : AirflowNetworkLinkageData(i).Name);
11000 44 : SetupOutputVariable(m_state,
11001 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
11002 : OutputProcessor::Unit::m3_s,
11003 11 : linkReport(i).VolFLOW,
11004 : OutputProcessor::SOVTimeStepType::System,
11005 : OutputProcessor::SOVStoreType::Average,
11006 22 : AirflowNetworkLinkageData(i).Name);
11007 44 : SetupOutputVariable(m_state,
11008 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
11009 : OutputProcessor::Unit::m3_s,
11010 11 : linkReport(i).VolFLOW2,
11011 : OutputProcessor::SOVTimeStepType::System,
11012 : OutputProcessor::SOVStoreType::Average,
11013 22 : AirflowNetworkLinkageData(i).Name);
11014 44 : SetupOutputVariable(m_state,
11015 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
11016 : OutputProcessor::Unit::Pa,
11017 11 : AirflowNetworkLinkSimu(i).DP,
11018 : OutputProcessor::SOVTimeStepType::System,
11019 : OutputProcessor::SOVStoreType::Average,
11020 22 : AirflowNetworkLinkageData(i).Name);
11021 : }
11022 : }
11023 : }
11024 : }
11025 : }
11026 23 : bool FanModelConstFlag = false;
11027 47 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
11028 24 : if (DisSysCompCVFData(i).FanModelFlag) {
11029 1 : int fanIndex = HVACFan::getFanObjectVectorIndex(m_state, DisSysCompCVFData(i).name);
11030 1 : if (DisSysCompCVFData(i).FanTypeNum == FanType_SimpleOnOff && m_state.dataHVACFan->fanObjs[fanIndex]->AirPathFlag) {
11031 0 : DisSysCompCVFData(i).FanTypeNum = FanType_SimpleConstVolume;
11032 0 : SupplyFanType = FanType_SimpleConstVolume;
11033 0 : FanModelConstFlag = true;
11034 0 : break;
11035 : }
11036 : }
11037 : }
11038 23 : if (FanModelConstFlag) {
11039 0 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
11040 0 : if (SupplyFanType == FanType_SimpleConstVolume) {
11041 0 : SetupOutputVariable(m_state,
11042 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
11043 : OutputProcessor::Unit::kg_s,
11044 0 : linkReport(i).FLOW,
11045 : OutputProcessor::SOVTimeStepType::System,
11046 : OutputProcessor::SOVStoreType::Average,
11047 0 : AirflowNetworkLinkageData(i).Name);
11048 0 : SetupOutputVariable(m_state,
11049 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
11050 : OutputProcessor::Unit::kg_s,
11051 0 : linkReport(i).FLOW2,
11052 : OutputProcessor::SOVTimeStepType::System,
11053 : OutputProcessor::SOVStoreType::Average,
11054 0 : AirflowNetworkLinkageData(i).Name);
11055 0 : SetupOutputVariable(m_state,
11056 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
11057 : OutputProcessor::Unit::m3_s,
11058 0 : linkReport(i).VolFLOW,
11059 : OutputProcessor::SOVTimeStepType::System,
11060 : OutputProcessor::SOVStoreType::Average,
11061 0 : AirflowNetworkLinkageData(i).Name);
11062 0 : SetupOutputVariable(m_state,
11063 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
11064 : OutputProcessor::Unit::m3_s,
11065 0 : linkReport(i).VolFLOW2,
11066 : OutputProcessor::SOVTimeStepType::System,
11067 : OutputProcessor::SOVStoreType::Average,
11068 0 : AirflowNetworkLinkageData(i).Name);
11069 0 : SetupOutputVariable(m_state,
11070 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
11071 : OutputProcessor::Unit::Pa,
11072 0 : AirflowNetworkLinkSimu(i).DP,
11073 : OutputProcessor::SOVTimeStepType::System,
11074 : OutputProcessor::SOVStoreType::Average,
11075 0 : AirflowNetworkLinkageData(i).Name);
11076 : }
11077 : }
11078 : }
11079 :
11080 : // Add AirLoopNum to pressure control object
11081 24 : for (i = 1; i <= NumOfPressureControllers; ++i) {
11082 5 : for (j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11083 4 : if (PressureControllerData(i).ZoneNum == j) {
11084 2 : for (k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumInletNodes; ++k) {
11085 1 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(k) > 0) {
11086 1 : PressureControllerData(i).AirLoopNum = m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(k);
11087 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlRelief) {
11088 1 : PressureControllerData(i).OANodeNum =
11089 1 : m_state.dataAirSystemsData->PrimaryAirSystems(PressureControllerData(i).AirLoopNum).OAMixOAInNodeNum;
11090 2 : for (n = 1; n <= NumOfReliefFans; ++n) {
11091 1 : if (DisSysCompReliefAirData(n).OutletNode == PressureControllerData(i).OANodeNum) {
11092 1 : DisSysCompReliefAirData(n).PressCtrlNum = i;
11093 : }
11094 : }
11095 : }
11096 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlExhaust) {
11097 0 : PressureControllerData(i).OANodeNum =
11098 0 : m_state.dataZoneEquip->ZoneEquipConfig(PressureControllerData(i).ZoneNum).ExhaustNode(1);
11099 0 : for (n = 1; n <= AirflowNetworkNumOfExhFan; ++n) {
11100 0 : if (MultizoneCompExhaustFanData(n).EPlusZoneNum == PressureControllerData(i).ZoneNum) {
11101 0 : MultizoneCompExhaustFanData(n).PressCtrlNum = i;
11102 : }
11103 : }
11104 : }
11105 : }
11106 : }
11107 : }
11108 : }
11109 : }
11110 :
11111 : // Check number of fans specified in an AirLoop #6748
11112 : int BranchNum;
11113 : int CompNum;
11114 : int NumOfFans;
11115 46 : std::string FanNames;
11116 46 : for (BranchNum = 1; BranchNum <= m_state.dataAirSystemsData->PrimaryAirSystems(1).NumBranches; ++BranchNum) {
11117 23 : NumOfFans = 0;
11118 23 : FanNames = "";
11119 87 : for (CompNum = 1; CompNum <= m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).TotalComponents; ++CompNum) {
11120 128 : if (UtilityRoutines::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf,
11121 115 : "Fan:ConstantVolume") ||
11122 115 : UtilityRoutines::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf,
11123 115 : "Fan:OnOff") ||
11124 115 : UtilityRoutines::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf,
11125 51 : "Fan:VariableVolume")) {
11126 14 : NumOfFans++;
11127 14 : if (NumOfFans > 1) {
11128 0 : FanNames += m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).Name;
11129 0 : break;
11130 : } else {
11131 14 : FanNames += m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).Name + ",";
11132 : }
11133 : }
11134 : }
11135 23 : if (NumOfFans > 1) break;
11136 : }
11137 23 : if (NumOfFans > 1) {
11138 0 : ShowSevereError(m_state,
11139 0 : format(RoutineName) + "An AirLoop branch, " + m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Name +
11140 0 : ", has two or more fans: " + FanNames);
11141 0 : ShowContinueError(m_state,
11142 : "The AirflowNetwork model allows a single supply fan in an AirLoop only. Please make changes in the input "
11143 : "file accordingly.");
11144 0 : ErrorsFound = true;
11145 : }
11146 :
11147 23 : if (ErrorsFound) {
11148 0 : ShowFatalError(m_state, format("{}Program terminates for preceding reason(s).", RoutineName));
11149 : }
11150 23 : }
11151 :
11152 23 : void Solver::validate_fan_flowrate()
11153 : {
11154 :
11155 : // Catch a fan flow rate from EPlus input file and add a flag for VAV terminal damper
11156 1053 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
11157 1030 : switch (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum) {
11158 24 : case iComponentTypeNum::CVF: { // 'CVF'
11159 24 : int typeNum = AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum;
11160 24 : if (DisSysCompCVFData(typeNum).FanTypeNum == FanType_SimpleVAV) {
11161 1 : if (DisSysCompCVFData(typeNum).FanModelFlag) {
11162 0 : DisSysCompCVFData(typeNum).MaxAirMassFlowRate =
11163 0 : m_state.dataHVACFan->fanObjs[DisSysCompCVFData(typeNum).FanIndex]->designAirVolFlowRate * m_state.dataEnvrn->StdRhoAir;
11164 : } else {
11165 : Real64 FanFlow; // Return type
11166 1 : GetFanVolFlow(m_state, DisSysCompCVFData(typeNum).FanIndex, FanFlow);
11167 1 : DisSysCompCVFData(typeNum).MaxAirMassFlowRate = FanFlow * m_state.dataEnvrn->StdRhoAir;
11168 : }
11169 : }
11170 24 : } break;
11171 42 : case iComponentTypeNum::FAN:
11172 : case iComponentTypeNum::SOP:
11173 : case iComponentTypeNum::TMU:
11174 42 : break;
11175 964 : default:
11176 964 : break;
11177 : }
11178 : }
11179 23 : }
11180 :
11181 656869 : void Solver::validate_exhaust_fan_input()
11182 : {
11183 :
11184 : // SUBROUTINE INFORMATION:
11185 : // AUTHOR Lixing Gu
11186 : // DATE WRITTEN Dec. 2006
11187 : // MODIFIED na
11188 : // RE-ENGINEERED na
11189 :
11190 : // PURPOSE OF THIS SUBROUTINE:
11191 : // This subroutine validate zone exhaust fan and associated surface
11192 :
11193 : // SUBROUTINE PARAMETER DEFINITIONS:
11194 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::validate_exhaust_fan_input: "); // include trailing blank space
11195 :
11196 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11197 : int i;
11198 : int j;
11199 : int k;
11200 656869 : bool ErrorsFound(false);
11201 : bool found;
11202 : int EquipTypeNum; // Equipment type number
11203 1313738 : std::string CurrentModuleObject;
11204 :
11205 : // Validate supply and return connections
11206 656869 : if (ValidateExhaustFanInputOneTimeFlag) {
11207 34 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:ZoneExhaustFan";
11208 34 : if (std::any_of(m_state.dataZoneEquip->ZoneEquipConfig.begin(),
11209 34 : m_state.dataZoneEquip->ZoneEquipConfig.end(),
11210 51 : [](DataZoneEquipment::EquipConfiguration const &e) { return e.IsControlled; })) {
11211 25 : AirflowNetworkZoneExhaustFan.dimension(m_state.dataGlobal->NumOfZones, false);
11212 : }
11213 : // Ensure the number of exhaust fan defined in the AirflowNetwork model matches the number of Zone Exhaust Fan objects
11214 34 : if (NumOfExhaustFans != AirflowNetworkNumOfExhFan) {
11215 0 : ShowSevereError(
11216 : m_state,
11217 0 : format("{}The number of {} is not equal to the number of Fan:ZoneExhaust fans defined in ZoneHVAC:EquipmentConnections",
11218 : RoutineName,
11219 0 : CurrentModuleObject));
11220 0 : ShowContinueError(m_state, format("The number of {} is {}", CurrentModuleObject, AirflowNetworkNumOfExhFan));
11221 0 : ShowContinueError(m_state,
11222 0 : format("The number of Zone exhaust fans defined in ZoneHVAC:EquipmentConnections is {}", NumOfExhaustFans));
11223 0 : ErrorsFound = true;
11224 : }
11225 :
11226 48 : for (i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
11227 : // Get zone number
11228 66 : for (j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11229 52 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) continue;
11230 39 : for (k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumExhaustNodes; ++k) {
11231 15 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).ExhaustNode(k) == MultizoneCompExhaustFanData(i).InletNode) {
11232 14 : MultizoneCompExhaustFanData(i).EPlusZoneNum = j;
11233 14 : break;
11234 : }
11235 : }
11236 : }
11237 14 : if (MultizoneCompExhaustFanData(i).EPlusZoneNum == 0) {
11238 0 : ShowSevereError(m_state,
11239 0 : format("{}Zone name in {} = {} does not match the zone name in ZoneHVAC:EquipmentConnections",
11240 : RoutineName,
11241 : CurrentModuleObject,
11242 0 : MultizoneCompExhaustFanData(i).name));
11243 0 : ErrorsFound = true;
11244 : }
11245 : // Ensure a surface using zone exhaust fan to expose to the same zone
11246 14 : found = false;
11247 220 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
11248 220 : if (UtilityRoutines::SameString(MultizoneSurfaceData(j).OpeningName, MultizoneCompExhaustFanData(i).name)) {
11249 14 : found = true;
11250 14 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond != ExternalEnvironment &&
11251 0 : !(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
11252 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
11253 0 : ShowSevereError(m_state,
11254 0 : format("{}The surface using {} is not an exterior surface: {}",
11255 : RoutineName,
11256 : CurrentModuleObject,
11257 0 : MultizoneSurfaceData(j).SurfName));
11258 0 : ErrorsFound = true;
11259 : }
11260 14 : break;
11261 : }
11262 : }
11263 14 : if (!found) {
11264 0 : ShowSevereError(m_state, CurrentModuleObject + " = " + MultizoneCompExhaustFanData(i).name + " is defined and never used.");
11265 0 : ErrorsFound = true;
11266 : } else {
11267 14 : if (MultizoneCompExhaustFanData(i).EPlusZoneNum != m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Zone) {
11268 0 : ShowSevereError(m_state,
11269 0 : format("{}Zone name in {} = {} does not match the zone name",
11270 : RoutineName,
11271 : CurrentModuleObject,
11272 0 : MultizoneCompExhaustFanData(i).name));
11273 0 : ShowContinueError(m_state, "the surface is exposed to " + m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Name);
11274 0 : ErrorsFound = true;
11275 : } else {
11276 14 : AirflowNetworkZoneExhaustFan(MultizoneCompExhaustFanData(i).EPlusZoneNum) = true;
11277 : }
11278 : }
11279 : }
11280 :
11281 : // Ensure all zone exhaust fans are defined
11282 146 : for (j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11283 112 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) continue;
11284 125 : for (EquipTypeNum = 1; EquipTypeNum <= m_state.dataZoneEquip->ZoneEquipList(j).NumOfEquipTypes; ++EquipTypeNum) {
11285 72 : if (m_state.dataZoneEquip->ZoneEquipList(j).EquipTypeEnum(EquipTypeNum) == DataZoneEquipment::ZoneEquip::ZoneExhaustFan) {
11286 14 : found = false;
11287 31 : for (k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumExhaustNodes; ++k) {
11288 34 : for (i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
11289 17 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).ExhaustNode(k) == MultizoneCompExhaustFanData(i).InletNode) {
11290 14 : MultizoneCompExhaustFanData(i).EPlusZoneNum = j;
11291 14 : found = true;
11292 : }
11293 : }
11294 17 : if (!found) {
11295 0 : ShowSevereError(m_state, format("{}Fan:ZoneExhaust is not defined in {}", RoutineName, CurrentModuleObject));
11296 0 : ShowContinueError(m_state,
11297 0 : "Zone Air Exhaust Node in ZoneHVAC:EquipmentConnections =" +
11298 0 : m_state.dataLoopNodes->NodeID(m_state.dataZoneEquip->ZoneEquipConfig(j).ExhaustNode(k)));
11299 0 : ErrorsFound = true;
11300 : }
11301 : }
11302 : }
11303 : }
11304 : }
11305 :
11306 34 : ValidateExhaustFanInputOneTimeFlag = false;
11307 34 : if (ErrorsFound) {
11308 0 : ShowFatalError(m_state, format("{}Program terminates for preceding reason(s).", RoutineName));
11309 : }
11310 : } // End if OneTimeFlag_FindFirstLastPtr
11311 656869 : }
11312 :
11313 82448 : void Solver::hybrid_ventilation_control()
11314 : {
11315 :
11316 : // SUBROUTINE INFORMATION:
11317 : // AUTHOR Lixing Gu
11318 : // DATE WRITTEN Dec. 2006
11319 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone hybrid ventilation managers
11320 :
11321 : // PURPOSE OF THIS SUBROUTINE:
11322 : // This subroutine performs hybrid ventilation control
11323 :
11324 82448 : auto &HybridVentSysAvailActualZoneNum = m_state.dataHVACGlobal->HybridVentSysAvailActualZoneNum;
11325 82448 : auto &HybridVentSysAvailAirLoopNum = m_state.dataHVACGlobal->HybridVentSysAvailAirLoopNum;
11326 82448 : auto &HybridVentSysAvailANCtrlStatus = m_state.dataHVACGlobal->HybridVentSysAvailANCtrlStatus;
11327 82448 : auto &HybridVentSysAvailMaster = m_state.dataHVACGlobal->HybridVentSysAvailMaster;
11328 82448 : auto &HybridVentSysAvailVentCtrl = m_state.dataHVACGlobal->HybridVentSysAvailVentCtrl;
11329 82448 : auto &HybridVentSysAvailWindModifier = m_state.dataHVACGlobal->HybridVentSysAvailWindModifier;
11330 82448 : auto &NumHybridVentSysAvailMgrs = m_state.dataHVACGlobal->NumHybridVentSysAvailMgrs;
11331 :
11332 : // SUBROUTINE PARAMETER DEFINITIONS:
11333 82448 : int constexpr HybridVentCtrl_Close(2); // Open windows or doors
11334 82448 : int constexpr IndividualCtrlType(0); // Individual window or door control
11335 82448 : int constexpr GlobalCtrlType(1); // Global window or door control
11336 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::hybrid_ventilation_control: "); // include trailing blank space
11337 :
11338 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11339 : int SysAvailNum; // Hybrid ventilation control number
11340 : int AirLoopNum; // Airloop number
11341 : int ControlledZoneNum; // Controlled zone number
11342 : int ANSurfaceNum; // AirflowNetwork Surface Number
11343 : int SurfNum; // Surface number
11344 : int ControlType; // Hybrid ventilation control type: 0 individual; 1 global
11345 : bool Found; // Logical to indicate whether a master surface is found or not
11346 :
11347 1779704 : for (auto &e : MultizoneSurfaceData) {
11348 1697256 : e.HybridVentClose = false;
11349 1697256 : e.HybridCtrlGlobal = false;
11350 1697256 : e.HybridCtrlMaster = false;
11351 1697256 : e.WindModifier = 1.0;
11352 : }
11353 82448 : ControlType = IndividualCtrlType;
11354 :
11355 180517 : for (SysAvailNum = 1; SysAvailNum <= NumHybridVentSysAvailMgrs; ++SysAvailNum) {
11356 98069 : AirLoopNum = HybridVentSysAvailAirLoopNum(SysAvailNum);
11357 98069 : VentilationCtrl = HybridVentSysAvailVentCtrl(SysAvailNum);
11358 98069 : if (HybridVentSysAvailANCtrlStatus(SysAvailNum) > 0) {
11359 41869 : ControlType = static_cast<int>(GetCurrentScheduleValue(m_state, HybridVentSysAvailANCtrlStatus(SysAvailNum)));
11360 : }
11361 98069 : Found = false;
11362 98069 : int ActualZoneNum = 0;
11363 490345 : for (ControlledZoneNum = 1; ControlledZoneNum <= m_state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
11364 392276 : if (!m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).IsControlled) continue;
11365 : // Ensure all the zones served by this AirLoopHVAC to be controlled by the hybrid ventilation
11366 356708 : for (int zoneInNode = 1; zoneInNode <= m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
11367 294207 : if (AirLoopNum > 0) {
11368 247347 : if (AirLoopNum == m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode)) {
11369 231706 : ActualZoneNum = ControlledZoneNum;
11370 231706 : break;
11371 : }
11372 : } else {
11373 46860 : if (HybridVentSysAvailActualZoneNum(SysAvailNum) == ControlledZoneNum) {
11374 15620 : ActualZoneNum = HybridVentSysAvailActualZoneNum(SysAvailNum);
11375 : }
11376 : }
11377 : }
11378 294207 : if (ActualZoneNum > 0) {
11379 6025996 : for (ANSurfaceNum = 1; ANSurfaceNum <= AirflowNetworkNumOfSurfaces; ++ANSurfaceNum) {
11380 5747430 : SurfNum = MultizoneSurfaceData(ANSurfaceNum).SurfNum;
11381 5747430 : if (m_state.dataSurface->Surface(SurfNum).Zone == ActualZoneNum) {
11382 1699724 : if (VentilationCtrl == HybridVentCtrl_Close) {
11383 865838 : MultizoneSurfaceData(ANSurfaceNum).HybridVentClose = true;
11384 : } else {
11385 833886 : if (HybridVentSysAvailWindModifier(SysAvailNum) >= 0) {
11386 156892 : MultizoneSurfaceData(ANSurfaceNum).WindModifier = HybridVentSysAvailWindModifier(SysAvailNum);
11387 : }
11388 833886 : if (ControlType == GlobalCtrlType) {
11389 229552 : MultizoneSurfaceData(ANSurfaceNum).HybridCtrlGlobal = true;
11390 229552 : if (HybridVentSysAvailMaster(SysAvailNum) == ActualZoneNum) {
11391 545993 : if ((m_state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::Window ||
11392 288692 : m_state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::Door ||
11393 381256 : m_state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::GlassDoor) &&
11394 66673 : m_state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment) {
11395 25891 : MultizoneSurfaceData(ANSurfaceNum).HybridCtrlMaster = true;
11396 25891 : Found = true;
11397 : }
11398 : }
11399 : }
11400 : }
11401 : }
11402 : }
11403 : }
11404 : }
11405 98069 : if (ControlType == GlobalCtrlType && !Found && !m_state.dataGlobal->WarmupFlag && VentilationCtrl != HybridVentCtrl_Close) {
11406 0 : ++HybridGlobalErrCount;
11407 0 : if (HybridGlobalErrCount < 2) {
11408 0 : ShowWarningError(m_state,
11409 0 : format("{}The hybrid ventilation control schedule value indicates global control in the controlled zone = {}",
11410 : RoutineName,
11411 0 : m_state.dataHeatBal->Zone(HybridVentSysAvailMaster(SysAvailNum)).Name));
11412 0 : ShowContinueError(m_state,
11413 : "The exterior surface containing an opening component in the controlled zone is not found. No global control "
11414 : "will not be modeled.");
11415 0 : ShowContinueError(m_state, "The individual control is assumed.");
11416 0 : ShowContinueErrorTimeStamp(m_state, "");
11417 : } else {
11418 0 : ShowRecurringWarningErrorAtEnd(
11419 : m_state,
11420 0 : format("{}The hybrid ventilation control requires a global control. The individual control continues...", RoutineName),
11421 : HybridGlobalErrIndex,
11422 0 : double(ControlType),
11423 0 : double(ControlType));
11424 : }
11425 : }
11426 : }
11427 82448 : }
11428 :
11429 1 : void Solver::single_sided_Cps(std::vector<std::vector<Real64>> &valsByFacade, int numWindDir)
11430 : {
11431 : // SUBROUTINE INFORMATION:
11432 : // AUTHOR Sam Brunswick
11433 : // DATE WRITTEN September 2013
11434 : // MODIFIED Revised by J. DeGraw, May 2017, to use tables
11435 : // RE-ENGINEERED n/a
11436 :
11437 : // PURPOSE OF THIS SUBROUTINE:
11438 : // Modify the wind pressure coefficients for single sided ventilation.
11439 :
11440 : // Using/Aliasing
11441 : using namespace DataEnvironment;
11442 :
11443 : // Locals
11444 : int windDirNum;
11445 :
11446 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11447 : int AFNZnNum; // counters
11448 : int SrfNum;
11449 : int ExtOpenNum;
11450 : int ZnNum;
11451 : int DetOpenNum; // row index of surface in MultizoneCompDetOpeningData
11452 : int SimOpenNum; // row index of surface in MultizoneCompSimOpeningData
11453 : int MZDZoneNum; // row index of surface zone in MultizoneZoneData
11454 : Real64 X1;
11455 : Real64 Y1;
11456 : Real64 X2;
11457 : Real64 Y2;
11458 : Real64 ZoneAng1;
11459 : Real64 ZoneAng2;
11460 : Real64 ZoneAngDiff;
11461 2 : Array1D<Real64> ZoneAng; // Azimuth angle of the exterior wall of the zone
11462 2 : Array1D<Real64> PiFormula; // Formula for the mean pressure difference
11463 2 : Array1D<Real64> SigmaFormula; // Formula for the fluctuating pressure difference
11464 2 : Array1D<Real64> Sprime; // The dimensionless ratio of the window separation to the building width
11465 2 : Array1D<Real64> CPV1; // Wind pressure coefficient for the first opening in the zone
11466 2 : Array1D<Real64> CPV2; // Wind pressure coefficient for the second opening in the zone
11467 2 : std::string Name; // External node name
11468 2 : Array1D_int NumofExtSurfInZone; // List of the number of exterior openings in each zone
11469 :
11470 13 : struct AFNExtSurfacesProp // External opening information
11471 : {
11472 : // Members
11473 : int SurfNum; // row index of the external opening in the Surface array
11474 : std::string SurfName; // Surface name
11475 : int MSDNum; // row index of the external opening in the MultizoneSurfaceData array
11476 : int ZoneNum; // EnergyPlus zone number
11477 : int MZDZoneNum; // row index of the zone in the MultizoneZoneData array
11478 : int ExtNodeNum; // External node number; = row index in MultizoneExternalNodeData array +
11479 : // AirflowNetworkNumOfZones
11480 : std::string ZoneName; // EnergyPlus zone name
11481 : int facadeNum;
11482 : int curve; // wind pressure coefficient curve index
11483 : iComponentTypeNum CompTypeNum; // Opening type (detailed, simple, etc.)
11484 : Real64 NodeHeight; // Elevation of the opening node
11485 : Real64 OpeningArea; // Opening area (=Height*Width)
11486 : Real64 Height; // Opening height = MultizoneSurfaceData()%Height
11487 : Real64 Width; // Opening width = MultizoneSurfaceData()%Width
11488 : Real64 DischCoeff; // Opening discharge coefficient
11489 :
11490 : // Default Constructor
11491 1 : AFNExtSurfacesProp()
11492 1 : : SurfNum(0), MSDNum(0), ZoneNum(0), MZDZoneNum(0), ExtNodeNum(0), facadeNum(0), curve(0), CompTypeNum(iComponentTypeNum::Invalid),
11493 1 : NodeHeight(0.0), OpeningArea(0.0), Height(0.0), Width(0.0), DischCoeff(0.0)
11494 : {
11495 1 : }
11496 : };
11497 :
11498 : // Object Data
11499 2 : Array1D<AFNExtSurfacesProp> AFNExtSurfaces; // Surface numbers of all exterior openings
11500 : // Count the total number of exterior simple and detailed openings and the number in each zone
11501 : // Verify that each zone with "ADVANCED" single sided wind pressure coefficients has exactly two openings.
11502 : // If it doesn't have two openings, change "ADVANCED" to "STANDARD"
11503 1 : NumofExtSurfInZone.dimension(AirflowNetworkNumOfZones, 0);
11504 5 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
11505 4 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
11506 45 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11507 42 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond ==
11508 : ExternalEnvironment) { // check if outdoor boundary condition
11509 42 : MZDZoneNum = UtilityRoutines::FindItemInList(m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName,
11510 : MultizoneZoneData,
11511 : &MultizoneZoneProp::ZoneName);
11512 42 : if (MZDZoneNum == AFNZnNum) {
11513 : // This is terrible, should not do it this way
11514 18 : auto afe = elements.find(MultizoneSurfaceData(SrfNum).OpeningName);
11515 9 : if (afe != elements.end()) {
11516 9 : auto type = afe->second->type();
11517 9 : if (type == ComponentType::DOP) {
11518 6 : ++AFNNumOfExtOpenings;
11519 6 : ++NumofExtSurfInZone(AFNZnNum);
11520 3 : } else if (type == ComponentType::SOP) {
11521 0 : ++AFNNumOfExtOpenings;
11522 0 : ++NumofExtSurfInZone(AFNZnNum);
11523 : }
11524 : }
11525 : }
11526 : }
11527 : }
11528 3 : if (NumofExtSurfInZone(AFNZnNum) == 0) {
11529 0 : ShowWarningError(m_state,
11530 0 : "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName +
11531 : " has single side wind pressure coefficient type \"ADVANCED\", but has no exterior "
11532 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or AirflowNetwork:MultiZone:Component:SimpleOpening "
11533 : "objects.");
11534 0 : ShowContinueError(m_state,
11535 : "Zones must have exactly two exterior openings in order for the \"ADVANCED\" single sided wind pressure "
11536 : "coefficient model to be used.");
11537 0 : ShowContinueError(m_state,
11538 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11539 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11540 3 : } else if (NumofExtSurfInZone(AFNZnNum) == 1) {
11541 0 : ShowWarningError(m_state, "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName);
11542 0 : ShowContinueError(m_state,
11543 : "has single side wind pressure coefficient type \"ADVANCED\", but has only one exterior "
11544 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or "
11545 : "AirflowNetwork:MultiZone:Component:SimpleOpening objects.");
11546 0 : ShowContinueError(m_state,
11547 : "Zones must have exactly two openings in order for the \"ADVANCED\" single side wind pressure coefficient "
11548 : "model to be used.");
11549 0 : ShowContinueError(m_state,
11550 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11551 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11552 3 : } else if (NumofExtSurfInZone(AFNZnNum) > 2) {
11553 0 : ShowWarningError(m_state,
11554 0 : format("AirflowNetwork:Multizone:Zone = {} has single side wind pressure coefficient type "
11555 : "\"ADVANCED\", but has {} exterior "
11556 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or "
11557 : "AirflowNetwork:MultiZone:Component:SimpleOpening objects.",
11558 0 : MultizoneZoneData(AFNZnNum).ZoneName,
11559 0 : NumofExtSurfInZone(AFNZnNum)));
11560 0 : ShowContinueError(m_state,
11561 : "Zones must have exactly two openings in order for the \"ADVANCED\" single side wind pressure coefficient "
11562 : "model to be used.");
11563 0 : ShowContinueError(m_state,
11564 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11565 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11566 : }
11567 : }
11568 : }
11569 1 : if (AFNNumOfExtOpenings == 0) return;
11570 : // Recount the number of single sided zones
11571 1 : AirflowNetworkNumOfSingleSideZones = 0;
11572 5 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
11573 4 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
11574 3 : ++AirflowNetworkNumOfSingleSideZones;
11575 : }
11576 : }
11577 1 : if (AirflowNetworkNumOfSingleSideZones == 0) return; // Bail if no zones call for the advanced single sided model.
11578 : // Recount the number of detailed and simple exterior openings in zones with "ADVANCED" single sided wind pressure coefficients
11579 1 : AFNNumOfExtOpenings = 0;
11580 15 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11581 28 : MZDZoneNum = UtilityRoutines::FindItemInList(
11582 14 : m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11583 14 : if (MultizoneZoneData(MZDZoneNum).SingleSidedCpType == "ADVANCED") {
11584 9 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond ==
11585 : ExternalEnvironment) { // check if outdoor boundary condition
11586 : // This is terrible, should not do it this way
11587 18 : auto afe = elements.find(MultizoneSurfaceData(SrfNum).OpeningName);
11588 9 : if (afe != elements.end()) {
11589 9 : auto type = afe->second->type();
11590 9 : if (type == ComponentType::DOP) {
11591 6 : ++AFNNumOfExtOpenings;
11592 3 : } else if (type == ComponentType::SOP) {
11593 0 : ++AFNNumOfExtOpenings;
11594 : }
11595 : }
11596 : }
11597 : }
11598 : }
11599 1 : AFNExtSurfaces.allocate(AFNNumOfExtOpenings);
11600 : // Create array of properties for all the exterior single sided openings
11601 1 : ExtOpenNum = 1;
11602 15 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11603 14 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond == ExternalEnvironment) {
11604 14 : if (AirflowNetworkNumOfDetOpenings > 0) {
11605 28 : DetOpenNum = UtilityRoutines::FindItemInList(
11606 14 : MultizoneSurfaceData(SrfNum).OpeningName, MultizoneCompDetOpeningData, &AirflowNetwork::DetailedOpening::name);
11607 28 : MZDZoneNum = UtilityRoutines::FindItemInList(
11608 14 : m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11609 14 : if (MultizoneZoneData(MZDZoneNum).SingleSidedCpType == "ADVANCED") {
11610 9 : if (DetOpenNum > 0) {
11611 6 : AFNExtSurfaces(ExtOpenNum).MSDNum = SrfNum;
11612 6 : AFNExtSurfaces(ExtOpenNum).SurfNum = MultizoneSurfaceData(SrfNum).SurfNum;
11613 6 : AFNExtSurfaces(ExtOpenNum).NodeHeight = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.z;
11614 6 : AFNExtSurfaces(ExtOpenNum).SurfName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Name;
11615 6 : AFNExtSurfaces(ExtOpenNum).ZoneNum = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Zone;
11616 6 : AFNExtSurfaces(ExtOpenNum).ZoneName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName;
11617 6 : AFNExtSurfaces(ExtOpenNum).MZDZoneNum =
11618 6 : UtilityRoutines::FindItemInList(AFNExtSurfaces(ExtOpenNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11619 6 : AFNExtSurfaces(ExtOpenNum).CompTypeNum = iComponentTypeNum::DOP;
11620 6 : AFNExtSurfaces(ExtOpenNum).Height = MultizoneSurfaceData(SrfNum).Height;
11621 6 : AFNExtSurfaces(ExtOpenNum).Width = MultizoneSurfaceData(SrfNum).Width;
11622 6 : AFNExtSurfaces(ExtOpenNum).OpeningArea =
11623 6 : MultizoneSurfaceData(SrfNum).Width * MultizoneSurfaceData(SrfNum).Height * MultizoneSurfaceData(SrfNum).OpenFactor;
11624 6 : AFNExtSurfaces(ExtOpenNum).ExtNodeNum = MultizoneSurfaceData(ExtOpenNum).NodeNums[1];
11625 6 : AFNExtSurfaces(ExtOpenNum).facadeNum =
11626 6 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum;
11627 6 : AFNExtSurfaces(ExtOpenNum).curve =
11628 6 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).curve;
11629 6 : AFNExtSurfaces(ExtOpenNum).DischCoeff = MultizoneCompDetOpeningData(DetOpenNum).DischCoeff2;
11630 6 : ++ExtOpenNum;
11631 : }
11632 : }
11633 0 : } else if (AirflowNetworkNumOfSimOpenings > 0) {
11634 0 : SimOpenNum = UtilityRoutines::FindItemInList(
11635 0 : MultizoneSurfaceData(SrfNum).OpeningName, MultizoneCompSimpleOpeningData, &AirflowNetwork::SimpleOpening::name);
11636 0 : if (SimOpenNum > 0) {
11637 0 : AFNExtSurfaces(ExtOpenNum).MSDNum = SrfNum;
11638 0 : AFNExtSurfaces(ExtOpenNum).SurfNum = MultizoneSurfaceData(SrfNum).SurfNum;
11639 0 : AFNExtSurfaces(ExtOpenNum).SurfName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Name;
11640 0 : AFNExtSurfaces(ExtOpenNum).ZoneNum = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Zone;
11641 0 : AFNExtSurfaces(ExtOpenNum).ZoneName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName;
11642 0 : AFNExtSurfaces(ExtOpenNum).MZDZoneNum =
11643 0 : UtilityRoutines::FindItemInList(AFNExtSurfaces(ExtOpenNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11644 0 : AFNExtSurfaces(ExtOpenNum).CompTypeNum = iComponentTypeNum::SOP;
11645 0 : AFNExtSurfaces(ExtOpenNum).Height = MultizoneSurfaceData(SrfNum).Height;
11646 0 : AFNExtSurfaces(ExtOpenNum).Width = MultizoneSurfaceData(SrfNum).Width;
11647 0 : AFNExtSurfaces(ExtOpenNum).OpeningArea =
11648 0 : MultizoneSurfaceData(SrfNum).Width * MultizoneSurfaceData(SrfNum).Height * MultizoneSurfaceData(SrfNum).OpenFactor;
11649 0 : AFNExtSurfaces(ExtOpenNum).ExtNodeNum = MultizoneSurfaceData(ExtOpenNum).NodeNums[1];
11650 0 : AFNExtSurfaces(ExtOpenNum).curve =
11651 0 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).curve;
11652 0 : AFNExtSurfaces(ExtOpenNum).DischCoeff = MultizoneCompSimpleOpeningData(SimOpenNum).DischCoeff;
11653 0 : ++ExtOpenNum;
11654 : }
11655 : }
11656 : }
11657 : }
11658 : // Calculate the azimuth and the coordinates of the centroid of each opening.
11659 : // Calculate Sprime and DeltaCp for each zone.
11660 1 : PiFormula.allocate(numWindDir);
11661 1 : SigmaFormula.allocate(numWindDir);
11662 1 : DeltaCp.allocate(AirflowNetworkNumOfZones);
11663 1 : EPDeltaCP.allocate(AirflowNetworkNumOfZones);
11664 1 : Sprime.allocate(AirflowNetworkNumOfZones);
11665 1 : ZoneAng.allocate(AirflowNetworkNumOfZones);
11666 5 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11667 4 : DeltaCp(ZnNum).WindDir.allocate(numWindDir);
11668 4 : EPDeltaCP(ZnNum).WindDir.allocate(numWindDir);
11669 148 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11670 144 : DeltaCp(ZnNum).WindDir(windDirNum) = 0.0;
11671 144 : EPDeltaCP(ZnNum).WindDir(windDirNum) = 0.0;
11672 : }
11673 : }
11674 1 : Sprime = 0.0;
11675 1 : ZoneAng = 0.0;
11676 5 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11677 4 : if (MultizoneZoneData(ZnNum).SingleSidedCpType == "ADVANCED") {
11678 3 : OpenNuminZone = 1;
11679 15 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11680 14 : if (OpenNuminZone > 2) break; // Tuned
11681 12 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11682 6 : if (OpenNuminZone == 1) {
11683 3 : X1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.x;
11684 3 : Y1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.y;
11685 3 : ZoneAng1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Azimuth;
11686 3 : ++OpenNuminZone;
11687 3 : } else if (OpenNuminZone == 2) {
11688 3 : X2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.x;
11689 3 : Y2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.y;
11690 3 : ZoneAng2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Azimuth;
11691 3 : ++OpenNuminZone;
11692 : }
11693 : }
11694 : }
11695 3 : ZoneAngDiff = ZoneAng1 - ZoneAng2;
11696 3 : if (ZoneAngDiff > 0.01) {
11697 0 : ShowWarningError(m_state,
11698 0 : "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName +
11699 : " has single side wind pressure coefficient type \"ADVANCED\", but has openings which are not coplanar.");
11700 0 : ShowContinueError(m_state, "The openings should be coplanar for the model to be valid. Simulation Continues.");
11701 : }
11702 3 : ZoneAng(ZnNum) = ZoneAng1;
11703 3 : Sprime(ZnNum) = std::sqrt(pow_2(X1 - X2) + pow_2(Y1 - Y2)) / MultizoneZoneData(ZnNum).BuildWidth;
11704 : // Calculate DeltaCp for each wind direction for each zone
11705 111 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11706 108 : m_state.dataEnvrn->WindDir = (windDirNum - 1) * 10.0;
11707 108 : Real64 WindAng = (windDirNum - 1) * 10.0;
11708 108 : IncAng = std::abs(WindAng - ZoneAng(ZnNum));
11709 108 : if (std::abs(IncAng) > 180.0) IncAng -= 360.0;
11710 108 : if (UtilityRoutines::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
11711 108 : if (std::abs(IncAng) <= 67.5) {
11712 39 : PiFormula(windDirNum) = 0.44 * sign(std::sin(2.67 * std::abs(IncAng) * DataGlobalConstants::Pi / 180.0), IncAng);
11713 69 : } else if (std::abs(IncAng) <= 180.0) {
11714 69 : PiFormula(windDirNum) = -0.69 * sign(std::sin((288 - 1.6 * std::abs(IncAng)) * DataGlobalConstants::Pi / 180.0), IncAng);
11715 : }
11716 108 : SigmaFormula(windDirNum) = 0.423 - 0.00163 * std::abs(IncAng);
11717 108 : DeltaCp(ZnNum).WindDir(windDirNum) =
11718 108 : (0.02 + (0.346 * std::abs(PiFormula(windDirNum)) + 0.084 * SigmaFormula(windDirNum)) * Sprime(ZnNum));
11719 : }
11720 : }
11721 : }
11722 : }
11723 :
11724 : // Calculate the single sided Cp arrays from DeltaCp for each single sided opening
11725 1 : CPV1.allocate(numWindDir); // These two arrays should probably be removed
11726 1 : CPV2.allocate(numWindDir);
11727 1 : CPV1 = 0.0;
11728 1 : CPV2 = 0.0;
11729 1 : SrfNum = 6;
11730 5 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11731 4 : if (MultizoneZoneData(ZnNum).SingleSidedCpType == "ADVANCED") {
11732 3 : OpenNuminZone = 1;
11733 15 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11734 14 : if (OpenNuminZone > 2) break; // Tuned
11735 12 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11736 6 : Real64 const VelRatio_2(std::pow(10.0 / AFNExtSurfaces(ExtOpenNum).NodeHeight, 2.0 * m_state.dataEnvrn->SiteWindExp));
11737 6 : Real64 const AFNEExtSurface_fac(0.5 * (1.0 / pow_2(AFNExtSurfaces(ExtOpenNum).DischCoeff)));
11738 6 : if (OpenNuminZone == 1) {
11739 6 : std::vector<Real64> cpvalues(numWindDir);
11740 111 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11741 108 : Real64 unmodifiedValue = valsByFacade[AFNExtSurfaces(ExtOpenNum).facadeNum - 1][windDirNum - 1] +
11742 108 : AFNEExtSurface_fac * DeltaCp(ZnNum).WindDir(windDirNum);
11743 108 : cpvalues[windDirNum - 1] = CPV1(windDirNum) = VelRatio_2 * unmodifiedValue;
11744 : }
11745 3 : valsByFacade.push_back(cpvalues);
11746 3 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum = SrfNum;
11747 3 : ++OpenNuminZone;
11748 3 : ++SrfNum;
11749 3 : } else if (OpenNuminZone == 2) {
11750 6 : std::vector<Real64> cpvalues(numWindDir);
11751 111 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11752 108 : Real64 unmodifiedValue = valsByFacade[AFNExtSurfaces(ExtOpenNum).facadeNum - 1][windDirNum - 1] -
11753 108 : AFNEExtSurface_fac * DeltaCp(ZnNum).WindDir(windDirNum);
11754 108 : cpvalues[windDirNum - 1] = CPV2(windDirNum) = VelRatio_2 * unmodifiedValue;
11755 108 : EPDeltaCP(ZnNum).WindDir(windDirNum) = std::abs(CPV2(windDirNum) - CPV1(windDirNum));
11756 : }
11757 3 : valsByFacade.push_back(cpvalues);
11758 3 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum = SrfNum;
11759 3 : ++OpenNuminZone;
11760 3 : ++SrfNum;
11761 : }
11762 : }
11763 : }
11764 : }
11765 : }
11766 : // Rewrite the CPVNum for all nodes that correspond with a simple or detailed opening
11767 : // Does this loop really do anything?
11768 5 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11769 4 : OpenNuminZone = 1;
11770 28 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11771 24 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11772 6 : if (OpenNuminZone == 1) {
11773 3 : ++OpenNuminZone;
11774 3 : } else if (OpenNuminZone == 2) {
11775 3 : ++OpenNuminZone;
11776 : }
11777 : }
11778 : }
11779 : }
11780 : }
11781 :
11782 6012112 : Real64 Solver::zone_OA_change_rate(int const ZoneNum) // hybrid ventilation system controlled zone number
11783 : {
11784 :
11785 : // SUBROUTINE INFORMATION:
11786 : // AUTHOR Lixing Gu
11787 : // DATE WRITTEN May. 2007
11788 :
11789 : // PURPOSE OF THIS SUBROUTINE:
11790 : // This function outputs air change per hour in a given zone
11791 :
11792 6012112 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
11793 6012112 : auto &thisZoneHB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
11794 :
11795 6012112 : Real64 CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat);
11796 6012112 : Real64 RhoAir = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat);
11797 : Real64 InfilVolume =
11798 6012112 : ((exchangeData(ZoneNum).SumMCp + exchangeData(ZoneNum).SumMVCp) / CpAir / RhoAir) * TimeStepSys * DataGlobalConstants::SecInHour;
11799 6012112 : Real64 ACH = InfilVolume / (TimeStepSys * m_state.dataHeatBal->Zone(ZoneNum).Volume);
11800 :
11801 6012112 : return ACH;
11802 : }
11803 :
11804 333 : int Solver::get_airloop_number(int const NodeNumber) // Get air loop number for each distribution node and linkage
11805 : {
11806 : // SUBROUTINE INFORMATION:
11807 : // AUTHOR Lixing Gu
11808 : // DATE WRITTEN Feb. 2018
11809 :
11810 : // PURPOSE OF THIS SUBROUTINE:
11811 : // This function outputs an AirLoopNum based on node number
11812 :
11813 : // Using/Aliasing
11814 : using BranchNodeConnections::GetChildrenData;
11815 : using BranchNodeConnections::GetNumChildren;
11816 : using BranchNodeConnections::IsParentObject;
11817 333 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
11818 : using SingleDuct::GetHVACSingleDuctSysIndex;
11819 :
11820 : // Return value
11821 333 : int AirLoopNumber = 0;
11822 :
11823 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11824 : int BranchNum;
11825 : int NumOfNodes;
11826 : int NodeNum;
11827 : int OutNum;
11828 : int SupAirPath;
11829 : int SupAirPathOutNodeNum;
11830 : int CtrlZoneNum;
11831 : int ZoneInNum;
11832 : int ZoneOutNum;
11833 : int AirLoopNum;
11834 333 : int TUNum = 0;
11835 333 : int TermNum = 0;
11836 : bool LocalError;
11837 : int NumOfComp;
11838 : int NumOfSubComp;
11839 : bool ErrorsFound;
11840 666 : std::string TypeOfComp;
11841 666 : std::string NameOfComp;
11842 : int NumOfSubSubComp;
11843 :
11844 447 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
11845 : // Check OAMixer OA inlet node
11846 349 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).OAMixOAInNodeNum) {
11847 13 : return AirLoopNum;
11848 : }
11849 : // Check branch
11850 550 : for (BranchNum = 1; BranchNum <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
11851 336 : NumOfNodes = m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalNodes;
11852 1456 : for (NodeNum = 1; NodeNum <= NumOfNodes; ++NodeNum) {
11853 1210 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).NodeNum(NodeNum)) {
11854 90 : return AirLoopNum;
11855 : }
11856 : }
11857 939 : for (NumOfComp = 1; NumOfComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
11858 : ++NumOfComp) {
11859 725 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NodeNumIn) {
11860 0 : return AirLoopNum;
11861 : }
11862 725 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NodeNumOut) {
11863 0 : return AirLoopNum;
11864 : }
11865 725 : if (m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NumSubComps == 0) {
11866 : DataLoopNode::ConnectionObjectType TypeOfComp =
11867 1450 : static_cast<DataLoopNode::ConnectionObjectType>(EnergyPlus::getEnumerationValue(
11868 : BranchNodeConnections::ConnectionObjectTypeNamesUC,
11869 1450 : m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).TypeOf));
11870 : std::string const &NameOfComp =
11871 725 : m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).Name;
11872 725 : if (IsParentObject(m_state, TypeOfComp, NameOfComp)) {
11873 :
11874 417 : int NumChildren = GetNumChildren(m_state, TypeOfComp, NameOfComp);
11875 802 : EPVector<DataLoopNode::ConnectionObjectType> SubCompTypes;
11876 802 : Array1D_string SubCompNames;
11877 802 : Array1D_string InletNodeNames;
11878 802 : Array1D_int InletNodeNumbers;
11879 802 : Array1D_string OutletNodeNames;
11880 802 : Array1D_int OutletNodeNumbers;
11881 :
11882 417 : SubCompTypes.allocate(NumChildren);
11883 417 : SubCompNames.allocate(NumChildren);
11884 417 : InletNodeNames.allocate(NumChildren);
11885 417 : InletNodeNumbers.allocate(NumChildren);
11886 417 : OutletNodeNames.allocate(NumChildren);
11887 417 : OutletNodeNumbers.allocate(NumChildren);
11888 :
11889 417 : GetChildrenData(m_state,
11890 : TypeOfComp,
11891 : NameOfComp,
11892 : NumChildren,
11893 : SubCompTypes,
11894 : SubCompNames,
11895 : InletNodeNames,
11896 : InletNodeNumbers,
11897 : OutletNodeNames,
11898 : OutletNodeNumbers,
11899 : ErrorsFound);
11900 :
11901 1016 : for (NumOfSubComp = 1; NumOfSubComp <= NumChildren; ++NumOfSubComp) {
11902 629 : if (NodeNumber == InletNodeNumbers(NumOfSubComp)) {
11903 1 : SubCompTypes.deallocate();
11904 1 : SubCompNames.deallocate();
11905 1 : InletNodeNames.deallocate();
11906 1 : InletNodeNumbers.deallocate();
11907 1 : OutletNodeNames.deallocate();
11908 1 : OutletNodeNumbers.deallocate();
11909 1 : return AirLoopNum;
11910 : }
11911 628 : if (NodeNumber == OutletNodeNumbers(NumOfSubComp)) {
11912 29 : SubCompTypes.deallocate();
11913 29 : SubCompNames.deallocate();
11914 29 : InletNodeNames.deallocate();
11915 29 : InletNodeNumbers.deallocate();
11916 29 : OutletNodeNames.deallocate();
11917 29 : OutletNodeNumbers.deallocate();
11918 29 : return AirLoopNum;
11919 : }
11920 : }
11921 954 : for (NumOfSubComp = 1; NumOfSubComp <= NumChildren; ++NumOfSubComp) {
11922 569 : DataLoopNode::ConnectionObjectType TypeOfComp = SubCompTypes(NumOfSubComp);
11923 1136 : std::string NameOfComp = SubCompNames(NumOfSubComp);
11924 569 : if (IsParentObject(m_state, TypeOfComp, NameOfComp)) {
11925 :
11926 13 : int NumGrandChildren = GetNumChildren(m_state, TypeOfComp, NameOfComp);
11927 24 : EPVector<DataLoopNode::ConnectionObjectType> SubSubCompTypes;
11928 24 : Array1D_string SubSubCompNames;
11929 24 : Array1D_string SubSubInletNodeNames;
11930 24 : Array1D_int SubSubInletNodeNumbers;
11931 24 : Array1D_string SubSubOutletNodeNames;
11932 24 : Array1D_int SubSubOutletNodeNumbers;
11933 :
11934 13 : SubSubCompTypes.allocate(NumGrandChildren);
11935 13 : SubSubCompNames.allocate(NumGrandChildren);
11936 13 : SubSubInletNodeNames.allocate(NumGrandChildren);
11937 13 : SubSubInletNodeNumbers.allocate(NumGrandChildren);
11938 13 : SubSubOutletNodeNames.allocate(NumGrandChildren);
11939 13 : SubSubOutletNodeNumbers.allocate(NumGrandChildren);
11940 :
11941 13 : GetChildrenData(m_state,
11942 : TypeOfComp,
11943 : NameOfComp,
11944 : NumGrandChildren,
11945 : SubSubCompTypes,
11946 : SubSubCompNames,
11947 : SubSubInletNodeNames,
11948 : SubSubInletNodeNumbers,
11949 : SubSubOutletNodeNames,
11950 : SubSubOutletNodeNumbers,
11951 : ErrorsFound);
11952 47 : for (int SubSubCompNum = 1; SubSubCompNum <= NumGrandChildren; ++SubSubCompNum) {
11953 36 : if (NodeNumber == SubSubInletNodeNumbers(SubSubCompNum)) {
11954 0 : SubSubCompTypes.deallocate();
11955 0 : SubSubCompNames.deallocate();
11956 0 : SubSubInletNodeNames.deallocate();
11957 0 : SubSubInletNodeNumbers.deallocate();
11958 0 : SubSubOutletNodeNames.deallocate();
11959 0 : SubSubOutletNodeNumbers.deallocate();
11960 0 : SubCompTypes.deallocate();
11961 0 : SubCompNames.deallocate();
11962 0 : InletNodeNames.deallocate();
11963 0 : InletNodeNumbers.deallocate();
11964 0 : OutletNodeNames.deallocate();
11965 0 : OutletNodeNumbers.deallocate();
11966 0 : return AirLoopNum;
11967 : }
11968 36 : if (NodeNumber == SubSubOutletNodeNumbers(SubSubCompNum)) {
11969 2 : SubSubCompTypes.deallocate();
11970 2 : SubSubCompNames.deallocate();
11971 2 : SubSubInletNodeNames.deallocate();
11972 2 : SubSubInletNodeNumbers.deallocate();
11973 2 : SubSubOutletNodeNames.deallocate();
11974 2 : SubSubOutletNodeNumbers.deallocate();
11975 2 : SubCompTypes.deallocate();
11976 2 : SubCompNames.deallocate();
11977 2 : InletNodeNames.deallocate();
11978 2 : InletNodeNumbers.deallocate();
11979 2 : OutletNodeNames.deallocate();
11980 2 : OutletNodeNumbers.deallocate();
11981 2 : return AirLoopNum;
11982 : }
11983 : }
11984 11 : SubSubCompTypes.deallocate();
11985 11 : SubSubCompNames.deallocate();
11986 11 : SubSubInletNodeNames.deallocate();
11987 11 : SubSubInletNodeNumbers.deallocate();
11988 11 : SubSubOutletNodeNames.deallocate();
11989 11 : SubSubOutletNodeNumbers.deallocate();
11990 : }
11991 : }
11992 :
11993 385 : SubCompTypes.deallocate();
11994 385 : SubCompNames.deallocate();
11995 385 : InletNodeNames.deallocate();
11996 385 : InletNodeNumbers.deallocate();
11997 385 : OutletNodeNames.deallocate();
11998 385 : OutletNodeNumbers.deallocate();
11999 : }
12000 : } else {
12001 0 : for (NumOfSubComp = 1;
12002 0 : NumOfSubComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NumSubComps;
12003 : ++NumOfSubComp) {
12004 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
12005 0 : .Branch(BranchNum)
12006 0 : .Comp(NumOfComp)
12007 0 : .SubComp(NumOfSubComp)
12008 0 : .NodeNumIn) {
12009 0 : return AirLoopNum;
12010 : }
12011 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
12012 0 : .Branch(BranchNum)
12013 0 : .Comp(NumOfComp)
12014 0 : .SubComp(NumOfSubComp)
12015 0 : .NodeNumOut) {
12016 0 : return AirLoopNum;
12017 : }
12018 0 : for (NumOfSubSubComp = 1; NumOfSubSubComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
12019 0 : .Branch(BranchNum)
12020 0 : .Comp(NumOfComp)
12021 0 : .SubComp(NumOfSubComp)
12022 0 : .NumSubSubComps;
12023 : ++NumOfSubSubComp) {
12024 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
12025 0 : .Branch(BranchNum)
12026 0 : .Comp(NumOfComp)
12027 0 : .SubComp(NumOfSubComp)
12028 0 : .SubSubComp(NumOfSubSubComp)
12029 0 : .NodeNumIn) {
12030 0 : return AirLoopNum;
12031 : }
12032 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
12033 0 : .Branch(BranchNum)
12034 0 : .Comp(NumOfComp)
12035 0 : .SubComp(NumOfSubComp)
12036 0 : .SubSubComp(NumOfSubSubComp)
12037 0 : .NodeNumOut) {
12038 0 : return AirLoopNum;
12039 : }
12040 : }
12041 : }
12042 : }
12043 : }
12044 : }
12045 :
12046 : // Check connection between supply and demand
12047 328 : for (OutNum = 1; OutNum <= m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumSupplyNodes; ++OutNum) {
12048 : // AirLoop supply outlet node
12049 214 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopSupplyNodeNum(OutNum) == NodeNumber) {
12050 0 : return AirLoopNum;
12051 : }
12052 214 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(OutNum) == NodeNumber) {
12053 24 : return AirLoopNum;
12054 : }
12055 : // supply path
12056 353 : for (SupAirPath = 1; SupAirPath <= m_state.dataZoneEquip->NumSupplyAirPaths; ++SupAirPath) {
12057 430 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).InletNodeNum ==
12058 215 : m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(OutNum)) {
12059 553 : for (SupAirPathOutNodeNum = 1; SupAirPathOutNodeNum <= m_state.dataZoneEquip->SupplyAirPath(SupAirPath).NumOutletNodes;
12060 : ++SupAirPathOutNodeNum) {
12061 415 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).OutletNode(SupAirPathOutNodeNum) == NodeNumber) {
12062 49 : return AirLoopNum;
12063 : }
12064 972 : for (TUNum = 1; TUNum <= DisSysNumOfTermUnits; ++TUNum) {
12065 609 : if (UtilityRoutines::SameString(DisSysCompTermUnitData(TUNum).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
12066 87 : LocalError = false;
12067 261 : GetHVACSingleDuctSysIndex(m_state,
12068 87 : DisSysCompTermUnitData(TUNum).name,
12069 : TermNum,
12070 : LocalError,
12071 : "AirflowNetwork:Distribution:Component:TerminalUnit",
12072 87 : DisSysCompTermUnitData(TUNum).DamperInletNode,
12073 174 : DisSysCompTermUnitData(TUNum).DamperOutletNode);
12074 174 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).OutletNode(SupAirPathOutNodeNum) ==
12075 87 : DisSysCompTermUnitData(TUNum).DamperInletNode) {
12076 30 : if (DisSysCompTermUnitData(TUNum).DamperOutletNode == NodeNumber) {
12077 3 : DisSysCompTermUnitData(TUNum).AirLoopNum = AirLoopNum;
12078 3 : return AirLoopNum;
12079 : }
12080 : }
12081 84 : if (LocalError) {
12082 : }
12083 : }
12084 : }
12085 : }
12086 : }
12087 : }
12088 : // return path
12089 138 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopReturnNodeNum(OutNum) == NodeNumber) {
12090 0 : return AirLoopNum;
12091 : }
12092 138 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipReturnNodeNum(OutNum) == NodeNumber) {
12093 24 : return AirLoopNum;
12094 : }
12095 250 : for (int retPathNum = 1; retPathNum <= m_state.dataZoneEquip->NumReturnAirPaths; ++retPathNum) {
12096 272 : if (m_state.dataZoneEquip->ReturnAirPath(retPathNum).OutletNodeNum ==
12097 136 : m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipReturnNodeNum(1)) {
12098 114 : if (m_state.dataZoneEquip->ReturnAirPath(retPathNum).OutletNodeNum == NodeNumber) {
12099 0 : return AirLoopNum;
12100 : }
12101 : }
12102 : }
12103 : // Supply inlet node
12104 :
12105 : // Terminal damper node
12106 : }
12107 : }
12108 :
12109 178 : for (CtrlZoneNum = 1; CtrlZoneNum <= m_state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
12110 178 : if (!m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
12111 308 : for (ZoneInNum = 1; ZoneInNum <= m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumInletNodes; ++ZoneInNum) {
12112 181 : if (m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNode(ZoneInNum) == NodeNumber) {
12113 49 : return m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNodeAirLoopNum(ZoneInNum);
12114 : }
12115 : }
12116 205 : for (ZoneOutNum = 1; ZoneOutNum <= m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumReturnNodes; ++ZoneOutNum) {
12117 127 : if (m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ReturnNode(ZoneOutNum) == NodeNumber) {
12118 49 : return m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ReturnNodeAirLoopNum(ZoneOutNum);
12119 : }
12120 : }
12121 : }
12122 :
12123 0 : return AirLoopNumber;
12124 : }
12125 :
12126 1 : void Solver::SizeDucts()
12127 : {
12128 1 : Real64 constexpr EPS(0.001);
12129 1 : int constexpr MaxIte(500);
12130 1 : Real64 constexpr MinVelocity(0.5); // minimum airflow velocity (m/s)
12131 1 : Real64 constexpr MaxVelocity(20.0); // maximum airflow velocity (m/s)
12132 :
12133 1 : int NodeLoopSupply = 0;
12134 1 : int NodeLoopReturn = 0;
12135 1 : int NodeSplitter = 0;
12136 1 : int NodeMixer = 0;
12137 1 : int NodeZoneIntlet = 0;
12138 1 : int NodeZoneReturn = 0;
12139 1 : int NumOfBranches = 0;
12140 : int AFNNodeNum;
12141 : int AFNLinkNum;
12142 : int AFNLinkNum1;
12143 1 : Real64 SumLength = 0.0;
12144 1 : Real64 DynamicLoss = 0.0;
12145 1 : Real64 MaxRough = 0.0;
12146 : bool DuctSizingSTFlag;
12147 : bool DuctSizingSBFlag;
12148 : bool DuctSizingRTFlag;
12149 : bool DuctSizingRBFlag;
12150 1 : Real64 hydraulicDiameter = 0.0;
12151 1 : Real64 SupplyTrunkD = 0.0;
12152 1 : Real64 SupplyTrunkArea = 0.0;
12153 1 : Real64 SupplyBranchD = 0.0;
12154 1 : Real64 SupplyBranchArea = 0.0;
12155 1 : Real64 ReturnTrunkD = 0.0;
12156 1 : Real64 ReturnTrunkArea = 0.0;
12157 1 : Real64 ReturnBranchD = 0.0;
12158 1 : Real64 ReturnBranchArea = 0.0;
12159 1 : Real64 MdotBranch = 0.0;
12160 1 : int SolFla = 0;
12161 :
12162 1 : int NumOfCtrlZones = 0;
12163 4 : for (int ZoneNum = 1; ZoneNum <= m_state.dataGlobal->NumOfZones; ++ZoneNum) {
12164 3 : if (!m_state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) continue;
12165 1 : NumOfCtrlZones++;
12166 1 : for (int EquipTypeNum = 1; EquipTypeNum <= m_state.dataZoneEquip->ZoneEquipList(ZoneNum).NumOfEquipTypes; ++EquipTypeNum) {
12167 1 : if (m_state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipTypeEnum(EquipTypeNum) == DataZoneEquipment::ZoneEquip::AirDistUnit) {
12168 1 : int AirDistUnitNum = m_state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipIndex(EquipTypeNum);
12169 1 : MdotBranch = m_state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).MassFlowRateTU;
12170 1 : break;
12171 : }
12172 : }
12173 : }
12174 1 : if (NumOfCtrlZones != 1) {
12175 0 : ShowWarningError(m_state, "AirflowNetwork Duct Sizing: The current restriction is limited to a single controlled zone only");
12176 0 : ShowContinueError(m_state, format("The number of controlled zone is {}", NumOfCtrlZones));
12177 0 : ShowContinueError(m_state, "..Duct sizing is not performed");
12178 0 : simulation_control.autosize_ducts = false;
12179 0 : simulation_control.iWPCCnt = iWPCCntr::Input;
12180 0 : simulation_control.allow_unsupported_zone_equipment = false;
12181 : }
12182 1 : Real64 factor = simulation_control.ductSizing.factor;
12183 :
12184 1 : NodeLoopSupply = m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipSupplyNodeNum(1);
12185 1 : NodeLoopReturn = m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipReturnNodeNum(1);
12186 23 : for (AFNNodeNum = 1; AFNNodeNum <= AirflowNetworkNumOfNodes; AFNNodeNum++) {
12187 22 : if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::SPL) {
12188 1 : NodeSplitter = AFNNodeNum;
12189 21 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::MIX) {
12190 1 : NodeMixer = AFNNodeNum;
12191 20 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipSupplyNodeNum(1)) {
12192 1 : NodeLoopSupply = AFNNodeNum;
12193 19 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipReturnNodeNum(1)) {
12194 1 : NodeLoopReturn = AFNNodeNum;
12195 18 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::ZIN) {
12196 1 : NodeZoneIntlet = AFNNodeNum;
12197 17 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::ZOU) {
12198 1 : NodeZoneReturn = AFNNodeNum;
12199 : }
12200 : }
12201 :
12202 : // find trunk ducts
12203 1 : DuctSizingSTFlag = false;
12204 1 : DuctSizingSBFlag = false;
12205 1 : int CompNum = 0;
12206 1 : int TypeNum = 0;
12207 :
12208 25 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12209 24 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12210 24 : iComponentTypeNum CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
12211 24 : SumLength = 0.0;
12212 24 : DynamicLoss = 0.0;
12213 24 : MaxRough = 0.0;
12214 : // supply duct trunk
12215 24 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeLoopSupply) {
12216 1 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeSplitter) {
12217 : // A single trunk duct
12218 1 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12219 1 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12220 1 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12221 1 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12222 1 : SumLength = disSysCompDuct.L;
12223 1 : MaxRough = disSysCompDuct.roughness;
12224 1 : DynamicLoss = disSysCompDuct.TurDynCoef;
12225 1 : DuctSizingSTFlag = true;
12226 : }
12227 : } else {
12228 0 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1];
12229 : int CompNum1;
12230 : iComponentTypeNum CompTypeNum1;
12231 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12232 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12233 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12234 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12235 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12236 0 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12237 0 : SumLength += disSysCompDuct.L;
12238 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12239 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12240 : // NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12241 0 : DuctSizingSBFlag = true;
12242 : }
12243 0 : while (NodeNum1 != NodeSplitter) {
12244 0 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12245 0 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) continue;
12246 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12247 0 : continue;
12248 0 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
12249 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12250 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12251 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12252 0 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::SupplyTrunk;
12253 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12254 0 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12255 0 : SumLength += disSysCompDuct.L;
12256 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12257 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12258 0 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1];
12259 0 : DuctSizingSTFlag = true;
12260 0 : break;
12261 : }
12262 : }
12263 : }
12264 : }
12265 : }
12266 1 : if (DuctSizingSTFlag) {
12267 1 : Real64 Velocity = 0.0;
12268 1 : Real64 flowrate = DisSysCompCVFData(1).FlowRate / m_state.dataEnvrn->StdRhoAir;
12269 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12270 0 : SupplyTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / DataGlobalConstants::Pi);
12271 0 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * DataGlobalConstants::Pi;
12272 : } else {
12273 1 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / DataGlobalConstants::Pi);
12274 1 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / DataGlobalConstants::Pi);
12275 1 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12276 1 : auto &deltaP = simulation_control.ductSizing.supply_trunk_pressure_loss;
12277 1 : auto &MassFlowRate = DisSysCompCVFData(1).FlowRate;
12278 90 : auto f = [&thisState, deltaP, MassFlowRate, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12279 : return DuctDResidual(thisState, D, deltaP, MassFlowRate, SumLength, DynamicLoss, MaxRough);
12280 91 : };
12281 1 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12282 1 : if (SolFla == -1) {
12283 0 : if (!m_state.dataGlobal->WarmupFlag) {
12284 0 : if (ErrCountDuct == 0) {
12285 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12286 0 : ShowWarningError(m_state,
12287 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Supply Duct Trunk size.");
12288 0 : ShowContinueErrorTimeStamp(m_state, format("Supply Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12289 : } else {
12290 0 : ++ErrCountDuct;
12291 0 : ShowRecurringWarningErrorAtEnd(
12292 : m_state,
12293 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Trunk "
12294 : "size. Supply Trunk is calculated using velocity at 5m/s. Simulation continues...",
12295 : ErrIndexDuct,
12296 : hydraulicDiameter,
12297 : hydraulicDiameter);
12298 : }
12299 : }
12300 1 : } else if (SolFla == -2) {
12301 0 : ShowFatalError(
12302 : m_state,
12303 : "Duct Autosizing for Supply Trunk calculation failed: iteration limits exceeded. Supply Trunk is calculated "
12304 : "using velocity at 5m/s.");
12305 : }
12306 1 : if (SolFla < 0) {
12307 0 : SupplyTrunkD = sqrt(4.0 * flowrate / 5.0 / DataGlobalConstants::Pi) * factor;
12308 : } else {
12309 1 : SupplyTrunkD = hydraulicDiameter * factor;
12310 : }
12311 1 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * DataGlobalConstants::Pi;
12312 1 : Velocity = flowrate / SupplyTrunkArea;
12313 : }
12314 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12315 0 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12316 0 : SupplyTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / DataGlobalConstants::Pi);
12317 0 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * DataGlobalConstants::Pi;
12318 0 : ShowWarningError(
12319 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Supply Trunk size");
12320 0 : ShowContinueError(
12321 : m_state,
12322 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12323 : simulation_control.ductSizing.max_velocity,
12324 0 : Velocity));
12325 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Supply Trunk Diameter");
12326 : }
12327 : }
12328 : }
12329 : }
12330 : // supply duct branch
12331 24 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeZoneIntlet) {
12332 1 : SumLength = 0.0;
12333 1 : DynamicLoss = 0.0;
12334 1 : MaxRough = 0.0;
12335 1 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeSplitter) {
12336 : // A single branch duct
12337 0 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12338 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12339 0 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12340 0 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12341 0 : SumLength = disSysCompDuct.L;
12342 0 : MaxRough = disSysCompDuct.roughness;
12343 0 : DynamicLoss = disSysCompDuct.TurDynCoef;
12344 0 : DuctSizingSTFlag = true;
12345 : }
12346 : } else {
12347 1 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12348 : int CompNum1;
12349 : iComponentTypeNum CompTypeNum1;
12350 1 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12351 1 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12352 1 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12353 1 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyBranch;
12354 1 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12355 1 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12356 1 : SumLength += disSysCompDuct.L;
12357 1 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12358 1 : DynamicLoss += disSysCompDuct.TurDynCoef;
12359 1 : DuctSizingSBFlag = true;
12360 : }
12361 5 : while (NodeNum1 != NodeSplitter) {
12362 18 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12363 18 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) continue;
12364 2 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12365 0 : continue;
12366 2 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
12367 2 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12368 2 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12369 2 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12370 2 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::SupplyBranch;
12371 2 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12372 2 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12373 2 : SumLength += disSysCompDuct.L;
12374 2 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12375 2 : DynamicLoss += disSysCompDuct.TurDynCoef;
12376 2 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0];
12377 2 : DuctSizingSBFlag = true;
12378 2 : break;
12379 : }
12380 : }
12381 : }
12382 : }
12383 : }
12384 1 : if (DuctSizingSBFlag) {
12385 1 : SolFla = 0;
12386 : Real64 Velocity;
12387 1 : Real64 flowrate = MdotBranch / m_state.dataEnvrn->StdRhoAir;
12388 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12389 0 : SupplyBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / DataGlobalConstants::Pi);
12390 0 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * DataGlobalConstants::Pi;
12391 : } else {
12392 1 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / DataGlobalConstants::Pi);
12393 1 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / DataGlobalConstants::Pi);
12394 1 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12395 1 : auto &deltaP = simulation_control.ductSizing.supply_branch_pressure_loss;
12396 65 : auto f = [&thisState, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12397 : return DuctDResidual(thisState, D, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough);
12398 66 : };
12399 1 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12400 1 : if (SolFla == -1) {
12401 0 : if (!m_state.dataGlobal->WarmupFlag) {
12402 0 : if (ErrCountDuct == 0) {
12403 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12404 0 : ShowWarningError(m_state,
12405 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Supply Duct Branch size.");
12406 0 : ShowContinueErrorTimeStamp(m_state, format("Supply Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12407 : } else {
12408 0 : ++ErrCountDuct;
12409 0 : ShowRecurringWarningErrorAtEnd(
12410 : m_state,
12411 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Branch "
12412 : "size. Supply Branch is calculated using velocity at 5m/s. Simulation continues...",
12413 : ErrIndexDuct,
12414 : hydraulicDiameter,
12415 : hydraulicDiameter);
12416 : }
12417 : }
12418 1 : } else if (SolFla == -2) {
12419 0 : ShowFatalError(
12420 : m_state,
12421 : "Duct Autosizing for Supply Branch calculation failed: iteration limits exceeded. Supply Branch is calculated "
12422 : "using velocity at 5m/s.");
12423 : }
12424 1 : if (SolFla < 0) {
12425 0 : SupplyBranchD = sqrt(4.0 * flowrate / 5.0 / DataGlobalConstants::Pi) * factor;
12426 : } else {
12427 1 : SupplyBranchD = hydraulicDiameter * factor;
12428 : }
12429 1 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * DataGlobalConstants::Pi;
12430 1 : Velocity = flowrate / SupplyBranchArea;
12431 : }
12432 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12433 0 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12434 0 : SupplyBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / DataGlobalConstants::Pi);
12435 0 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * DataGlobalConstants::Pi;
12436 0 : ShowWarningError(
12437 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Supply Branch size");
12438 0 : ShowContinueError(
12439 : m_state,
12440 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12441 : simulation_control.ductSizing.max_velocity,
12442 0 : Velocity));
12443 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Supply Branch Diameter");
12444 : }
12445 : }
12446 : }
12447 : }
12448 :
12449 24 : DuctSizingRTFlag = false;
12450 24 : DuctSizingRBFlag = false;
12451 :
12452 : // return duct trunk
12453 24 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeLoopReturn) {
12454 1 : SumLength = 0.0;
12455 1 : DynamicLoss = 0.0;
12456 1 : MaxRough = 0.0;
12457 1 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeMixer) {
12458 : // A single branch duct
12459 1 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12460 1 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnTrunk;
12461 1 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12462 1 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12463 1 : SumLength = disSysCompDuct.L;
12464 1 : MaxRough = disSysCompDuct.roughness;
12465 1 : DynamicLoss = disSysCompDuct.TurDynCoef;
12466 1 : DuctSizingRTFlag = true;
12467 : }
12468 : } else {
12469 0 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12470 : int CompNum1;
12471 : iComponentTypeNum CompTypeNum1;
12472 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12473 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12474 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12475 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnTrunk;
12476 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12477 0 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12478 0 : SumLength += disSysCompDuct.L;
12479 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12480 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12481 0 : DuctSizingRTFlag = true;
12482 : }
12483 0 : while (NodeNum1 != NodeMixer) {
12484 0 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12485 0 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) continue;
12486 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12487 0 : continue;
12488 0 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
12489 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12490 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12491 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12492 0 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::ReturnTrunk;
12493 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12494 0 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12495 0 : SumLength += disSysCompDuct.L;
12496 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12497 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12498 0 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0];
12499 0 : DuctSizingRTFlag = true;
12500 0 : break;
12501 : }
12502 : }
12503 : }
12504 : }
12505 : }
12506 1 : if (DuctSizingRTFlag) {
12507 1 : SolFla = 0;
12508 : Real64 Velocity;
12509 1 : Real64 flowrate = DisSysCompCVFData(1).FlowRate / m_state.dataEnvrn->StdRhoAir;
12510 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12511 0 : ReturnTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / DataGlobalConstants::Pi);
12512 0 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * DataGlobalConstants::Pi;
12513 : } else {
12514 1 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / DataGlobalConstants::Pi);
12515 1 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / DataGlobalConstants::Pi);
12516 1 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12517 1 : auto &deltaP = simulation_control.ductSizing.return_trunk_pressure_loss;
12518 1 : auto &massFlowRate = DisSysCompCVFData(1).FlowRate;
12519 145 : auto f = [&thisState, deltaP, massFlowRate, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12520 : return DuctDResidual(thisState, D, deltaP, massFlowRate, SumLength, DynamicLoss, MaxRough);
12521 146 : };
12522 1 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12523 1 : if (SolFla == -1) {
12524 0 : if (!m_state.dataGlobal->WarmupFlag) {
12525 0 : if (ErrCountDuct == 0) {
12526 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12527 0 : ShowWarningError(m_state,
12528 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Return Duct Trunk size.");
12529 0 : ShowContinueErrorTimeStamp(m_state, format("Return Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12530 : } else {
12531 0 : ++ErrCountDuct;
12532 0 : ShowRecurringWarningErrorAtEnd(
12533 : m_state,
12534 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Return Duct Trunk "
12535 : "size. Supply Branch is calculated using velocity at 5m/s. Simulation continues...",
12536 : ErrIndexDuct,
12537 : hydraulicDiameter,
12538 : hydraulicDiameter);
12539 : }
12540 : }
12541 1 : } else if (SolFla == -2) {
12542 0 : ShowFatalError(
12543 : m_state,
12544 : "Duct Autosizing for Return Trunk calculation failed: iteration limits exceeded. Return Trunk is calculated "
12545 : "using velocity at 5m/s.");
12546 : }
12547 1 : if (SolFla < 0) {
12548 0 : ReturnTrunkD = sqrt(4.0 * flowrate / 5.0 / DataGlobalConstants::Pi) * factor;
12549 : } else {
12550 1 : ReturnTrunkD = hydraulicDiameter * factor;
12551 : }
12552 1 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * DataGlobalConstants::Pi;
12553 1 : Velocity = flowrate / SupplyBranchArea;
12554 : }
12555 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12556 0 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12557 0 : ReturnTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / DataGlobalConstants::Pi);
12558 0 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * DataGlobalConstants::Pi;
12559 0 : ShowWarningError(
12560 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Return Trunk size");
12561 0 : ShowContinueError(
12562 : m_state,
12563 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12564 : simulation_control.ductSizing.max_velocity,
12565 0 : Velocity));
12566 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Return Trunk Diameter");
12567 : }
12568 : }
12569 : }
12570 : }
12571 :
12572 : // return duct branch
12573 24 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeZoneReturn) {
12574 1 : SumLength = 0.0;
12575 1 : DynamicLoss = 0.0;
12576 1 : MaxRough = 0.0;
12577 1 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeMixer) {
12578 : // A single trunk duct
12579 0 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12580 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnBranch;
12581 0 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12582 0 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12583 0 : SumLength = disSysCompDuct.L;
12584 0 : MaxRough = disSysCompDuct.roughness;
12585 0 : DynamicLoss = disSysCompDuct.TurDynCoef;
12586 0 : DuctSizingRBFlag = true;
12587 : }
12588 : } else {
12589 1 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1];
12590 : int CompNum1;
12591 : iComponentTypeNum CompTypeNum1;
12592 1 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12593 1 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12594 1 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12595 1 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnBranch;
12596 1 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12597 1 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12598 1 : SumLength += disSysCompDuct.L;
12599 1 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12600 1 : DynamicLoss += disSysCompDuct.TurDynCoef;
12601 1 : DuctSizingRBFlag = true;
12602 : }
12603 3 : while (NodeNum1 != NodeMixer) {
12604 14 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12605 14 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) continue;
12606 1 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12607 0 : continue;
12608 1 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
12609 1 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12610 1 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12611 1 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12612 1 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::ReturnBranch;
12613 1 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12614 1 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12615 1 : SumLength += disSysCompDuct.L;
12616 1 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12617 1 : DynamicLoss += disSysCompDuct.TurDynCoef;
12618 1 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1];
12619 1 : DuctSizingRBFlag = true;
12620 1 : break;
12621 : }
12622 : }
12623 : }
12624 : }
12625 : }
12626 1 : if (DuctSizingRBFlag) {
12627 1 : SolFla = 0;
12628 : Real64 Velocity;
12629 1 : Real64 flowrate = MdotBranch / m_state.dataEnvrn->StdRhoAir;
12630 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12631 0 : ReturnBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / DataGlobalConstants::Pi);
12632 0 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * DataGlobalConstants::Pi;
12633 : } else {
12634 1 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / DataGlobalConstants::Pi);
12635 1 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / DataGlobalConstants::Pi);
12636 1 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12637 1 : auto &deltaP = simulation_control.ductSizing.return_branch_pressure_loss;
12638 196 : auto f = [&thisState, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12639 : return DuctDResidual(thisState, D, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough);
12640 197 : };
12641 1 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12642 1 : if (SolFla == -1) {
12643 0 : if (!m_state.dataGlobal->WarmupFlag) {
12644 0 : if (ErrCountDuct == 0) {
12645 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12646 0 : ShowWarningError(m_state,
12647 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Return Duct Branch size.");
12648 0 : ShowContinueErrorTimeStamp(m_state, format("Return Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12649 : } else {
12650 0 : ++ErrCountDuct;
12651 0 : ShowRecurringWarningErrorAtEnd(
12652 : m_state,
12653 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Branch "
12654 : "size. Return Branch is calculated using velocity at 5m/s. Simulation continues...",
12655 : ErrIndexDuct,
12656 : hydraulicDiameter,
12657 : hydraulicDiameter);
12658 : }
12659 : }
12660 1 : } else if (SolFla == -2) {
12661 0 : ShowFatalError(
12662 : m_state,
12663 : "Duct Autosizing for Return Branch calculation failed: iteration limits exceeded. Return Branch is calculated "
12664 : "using velocity at 5m/s.");
12665 : }
12666 1 : if (SolFla < 0) {
12667 0 : ReturnBranchD = sqrt(4.0 * flowrate / 5.0 / DataGlobalConstants::Pi) * factor;
12668 : } else {
12669 1 : ReturnBranchD = hydraulicDiameter * factor;
12670 : }
12671 1 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * DataGlobalConstants::Pi;
12672 1 : Velocity = flowrate / ReturnBranchArea;
12673 : }
12674 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12675 0 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12676 0 : ReturnBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / DataGlobalConstants::Pi);
12677 0 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * DataGlobalConstants::Pi;
12678 0 : ShowWarningError(
12679 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Return Branch size");
12680 0 : ShowContinueError(
12681 : m_state,
12682 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12683 : simulation_control.ductSizing.max_velocity,
12684 0 : Velocity));
12685 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Return Branch Diameter");
12686 : }
12687 : }
12688 : }
12689 : }
12690 : }
12691 : // Assign autosize values in Duct element
12692 25 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12693 24 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12694 24 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12695 24 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12696 24 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyTrunk) {
12697 1 : disSysCompDuct.hydraulicDiameter = SupplyTrunkD;
12698 1 : disSysCompDuct.A = SupplyTrunkArea;
12699 1 : disSysCompDuct.RelRough = disSysCompDuct.roughness / SupplyTrunkD; // e/D: relative roughness
12700 1 : disSysCompDuct.RelL = disSysCompDuct.L / SupplyTrunkD; // L/D: relative length
12701 1 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12702 1 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12703 23 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyBranch) {
12704 3 : disSysCompDuct.hydraulicDiameter = SupplyBranchD;
12705 3 : disSysCompDuct.A = SupplyBranchArea;
12706 3 : disSysCompDuct.RelRough = disSysCompDuct.roughness / SupplyBranchD; // e/D: relative roughness
12707 3 : disSysCompDuct.RelL = disSysCompDuct.L / SupplyBranchD; // L/D: relative length
12708 3 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12709 3 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12710 20 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnTrunk) {
12711 1 : disSysCompDuct.hydraulicDiameter = ReturnTrunkD;
12712 1 : disSysCompDuct.A = ReturnTrunkArea;
12713 1 : disSysCompDuct.RelRough = disSysCompDuct.roughness / ReturnTrunkD; // e/D: relative roughness
12714 1 : disSysCompDuct.RelL = disSysCompDuct.L / ReturnTrunkD; // L/D: relative length
12715 1 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12716 1 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12717 19 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnBranch) {
12718 2 : disSysCompDuct.hydraulicDiameter = ReturnBranchD;
12719 2 : disSysCompDuct.A = ReturnBranchArea;
12720 2 : disSysCompDuct.RelRough = disSysCompDuct.roughness / ReturnBranchD; // e/D: relative roughness
12721 2 : disSysCompDuct.RelL = disSysCompDuct.L / ReturnBranchD; // L/D: relative length
12722 2 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12723 2 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12724 : }
12725 : }
12726 :
12727 : // Print data in eio
12728 1 : print(m_state.files.eio,
12729 1 : "! <AirflowNetwork Model:Duct Autosizing>, Linkage Name, Duct Type, Duct Name, Duct Hydraunic Diameter, Duct Cross Section Area\n");
12730 :
12731 : // Assign autosize values in Duct element
12732 25 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12733 24 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12734 24 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12735 24 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12736 24 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyTrunk) {
12737 3 : print(m_state.files.eio,
12738 : "AirflowNetwork Model:Duct Autosizing, {}, Supply Trunk, {}, ",
12739 1 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12740 1 : disSysCompDuct.name);
12741 1 : print(m_state.files.eio, "{:.4R},{:.4R}\n", SupplyTrunkD, SupplyTrunkArea);
12742 : }
12743 24 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyBranch) {
12744 9 : print(m_state.files.eio,
12745 : "AirflowNetwork Model:Duct Autosizing, {}, Supply Branch, {}, ",
12746 3 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12747 3 : disSysCompDuct.name);
12748 3 : print(m_state.files.eio, "{:.4R},{:.4R}\n", SupplyBranchD, SupplyBranchArea);
12749 : }
12750 24 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnTrunk) {
12751 3 : print(m_state.files.eio,
12752 : "AirflowNetwork Model:Duct Autosizing, {}, Return Trunk, {}, ",
12753 1 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12754 1 : disSysCompDuct.name);
12755 1 : print(m_state.files.eio, "{:.4R},{:.4R}\n", ReturnTrunkD, ReturnTrunkArea);
12756 : }
12757 24 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnBranch) {
12758 6 : print(m_state.files.eio,
12759 : "AirflowNetwork Model:Duct Autosizing, {}, Return Branch, {}, ",
12760 2 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12761 2 : disSysCompDuct.name);
12762 2 : print(m_state.files.eio, "{:.4R},{:.4R}\n", ReturnBranchD, ReturnBranchArea);
12763 : }
12764 : }
12765 1 : }
12766 :
12767 496 : Real64 Solver::CalcDuctDiameter(Real64 hydraulicDiameter, Real64 DeltaP, Real64 MassFlowrate, Real64 TotalL, Real64 TotalLossCoe, Real64 MaxRough)
12768 : {
12769 496 : Real64 CalcDeltaP = 0.0;
12770 :
12771 : Real64 A;
12772 : Real64 A0;
12773 : Real64 A1;
12774 : Real64 A2;
12775 : Real64 B;
12776 : Real64 D;
12777 : Real64 S2;
12778 : Real64 CDM;
12779 : Real64 FL; // friction factor for laminar flow.
12780 : Real64 FT; // friction factor for turbulent flow.
12781 : Real64 FTT;
12782 : Real64 RE; // Reynolds number.
12783 : Real64 ed;
12784 : Real64 ld;
12785 : Real64 g;
12786 : Real64 AA1;
12787 : Real64 velocity;
12788 496 : Real64 constexpr LamDynCoef(64.0);
12789 496 : Real64 constexpr LamFriCoef(0.001);
12790 496 : Real64 constexpr EPS(0.001);
12791 496 : Real64 constexpr C(0.868589);
12792 :
12793 : //// Initial guess with 5 m/s
12794 496 : Real64 flowrate = MassFlowrate / m_state.dataEnvrn->StdRhoAir;
12795 :
12796 496 : ed = MaxRough / hydraulicDiameter;
12797 496 : ld = TotalL / hydraulicDiameter;
12798 496 : g = 1.14 - 0.868589 * std::log(ed);
12799 496 : AA1 = g;
12800 496 : A = hydraulicDiameter * hydraulicDiameter / 4.0 * DataGlobalConstants::Pi;
12801 496 : Real64 viscosity{AirflowNetwork::AIRDYNAMICVISCOSITY_CONSTEXPR(20)};
12802 496 : velocity = flowrate / A;
12803 :
12804 : if (LamFriCoef >= 0.001) {
12805 496 : A2 = LamFriCoef / (2.0 * m_state.dataEnvrn->StdRhoAir * A * A);
12806 496 : A1 = (viscosity * LamDynCoef * ld) / (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter);
12807 496 : A0 = -DeltaP;
12808 496 : CDM = std::sqrt(A1 * A1 - 4.0 * A2 * A0);
12809 496 : FL = (CDM - A1) / (2.0 * A2);
12810 496 : CDM = 1.0 / CDM;
12811 : } else {
12812 : CDM = (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter) / (viscosity * LamDynCoef * ld);
12813 : FL = CDM * DeltaP;
12814 : }
12815 :
12816 : // CDM = (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter) / (viscosity * LamDynCoef * ld);
12817 : // FL = CDM * DeltaP;
12818 :
12819 496 : RE = FL * hydraulicDiameter / (viscosity * A);
12820 496 : S2 = std::sqrt(2.0 * m_state.dataEnvrn->StdRhoAir * DeltaP) * A;
12821 496 : FTT = S2 / std::sqrt(ld / pow_2(g) + TotalLossCoe);
12822 : while (true) {
12823 1454 : FT = FTT;
12824 975 : B = (9.3 * viscosity * A) / (FT * MaxRough);
12825 975 : D = 1.0 + g * B;
12826 975 : g -= (g - AA1 + C * std::log(D)) / (1.0 + C * B / D);
12827 975 : FTT = S2 / std::sqrt(ld / pow_2(g) + TotalLossCoe);
12828 975 : if (std::abs(FTT - FT) / FTT < EPS) break;
12829 : }
12830 496 : FT = FTT;
12831 :
12832 496 : Real64 f = 1.0 / (g * g);
12833 :
12834 : // CalcDeltaP = ((FT * TotalL) / hydraulicDiameter + TotalLossCoe) * (m_state.dataEnvrn->StdRhoAir * velocity * velocity / 2.0);
12835 496 : CalcDeltaP = ((f * TotalL) / hydraulicDiameter + TotalLossCoe) * (m_state.dataEnvrn->StdRhoAir * velocity * velocity / 2.0);
12836 :
12837 496 : return CalcDeltaP;
12838 : }
12839 :
12840 496 : Real64 DuctDResidual(EnergyPlusData &state,
12841 : Real64 D, // duct diameter
12842 : Real64 DeltaP,
12843 : Real64 MassFlowrate,
12844 : Real64 TotalL,
12845 : Real64 TotalLossCoe,
12846 : Real64 MaxRough)
12847 : {
12848 496 : Real64 CalcDeltaP = state.afn->CalcDuctDiameter(D, DeltaP, MassFlowrate, TotalL, TotalLossCoe, MaxRough);
12849 496 : return (CalcDeltaP - DeltaP) / DeltaP;
12850 : }
12851 :
12852 5192 : void OccupantVentilationControlProp::calc(EnergyPlusData &state,
12853 : int const ZoneNum,
12854 : Real64 const TimeOpenDuration,
12855 : Real64 const TimeCloseDuration,
12856 : int &OpeningStatus,
12857 : int &OpeningProbStatus,
12858 : int &ClosingProbStatus)
12859 : {
12860 :
12861 : Real64 Tcomfort; // Thermal comfort temperature
12862 : Real64 ComfortBand; // Thermal comfort band
12863 : Real64 Toperative; // Operative temperature
12864 : Real64 OutDryBulb; // Outdoor dry-bulb temperature
12865 :
12866 5192 : auto &Zone(state.dataHeatBal->Zone);
12867 :
12868 5192 : if (TimeOpenDuration > 0) {
12869 1832 : if (TimeOpenDuration >= MinOpeningTime) {
12870 1622 : OpeningStatus = OpenStatus::FreeOperation; // free operation
12871 : } else {
12872 210 : OpeningStatus = OpenStatus::MinCheckForceOpen; // forced to open
12873 : }
12874 : }
12875 5192 : if (TimeCloseDuration > 0) {
12876 3360 : if (TimeCloseDuration >= MinClosingTime) {
12877 3124 : OpeningStatus = OpenStatus::FreeOperation; // free operation
12878 : } else {
12879 236 : OpeningStatus = OpenStatus::MinCheckForceClose; // forced to close
12880 : }
12881 : }
12882 :
12883 5192 : if (MinTimeControlOnly) return;
12884 :
12885 5192 : if (Zone(ZoneNum).LinkedOutAirNode > 0) {
12886 0 : OutDryBulb = Zone(ZoneNum).OutDryBulbTemp;
12887 : } else {
12888 5192 : OutDryBulb = OutDryBulbTempAt(state, Zone(ZoneNum).Centroid.z);
12889 : }
12890 :
12891 5192 : if (OutDryBulb < ComfortBouPoint) {
12892 2616 : Tcomfort = CurveValue(state, ComfortLowTempCurveNum, OutDryBulb);
12893 : } else {
12894 2576 : Tcomfort = CurveValue(state, ComfortHighTempCurveNum, OutDryBulb);
12895 : }
12896 5192 : ComfortBand = -0.0028 * (100 - MaxPPD) * (100 - MaxPPD) + 0.3419 * (100 - MaxPPD) - 6.6275;
12897 5192 : Toperative = 0.5 * (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBal->ZoneMRT(ZoneNum));
12898 :
12899 5192 : if (Toperative > (Tcomfort + ComfortBand)) {
12900 770 : if (opening_probability(state, ZoneNum, TimeCloseDuration)) {
12901 16 : OpeningProbStatus = ProbabilityCheck::ForceChange;
12902 : ; // forced to open
12903 : } else {
12904 754 : OpeningProbStatus = ProbabilityCheck::KeepStatus; // Keep previous status
12905 : }
12906 : } else {
12907 4422 : OpeningProbStatus = ProbabilityCheck::NoAction; // free operation
12908 : }
12909 :
12910 5192 : if (Toperative < (Tcomfort - ComfortBand)) {
12911 2872 : if (closing_probability(state, TimeOpenDuration)) {
12912 82 : ClosingProbStatus = ProbabilityCheck::ForceChange; // forced to close
12913 : } else {
12914 2790 : ClosingProbStatus = ProbabilityCheck::KeepStatus; // Keep previous status
12915 : }
12916 : } else {
12917 2320 : ClosingProbStatus = ProbabilityCheck::NoAction; // free operation
12918 : }
12919 : }
12920 :
12921 : bool
12922 770 : OccupantVentilationControlProp::opening_probability(EnergyPlusData &state,
12923 : int const ZoneNum,
12924 : Real64 const TimeCloseDuration) // function to perform calculations of opening probability
12925 : {
12926 : Real64 SchValue;
12927 : Real64 RandomValue;
12928 770 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
12929 :
12930 770 : if (TimeCloseDuration < MinClosingTime) {
12931 754 : return false;
12932 : }
12933 16 : if (OccupancyCheck) {
12934 16 : if (state.dataHeatBal->ZoneIntGain(ZoneNum).NOFOCC <= 0.0) {
12935 0 : return false;
12936 : }
12937 : }
12938 :
12939 16 : switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
12940 0 : case DataHVACGlobals::ThermostatType::SingleHeating:
12941 0 : if (thisZoneHB.MAT <= state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum)) {
12942 0 : return false;
12943 : }
12944 0 : break;
12945 0 : case DataHVACGlobals::ThermostatType::SingleCooling:
12946 0 : if (thisZoneHB.MAT >= state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum)) {
12947 0 : return false;
12948 : }
12949 0 : break;
12950 0 : case DataHVACGlobals::ThermostatType::SingleHeatCool:
12951 0 : return false;
12952 0 : case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand:
12953 0 : if (thisZoneHB.MAT < state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum) ||
12954 0 : thisZoneHB.MAT > state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum)) {
12955 0 : return false;
12956 : }
12957 0 : break;
12958 16 : default:
12959 16 : break;
12960 : }
12961 :
12962 16 : if (OpeningProbSchNum == 0) {
12963 16 : return true;
12964 : } else {
12965 0 : SchValue = GetCurrentScheduleValue(state, OpeningProbSchNum);
12966 0 : RandomValue = Real64(rand()) / RAND_MAX;
12967 0 : if (SchValue > RandomValue) {
12968 0 : return true;
12969 : } else {
12970 0 : return false;
12971 : }
12972 : }
12973 : }
12974 :
12975 2872 : bool OccupantVentilationControlProp::closing_probability(EnergyPlusData &state,
12976 : Real64 const TimeOpenDuration) // function to perform calculations of closing probability
12977 : {
12978 : Real64 SchValue;
12979 : Real64 RandomValue;
12980 :
12981 2872 : if (TimeOpenDuration < MinOpeningTime) {
12982 2790 : return false;
12983 : }
12984 82 : if (ClosingProbSchNum == 0) {
12985 82 : return true;
12986 : } else {
12987 0 : SchValue = GetCurrentScheduleValue(state, ClosingProbSchNum);
12988 0 : RandomValue = Real64(rand()) / RAND_MAX;
12989 0 : if (SchValue > RandomValue) {
12990 0 : return true;
12991 : } else {
12992 0 : return false;
12993 : }
12994 : }
12995 : }
12996 :
12997 34 : void Solver::allocate()
12998 : {
12999 :
13000 : // SUBROUTINE INFORMATION:
13001 : // AUTHOR Lixing Gu
13002 : // DATE WRITTEN Aug. 2003
13003 : // MODIFIED na
13004 : // RE-ENGINEERED na
13005 :
13006 : // PURPOSE OF THIS SUBROUTINE:
13007 : // This subroutine allocates dynamic arrays for AirflowNetworkSolver.
13008 :
13009 : // METHODOLOGY EMPLOYED:
13010 : // na
13011 :
13012 : // REFERENCES:
13013 : // na
13014 :
13015 : // USE STATEMENTS:
13016 : // na
13017 :
13018 : // Locals
13019 : // SUBROUTINE ARGUMENT DEFINITIONS:
13020 : // na
13021 :
13022 : // SUBROUTINE PARAMETER DEFINITIONS:
13023 : // na
13024 :
13025 : // INTERFACE BLOCK SPECIFICATIONS
13026 : // na
13027 :
13028 : // DERIVED TYPE DEFINITIONS
13029 : // na
13030 :
13031 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13032 : int i;
13033 : iComponentTypeNum j;
13034 : int n;
13035 :
13036 : // Formats
13037 :
13038 : // Assume a network to simulate multizone airflow is a subset of the network to simulate air distribution system.
13039 : // Network array size is allocated based on the network of air distribution system.
13040 : // If multizone airflow is simulated only, the array size is allocated based on the multizone network.
13041 :
13042 34 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13043 34 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13044 :
13045 34 : NetworkNumOfLinks = AirflowNetworkNumOfLinks;
13046 34 : NetworkNumOfNodes = AirflowNetworkNumOfNodes;
13047 :
13048 34 : AFECTL.allocate(NetworkNumOfLinks);
13049 34 : AFLOW2.allocate(NetworkNumOfLinks);
13050 34 : AFLOW.allocate(NetworkNumOfLinks);
13051 34 : PW.allocate(NetworkNumOfLinks);
13052 34 : PS.allocate(NetworkNumOfLinks);
13053 :
13054 : // TZ.allocate(NetworkNumOfNodes);
13055 : // WZ.allocate(NetworkNumOfNodes);
13056 34 : PZ.allocate(NetworkNumOfNodes);
13057 : // RHOZ.allocate(NetworkNumOfNodes);
13058 : // SQRTDZ.allocate(NetworkNumOfNodes);
13059 : // VISCZ.allocate(NetworkNumOfNodes);
13060 34 : SUMAF.allocate(NetworkNumOfNodes);
13061 :
13062 928 : for (int it = 0; it <= NetworkNumOfNodes + 1; ++it)
13063 894 : node_states.emplace_back(properties.density(101325.0, 20.0, 0.0));
13064 :
13065 34 : ID.allocate(NetworkNumOfNodes);
13066 34 : IK.allocate(NetworkNumOfNodes + 1);
13067 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13068 34 : newIK.allocate(NetworkNumOfNodes + 1);
13069 : #endif
13070 34 : AD.allocate(NetworkNumOfNodes);
13071 34 : SUMF.allocate(NetworkNumOfNodes);
13072 :
13073 34 : n = 0;
13074 1215 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
13075 1181 : j = AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum;
13076 1181 : if (j == iComponentTypeNum::DOP) {
13077 70 : ++n;
13078 : }
13079 : }
13080 :
13081 34 : dos.allocate(AirflowNetworkNumOfLinks, n);
13082 :
13083 34 : PB = 101325.0;
13084 : // LIST = 5
13085 : // LIST = 0;
13086 :
13087 860 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13088 826 : ID(n) = n;
13089 : }
13090 1215 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13091 1181 : AFECTL(i) = 1.0;
13092 1181 : AFLOW(i) = 0.0;
13093 1181 : AFLOW2(i) = 0.0;
13094 : }
13095 :
13096 860 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13097 : // TZ(i) = AirflowNetworkNodeSimu(i).TZ;
13098 : // WZ(i) = AirflowNetworkNodeSimu(i).WZ;
13099 826 : PZ(i) = AirflowNetworkNodeSimu(i).PZ;
13100 826 : node_states[i].temperature = AirflowNetworkNodeSimu(i).TZ;
13101 826 : node_states[i].humidity_ratio = AirflowNetworkNodeSimu(i).WZ;
13102 : // properties[i].pressure = AirflowNetworkNodeSimu(i).PZ;
13103 : }
13104 :
13105 : // Assign linkage values
13106 1215 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13107 1181 : PW(i) = 0.0;
13108 : }
13109 : // Write an ouput file used for AIRNET input
13110 : /*
13111 : if (LIST >= 5) {
13112 : Unit11 = GetNewUnitNumber();
13113 : ObjexxFCL::gio::open(Unit11, DataStringGlobals::eplusADSFileName);
13114 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13115 : ObjexxFCL::gio::write(Unit11, Format_901) << i << state.afn->AirflowNetworkNodeData(i).NodeTypeNum <<
13116 : state.afn->AirflowNetworkNodeData(i).NodeHeight << TZ(i)
13117 : << PZ(i);
13118 : }
13119 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13120 : for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
13121 : j = state.afn->AirflowNetworkCompData(i).TypeNum;
13122 : {
13123 : auto const SELECT_CASE_var(state.afn->AirflowNetworkCompData(i).CompTypeNum);
13124 : if (SELECT_CASE_var == CompTypeNum_PLR) { //'PLR' Power law component
13125 : // WRITE(Unit11,902)
13126 : state.afn->AirflowNetworkCompData(i)%CompNum,1,DisSysCompLeakData(j)%FlowCoef, &
13127 : // DisSysCompLeakData(j)%FlowCoef,DisSysCompLeakData(j)%FlowCoef,DisSysCompLeakData(j)%FlowExpo
13128 : } else if (SELECT_CASE_var == CompTypeNum_SCR) { //'SCR' Surface crack component
13129 : ObjexxFCL::gio::write(Unit11, Format_902) << state.afn->AirflowNetworkCompData(i).CompNum << 1 <<
13130 : MultizoneSurfaceCrackData(j).FlowCoef
13131 : << MultizoneSurfaceCrackData(j).FlowCoef << MultizoneSurfaceCrackData(j).FlowCoef
13132 : << MultizoneSurfaceCrackData(j).FlowExpo;
13133 : } else if (SELECT_CASE_var == CompTypeNum_DWC) { //'DWC' Duct component
13134 : // WRITE(Unit11,902)
13135 : state.afn->AirflowNetworkCompData(i)%CompNum,2,DisSysCompDuctData(j)%L,DisSysCompDuctData(j)%D, &
13136 : // DisSysCompDuctData(j)%A,DisSysCompDuctData(j)%Rough
13137 : // WRITE(Unit11,903) DisSysCompDuctData(i)%TurDynCoef,DisSysCompDuctData(j)%LamFriCoef, &
13138 : // DisSysCompDuctData(j)%LamFriCoef,DisSysCompDuctData(j)%InitLamCoef
13139 : // CASE (CompTypeNum_CVF) ! 'CVF' Constant volume fan component
13140 : // WRITE(Unit11,904) state.afn->AirflowNetworkCompData(i)%CompNum,4,DisSysCompCVFData(j)%FlowRate
13141 : } else if (SELECT_CASE_var == CompTypeNum_EXF) { // 'EXF' Zone exhaust fan
13142 : ObjexxFCL::gio::write(Unit11, Format_904) << state.afn->AirflowNetworkCompData(i).CompNum << 4 <<
13143 : MultizoneCompExhaustFanData(j).FlowRate; } else {
13144 : }
13145 : }
13146 : }
13147 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13148 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13149 : gio::write(Unit11, Format_910) << i << state.afn->AirflowNetworkLinkageData(i).NodeNums[0] <<
13150 : state.afn->AirflowNetworkLinkageData(i).NodeHeights[0]
13151 : << state.afn->AirflowNetworkLinkageData(i).NodeNums[1] <<
13152 : state.afn->AirflowNetworkLinkageData(i).NodeHeights[1]
13153 : << state.afn->AirflowNetworkLinkageData(i).CompNum << 0 << 0;
13154 : }
13155 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13156 : }
13157 : */
13158 34 : setsky();
13159 :
13160 : // SETSKY figures out the IK stuff -- which is why E+ doesn't allocate AU until here
13161 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13162 : // ! only printing to screen, can be commented
13163 : // print*, "SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS is defined"
13164 : // write(*,'(2(a,i8))') "AllocateAirflowNetworkData: after SETSKY, allocating AU. NetworkNumOfNodes=", &
13165 : // NetworkNumOfNodes, " IK(NetworkNumOfNodes+1)= NNZE=", IK(NetworkNumOfNodes+1)
13166 : // print*, " NetworkNumOfLinks=", NetworkNumOfLinks
13167 : // allocate same size as others -- this will be maximum !noel
13168 34 : newAU.allocate(IK(NetworkNumOfNodes + 1));
13169 : #endif
13170 :
13171 : // noel, GNU says the AU is indexed above its upper bound
13172 : // ALLOCATE(AU(IK(NetworkNumOfNodes+1)-1))
13173 34 : AU.allocate(IK(NetworkNumOfNodes + 1));
13174 34 : }
13175 :
13176 698875 : void Solver::initialize_calculation()
13177 : {
13178 :
13179 : // SUBROUTINE INFORMATION:
13180 : // AUTHOR Lixing Gu
13181 : // DATE WRITTEN Aug. 2003
13182 : // MODIFIED na
13183 : // RE-ENGINEERED na
13184 :
13185 : // PURPOSE OF THIS SUBROUTINE:
13186 : // This subroutine initializes variables for AirflowNetworkSolver.
13187 :
13188 : // METHODOLOGY EMPLOYED:
13189 : // na
13190 :
13191 : // REFERENCES:
13192 : // na
13193 :
13194 : // USE STATEMENTS:
13195 : // na
13196 :
13197 : // Locals
13198 : // SUBROUTINE ARGUMENT DEFINITIONS:
13199 : // na
13200 :
13201 : // SUBROUTINE PARAMETER DEFINITIONS:
13202 : // na
13203 :
13204 : // INTERFACE BLOCK SPECIFICATIONS
13205 : // na
13206 :
13207 : // DERIVED TYPE DEFINITIONS
13208 : // na
13209 :
13210 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13211 :
13212 15956040 : for (int i = 1; i <= ActualNumOfNodes; ++i) {
13213 15257165 : ID(i) = i;
13214 : }
13215 21029108 : for (int i = 1; i <= ActualNumOfLinks; ++i) {
13216 20330233 : AFECTL(i) = 1.0;
13217 20330233 : AFLOW(i) = 0.0;
13218 20330233 : AFLOW2(i) = 0.0;
13219 : }
13220 :
13221 15956040 : for (int i = 1; i <= ActualNumOfNodes; ++i) {
13222 : // TZ(i) = AirflowNetworkNodeSimu(i).TZ;
13223 : // WZ(i) = AirflowNetworkNodeSimu(i).WZ;
13224 15257165 : PZ(i) = AirflowNetworkNodeSimu(i).PZ;
13225 15257165 : node_states[i].temperature = AirflowNetworkNodeSimu(i).TZ;
13226 15257165 : node_states[i].humidity_ratio = AirflowNetworkNodeSimu(i).WZ;
13227 : // properties[i].pressure = AirflowNetworkNodeSimu(i).PZ;
13228 : }
13229 698875 : }
13230 :
13231 34 : void Solver::setsky()
13232 : {
13233 : // SUBROUTINE INFORMATION:
13234 : // AUTHOR George Walton
13235 : // DATE WRITTEN 1998
13236 : // MODIFIED Feb. 2006 (L. Gu) to meet requirements of AirflowNetwork
13237 : // RE-ENGINEERED na
13238 :
13239 : // PURPOSE OF THIS SUBROUTINE:
13240 : // This subroutine sets up the "IK" array describing the sparse matrix [A] in skyline
13241 : // form by using the location matrix.
13242 :
13243 : // METHODOLOGY EMPLOYED:
13244 : // na
13245 :
13246 : // REFERENCES:
13247 : // AIRNET
13248 :
13249 : // USE STATEMENTS:
13250 : // na
13251 :
13252 : // Locals
13253 : // SUBROUTINE ARGUMENT DEFINITIONS:
13254 : // na
13255 :
13256 : // SUBROUTINE PARAMETER DEFINITIONS:
13257 : // na
13258 :
13259 : // INTERFACE BLOCK SPECIFICATIONS
13260 : // na
13261 :
13262 : // DERIVED TYPE DEFINITIONS
13263 : // na
13264 :
13265 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13266 : // IK(K) - pointer to the top of column/row "K".
13267 : int i;
13268 : int j;
13269 : int k;
13270 : int L;
13271 : int M;
13272 : int N1;
13273 : int N2;
13274 :
13275 : // Initialize "IK".
13276 894 : for (i = 1; i <= ActualNumOfNodes + 1; ++i) {
13277 860 : IK(i) = 0;
13278 : }
13279 : // Determine column heights.
13280 1215 : for (M = 1; M <= ActualNumOfLinks; ++M) {
13281 1181 : j = AirflowNetworkLinkageData(M).NodeNums[1];
13282 1181 : if (j == 0) continue;
13283 1181 : L = ID(j);
13284 1181 : i = AirflowNetworkLinkageData(M).NodeNums[0];
13285 1181 : k = ID(i);
13286 1181 : N1 = std::abs(L - k);
13287 1181 : N2 = max(k, L);
13288 1181 : IK(N2) = max(IK(N2), N1);
13289 : }
13290 : // Convert heights to column addresses.
13291 34 : j = IK(1);
13292 34 : IK(1) = 1;
13293 860 : for (k = 1; k <= ActualNumOfNodes; ++k) {
13294 826 : i = IK(k + 1);
13295 826 : IK(k + 1) = IK(k) + j;
13296 826 : j = i;
13297 : }
13298 34 : }
13299 :
13300 693100 : void Solver::airmov()
13301 : {
13302 : // SUBROUTINE INFORMATION:
13303 : // AUTHOR George Walton
13304 : // DATE WRITTEN Extracted from AIRNETf
13305 : // MODIFIED Lixing Gu, 2/1/04
13306 : // Revised the subroutine to meet E+ needs
13307 : // MODIFIED Lixing Gu, 6/8/05
13308 : // RE-ENGINEERED na
13309 :
13310 : // PURPOSE OF THIS SUBROUTINE:
13311 : // This subroutine is a driver for AIRNET to calculate nodal pressures and linkage airflows
13312 :
13313 : // METHODOLOGY EMPLOYED:
13314 : // na
13315 :
13316 : // REFERENCES:
13317 : // na
13318 :
13319 : // USE STATEMENTS:
13320 :
13321 : // Locals
13322 : // SUBROUTINE ARGUMENT DEFINITIONS:
13323 : // na
13324 :
13325 : // SUBROUTINE PARAMETER DEFINITIONS:
13326 : // na
13327 :
13328 : // INTERFACE BLOCK SPECIFICATIONS
13329 : // na
13330 :
13331 : // DERIVED TYPE DEFINITIONS
13332 : // na
13333 :
13334 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13335 : int i;
13336 : int m;
13337 : int n;
13338 : int ITER;
13339 :
13340 : // Formats
13341 :
13342 : // static ObjexxFCL::gio::Fmt Format_900("(,/,11X,'i n m DP',12x,'F1',12X,'F2')");
13343 : // static ObjexxFCL::gio::Fmt Format_901("(1X,A6,3I5,3F14.6)");
13344 : // static ObjexxFCL::gio::Fmt Format_902("(,/,11X,'n P',12x,'sumF')");
13345 : // static ObjexxFCL::gio::Fmt Format_903("(1X,A6,I5,3F14.6)");
13346 : // static ObjexxFCL::gio::Fmt Format_907("(,/,' CPU seconds for ',A,F12.3)");
13347 :
13348 693100 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13349 693100 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13350 :
13351 : // Initialize pressure for pressure control and for Initialization Type = LinearInitializationMethod
13352 693100 : if ((simulation_control.InitFlag == 0) || (PressureSetFlag > 0 && AirflowNetworkFanActivated)) {
13353 1596076 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13354 1554074 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) PZ(n) = 0.0;
13355 : }
13356 : }
13357 : // Compute zone air properties.
13358 15736590 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13359 15043490 : node_states[n].density =
13360 15043490 : properties.density(m_state.dataEnvrn->StdBaroPress + PZ(n), node_states[n].temperature, node_states[n].humidity_ratio);
13361 : // RHOZ(n) = PsyRhoAirFnPbTdbW(StdBaroPress + PZ(n), TZ(n), WZ(n));
13362 15043490 : if (AirflowNetworkNodeData(n).ExtNodeNum > 0) {
13363 5201416 : node_states[n].density =
13364 5201416 : properties.density(m_state.dataEnvrn->StdBaroPress + PZ(n), m_state.dataEnvrn->OutDryBulbTemp, m_state.dataEnvrn->OutHumRat);
13365 5201416 : node_states[n].temperature = m_state.dataEnvrn->OutDryBulbTemp;
13366 5201416 : node_states[n].humidity_ratio = m_state.dataEnvrn->OutHumRat;
13367 : }
13368 15043490 : node_states[n].sqrt_density = std::sqrt(node_states[n].density);
13369 15043490 : node_states[n].viscosity = 1.71432e-5 + 4.828e-8 * node_states[n].temperature;
13370 : // if (LIST >= 2) ObjexxFCL::gio::write(outputFile, Format_903) << "D,V:" << n << properties[n].density << properties[n].viscosity;
13371 : }
13372 : // Compute stack pressures.
13373 20676833 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13374 19983733 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13375 19983733 : m = AirflowNetworkLinkageData(i).NodeNums[1];
13376 19983733 : if (AFLOW(i) > 0.0) {
13377 0 : PS(i) = 9.80 * (node_states[n].density * (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13378 0 : m_state.afn->AirflowNetworkLinkageData(i).NodeHeights[1] * (node_states[m].density - node_states[n].density));
13379 19983733 : } else if (AFLOW(i) < 0.0) {
13380 0 : PS(i) = 9.80 * (node_states[m].density * (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13381 0 : AirflowNetworkLinkageData(i).NodeHeights[0] * (node_states[m].density - node_states[n].density));
13382 : } else {
13383 59951199 : PS(i) = 4.90 * ((node_states[n].density + node_states[m].density) *
13384 39967466 : (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13385 39967466 : (AirflowNetworkLinkageData(i).NodeHeights[0] + AirflowNetworkLinkageData(i).NodeHeights[1]) *
13386 19983733 : (node_states[m].density - node_states[n].density));
13387 : }
13388 : }
13389 :
13390 : // Calculate pressure field in a large opening
13391 693100 : dos.pstack(m_state, node_states, PZ);
13392 693100 : solvzp(ITER);
13393 :
13394 : // Report element flows and zone pressures.
13395 15736590 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13396 15043490 : SUMAF(n) = 0.0;
13397 : }
13398 : // if (LIST >= 1) ObjexxFCL::gio::write(outputFile, Format_900);
13399 20676833 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13400 19983733 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13401 19983733 : m = AirflowNetworkLinkageData(i).NodeNums[1];
13402 : // if (LIST >= 1) {
13403 : // gio::write(outputFile, Format_901) << "Flow: " << i << n << m << AirflowNetworkLinkSimu(i).DP << AFLOW(i) << AFLOW2(i);
13404 : //}
13405 19983733 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
13406 7335 : SUMAF(n) = SUMAF(n) - AFLOW(i);
13407 7335 : SUMAF(m) += AFLOW(i);
13408 : } else {
13409 19976398 : SUMAF(n) = SUMAF(n) - AFLOW(i) - AFLOW2(i);
13410 19976398 : SUMAF(m) += AFLOW(i) + AFLOW2(i);
13411 : }
13412 : }
13413 : // for (n = 1; n <= NetworkNumOfNodes; ++n) {
13414 : // if (LIST >= 1) gio::write(outputFile, Format_903) << "Room: " << n << PZ(n) << SUMAF(n) << properties[n].temperature;
13415 : //}
13416 :
13417 20676833 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13418 19983733 : if (AFLOW2(i) != 0.0) {
13419 : }
13420 19983733 : if (AFLOW(i) > 0.0) {
13421 15139134 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i);
13422 15139134 : AirflowNetworkLinkSimu(i).FLOW2 = 0.0;
13423 : } else {
13424 4844599 : AirflowNetworkLinkSimu(i).FLOW = 0.0;
13425 4844599 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i);
13426 : }
13427 19983733 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
13428 7335 : if (AFLOW(i) > 0.0) {
13429 765 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i) + AFLOW2(i);
13430 765 : AirflowNetworkLinkSimu(i).FLOW2 = AFLOW2(i);
13431 : } else {
13432 6570 : AirflowNetworkLinkSimu(i).FLOW = AFLOW2(i);
13433 6570 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i) + AFLOW2(i);
13434 : }
13435 : }
13436 19983733 : if (AirflowNetworkLinkageData(i).DetOpenNum > 0) {
13437 749727 : if (AFLOW2(i) != 0.0) {
13438 188066 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i) + AFLOW2(i);
13439 188066 : AirflowNetworkLinkSimu(i).FLOW2 = AFLOW2(i);
13440 : }
13441 : }
13442 19983733 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SOP && AFLOW2(i) != 0.0) {
13443 4804 : if (AFLOW(i) >= 0.0) {
13444 3152 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i);
13445 3152 : AirflowNetworkLinkSimu(i).FLOW2 = std::abs(AFLOW2(i));
13446 : } else {
13447 1652 : AirflowNetworkLinkSimu(i).FLOW = std::abs(AFLOW2(i));
13448 1652 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i);
13449 : }
13450 : }
13451 : }
13452 :
13453 15736590 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13454 15043490 : AirflowNetworkNodeSimu(i).PZ = PZ(i);
13455 : }
13456 693100 : }
13457 :
13458 693100 : void Solver::solvzp(int &ITER) // number of iterations
13459 : {
13460 :
13461 : // SUBROUTINE INFORMATION:
13462 : // AUTHOR George Walton
13463 : // DATE WRITTEN Extracted from AIRNET
13464 : // MODIFIED Lixing Gu, 2/1/04
13465 : // Revised the subroutine to meet E+ needs
13466 : // MODIFIED Lixing Gu, 6/8/05
13467 : // RE-ENGINEERED na
13468 :
13469 : // PURPOSE OF THIS SUBROUTINE:
13470 : // This subroutine solves zone pressures by modified Newton-Raphson iteration
13471 :
13472 : // METHODOLOGY EMPLOYED:
13473 : // na
13474 :
13475 : // REFERENCES:
13476 : // na
13477 :
13478 693100 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13479 693100 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13480 :
13481 : // Argument array dimensioning (these used to be arguments, need to also test newAU and newIK)
13482 693100 : EP_SIZE_CHECK(IK, NetworkNumOfNodes + 1);
13483 693100 : EP_SIZE_CHECK(AD, NetworkNumOfNodes);
13484 693100 : EP_SIZE_CHECK(AU, IK(NetworkNumOfNodes + 1));
13485 :
13486 : // Locals
13487 : // SUBROUTINE ARGUMENT DEFINITIONS:
13488 : // noel GNU says AU is being indexed beyound bounds
13489 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
13490 :
13491 : // SUBROUTINE PARAMETER DEFINITIONS:
13492 :
13493 : // INTERFACE BLOCK SPECIFICATIONS
13494 : // na
13495 :
13496 : // DERIVED TYPE DEFINITIONS
13497 : // na
13498 :
13499 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13500 :
13501 : // NNZE - number of nonzero entries in the "AU" array.
13502 : // LFLAG - if = 1, use laminar relationship (initialization).
13503 : // I - element number.
13504 : // N - number of node/zone 1.
13505 : // M - number of node/zone 2.
13506 : // F - flows through the element (kg/s).
13507 : // DF - partial derivatives: DF/DP.
13508 : // NF - number of flows, 1 or 2.
13509 : // SUMF - sum of flows into node/zone.
13510 : // CCF - current pressure correction (Pa).
13511 : // PCF - previous pressure correction (Pa).
13512 : // CEF - convergence enhancement factor.
13513 : int n;
13514 : int NNZE;
13515 : int NSYM;
13516 : bool LFLAG;
13517 : int CONVG;
13518 : int ACCEL;
13519 693100 : Array1D<Real64> PCF(NetworkNumOfNodes);
13520 693100 : Array1D<Real64> CEF(NetworkNumOfNodes);
13521 : Real64 C;
13522 : Real64 SSUMF;
13523 : Real64 SSUMAF;
13524 : Real64 ACC0;
13525 : Real64 ACC1;
13526 693100 : Array1D<Real64> CCF(NetworkNumOfNodes);
13527 :
13528 : // auto &outputFile = std::cout;
13529 :
13530 693100 : ACC1 = 0.0;
13531 693100 : ACCEL = 0;
13532 693100 : NSYM = 0;
13533 693100 : NNZE = IK(NetworkNumOfNodes + 1) - 1;
13534 : // if (LIST >= 2) print(outputFile, "Initialization{:16}{:16}{:16}\n", NetworkNumOfNodes, NetworkNumOfLinks, NNZE);
13535 693100 : ITER = 0;
13536 :
13537 15736590 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13538 15043490 : PCF(n) = 0.0;
13539 15043490 : CEF(n) = 0.0;
13540 : }
13541 :
13542 693100 : if (simulation_control.InitFlag != 1) {
13543 : // Initialize node/zone pressure values by assuming only linear relationship between
13544 : // airflows and pressure drops.
13545 0 : LFLAG = true;
13546 0 : filjac(NNZE, LFLAG);
13547 0 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13548 0 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) PZ(n) = SUMF(n);
13549 : }
13550 : // Data dump.
13551 : // if (LIST >= 3) {
13552 : // DUMPVD("AD:", AD, NetworkNumOfNodes, outputFile);
13553 : // DUMPVD("AU:", AU, NNZE, outputFile);
13554 : // DUMPVR("AF:", SUMF, NetworkNumOfNodes, outputFile);
13555 : // }
13556 : // Solve linear system for approximate PZ.
13557 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13558 0 : facsky(newAU, AD, newAU, newIK, NetworkNumOfNodes, NSYM); // noel
13559 0 : slvsky(newAU, AD, newAU, PZ, newIK, NetworkNumOfNodes, NSYM); // noel
13560 : #else
13561 : facsky(AU, AD, AU, IK, NetworkNumOfNodes, NSYM);
13562 : slvsky(AU, AD, AU, PZ, IK, NetworkNumOfNodes, NSYM);
13563 : #endif
13564 : // if (LIST >= 2) DUMPVD("PZ:", PZ, NetworkNumOfNodes, outputFile);
13565 : }
13566 : // Solve nonlinear airflow network equations by modified Newton's method.
13567 16851330 : while (ITER < simulation_control.maximum_iterations) {
13568 8772215 : LFLAG = false;
13569 8772215 : ++ITER;
13570 : // if (LIST >= 2) {
13571 : // print(outputFile, "Begin iteration {}\n", ITER);
13572 : // }
13573 : // Set up the Jacobian matrix.
13574 8772215 : filjac(NNZE, LFLAG);
13575 : // Data dump.
13576 : // if (LIST >= 3) {
13577 : // DUMPVR("SUMF:", SUMF, NetworkNumOfNodes, outputFile);
13578 : // DUMPVR("SUMAF:", SUMAF, NetworkNumOfNodes, outputFile);
13579 : // }
13580 : // Check convergence.
13581 8772215 : CONVG = 1;
13582 8772215 : SSUMF = 0.0;
13583 8772215 : SSUMAF = 0.0;
13584 231325435 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13585 222553220 : SSUMF += std::abs(SUMF(n));
13586 222553220 : SSUMAF += SUMAF(n);
13587 222553220 : if (CONVG == 1) {
13588 83917248 : if (std::abs(SUMF(n)) <= simulation_control.absolute_convergence_tolerance) continue;
13589 10518881 : if (std::abs(SUMF(n) / SUMAF(n)) > simulation_control.relative_convergence_tolerance) CONVG = 0;
13590 : }
13591 : }
13592 8772215 : ACC0 = ACC1;
13593 8772215 : if (SSUMAF > 0.0) ACC1 = SSUMF / SSUMAF;
13594 8772215 : if (CONVG == 1 && ITER > 1) return;
13595 8079115 : if (ITER >= simulation_control.maximum_iterations) break;
13596 : // Data dump.
13597 : // if (LIST >= 3) {
13598 : // DUMPVD("AD:", AD, NetworkNumOfNodes, outputFile);
13599 : // DUMPVD("AU:", AU, NNZE, outputFile);
13600 : // }
13601 : // Solve AA * CCF = SUMF.
13602 215588845 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13603 207509730 : CCF(n) = SUMF(n);
13604 : }
13605 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13606 8079115 : facsky(newAU, AD, newAU, newIK, NetworkNumOfNodes, NSYM); // noel
13607 8079115 : slvsky(newAU, AD, newAU, CCF, newIK, NetworkNumOfNodes, NSYM); // noel
13608 : #else
13609 : facsky(AU, AD, AU, IK, NetworkNumOfNodes, NSYM);
13610 : slvsky(AU, AD, AU, CCF, IK, NetworkNumOfNodes, NSYM);
13611 : #endif
13612 : // Revise PZ (Steffensen iteration on the N-R correction factors to handle oscillating corrections).
13613 8079115 : if (ACCEL == 1) {
13614 2456743 : ACCEL = 0;
13615 : } else {
13616 5622372 : if (ITER > 2 && ACC1 > 0.5 * ACC0) ACCEL = 1;
13617 : }
13618 215588845 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13619 207509730 : if (AirflowNetworkNodeData(n).NodeTypeNum == 1) continue;
13620 143003788 : CEF(n) = 1.0;
13621 143003788 : if (ACCEL == 1) {
13622 47237112 : C = CCF(n) / PCF(n);
13623 47237112 : if (C < simulation_control.convergence_acceleration_limit) CEF(n) = 1.0 / (1.0 - C);
13624 47237112 : C = CCF(n) * CEF(n);
13625 : } else {
13626 : // IF (CCF(N) .EQ. 0.0d0) CCF(N)=TINY(CCF(N)) ! 1.0E-40
13627 95766676 : if (CCF(n) == 0.0) CCF(n) = DataGlobalConstants::rTinyValue; // 1.0E-40 (Epsilon)
13628 95766676 : PCF(n) = CCF(n);
13629 95766676 : C = CCF(n);
13630 : }
13631 143003788 : if (std::abs(C) > simulation_control.MaxPressure) {
13632 0 : CEF(n) *= simulation_control.MaxPressure / std::abs(C);
13633 0 : PZ(n) -= CCF(n) * CEF(n);
13634 : } else {
13635 143003788 : PZ(n) -= C;
13636 : }
13637 : }
13638 : // Data revision dump.
13639 : // if (LIST >= 2) {
13640 : // for (n = 1; n <= NetworkNumOfNodes; ++n) {
13641 : // if (state.afn->AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13642 : // print(outputFile, "Rev: {:5}{:3}{:14.6E} {:8.4F}{:24.14F}", n, SUMF(n), CCF(n), CEF(n), PZ(n));
13643 : // }
13644 : // }
13645 : // }
13646 : }
13647 :
13648 : // Error termination.
13649 0 : ShowSevereError(m_state, "Too many iterations (SOLVZP) in Airflow Network simulation");
13650 0 : ++ExtLargeOpeningErrCount;
13651 0 : if (ExtLargeOpeningErrCount < 2) {
13652 0 : ShowWarningError(m_state,
13653 : "AirflowNetwork: SOLVER, Changing values for initialization flag, Relative airflow convergence, Absolute airflow "
13654 : "convergence, Convergence acceleration limit or Maximum Iteration Number may solve the problem.");
13655 0 : ShowContinueErrorTimeStamp(m_state, "");
13656 0 : ShowContinueError(m_state,
13657 0 : "..Iterations=" + std::to_string(ITER) + ", Max allowed=" + std::to_string(simulation_control.maximum_iterations));
13658 0 : ShowFatalError(m_state, "AirflowNetwork: SOLVER, The previous error causes termination.");
13659 : } else {
13660 0 : ShowRecurringWarningErrorAtEnd(
13661 : m_state, "AirFlowNetwork: Too many iterations (SOLVZP) in AirflowNetwork simulation continues.", ExtLargeOpeningErrIndex);
13662 : }
13663 : }
13664 :
13665 8772215 : void Solver::filjac(int const NNZE, // number of nonzero entries in the "AU" array.
13666 : bool const LFLAG // if = 1, use laminar relationship (initialization).
13667 : )
13668 : {
13669 :
13670 : // SUBROUTINE INFORMATION:
13671 : // AUTHOR George Walton
13672 : // DATE WRITTEN Extracted from AIRNET
13673 : // MODIFIED Lixing Gu, 2/1/04
13674 : // Revised the subroutine to meet E+ needs
13675 : // MODIFIED Lixing Gu, 6/8/05
13676 : // RE-ENGINEERED na
13677 :
13678 : // PURPOSE OF THIS SUBROUTINE:
13679 : // This subroutine creates matrices for solution of flows
13680 :
13681 : // METHODOLOGY EMPLOYED:
13682 : // na
13683 :
13684 : // REFERENCES:
13685 : // na
13686 :
13687 : // USE STATEMENTS:
13688 : // na
13689 :
13690 : // Locals
13691 : // SUBROUTINE ARGUMENT DEFINITIONS:
13692 :
13693 : // SUBROUTINE PARAMETER DEFINITIONS:
13694 : // na
13695 :
13696 : // INTERFACE BLOCK SPECIFICATIONS
13697 : // na
13698 :
13699 : // DERIVED TYPE DEFINITIONS
13700 : // na
13701 :
13702 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13703 :
13704 : // I - component number.
13705 : // N - number of node/zone 1.
13706 : // M - number of node/zone 2.
13707 : // F - flows through the element (kg/s).
13708 : // DF - partial derivatives: DF/DP.
13709 : // NF - number of flows, 1 or 2.
13710 : int i;
13711 : int j;
13712 : int n;
13713 : int FLAG;
13714 : int NF;
13715 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13716 : int LHK; // noel
13717 : int JHK;
13718 : int JHK1;
13719 : int newsum;
13720 : int newh;
13721 : int ispan;
13722 : int thisIK;
13723 : bool allZero; // noel
13724 : #endif
13725 17544430 : Array1D<Real64> X(4);
13726 : Real64 DP;
13727 8772215 : std::array<Real64, 2> F{{0.0, 0.0}};
13728 8772215 : std::array<Real64, 2> DF{{0.0, 0.0}};
13729 :
13730 8772215 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13731 8772215 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13732 :
13733 231325435 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13734 222553220 : SUMF(n) = 0.0;
13735 222553220 : SUMAF(n) = 0.0;
13736 222553220 : if (AirflowNetworkNodeData(n).NodeTypeNum == 1) {
13737 69707358 : AD(n) = 1.0;
13738 : } else {
13739 152845862 : AD(n) = 0.0;
13740 : }
13741 : }
13742 1342004243 : for (n = 1; n <= NNZE; ++n) {
13743 1333232028 : AU(n) = 0.0;
13744 : }
13745 : // Loop(s) to calculate control, etc.
13746 : // Set up the Jacobian matrix.
13747 297770703 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13748 288998488 : if (AirflowNetworkLinkageData(i).element == nullptr) {
13749 0 : continue;
13750 : }
13751 288998488 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13752 288998488 : int m = AirflowNetworkLinkageData(i).NodeNums[1];
13753 : //!!! Check array of DP. DpL is used for multizone air flow calculation only
13754 : //!!! and is not for forced air calculation
13755 288998488 : if (i > NumOfLinksMultiZone) {
13756 164691627 : DP = PZ(n) - PZ(m) + PS(i) + PW(i);
13757 : } else {
13758 124306861 : DP = PZ(n) - PZ(m) + dos.DpL(i, 1) + PW(i);
13759 : }
13760 288998488 : Real64 multiplier = 1.0;
13761 288998488 : Real64 control = AirflowNetworkLinkageData(i).control;
13762 : // if (LIST >= 4) ObjexxFCL::gio::write(outputFile, Format_901) << "PS:" << i << n << M << PS(i) << PW(i) << AirflowNetworkLinkSimu(i).DP;
13763 288998488 : j = AirflowNetworkLinkageData(i).CompNum;
13764 :
13765 288998488 : NF = AirflowNetworkLinkageData(i).element->calculate(m_state, LFLAG, DP, i, multiplier, control, node_states[n], node_states[m], F, DF);
13766 288998488 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::CPD && DP != 0.0) {
13767 1714157 : DP = DisSysCompCPDData(AirflowNetworkCompData(j).TypeNum).DP;
13768 : }
13769 :
13770 288998488 : AirflowNetworkLinkSimu(i).DP = DP;
13771 288998488 : AFLOW(i) = F[0];
13772 288998488 : AFLOW2(i) = 0.0;
13773 288998488 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DOP) {
13774 6828273 : AFLOW2(i) = F[1];
13775 : }
13776 : // if (LIST >= 3) ObjexxFCL::gio::write(outputFile, Format_901) << " NRi:" << i << n << M << AirflowNetworkLinkSimu(i).DP << F[0] <<
13777 : // DF[0];
13778 288998488 : FLAG = 1;
13779 288998488 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13780 287984273 : ++FLAG;
13781 287984273 : X(1) = DF[0];
13782 287984273 : X(2) = -DF[0];
13783 287984273 : SUMF(n) += F[0];
13784 287984273 : SUMAF(n) += std::abs(F[0]);
13785 : }
13786 288998488 : if (AirflowNetworkNodeData(m).NodeTypeNum == 0) {
13787 192786402 : FLAG += 2;
13788 192786402 : X(4) = DF[0];
13789 192786402 : X(3) = -DF[0];
13790 192786402 : SUMF(m) -= F[0];
13791 192786402 : SUMAF(m) += std::abs(F[0]);
13792 : }
13793 288998488 : if (FLAG != 1) filsky(X, AirflowNetworkLinkageData(i).NodeNums, IK, AU, AD, FLAG);
13794 288998488 : if (NF == 1) continue;
13795 31015 : AFLOW2(i) = F[1];
13796 : // if (LIST >= 3) ObjexxFCL::gio::write(outputFile, Format_901) << " NRj:" << i << n << m << AirflowNetworkLinkSimu(i).DP << F[1] <<
13797 : // DF[1];
13798 31015 : FLAG = 1;
13799 31015 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13800 31015 : ++FLAG;
13801 31015 : X(1) = DF[1];
13802 31015 : X(2) = -DF[1];
13803 31015 : SUMF(n) += F[1];
13804 31015 : SUMAF(n) += std::abs(F[1]);
13805 : }
13806 31015 : if (AirflowNetworkNodeData(m).NodeTypeNum == 0) {
13807 31015 : FLAG += 2;
13808 31015 : X(4) = DF[1];
13809 31015 : X(3) = -DF[1];
13810 31015 : SUMF(m) -= F[1];
13811 31015 : SUMAF(m) += std::abs(F[1]);
13812 : }
13813 31015 : if (FLAG != 1) filsky(X, AirflowNetworkLinkageData(i).NodeNums, IK, AU, AD, FLAG);
13814 : }
13815 :
13816 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13817 :
13818 : // After the matrix values have been set, we can look at them and see if any columns are filled with zeros.
13819 : // If they are, let's remove them from the matrix -- but only for the purposes of doing the solve.
13820 : // They way I do this is building a separate IK array (newIK) that simply changes the column heights.
13821 : // So the affected SOLVEs would use this newIK and nothing else changes.
13822 240097650 : for (n = 1; n <= NetworkNumOfNodes + 1; ++n) {
13823 231325435 : newIK(n) = IK(n);
13824 : // print*, " NetworkNumOfNodes n=", n, " IK(n)=", IK(n)
13825 : }
13826 :
13827 8772215 : newsum = IK(2) - IK(1); // always 0?
13828 :
13829 8772215 : JHK = 1;
13830 222553220 : for (n = 2; n <= NetworkNumOfNodes; ++n) {
13831 213781005 : JHK1 = IK(n + 1); // starts at IK(3)-IK(2)
13832 213781005 : LHK = JHK1 - JHK;
13833 223608688 : if (LHK <= 0) {
13834 9827683 : newIK(n + 1) = newIK(n);
13835 9827683 : continue;
13836 : }
13837 : // write(*,'(4(a,i8))') "n=", n, " ik=", ik(n), " JHK=", JHK, " LHK=", LHK
13838 :
13839 : // is the entire column zero? noel
13840 203953322 : allZero = true;
13841 657936103 : for (i = 0; i <= LHK - 1; ++i) {
13842 583175016 : if (AU(JHK + i) != 0.0) {
13843 129192235 : allZero = false;
13844 129192235 : break;
13845 : }
13846 : }
13847 :
13848 203953322 : newh = LHK;
13849 203953322 : if (allZero) {
13850 : // print*, "allzero n=", n
13851 74761087 : newh = 0;
13852 : } else {
13853 : // DO i=0,LHK-1
13854 : // write(*, '(2(a,i8),a, f15.3)') " n=", n, " i=", i, " AU(JHK+i)=", AU(JHK+i)
13855 : // enddo
13856 : }
13857 203953322 : newIK(n + 1) = newIK(n) + newh;
13858 203953322 : newsum += newh;
13859 :
13860 : // do i = LHK-1,0, -1
13861 : // write(*, '(2(a,i8),a, f15.3)') " n=", n, " i=", i, " AU(JHK+i)=", AU(JHK+i)
13862 : // enddo
13863 203953322 : JHK = JHK1;
13864 : }
13865 :
13866 : // this is just a print to screen, is not necessary
13867 : // if (firstTime) then
13868 : // write(*, '(2(a,i8))') " After SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS: newsum=", newsum, " oldsum=", IK(NetworkNumOfNodes+1)
13869 : // firstTime=.FALSE.
13870 : // endif
13871 :
13872 : // Now fill newAU from AU, using newIK
13873 8772215 : thisIK = 1;
13874 222553220 : for (n = 2; n <= NetworkNumOfNodes; ++n) {
13875 213781005 : thisIK = newIK(n);
13876 213781005 : ispan = newIK(n + 1) - thisIK;
13877 :
13878 213781005 : if (ispan <= 0) continue;
13879 1008441482 : for (i = 0; i <= ispan - 1; ++i) {
13880 879249247 : newAU(thisIK + i) = AU(IK(n) + i);
13881 : }
13882 : }
13883 : #endif
13884 8772215 : }
13885 :
13886 8079115 : void Solver::facsky(Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
13887 : Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
13888 : Array1D<Real64> &AL, // the lower triangle of [A] before and after factoring
13889 : const Array1D_int &IK, // pointer to the top of column/row "K"
13890 : int const NEQ, // number of equations
13891 : int const NSYM // symmetry: 0 = symmetric matrix, 1 = non-symmetric
13892 : )
13893 : {
13894 :
13895 : // SUBROUTINE INFORMATION:
13896 : // AUTHOR George Walton
13897 : // DATE WRITTEN Extracted from AIRNET
13898 : // MODIFIED Lixing Gu, 2/1/04
13899 : // Revised the subroutine to meet E+ needs
13900 : // MODIFIED Lixing Gu, 6/8/05
13901 : // RE-ENGINEERED This subroutine is revised from FACSKY developed by George Walton, NIST
13902 :
13903 : // PURPOSE OF THIS SUBROUTINE:
13904 : // This subroutine performs L-U factorization of a skyline ordered matrix, [A]
13905 : // The algorithm has been restructured for clarity.
13906 : // Note dependence on compiler for optimizing the inner do loops.
13907 :
13908 : // METHODOLOGY EMPLOYED:
13909 : // L-U factorization of a skyline ordered matrix, [A], used for
13910 : // solution of simultaneous linear algebraic equations [A] * X = B.
13911 : // No pivoting! No scaling! No warnings!!!
13912 : // Related routines: SLVSKY, SETSKY, FILSKY.
13913 :
13914 : // REFERENCES:
13915 : // Algorithm is described in "The Finite Element Method Displayed",
13916 : // by G. Dhatt and G. Touzot, John Wiley & Sons, New York, 1984.
13917 :
13918 : // USE STATEMENTS:
13919 : // na
13920 :
13921 : // Argument array dimensioning
13922 8079115 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
13923 8079115 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
13924 8079115 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
13925 8079115 : EP_SIZE_CHECK(AL, IK(ActualNumOfNodes + 1) - 1);
13926 :
13927 : // Locals
13928 : // SUBROUTINE ARGUMENT DEFINITIONS:
13929 : // noel, GNU says the AU is indexed above its upper bound
13930 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
13931 :
13932 : // SUBROUTINE PARAMETER DEFINITIONS:
13933 : // na
13934 :
13935 : // INTERFACE BLOCK SPECIFICATIONS
13936 : // na
13937 :
13938 : // DERIVED TYPE DEFINITIONS
13939 : // na
13940 :
13941 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13942 : int JHK;
13943 : int JHK1;
13944 : int LHK;
13945 : int LHK1;
13946 : int IMIN;
13947 : int IMIN1;
13948 : int JHJ;
13949 : int JHJ1;
13950 : int IC;
13951 : int i;
13952 : int j;
13953 : int k;
13954 : Real64 T1;
13955 : Real64 T2;
13956 : Real64 SDOT;
13957 : Real64 SUMD;
13958 :
13959 8079115 : AD(1) = 1.0 / AD(1);
13960 8079115 : JHK = 1;
13961 207509730 : for (k = 2; k <= NEQ; ++k) {
13962 199430615 : SUMD = 0.0;
13963 199430615 : JHK1 = IK(k + 1);
13964 199430615 : LHK = JHK1 - JHK;
13965 199430615 : if (LHK > 0) {
13966 120957738 : LHK1 = LHK - 1;
13967 120957738 : IMIN = k - LHK1;
13968 120957738 : IMIN1 = IMIN - 1;
13969 120957738 : if (NSYM == 1) AL(JHK) *= AD(IMIN1);
13970 120957738 : if (LHK1 != 0) {
13971 64200250 : JHJ = IK(IMIN);
13972 64200250 : if (NSYM == 0) {
13973 767550348 : for (j = 1; j <= LHK1; ++j) {
13974 703350098 : JHJ1 = IK(IMIN + j);
13975 703350098 : IC = min(j, JHJ1 - JHJ);
13976 703350098 : if (IC > 0) {
13977 382589757 : SDOT = 0.0;
13978 2416619539 : for (i = 0; i <= IC - 1; ++i) {
13979 2034029782 : SDOT += AU(JHJ1 - IC + i) * AU(JHK + j - IC + i);
13980 : }
13981 382589757 : AU(JHK + j) -= SDOT;
13982 : }
13983 703350098 : JHJ = JHJ1;
13984 : }
13985 : } else {
13986 0 : for (j = 1; j <= LHK1; ++j) {
13987 0 : JHJ1 = IK(IMIN + j);
13988 0 : IC = min(j, JHJ1 - JHJ);
13989 0 : SDOT = 0.0;
13990 0 : if (IC > 0) {
13991 0 : for (i = 0; i <= IC - 1; ++i) {
13992 0 : SDOT += AL(JHJ1 - IC + i) * AU(JHK + j - IC + i);
13993 : }
13994 0 : AU(JHK + j) -= SDOT;
13995 0 : SDOT = 0.0;
13996 0 : for (i = 0; i <= IC - 1; ++i) {
13997 0 : SDOT += AU(JHJ1 - IC + i) * AL(JHK + j - IC + i);
13998 : }
13999 : }
14000 0 : AL(JHK + j) = (AL(JHK + j) - SDOT) * AD(IMIN1 + j);
14001 0 : JHJ = JHJ1;
14002 : }
14003 : }
14004 : }
14005 120957738 : if (NSYM == 0) {
14006 945265574 : for (i = 0; i <= LHK1; ++i) {
14007 824307836 : T1 = AU(JHK + i);
14008 824307836 : T2 = T1 * AD(IMIN1 + i);
14009 824307836 : AU(JHK + i) = T2;
14010 824307836 : SUMD += T1 * T2;
14011 : }
14012 : } else {
14013 0 : for (i = 0; i <= LHK1; ++i) {
14014 0 : SUMD += AU(JHK + i) * AL(JHK + i);
14015 : }
14016 : }
14017 : }
14018 199430615 : if (AD(k) - SUMD == 0.0) {
14019 0 : ShowSevereError(m_state, "AirflowNetworkSolver: L-U factorization in Subroutine FACSKY.");
14020 0 : ShowContinueError(
14021 : m_state,
14022 0 : "The denominator used in L-U factorizationis equal to 0.0 at node = " + m_state.afn->AirflowNetworkNodeData(k).Name + '.');
14023 0 : ShowContinueError(
14024 : m_state, "One possible cause is that this node may not be connected directly, or indirectly via airflow network connections ");
14025 0 : ShowContinueError(
14026 : m_state, "(e.g., AirflowNetwork:Multizone:SurfaceCrack, AirflowNetwork:Multizone:Component:SimpleOpening, etc.), to an external");
14027 0 : ShowContinueError(m_state, "node (AirflowNetwork:MultiZone:Surface).");
14028 0 : ShowContinueError(m_state,
14029 : "Please send your input file and weather file to EnergyPlus support/development team for further investigation.");
14030 0 : ShowFatalError(m_state, "Preceding condition causes termination.");
14031 : }
14032 199430615 : AD(k) = 1.0 / (AD(k) - SUMD);
14033 199430615 : JHK = JHK1;
14034 : }
14035 8079115 : }
14036 :
14037 8079115 : void Solver::slvsky(const Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
14038 : const Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
14039 : const Array1D<Real64> &AL, // the lower triangle of [A] before and after factoring
14040 : Array1D<Real64> &B, // "B" vector (input); "X" vector (output).
14041 : const Array1D_int &IK, // pointer to the top of column/row "K"
14042 : int const NEQ, // number of equations
14043 : int const NSYM // symmetry: 0 = symmetric matrix, 1 = non-symmetric
14044 : )
14045 : {
14046 :
14047 : // SUBROUTINE INFORMATION:
14048 : // AUTHOR George Walton
14049 : // DATE WRITTEN Extracted from AIRNET
14050 : // MODIFIED Lixing Gu, 2/1/04
14051 : // Revised the subroutine to meet E+ needs
14052 : // MODIFIED Lixing Gu, 6/8/05
14053 : // RE-ENGINEERED This subroutine is revised from CLVSKY developed by George Walton, NIST
14054 :
14055 : // PURPOSE OF THIS SUBROUTINE:
14056 : // This subroutine solves simultaneous linear algebraic equations [A] * X = B
14057 : // using L-U factored skyline form of [A] from "FACSKY"
14058 :
14059 : // METHODOLOGY EMPLOYED:
14060 : // na
14061 :
14062 : // REFERENCES:
14063 : // na
14064 :
14065 : // USE STATEMENTS:
14066 : // na
14067 :
14068 : // Argument array dimensioning
14069 8079115 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
14070 8079115 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
14071 8079115 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
14072 8079115 : EP_SIZE_CHECK(AL, IK(ActualNumOfNodes + 1) - 1);
14073 8079115 : EP_SIZE_CHECK(B, ActualNumOfNodes);
14074 :
14075 : // Locals
14076 : // SUBROUTINE ARGUMENT DEFINITIONS:
14077 : // noel, GNU says the AU is indexed above its upper bound
14078 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
14079 :
14080 : // SUBROUTINE PARAMETER DEFINITIONS:
14081 : // na
14082 :
14083 : // INTERFACE BLOCK SPECIFICATIONS
14084 : // na
14085 :
14086 : // DERIVED TYPE DEFINITIONS
14087 : // na
14088 :
14089 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14090 :
14091 : int i;
14092 : int JHK;
14093 : int JHK1;
14094 : int k;
14095 : int LHK;
14096 : Real64 SDOT;
14097 : Real64 T1;
14098 :
14099 8079115 : JHK = 1;
14100 207509730 : for (k = 2; k <= NEQ; ++k) {
14101 199430615 : JHK1 = IK(k + 1);
14102 199430615 : LHK = JHK1 - JHK;
14103 199430615 : if (LHK <= 0) continue;
14104 120957738 : SDOT = 0.0;
14105 120957738 : if (NSYM == 0) {
14106 945265574 : for (i = 0; i <= LHK - 1; ++i) {
14107 824307836 : SDOT += AU(JHK + i) * B(k - LHK + i);
14108 : }
14109 : } else {
14110 0 : for (i = 0; i <= LHK - 1; ++i) {
14111 0 : SDOT += AL(JHK + i) * B(k - LHK + i);
14112 : }
14113 : }
14114 120957738 : B(k) -= SDOT;
14115 120957738 : JHK = JHK1;
14116 : }
14117 8079115 : if (NSYM == 0) {
14118 215588845 : for (k = 1; k <= NEQ; ++k) {
14119 207509730 : B(k) *= AD(k);
14120 : }
14121 : }
14122 8079115 : k = NEQ + 1;
14123 8079115 : JHK1 = IK(k);
14124 406940345 : while (k != 1) {
14125 207509730 : --k;
14126 207509730 : if (NSYM == 1) B(k) *= AD(k);
14127 207509730 : if (k == 1) break;
14128 : // IF(K.EQ.1) RETURN
14129 199430615 : JHK = IK(k);
14130 199430615 : T1 = B(k);
14131 1023738451 : for (i = 0; i <= JHK1 - JHK - 1; ++i) {
14132 824307836 : B(k - JHK1 + JHK + i) -= AU(JHK + i) * T1;
14133 : }
14134 199430615 : JHK1 = JHK;
14135 : }
14136 8079115 : }
14137 :
14138 289029503 : void Solver::filsky(const Array1D<Real64> &X, // element array (row-wise sequence)
14139 : std::array<int, 2> const LM, // location matrix
14140 : const Array1D_int &IK, // pointer to the top of column/row "K"
14141 : Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
14142 : Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
14143 : int const FLAG // mode of operation
14144 : )
14145 : {
14146 :
14147 : // SUBROUTINE INFORMATION:
14148 : // AUTHOR George Walton
14149 : // DATE WRITTEN Extracted from AIRNET
14150 : // MODIFIED Lixing Gu, 2/1/04
14151 : // Revised the subroutine to meet E+ needs
14152 : // MODIFIED Lixing Gu, 6/8/05
14153 : // RE-ENGINEERED This subroutine is revised from FILSKY developed by George Walton, NIST
14154 :
14155 : // PURPOSE OF THIS SUBROUTINE:
14156 : // This subroutine adds element array "X" to the sparse skyline matrix [A]
14157 :
14158 : // METHODOLOGY EMPLOYED:
14159 : // na
14160 :
14161 : // REFERENCES:
14162 : // na
14163 :
14164 : // USE STATEMENTS:
14165 : // na
14166 :
14167 : // Argument array dimensioning
14168 289029503 : EP_SIZE_CHECK(X, 4);
14169 289029503 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
14170 289029503 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
14171 289029503 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
14172 :
14173 : // Locals
14174 : // SUBROUTINE ARGUMENT DEFINITIONS:
14175 : // noel, GNU says the AU is indexed above its upper bound
14176 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
14177 :
14178 : // SUBROUTINE PARAMETER DEFINITIONS:
14179 : // na
14180 :
14181 : // INTERFACE BLOCK SPECIFICATIONS
14182 : // na
14183 :
14184 : // DERIVED TYPE DEFINITIONS
14185 : // na
14186 :
14187 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14188 : int j;
14189 : int k;
14190 : int L;
14191 :
14192 : // K = row number, L = column number.
14193 289029503 : if (FLAG > 1) {
14194 289029503 : k = LM[0];
14195 289029503 : L = LM[1];
14196 289029503 : if (FLAG == 4) {
14197 191803202 : AD(k) += X(1);
14198 191803202 : if (k < L) {
14199 156315442 : j = IK(L + 1) - L + k;
14200 156315442 : AU(j) += X(2);
14201 : } else {
14202 35487760 : j = IK(k + 1) - k + L;
14203 35487760 : AU(j) += X(3);
14204 : }
14205 191803202 : AD(L) += X(4);
14206 97226301 : } else if (FLAG == 3) {
14207 1014215 : AD(L) += X(4);
14208 96212086 : } else if (FLAG == 2) {
14209 96212086 : AD(k) += X(1);
14210 : }
14211 : }
14212 289029503 : }
14213 :
14214 : } // namespace AirflowNetwork
14215 :
14216 2313 : } // namespace EnergyPlus
|