Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #include "AirflowNetwork/Solver.hpp"
49 :
50 : // C++ Headers
51 : #include <algorithm>
52 : #include <cmath>
53 : #include <set>
54 : #include <string>
55 :
56 : // ObjexxFCL Headers
57 : #include <ObjexxFCL/Array.functions.hh>
58 : #include <ObjexxFCL/Array2D.hh>
59 : // #include <ObjexxFCL/Fmath.hh>
60 :
61 : // EnergyPlus Headers
62 : #include <AirflowNetwork/Elements.hpp>
63 : #include <AirflowNetwork/Solver.hpp>
64 : #include <EnergyPlus/BranchNodeConnections.hh>
65 : #include <EnergyPlus/Coils/CoilCoolingDX.hh>
66 : #include <EnergyPlus/Construction.hh>
67 : #include <EnergyPlus/CurveManager.hh>
68 : #include <EnergyPlus/DXCoils.hh>
69 : #include <EnergyPlus/Data/EnergyPlusData.hh>
70 : #include <EnergyPlus/DataAirLoop.hh>
71 : #include <EnergyPlus/DataAirSystems.hh>
72 : #include <EnergyPlus/DataBranchNodeConnections.hh>
73 : #include <EnergyPlus/DataContaminantBalance.hh>
74 : #include <EnergyPlus/DataDefineEquip.hh>
75 : #include <EnergyPlus/DataEnvironment.hh>
76 : #include <EnergyPlus/DataHVACGlobals.hh>
77 : #include <EnergyPlus/DataHeatBalFanSys.hh>
78 : #include <EnergyPlus/DataHeatBalSurface.hh>
79 : #include <EnergyPlus/DataHeatBalance.hh>
80 : #include <EnergyPlus/DataLoopNode.hh>
81 : #include <EnergyPlus/DataRoomAirModel.hh>
82 : #include <EnergyPlus/DataSurfaces.hh>
83 : #include <EnergyPlus/DataZoneEquipment.hh>
84 : #include <EnergyPlus/EMSManager.hh>
85 : #include <EnergyPlus/Fans.hh>
86 : #include <EnergyPlus/General.hh>
87 : #include <EnergyPlus/GeneralRoutines.hh>
88 : #include <EnergyPlus/GlobalNames.hh>
89 : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
90 : #include <EnergyPlus/HVACStandAloneERV.hh>
91 : #include <EnergyPlus/HVACVariableRefrigerantFlow.hh>
92 : #include <EnergyPlus/HeatingCoils.hh>
93 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
94 : #include <EnergyPlus/MixedAir.hh>
95 : #include <EnergyPlus/NodeInputManager.hh>
96 : #include <EnergyPlus/OutAirNodeManager.hh>
97 : #include <EnergyPlus/OutputProcessor.hh>
98 : #include <EnergyPlus/Psychrometrics.hh>
99 : #include <EnergyPlus/RoomAirModelManager.hh>
100 : #include <EnergyPlus/ScheduleManager.hh>
101 : #include <EnergyPlus/SingleDuct.hh>
102 : #include <EnergyPlus/SplitterComponent.hh>
103 : #include <EnergyPlus/ThermalComfort.hh>
104 : #include <EnergyPlus/UnitarySystem.hh>
105 : #include <EnergyPlus/UtilityRoutines.hh>
106 : #include <EnergyPlus/WaterThermalTanks.hh>
107 : #include <EnergyPlus/WindowAC.hh>
108 : #include <EnergyPlus/ZoneDehumidifier.hh>
109 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
110 :
111 : namespace EnergyPlus {
112 :
113 : namespace AirflowNetwork {
114 :
115 : // MODULE INFORMATION:
116 : // AUTHOR Lixing Gu, Don Shirey, and Muthusamy V. Swami
117 : // DATE WRITTEN July 2005
118 : // MODIFIED na
119 : // RE-ENGINEERED na
120 :
121 : // PURPOSE OF THIS MODULE:
122 : // This module is used to simulate airflows and pressures. The module is modified to
123 : // meet requirements of EnergyPLus based on AIRNET, developed by
124 : // National Institute of Standards and Technology (NIST).
125 :
126 : // METHODOLOGY EMPLOYED:
127 : // An airflow network approach is used. It consists of nodes connected by airflow elements.
128 : // The Newton's method is applied to solve a sparse matrix. When a new solver is available, this
129 : // module will be replaced or updated.
130 :
131 : // REFERENCES:
132 : // Walton, G. N., 1989, "AIRNET - A Computer Program for Building Airflow Network Modeling,"
133 : // NISTIR 89-4072, National Institute of Standards and Technology, Gaithersburg, Maryland
134 :
135 : // Using/Aliasing
136 : using Curve::CurveValue;
137 : using Curve::GetCurveIndex;
138 : using DataEnvironment::OutDryBulbTempAt;
139 : using DataSurfaces::cExtBoundCondition;
140 : using DataSurfaces::ExternalEnvironment;
141 : using DataSurfaces::OtherSideCoefNoCalcExt;
142 : using DataSurfaces::SurfaceClass;
143 : using Fans::GetFanIndex;
144 : using Psychrometrics::PsyCpAirFnW;
145 : using Psychrometrics::PsyHFnTdbW;
146 : using Psychrometrics::PsyRhoAirFnPbTdbW;
147 :
148 2129 : Solver::Solver(EnergyPlusData &state) : m_state(state), properties(state)
149 : {
150 2129 : }
151 :
152 : int constexpr NumOfVentCtrTypes(6); // Number of zone level venting control types
153 :
154 16955 : void Solver::manage_balance(ObjexxFCL::Optional_bool_const FirstHVACIteration, // True when solution technique on first iteration
155 : ObjexxFCL::Optional_int_const Iter, // Iteration number
156 : ObjexxFCL::Optional_bool ResimulateAirZone // True when solution technique on third iteration
157 : )
158 : {
159 :
160 : // SUBROUTINE INFORMATION:
161 : // AUTHOR Lixing Gu
162 : // DATE WRITTEN July 28, 2005
163 :
164 : // PURPOSE OF THIS SUBROUTINE:
165 : // This subroutine performs simulation of air distribution system.
166 :
167 : // Locals
168 : int i;
169 16955 : HVAC::FanType AFNSupplyFanType = HVAC::FanType::Invalid;
170 :
171 16955 : if (AirflowNetworkGetInputFlag) {
172 102 : get_input();
173 102 : AirflowNetworkGetInputFlag = false;
174 102 : return;
175 : }
176 :
177 16853 : if (present(ResimulateAirZone)) {
178 8349 : ResimulateAirZone = false;
179 : }
180 :
181 16853 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) return;
182 :
183 16853 : if (m_state.dataGlobal->BeginEnvrnFlag) {
184 138 : m_state.dataHVACGlobal->TurnFansOn = false; // The FAN should be off when BeginEnvrnFlag = .True.
185 : }
186 :
187 16853 : initialize();
188 :
189 16853 : auto &NetworkNumOfNodes = ActualNumOfNodes;
190 16853 : auto &NetworkNumOfLinks = ActualNumOfLinks;
191 :
192 16853 : NetworkNumOfNodes = NumOfNodesMultiZone;
193 16853 : NetworkNumOfLinks = NumOfLinksMultiZone;
194 :
195 16853 : AirflowNetworkFanActivated = false;
196 :
197 16853 : if (present(FirstHVACIteration) && distribution_simulated) {
198 16852 : if (FirstHVACIteration) {
199 2820 : if (allocated(m_state.dataAirLoop->AirLoopAFNInfo)) {
200 5640 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
201 2820 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopHeatingCoilMaxRTF = 0.0;
202 2820 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopOnOffFanRTF = 0.0;
203 2820 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopDXCoilRTF = 0.0;
204 2820 : m_state.dataAirLoop->AirLoopAFNInfo(i).LoopOnOffFanPartLoadRatio = 0.0;
205 : }
206 : }
207 : }
208 16852 : Real64 FanMassFlowRate = 0.0;
209 16852 : HVAC::FanOp FanOperModeCyc = HVAC::FanOp::Invalid;
210 16852 : AFNSupplyFanType = HVAC::FanType::Invalid;
211 :
212 19888 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
213 16852 : AFNSupplyFanType = DisSysCompCVFData(i).fanType;
214 16852 : FanMassFlowRate = max(FanMassFlowRate, m_state.dataLoopNodes->Node(DisSysCompCVFData(i).OutletNode).MassFlowRate);
215 : // VAV take high priority
216 16852 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::VAV) {
217 0 : AFNSupplyFanType = DisSysCompCVFData(i).fanType;
218 0 : break;
219 : }
220 30668 : if (FanMassFlowRate > HVAC::VerySmallMassFlow &&
221 30668 : m_state.dataAirLoop->AirLoopAFNInfo(i).LoopFanOperationMode == HVAC::FanOp::Cycling &&
222 13816 : m_state.dataAirLoop->AirLoopAFNInfo(i).LoopSystemOnMassFlowrate > 0.0) {
223 13816 : FanOperModeCyc = HVAC::FanOp::Cycling;
224 13816 : AFNSupplyFanType = DisSysCompCVFData(i).fanType;
225 13816 : if (AFNSupplyFanType == HVAC::FanType::OnOff) {
226 13816 : break;
227 : }
228 : }
229 : }
230 : // Revised to meet heat exchanger requirement
231 16852 : if ((FanMassFlowRate > HVAC::VerySmallMassFlow) && (!FirstHVACIteration)) {
232 11054 : if (AFNSupplyFanType == HVAC::FanType::OnOff && FanOperModeCyc == HVAC::FanOp::Cycling) {
233 11054 : AirflowNetworkFanActivated = true;
234 0 : } else if (AFNSupplyFanType == HVAC::FanType::VAV) {
235 0 : if (present(Iter) && Iter > 1) AirflowNetworkFanActivated = true;
236 0 : } else if (AirflowNetworkUnitarySystem) {
237 0 : if (present(Iter) && Iter > 1) AirflowNetworkFanActivated = true;
238 : } else {
239 0 : AirflowNetworkFanActivated = true;
240 : }
241 : }
242 : }
243 16853 : if (allocated(m_state.dataZoneEquip->ZoneEquipConfig) && m_state.dataAvail->NumHybridVentSysAvailMgrs > 0 &&
244 0 : allocated(m_state.dataAirSystemsData->PrimaryAirSystems)) {
245 0 : hybrid_ventilation_control();
246 : }
247 16853 : if (ventCtrlStatus == Avail::VentCtrlStatus::Open && m_state.dataAvail->NumHybridVentSysAvailMgrs > 0) {
248 0 : AirflowNetworkFanActivated = false;
249 : }
250 :
251 16853 : if (present(Iter) && present(ResimulateAirZone) && distribution_simulated) {
252 8348 : if (AirflowNetworkFanActivated && Iter < 3 && AFNSupplyFanType == HVAC::FanType::OnOff) {
253 5528 : ResimulateAirZone = true;
254 : }
255 8348 : if (AFNSupplyFanType == HVAC::FanType::VAV) {
256 0 : if (!AirflowNetworkFanActivated && Iter < 3) ResimulateAirZone = true;
257 : }
258 8348 : if (AirflowNetworkUnitarySystem) {
259 0 : if (!AirflowNetworkFanActivated && Iter < 3) ResimulateAirZone = true;
260 : }
261 : }
262 16853 : if (AirflowNetworkFanActivated && distribution_simulated) {
263 11054 : NetworkNumOfNodes = AirflowNetworkNumOfNodes;
264 11054 : NetworkNumOfLinks = AirflowNetworkNumOfLinks;
265 : }
266 :
267 16853 : if (allocated(m_state.dataZoneEquip->ZoneEquipConfig)) validate_exhaust_fan_input();
268 :
269 : // VAV terminal set only
270 16853 : if (present(FirstHVACIteration) && FirstHVACIteration) VAVTerminalRatio = 0.0;
271 :
272 16853 : if (AirflowNetworkFanActivated && distribution_simulated) {
273 11054 : if (ValidateDistributionSystemFlag) {
274 1 : validate_distribution();
275 1 : validate_fan_flowrate();
276 1 : ValidateDistributionSystemFlag = false;
277 1 : if (simulation_control.autosize_ducts) {
278 0 : SizeDucts();
279 : }
280 : }
281 : }
282 16853 : calculate_balance();
283 :
284 16853 : if (AirflowNetworkFanActivated && distribution_simulated) {
285 :
286 11054 : LoopOnOffFlag = false;
287 22108 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
288 11054 : if (DisSysCompCVFData(i).AirLoopNum > 0) {
289 11054 : if (m_state.dataLoopNodes->Node(DisSysCompCVFData(i).InletNode).MassFlowRate > 0.0) {
290 11054 : LoopOnOffFlag(DisSysCompCVFData(i).AirLoopNum) = true;
291 : }
292 : }
293 : }
294 :
295 11054 : calculate_heat_balance();
296 11054 : calculate_moisture_balance();
297 11054 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) calculate_CO2_balance();
298 11054 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) calculate_GC_balance();
299 : }
300 :
301 16853 : update(FirstHVACIteration);
302 : }
303 :
304 25 : bool Solver::get_element_input()
305 : {
306 : // SUBROUTINE INFORMATION:
307 : // AUTHOR Jason DeGraw
308 : // DATE WRITTEN Oct. 2018
309 : // MODIFIED na
310 : // RE-ENGINEERED na
311 :
312 : // PURPOSE OF THIS SUBROUTINE:
313 : // This subroutine reads airflow element inputs (eventually)
314 :
315 : static constexpr std::string_view RoutineName{"get_element_input"};
316 25 : std::string CurrentModuleObject;
317 25 : bool success{true};
318 :
319 : // *** Read AirflowNetwork simulation reference crack conditions
320 25 : std::unordered_map<std::string, ReferenceConditions> referenceConditions; // Map for lookups
321 25 : ReferenceConditions defaultReferenceConditions("Default"); // Defaulted conditions
322 25 : bool conditionsAreDefaulted(true); // Conditions are defaulted?
323 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:ReferenceCrackConditions";
324 25 : auto instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
325 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
326 : // globalSolverObject.referenceConditions.clear();
327 17 : auto &instancesValue = instances.value();
328 35 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
329 18 : auto const &fields = instance.value();
330 18 : auto const &thisObjectName = Util::makeUPPER(instance.key());
331 18 : Real64 temperature(20.0);
332 54 : if (fields.find("reference_temperature") != fields.end()) { // required field, has default value
333 36 : temperature = fields.at("reference_temperature").get<Real64>();
334 : }
335 18 : Real64 pressure(101325.0);
336 54 : if (fields.find("reference_barometric_pressure") != fields.end()) { // not required field, has default value
337 17 : pressure = fields.at("reference_barometric_pressure").get<Real64>();
338 17 : if (std::abs((pressure - m_state.dataEnvrn->StdBaroPress) / m_state.dataEnvrn->StdBaroPress) > 0.1) { // 10% off
339 2 : ShowWarningError(m_state,
340 2 : format("{}: {}: Pressure = {:.0R} differs by more than 10% from Standard Barometric Pressure = {:.0R}.",
341 : RoutineName,
342 : CurrentModuleObject,
343 : pressure,
344 1 : m_state.dataEnvrn->StdBaroPress));
345 1 : ShowContinueError(m_state, "...occurs in " + CurrentModuleObject + " = " + thisObjectName);
346 : }
347 17 : if (pressure <= 31000.0) {
348 0 : ShowSevereError(m_state,
349 0 : format("{}: {}: {}. Reference Barometric Pressure must be greater than 31000 Pa.",
350 : RoutineName,
351 : CurrentModuleObject,
352 : thisObjectName));
353 0 : success = false;
354 : }
355 : }
356 18 : Real64 humidity(0.0);
357 54 : if (fields.find("reference_humidity_ratio") != fields.end()) { // not required field, has default value
358 34 : humidity = fields.at("reference_humidity_ratio").get<Real64>();
359 : }
360 : // globalSolverObject.referenceConditions.emplace_back(thisObjectName, temperature, pressure, humidity);
361 18 : referenceConditions.emplace(std::piecewise_construct,
362 18 : std::forward_as_tuple(thisObjectName),
363 18 : std::forward_as_tuple(instance.key(), temperature, pressure, humidity));
364 18 : }
365 : // Check that there is more than one
366 17 : if (referenceConditions.size() == 1) {
367 32 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
368 16 : referenceConditions.begin()->second.name);
369 16 : defaultReferenceConditions = referenceConditions.begin()->second;
370 :
371 : } else {
372 1 : conditionsAreDefaulted = false;
373 : }
374 : }
375 25 : if (!success) {
376 0 : return false;
377 : }
378 :
379 : // *** Read AirflowNetwork simulation surface crack component
380 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface:Crack";
381 25 : AirflowNetworkNumOfSurCracks =
382 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
383 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
384 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
385 18 : int i = 1; // Temporary workaround
386 18 : MultizoneSurfaceCrackData.allocate(AirflowNetworkNumOfSurCracks); // Temporary workaround
387 18 : auto &instancesValue = instances.value();
388 54 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
389 36 : auto const &fields = instance.value();
390 36 : auto const &thisObjectName = Util::makeUPPER(instance.key());
391 36 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
392 :
393 36 : Real64 coeff{fields.at("air_mass_flow_coefficient_at_reference_conditions")}; // Required field
394 36 : Real64 expnt{0.65};
395 108 : if (fields.find("air_mass_flow_exponent") != fields.end()) { // not required field, has default value
396 72 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
397 : }
398 36 : Real64 refT = defaultReferenceConditions.temperature;
399 36 : Real64 refP = defaultReferenceConditions.pressure;
400 36 : Real64 refW = defaultReferenceConditions.humidity_ratio;
401 36 : if (!conditionsAreDefaulted) {
402 6 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
403 2 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
404 2 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
405 :
406 2 : if (result == referenceConditions.end()) {
407 0 : ShowSevereError(m_state,
408 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
409 : RoutineName,
410 : CurrentModuleObject,
411 : thisObjectName,
412 : refCrackCondName));
413 0 : success = false;
414 : } else {
415 2 : refT = result->second.temperature;
416 2 : refP = result->second.pressure;
417 2 : refW = result->second.humidity_ratio;
418 6 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
419 2 : result->second.name);
420 : }
421 2 : }
422 : }
423 : // globalSolverObject.cracks[thisObjectName] = SurfaceCrack(coeff, expnt, refT, refP, refW);
424 36 : MultizoneSurfaceCrackData(i).name = thisObjectName; // Name of surface crack component
425 36 : MultizoneSurfaceCrackData(i).coefficient = coeff; // Air Mass Flow Coefficient
426 36 : MultizoneSurfaceCrackData(i).exponent = expnt; // Air Mass Flow exponent
427 36 : MultizoneSurfaceCrackData(i).reference_density = properties.density(refP, refT, refW);
428 36 : MultizoneSurfaceCrackData(i).reference_viscosity = properties.dynamic_viscosity(refT);
429 :
430 : // This is the first element that is being added to the lookup table, so no check of naming overlaps
431 36 : elements[thisObjectName] = &MultizoneSurfaceCrackData(i); // Yet another workaround
432 :
433 36 : ++i;
434 36 : }
435 : }
436 :
437 : // *** Read AirflowNetwork simulation zone exhaust fan component
438 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:ZoneExhaustFan";
439 25 : AirflowNetworkNumOfExhFan =
440 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
441 25 : NumOfExhaustFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "Fan:ZoneExhaust"); // Temporary workaround
442 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
443 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
444 3 : int i = 1; // Temporary workaround
445 3 : MultizoneCompExhaustFanData.allocate(AirflowNetworkNumOfExhFan); // Temporary workaround
446 3 : auto &instancesValue = instances.value();
447 6 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
448 3 : auto const &fields = instance.value();
449 3 : auto const &thisObjectName = Util::makeUPPER(instance.key());
450 :
451 3 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
452 :
453 3 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_the_zone_exhaust_fan_is_off_at_reference_conditions")}; // Required field
454 3 : Real64 expnt{0.65};
455 9 : if (fields.find("air_mass_flow_exponent_when_the_zone_exhaust_fan_is_off") != fields.end()) { // not required field, has default value
456 6 : expnt = fields.at("air_mass_flow_exponent_when_the_zone_exhaust_fan_is_off").get<Real64>();
457 : }
458 :
459 : // This breaks the component model, need to fix
460 3 : int fanIndex = GetFanIndex(m_state, thisObjectName);
461 3 : if (fanIndex == 0) {
462 0 : ShowSevereError(m_state,
463 0 : format("{}: {} = {} is not found in Fan:ZoneExhaust objects.", RoutineName, CurrentModuleObject, thisObjectName));
464 0 : success = false;
465 : }
466 :
467 3 : auto *fan = m_state.dataFans->fans(fanIndex);
468 :
469 3 : Real64 flowRate = fan->maxAirFlowRate;
470 3 : flowRate *= m_state.dataEnvrn->StdRhoAir;
471 3 : int inletNode = fan->inletNodeNum;
472 3 : int outletNode = fan->outletNodeNum;
473 3 : HVAC::FanType fanType = fan->type;
474 3 : if (fanType != HVAC::FanType::Exhaust) {
475 0 : ShowSevereError(m_state,
476 0 : format("{}: {} = {}. The specified Name is not found as a valid Fan:ZoneExhaust object.",
477 : RoutineName,
478 : CurrentModuleObject,
479 : thisObjectName));
480 0 : success = false;
481 : }
482 :
483 3 : Real64 refT = defaultReferenceConditions.temperature;
484 3 : Real64 refP = defaultReferenceConditions.pressure;
485 3 : Real64 refW = defaultReferenceConditions.humidity_ratio;
486 3 : if (!conditionsAreDefaulted) {
487 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
488 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
489 0 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
490 0 : if (result == referenceConditions.end()) {
491 0 : ShowSevereError(m_state,
492 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
493 : RoutineName,
494 : CurrentModuleObject,
495 : thisObjectName,
496 0 : fields.at("reference_crack_conditions").get<std::string>()));
497 0 : success = false;
498 : } else {
499 0 : refT = result->second.temperature;
500 0 : refP = result->second.pressure;
501 0 : refW = result->second.humidity_ratio;
502 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
503 0 : result->second.name);
504 : }
505 0 : }
506 : }
507 :
508 3 : MultizoneCompExhaustFanData(i).name = thisObjectName; // Name of zone exhaust fan component
509 3 : MultizoneCompExhaustFanData(i).FlowCoef = coeff; // flow coefficient
510 3 : MultizoneCompExhaustFanData(i).FlowExpo = expnt; // Flow exponent
511 :
512 3 : MultizoneCompExhaustFanData(i).FlowRate = flowRate;
513 3 : MultizoneCompExhaustFanData(i).InletNode = inletNode;
514 3 : MultizoneCompExhaustFanData(i).OutletNode = outletNode;
515 :
516 3 : MultizoneCompExhaustFanData(i).StandardT = refT;
517 3 : MultizoneCompExhaustFanData(i).StandardP = refP;
518 3 : MultizoneCompExhaustFanData(i).StandardW = refW;
519 :
520 : // Add the element to the lookup table, check for name overlaps
521 3 : if (elements.find(thisObjectName) == elements.end()) {
522 3 : elements[thisObjectName] = &MultizoneCompExhaustFanData(i); // Yet another workaround
523 : } else {
524 0 : ShowSevereError(
525 : m_state,
526 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
527 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
528 0 : success = false;
529 : }
530 :
531 3 : ++i;
532 3 : }
533 : }
534 :
535 : // Read Outdoor Airflow object
536 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:OutdoorAirFlow";
537 25 : NumOfOAFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
538 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
539 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
540 2 : int i = 1; // Temporary workaround
541 2 : DisSysCompOutdoorAirData.allocate(NumOfOAFans); // Temporary workaround
542 2 : auto &instancesValue = instances.value();
543 5 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
544 3 : auto const &fields = instance.value();
545 3 : auto const &thisObjectName = Util::makeUPPER(instance.key());
546 3 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
547 :
548 6 : std::string mixer_name = Util::makeUPPER(fields.at("outdoor_air_mixer_name").get<std::string>());
549 3 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_no_outdoor_air_flow_at_reference_conditions")};
550 3 : Real64 expnt{0.65};
551 9 : if (fields.find("air_mass_flow_exponent_when_no_outdoor_air_flow") != fields.end()) {
552 6 : expnt = fields.at("air_mass_flow_exponent_when_no_outdoor_air_flow").get<Real64>();
553 : }
554 :
555 3 : int OAMixerNum = MixedAir::GetOAMixerNumber(m_state, mixer_name);
556 3 : if (OAMixerNum == 0) {
557 0 : ShowSevereError(m_state,
558 0 : format("{}: {}: {}. Invalid Outdoor Air Mixer Name \"{}\" given.",
559 : RoutineName,
560 : CurrentModuleObject,
561 : thisObjectName,
562 : mixer_name));
563 0 : success = false;
564 : }
565 :
566 3 : Real64 refT = defaultReferenceConditions.temperature;
567 3 : Real64 refP = defaultReferenceConditions.pressure;
568 3 : Real64 refW = defaultReferenceConditions.humidity_ratio;
569 3 : if (!conditionsAreDefaulted) {
570 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
571 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
572 0 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
573 0 : if (result == referenceConditions.end()) {
574 0 : ShowSevereError(m_state,
575 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
576 : RoutineName,
577 : CurrentModuleObject,
578 : thisObjectName,
579 : refCrackCondName));
580 0 : success = false;
581 : } else {
582 0 : refT = result->second.temperature;
583 0 : refP = result->second.pressure;
584 0 : refW = result->second.humidity_ratio;
585 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
586 0 : result->second.name);
587 : }
588 0 : }
589 : }
590 :
591 3 : DisSysCompOutdoorAirData(i).name = thisObjectName; // Name of zone exhaust fan component
592 3 : DisSysCompOutdoorAirData(i).FlowCoef = coeff; // flow coefficient
593 3 : DisSysCompOutdoorAirData(i).FlowExpo = expnt; // Flow exponent
594 :
595 3 : DisSysCompOutdoorAirData(i).OAMixerNum = OAMixerNum;
596 :
597 3 : DisSysCompOutdoorAirData(i).StandardT = refT;
598 3 : DisSysCompOutdoorAirData(i).StandardP = refP;
599 3 : DisSysCompOutdoorAirData(i).StandardW = refW;
600 :
601 : // Add the element to the lookup table, check for name overlaps
602 3 : if (elements.find(thisObjectName) == elements.end()) {
603 3 : elements[thisObjectName] = &DisSysCompOutdoorAirData(i); // Yet another workaround
604 : } else {
605 0 : ShowSevereError(
606 : m_state,
607 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
608 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
609 0 : success = false;
610 : }
611 :
612 3 : ++i;
613 3 : }
614 : }
615 :
616 : // Read Relief Airflow object
617 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ReliefAirFlow";
618 25 : NumOfReliefFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
619 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
620 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
621 2 : int i = 1; // Temporary workaround
622 2 : DisSysCompReliefAirData.allocate(m_state.afn->NumOfReliefFans); // Temporary workaround
623 2 : auto &instancesValue = instances.value();
624 4 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
625 2 : auto const &fields = instance.value();
626 2 : auto const &thisObjectName = Util::makeUPPER(instance.key());
627 2 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
628 :
629 4 : std::string mixer_name = Util::makeUPPER(fields.at("outdoor_air_mixer_name").get<std::string>());
630 2 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_no_outdoor_air_flow_at_reference_conditions")};
631 2 : Real64 expnt{0.65};
632 6 : if (fields.find("air_mass_flow_exponent_when_no_outdoor_air_flow") != fields.end()) {
633 4 : expnt = fields.at("air_mass_flow_exponent_when_no_outdoor_air_flow").get<Real64>();
634 : }
635 :
636 2 : int OAMixerNum{MixedAir::GetOAMixerNumber(m_state, mixer_name)};
637 2 : if (OAMixerNum == 0) {
638 0 : ShowSevereError(m_state,
639 0 : format(RoutineName) + ": " + CurrentModuleObject + " object " + thisObjectName + ". Invalid " +
640 0 : "Outdoor Air Mixer Name" + " \"" + mixer_name + "\" given.");
641 0 : success = false;
642 : }
643 :
644 2 : Real64 refT = defaultReferenceConditions.temperature;
645 2 : Real64 refP = defaultReferenceConditions.pressure;
646 2 : Real64 refW = defaultReferenceConditions.humidity_ratio;
647 2 : if (!conditionsAreDefaulted) {
648 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
649 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
650 0 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
651 0 : if (result == referenceConditions.end()) {
652 0 : ShowSevereError(m_state,
653 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
654 : RoutineName,
655 : CurrentModuleObject,
656 : thisObjectName,
657 : refCrackCondName));
658 0 : success = false;
659 : } else {
660 0 : refT = result->second.temperature;
661 0 : refP = result->second.pressure;
662 0 : refW = result->second.humidity_ratio;
663 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
664 0 : result->second.name);
665 : }
666 0 : }
667 : }
668 :
669 2 : DisSysCompReliefAirData(i).name = thisObjectName; // Name of zone exhaust fan component
670 2 : DisSysCompReliefAirData(i).FlowCoef = coeff; // flow coefficient
671 2 : DisSysCompReliefAirData(i).FlowExpo = expnt; // Flow exponent
672 2 : DisSysCompReliefAirData(i).OAMixerNum = OAMixerNum;
673 2 : DisSysCompReliefAirData(i).StandardT = refT;
674 2 : DisSysCompReliefAirData(i).StandardP = refP;
675 2 : DisSysCompReliefAirData(i).StandardW = refW;
676 :
677 : // Add the element to the lookup table, check for name overlaps
678 2 : if (elements.find(thisObjectName) == elements.end()) {
679 2 : elements[thisObjectName] = &DisSysCompReliefAirData(i); // Yet another workaround
680 : } else {
681 0 : ShowSevereError(
682 : m_state,
683 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
684 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
685 0 : success = false;
686 : }
687 :
688 2 : ++i;
689 2 : }
690 : }
691 :
692 : // Read AirflowNetwork simulation detailed openings
693 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:DetailedOpening";
694 25 : AirflowNetworkNumOfDetOpenings =
695 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
696 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
697 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
698 25 : int i = 1; // Temporary workaround
699 25 : MultizoneCompDetOpeningData.allocate(AirflowNetworkNumOfDetOpenings); // Temporary workaround
700 25 : auto &instancesValue = instances.value();
701 30 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
702 5 : auto const &fields = instance.value();
703 5 : auto const &thisObjectName = Util::makeUPPER(instance.key());
704 5 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
705 :
706 5 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
707 5 : Real64 expnt{0.65};
708 15 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
709 10 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
710 : }
711 :
712 5 : int LVOtype{1};
713 5 : std::string LVOstring;
714 15 : if (fields.find("type_of_rectangular_large_vertical_opening_lvo_") != fields.end()) {
715 5 : LVOstring = fields.at("type_of_rectangular_large_vertical_opening_lvo_").get<std::string>();
716 5 : if (Util::SameString(LVOstring, "NonPivoted") || Util::SameString(LVOstring, "1")) {
717 5 : LVOtype = 1; // Large vertical opening type number
718 0 : } else if (Util::SameString(LVOstring, "HorizontallyPivoted") || Util::SameString(LVOstring, "2")) {
719 0 : LVOtype = 2; // Large vertical opening type number
720 : } else {
721 : // Code will never be executed, validation will catch invalid input
722 0 : ShowSevereError(m_state,
723 0 : format(RoutineName) + "Invalid Type of Rectangular Large Vertical Opening (LVO) = " + LVOstring + "in " +
724 0 : CurrentModuleObject + " = " + thisObjectName);
725 0 : ShowContinueError(m_state, "Valid choices are NonPivoted and HorizontallyPivoted.");
726 0 : success = false;
727 : }
728 : }
729 :
730 5 : Real64 extra{0.0};
731 15 : if (fields.find("extra_crack_length_or_height_of_pivoting_axis") != fields.end()) {
732 10 : extra = fields.at("extra_crack_length_or_height_of_pivoting_axis").get<Real64>();
733 : }
734 :
735 10 : int N{fields.at("number_of_sets_of_opening_factor_data")};
736 :
737 10 : std::vector<Real64> factors(N);
738 10 : std::vector<Real64> cds(N);
739 10 : std::vector<Real64> width_factors(N);
740 10 : std::vector<Real64> height_factors(N);
741 5 : std::vector<Real64> start_height_factors(N);
742 :
743 : // Real64 factor{0.0};
744 : // if (fields.find("opening_factor_1") != fields.end()) {
745 : // factor = fields.at("opening_factor_1");
746 : //}
747 5 : Real64 cd{0.001};
748 15 : if (fields.find("discharge_coefficient_for_opening_factor_1") != fields.end()) {
749 10 : cd = fields.at("discharge_coefficient_for_opening_factor_1").get<Real64>();
750 : }
751 5 : Real64 width_factor{0.0};
752 15 : if (fields.find("width_factor_for_opening_factor_1") != fields.end()) {
753 10 : width_factor = fields.at("width_factor_for_opening_factor_1").get<Real64>();
754 : }
755 5 : Real64 height_factor{0.0};
756 15 : if (fields.find("height_factor_for_opening_factor_1") != fields.end()) {
757 10 : height_factor = fields.at("height_factor_for_opening_factor_1").get<Real64>();
758 : }
759 5 : Real64 start_height_factor{0.0};
760 15 : if (fields.find("start_height_factor_for_opening_factor_1") != fields.end()) {
761 10 : start_height_factor = fields.at("start_height_factor_for_opening_factor_1").get<Real64>();
762 : }
763 :
764 5 : factors[0] = 0.0; // factor; // This factor must be zero
765 5 : cds[0] = cd;
766 5 : width_factors[0] = width_factor;
767 5 : height_factors[0] = height_factor;
768 5 : start_height_factors[0] = start_height_factor;
769 :
770 5 : Real64 factor{fields.at("opening_factor_2")};
771 5 : cd = 1.0;
772 15 : if (fields.find("discharge_coefficient_for_opening_factor_2") != fields.end()) {
773 10 : cd = fields.at("discharge_coefficient_for_opening_factor_2").get<Real64>();
774 : }
775 5 : width_factor = 1.0;
776 15 : if (fields.find("width_factor_for_opening_factor_2") != fields.end()) {
777 10 : width_factor = fields.at("width_factor_for_opening_factor_2").get<Real64>();
778 : }
779 5 : height_factor = 1.0;
780 15 : if (fields.find("height_factor_for_opening_factor_2") != fields.end()) {
781 10 : height_factor = fields.at("height_factor_for_opening_factor_2").get<Real64>();
782 : }
783 5 : start_height_factor = 0.0;
784 15 : if (fields.find("start_height_factor_for_opening_factor_2") != fields.end()) {
785 10 : start_height_factor = fields.at("start_height_factor_for_opening_factor_2").get<Real64>();
786 : }
787 :
788 5 : factors[1] = factor;
789 5 : cds[1] = cd;
790 5 : width_factors[1] = width_factor;
791 5 : height_factors[1] = height_factor;
792 5 : start_height_factors[1] = start_height_factor;
793 :
794 5 : if (N >= 3) {
795 0 : factor = fields.at("opening_factor_3").get<Real64>();
796 0 : cd = 0.0;
797 0 : if (fields.find("discharge_coefficient_for_opening_factor_3") != fields.end()) {
798 0 : cd = fields.at("discharge_coefficient_for_opening_factor_3").get<Real64>();
799 : }
800 0 : width_factor = 0.0;
801 0 : if (fields.find("width_factor_for_opening_factor_3") != fields.end()) {
802 0 : width_factor = fields.at("width_factor_for_opening_factor_3").get<Real64>();
803 : }
804 0 : height_factor = 0.0;
805 0 : if (fields.find("height_factor_for_opening_factor_3") != fields.end()) {
806 0 : height_factor = fields.at("height_factor_for_opening_factor_3").get<Real64>();
807 : }
808 0 : start_height_factor = 0.0;
809 0 : if (fields.find("start_height_factor_for_opening_factor_3") != fields.end()) {
810 0 : start_height_factor = fields.at("start_height_factor_for_opening_factor_3").get<Real64>();
811 : }
812 :
813 0 : factors[2] = factor;
814 0 : cds[2] = cd;
815 0 : width_factors[2] = width_factor;
816 0 : height_factors[2] = height_factor;
817 0 : start_height_factors[2] = start_height_factor;
818 :
819 0 : if (N >= 4) {
820 0 : factor = fields.at("opening_factor_4").get<Real64>();
821 0 : cd = 0.0;
822 0 : if (fields.find("discharge_coefficient_for_opening_factor_4") != fields.end()) {
823 0 : cd = fields.at("discharge_coefficient_for_opening_factor_4").get<Real64>();
824 : }
825 0 : width_factor = 0.0;
826 0 : if (fields.find("width_factor_for_opening_factor_4") != fields.end()) {
827 0 : width_factor = fields.at("width_factor_for_opening_factor_4").get<Real64>();
828 : }
829 0 : height_factor = 0.0;
830 0 : if (fields.find("height_factor_for_opening_factor_4") != fields.end()) {
831 0 : height_factor = fields.at("height_factor_for_opening_factor_4").get<Real64>();
832 : }
833 0 : start_height_factor = 0.0;
834 0 : if (fields.find("start_height_factor_for_opening_factor_4") != fields.end()) {
835 0 : start_height_factor = fields.at("start_height_factor_for_opening_factor_4").get<Real64>();
836 : }
837 :
838 0 : factors[3] = factor;
839 0 : cds[3] = cd;
840 0 : width_factors[3] = width_factor;
841 0 : height_factors[3] = height_factor;
842 0 : start_height_factors[3] = start_height_factor;
843 : }
844 : }
845 :
846 5 : MultizoneCompDetOpeningData(i).name = thisObjectName; // Name of large detailed opening component
847 5 : MultizoneCompDetOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
848 5 : MultizoneCompDetOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
849 5 : MultizoneCompDetOpeningData(i).TypeName = LVOstring; // Large vertical opening type
850 5 : MultizoneCompDetOpeningData(i).LVOType = LVOtype; // Large vertical opening type number
851 5 : MultizoneCompDetOpeningData(i).LVOValue = extra; // Extra crack length for LVO type 1 with multiple openable
852 : // parts, or Height of pivoting axis for LVO type 2
853 :
854 5 : MultizoneCompDetOpeningData(i).NumFac = N; // Number of Opening Factor Values
855 :
856 5 : MultizoneCompDetOpeningData(i).OpenFac1 = factors[0]; // Opening factor #1
857 5 : MultizoneCompDetOpeningData(i).DischCoeff1 = cds[0]; // Discharge coefficient for opening factor #1
858 5 : MultizoneCompDetOpeningData(i).WidthFac1 = width_factors[0]; // Width factor for for Opening factor #1
859 5 : MultizoneCompDetOpeningData(i).HeightFac1 = height_factors[0]; // Height factor for opening factor #1
860 5 : MultizoneCompDetOpeningData(i).StartHFac1 = start_height_factors[0]; // Start height factor for opening factor #1
861 5 : MultizoneCompDetOpeningData(i).OpenFac2 = factors[1]; // Opening factor #2
862 5 : MultizoneCompDetOpeningData(i).DischCoeff2 = cds[1]; // Discharge coefficient for opening factor #2
863 5 : MultizoneCompDetOpeningData(i).WidthFac2 = width_factors[1]; // Width factor for for Opening factor #2
864 5 : MultizoneCompDetOpeningData(i).HeightFac2 = height_factors[1]; // Height factor for opening factor #2
865 5 : MultizoneCompDetOpeningData(i).StartHFac2 = start_height_factors[1]; // Start height factor for opening factor #2
866 :
867 5 : MultizoneCompDetOpeningData(i).OpenFac3 = 0.0; // Opening factor #3
868 5 : MultizoneCompDetOpeningData(i).DischCoeff3 = 0.0; // Discharge coefficient for opening factor #3
869 5 : MultizoneCompDetOpeningData(i).WidthFac3 = 0.0; // Width factor for for Opening factor #3
870 5 : MultizoneCompDetOpeningData(i).HeightFac3 = 0.0; // Height factor for opening factor #3
871 5 : MultizoneCompDetOpeningData(i).StartHFac3 = 0.0; // Start height factor for opening factor #3
872 5 : MultizoneCompDetOpeningData(i).OpenFac4 = 0.0; // Opening factor #4
873 5 : MultizoneCompDetOpeningData(i).DischCoeff4 = 0.0; // Discharge coefficient for opening factor #4
874 5 : MultizoneCompDetOpeningData(i).WidthFac4 = 0.0; // Width factor for for Opening factor #4
875 5 : MultizoneCompDetOpeningData(i).HeightFac4 = 0.0; // Height factor for opening factor #4
876 5 : MultizoneCompDetOpeningData(i).StartHFac4 = 0.0; // Start height factor for opening factor #4
877 5 : if (N == 2) {
878 5 : if (factors[1] != 1.0) {
879 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
880 0 : ShowContinueError(
881 : m_state,
882 : "..This object specifies that only 3 opening factors will be used. So, the value of Opening Factor #2 is set to 1.0.");
883 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac2));
884 0 : MultizoneCompDetOpeningData(i).OpenFac2 = 1.0;
885 : }
886 0 : } else if (N >= 3) {
887 0 : MultizoneCompDetOpeningData(i).OpenFac3 = factors[2]; // Opening factor #3
888 0 : MultizoneCompDetOpeningData(i).DischCoeff3 = cds[2]; // Discharge coefficient for opening factor #3
889 0 : MultizoneCompDetOpeningData(i).WidthFac3 = width_factors[2]; // Width factor for for Opening factor #3
890 0 : MultizoneCompDetOpeningData(i).HeightFac3 = height_factors[2]; // Height factor for opening factor #3
891 0 : MultizoneCompDetOpeningData(i).StartHFac3 = start_height_factors[2]; // Start height factor for opening factor #3
892 0 : if (N >= 4) {
893 0 : MultizoneCompDetOpeningData(i).OpenFac4 = factors[3]; // Opening factor #4
894 0 : if (factors[3] != 1.0) {
895 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
896 0 : ShowContinueError(m_state,
897 : "..This object specifies that 4 opening factors will be used. So, the value of Opening Factor #4 "
898 : "is set to 1.0.");
899 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac4));
900 0 : MultizoneCompDetOpeningData(i).OpenFac4 = 1.0;
901 : }
902 0 : MultizoneCompDetOpeningData(i).DischCoeff4 = cds[3]; // Discharge coefficient for opening factor #4
903 0 : MultizoneCompDetOpeningData(i).WidthFac4 = width_factors[3]; // Width factor for for Opening factor #4
904 0 : MultizoneCompDetOpeningData(i).HeightFac4 = height_factors[3]; // Height factor for opening factor #4
905 0 : MultizoneCompDetOpeningData(i).StartHFac4 = start_height_factors[3]; // Start height factor for opening factor #4
906 : } else {
907 0 : if (factors[2] != 1.0) {
908 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
909 0 : ShowContinueError(m_state,
910 : "..This object specifies that only 3 opening factors will be used. So, the value of Opening Factor #3 "
911 : "is set to 1.0.");
912 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac3));
913 0 : MultizoneCompDetOpeningData(i).OpenFac3 = 1.0;
914 : }
915 : }
916 : }
917 :
918 : // Sanity checks, check sum of Height Factor and the Start Height Factor
919 5 : if (MultizoneCompDetOpeningData(i).HeightFac1 + MultizoneCompDetOpeningData(i).StartHFac1 > 1.0) {
920 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
921 0 : ShowContinueError(
922 : m_state, "..The sum of Height Factor for Opening Factor 1 and Start Height Factor for Opening Factor 1 is greater than 1.0");
923 0 : success = false;
924 : }
925 5 : if (MultizoneCompDetOpeningData(i).HeightFac2 + MultizoneCompDetOpeningData(i).StartHFac2 > 1.0) {
926 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
927 0 : ShowContinueError(
928 : m_state, "..The sum of Height Factor for Opening Factor 2 and Start Height Factor for Opening Factor 2 is greater than 1.0");
929 0 : success = false;
930 : }
931 5 : if (MultizoneCompDetOpeningData(i).NumFac > 2) {
932 0 : if (MultizoneCompDetOpeningData(i).OpenFac2 >= MultizoneCompDetOpeningData(i).OpenFac3) {
933 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
934 0 : ShowContinueError(m_state, "..The value of Opening Factor #2 >= the value of Opening Factor #3");
935 0 : success = false;
936 : }
937 0 : if (MultizoneCompDetOpeningData(i).HeightFac3 + MultizoneCompDetOpeningData(i).StartHFac3 > 1.0) {
938 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
939 0 : ShowContinueError(
940 : m_state,
941 : "..The sum of Height Factor for Opening Factor 3 and Start Height Factor for Opening Factor 3 is greater than 1.0");
942 0 : success = false;
943 : }
944 0 : if (MultizoneCompDetOpeningData(i).NumFac == 4) {
945 0 : if (MultizoneCompDetOpeningData(i).OpenFac3 >= MultizoneCompDetOpeningData(i).OpenFac4) {
946 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
947 0 : ShowContinueError(m_state, "..The value of Opening Factor #3 >= the value of Opening Factor #4");
948 0 : success = false;
949 : }
950 0 : if (MultizoneCompDetOpeningData(i).HeightFac4 + MultizoneCompDetOpeningData(i).StartHFac4 > 1.0) {
951 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
952 0 : ShowContinueError(
953 : m_state,
954 : "..The sum of Height Factor for Opening Factor 4 and Start Height Factor for Opening Factor 4 is greater than 1.0");
955 0 : success = false;
956 : }
957 : }
958 : }
959 :
960 : // Add the element to the lookup table, check for name overlaps
961 5 : if (elements.find(thisObjectName) == elements.end()) {
962 5 : elements[thisObjectName] = &MultizoneCompDetOpeningData(i); // Yet another workaround
963 : } else {
964 0 : ShowSevereError(
965 : m_state,
966 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
967 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
968 0 : success = false;
969 : }
970 :
971 5 : ++i;
972 5 : }
973 : }
974 :
975 : // Read AirflowNetwork simulation simple openings
976 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:SimpleOpening";
977 25 : AirflowNetworkNumOfSimOpenings =
978 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
979 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
980 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
981 9 : int i = 1; // Temporary workaround
982 9 : MultizoneCompSimpleOpeningData.allocate(AirflowNetworkNumOfSimOpenings); // Temporary workaround
983 9 : auto &instancesValue = instances.value();
984 18 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
985 9 : auto const &fields = instance.value();
986 9 : auto const &thisObjectName = Util::makeUPPER(instance.key());
987 9 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
988 :
989 9 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
990 9 : Real64 expnt{0.65};
991 27 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
992 18 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
993 : }
994 18 : Real64 diff{fields.at("minimum_density_difference_for_two_way_flow")};
995 9 : Real64 dischargeCoeff{fields.at("discharge_coefficient")};
996 :
997 9 : MultizoneCompSimpleOpeningData(i).name = thisObjectName; // Name of large simple opening component
998 9 : MultizoneCompSimpleOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
999 9 : MultizoneCompSimpleOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
1000 9 : MultizoneCompSimpleOpeningData(i).MinRhoDiff = diff; // Minimum density difference for two-way flow
1001 9 : MultizoneCompSimpleOpeningData(i).DischCoeff = dischargeCoeff; // Discharge coefficient at full opening
1002 :
1003 : // Add the element to the lookup table, check for name overlaps
1004 9 : if (elements.find(thisObjectName) == elements.end()) {
1005 9 : elements[thisObjectName] = &MultizoneCompSimpleOpeningData(i); // Yet another workaround
1006 : } else {
1007 0 : ShowSevereError(
1008 : m_state,
1009 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1010 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1011 0 : success = false;
1012 : }
1013 :
1014 9 : ++i;
1015 9 : }
1016 : }
1017 :
1018 : // Read AirflowNetwork simulation horizontal openings
1019 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:HorizontalOpening";
1020 25 : AirflowNetworkNumOfHorOpenings =
1021 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1022 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1023 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1024 1 : int i = 1; // Temporary workaround
1025 1 : MultizoneCompHorOpeningData.allocate(AirflowNetworkNumOfHorOpenings); // Temporary workaround
1026 1 : auto &instancesValue = instances.value();
1027 2 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1028 1 : auto const &fields = instance.value();
1029 1 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1030 1 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1031 :
1032 1 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
1033 1 : Real64 expnt{0.65};
1034 3 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
1035 2 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
1036 : }
1037 1 : Real64 angle{90.0};
1038 3 : if (fields.find("sloping_plane_angle") != fields.end()) {
1039 2 : angle = fields.at("sloping_plane_angle").get<Real64>();
1040 : }
1041 1 : Real64 dischargeCoeff{fields.at("discharge_coefficient")};
1042 :
1043 1 : MultizoneCompHorOpeningData(i).name = thisObjectName; // Name of large simple opening component
1044 1 : MultizoneCompHorOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
1045 1 : MultizoneCompHorOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
1046 1 : MultizoneCompHorOpeningData(i).Slope = angle; // Sloping plane angle
1047 1 : MultizoneCompHorOpeningData(i).DischCoeff = dischargeCoeff; // Discharge coefficient at full opening
1048 :
1049 : // Add the element to the lookup table, check for name overlaps
1050 1 : if (elements.find(thisObjectName) == elements.end()) {
1051 1 : elements[thisObjectName] = &MultizoneCompHorOpeningData(i); // Yet another workaround
1052 : } else {
1053 0 : ShowSevereError(
1054 : m_state,
1055 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1056 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1057 0 : success = false;
1058 : }
1059 :
1060 1 : ++i;
1061 1 : }
1062 : }
1063 :
1064 : // *** Read AirflowNetwork simulation surface effective leakage area component
1065 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea";
1066 25 : AirflowNetworkNumOfSurELA =
1067 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1068 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1069 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1070 3 : int i = 1; // Temporary workaround
1071 3 : MultizoneSurfaceELAData.allocate(AirflowNetworkNumOfSurELA); // Temporary workaround
1072 3 : auto &instancesValue = instances.value();
1073 11 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1074 8 : auto const &fields = instance.value();
1075 8 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1076 :
1077 8 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1078 :
1079 8 : Real64 ela{fields.at("effective_leakage_area")};
1080 8 : Real64 cd{1.0};
1081 24 : if (fields.find("discharge_coefficient") != fields.end()) {
1082 16 : cd = fields.at("discharge_coefficient").get<Real64>();
1083 : }
1084 8 : Real64 dp{4.0};
1085 24 : if (fields.find("reference_pressure_difference") != fields.end()) {
1086 16 : dp = fields.at("reference_pressure_difference").get<Real64>();
1087 : }
1088 8 : Real64 expnt{0.65};
1089 24 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1090 16 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1091 : }
1092 :
1093 8 : MultizoneSurfaceELAData(i).name = thisObjectName; // Name of surface effective leakage area component
1094 8 : MultizoneSurfaceELAData(i).ELA = ela; // Effective leakage area
1095 8 : MultizoneSurfaceELAData(i).DischCoeff = cd; // Discharge coefficient
1096 8 : MultizoneSurfaceELAData(i).RefDeltaP = dp; // Reference pressure difference
1097 8 : MultizoneSurfaceELAData(i).FlowExpo = expnt; // Air Mass Flow exponent
1098 8 : MultizoneSurfaceELAData(i).TestDeltaP = 0.0; // Testing pressure difference
1099 8 : MultizoneSurfaceELAData(i).TestDisCoef = 0.0; // Testing Discharge coefficient
1100 :
1101 : // Add the element to the lookup table, check for name overlaps
1102 8 : if (elements.find(thisObjectName) == elements.end()) {
1103 8 : elements[thisObjectName] = &MultizoneSurfaceELAData(i); // Yet another workaround
1104 : } else {
1105 0 : ShowSevereError(
1106 : m_state,
1107 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1108 0 : success = false;
1109 : }
1110 :
1111 8 : ++i;
1112 8 : }
1113 : }
1114 :
1115 : // *** Read AirflowNetwork simulation specified flow components
1116 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:SpecifiedFlowRate";
1117 25 : AirflowNetworkNumOfSFR =
1118 25 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1119 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1120 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1121 0 : int i_mass = 0; // Temporary workaround that increasingly looks like the long term solution
1122 0 : int i_vol = 0;
1123 0 : auto &instancesValue = instances.value();
1124 :
1125 0 : instancesValue = instances.value();
1126 0 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1127 0 : auto const &fields = instance.value();
1128 0 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1129 :
1130 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1131 :
1132 0 : Real64 flow_rate{fields.at("air_flow_value")};
1133 0 : bool is_mass_flow = true;
1134 0 : if (fields.find("air_flow_units") != fields.end()) {
1135 0 : if (fields.at("air_flow_units") != "MassFlow") {
1136 0 : is_mass_flow = false;
1137 : }
1138 : }
1139 :
1140 : // Check for name overlaps
1141 0 : if (elements.find(thisObjectName) != elements.end()) {
1142 0 : ShowSevereError(
1143 : m_state,
1144 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1145 0 : success = false;
1146 : }
1147 :
1148 0 : if (is_mass_flow) {
1149 0 : SpecifiedMassFlowData.emplace_back();
1150 0 : SpecifiedMassFlowData[i_mass].name = thisObjectName;
1151 0 : SpecifiedMassFlowData[i_mass].mass_flow = flow_rate;
1152 0 : ++i_mass;
1153 : } else {
1154 0 : SpecifiedVolumeFlowData.emplace_back();
1155 0 : SpecifiedVolumeFlowData[i_vol].name = thisObjectName;
1156 0 : SpecifiedVolumeFlowData[i_vol].volume_flow = flow_rate;
1157 0 : ++i_vol;
1158 : }
1159 0 : }
1160 0 : for (auto &afe : SpecifiedMassFlowData) {
1161 0 : elements[afe.name] = &afe; // Yet another workaround
1162 : }
1163 0 : for (auto &afe : SpecifiedVolumeFlowData) {
1164 0 : elements[afe.name] = &afe; // Yet another workaround
1165 : }
1166 : }
1167 :
1168 : // Read AirflowNetwork Distribution system component: duct leakage
1169 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Leak";
1170 25 : DisSysNumOfLeaks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1171 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1172 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1173 2 : int i = 1; // Temporary workaround
1174 2 : DisSysCompLeakData.allocate(DisSysNumOfLeaks); // Temporary workaround
1175 2 : auto &instancesValue = instances.value();
1176 7 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1177 5 : auto const &fields = instance.value();
1178 5 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1179 5 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1180 :
1181 5 : Real64 coeff{fields.at("air_mass_flow_coefficient")};
1182 5 : Real64 expnt{0.65};
1183 15 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1184 10 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1185 : }
1186 :
1187 5 : DisSysCompLeakData(i).name = thisObjectName; // Name of duct leak component
1188 5 : DisSysCompLeakData(i).FlowCoef = coeff; // Air Mass Flow Coefficient
1189 5 : DisSysCompLeakData(i).FlowExpo = expnt; // Air Mass Flow exponent
1190 :
1191 : // Add the element to the lookup table, check for name overlaps
1192 5 : if (elements.find(thisObjectName) == elements.end()) {
1193 5 : elements[thisObjectName] = &DisSysCompLeakData(i); // Yet another workaround
1194 : } else {
1195 0 : ShowSevereError(
1196 : m_state,
1197 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1198 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1199 0 : success = false;
1200 : }
1201 :
1202 5 : ++i;
1203 5 : }
1204 : }
1205 :
1206 : // Read AirflowNetwork Distribution system component: duct effective leakage ratio
1207 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:LeakageRatio";
1208 25 : DisSysNumOfELRs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1209 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1210 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1211 5 : int i = 1; // Temporary workaround
1212 5 : DisSysCompELRData.allocate(DisSysNumOfELRs); // Temporary workaround
1213 5 : auto &instancesValue = instances.value();
1214 25 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1215 20 : auto const &fields = instance.value();
1216 20 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1217 20 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1218 :
1219 40 : Real64 elr{fields.at("effective_leakage_ratio")};
1220 40 : Real64 maxflow{fields.at("maximum_flow_rate")};
1221 20 : Real64 dp{fields.at("reference_pressure_difference")};
1222 20 : Real64 expnt{0.65};
1223 60 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1224 40 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1225 : }
1226 :
1227 20 : DisSysCompELRData(i).name = thisObjectName; // Name of duct effective leakage ratio component
1228 20 : DisSysCompELRData(i).ELR = elr; // Value of effective leakage ratio
1229 20 : DisSysCompELRData(i).FlowRate = maxflow * m_state.dataEnvrn->StdRhoAir; // Maximum airflow rate
1230 20 : DisSysCompELRData(i).RefPres = dp; // Reference pressure difference
1231 20 : DisSysCompELRData(i).FlowExpo = expnt; // Air Mass Flow exponent
1232 :
1233 : // Add the element to the lookup table, check for name overlaps
1234 20 : if (elements.find(thisObjectName) == elements.end()) {
1235 20 : elements[thisObjectName] = &DisSysCompELRData(i); // Yet another workaround
1236 : } else {
1237 0 : ShowSevereError(
1238 : m_state,
1239 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1240 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1241 0 : success = false;
1242 : }
1243 :
1244 20 : ++i;
1245 20 : }
1246 : }
1247 :
1248 : // Read AirflowNetwork Distribution system component: duct
1249 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Duct";
1250 25 : DisSysNumOfDucts = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1251 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1252 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1253 7 : int i = 1; // Temporary workaround
1254 7 : DisSysCompDuctData.allocate(DisSysNumOfDucts); // Temporary workaround
1255 7 : auto &instancesValue = instances.value();
1256 71 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1257 64 : auto const &fields = instance.value();
1258 64 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1259 64 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1260 :
1261 128 : Real64 L{fields.at("duct_length")};
1262 128 : Real64 D{fields.at("hydraulic_diameter")};
1263 64 : Real64 A{fields.at("cross_section_area")};
1264 64 : Real64 e{0.0009};
1265 192 : if (fields.find("surface_roughness") != fields.end()) {
1266 128 : e = fields.at("surface_roughness").get<Real64>();
1267 : }
1268 64 : Real64 dlc{0.0};
1269 192 : if (fields.find("coefficient_for_local_dynamic_loss_due_to_fitting") != fields.end()) {
1270 128 : dlc = fields.at("coefficient_for_local_dynamic_loss_due_to_fitting").get<Real64>();
1271 : }
1272 64 : Real64 U{0.943};
1273 192 : if (fields.find("heat_transmittance_coefficient_u_factor_for_duct_wall_construction") != fields.end()) {
1274 128 : U = fields.at("heat_transmittance_coefficient_u_factor_for_duct_wall_construction").get<Real64>();
1275 : }
1276 64 : Real64 Um{0.001};
1277 192 : if (fields.find("overall_moisture_transmittance_coefficient_from_air_to_air") != fields.end()) {
1278 128 : Um = fields.at("overall_moisture_transmittance_coefficient_from_air_to_air").get<Real64>();
1279 : }
1280 64 : Real64 hout{0.0};
1281 192 : if (fields.find("outside_convection_coefficient") != fields.end()) {
1282 80 : hout = fields.at("outside_convection_coefficient").get<Real64>();
1283 : }
1284 64 : Real64 hin{0.0};
1285 192 : if (fields.find("inside_convection_coefficient") != fields.end()) {
1286 80 : hin = fields.at("inside_convection_coefficient").get<Real64>();
1287 : }
1288 :
1289 64 : DisSysCompDuctData(i).name = thisObjectName; // Name of duct effective leakage ratio component
1290 64 : DisSysCompDuctData(i).L = L; // Duct length [m]
1291 64 : DisSysCompDuctData(i).hydraulicDiameter = D; // Hydraulic diameter [m]
1292 64 : DisSysCompDuctData(i).A = A; // Cross section area [m2]
1293 64 : DisSysCompDuctData(i).roughness = e; // Surface roughness [m]
1294 64 : DisSysCompDuctData(i).TurDynCoef = dlc; // Turbulent dynamic loss coefficient
1295 64 : DisSysCompDuctData(i).UThermConduct = U; // Conduction heat transmittance [W/m2.K]
1296 64 : DisSysCompDuctData(i).UMoisture = Um; // Overall moisture transmittance [kg/m2]
1297 64 : DisSysCompDuctData(i).OutsideConvCoeff = hout; // Outside convection coefficient [W/m2.K]
1298 64 : DisSysCompDuctData(i).InsideConvCoeff = hin; // Inside convection coefficient [W/m2.K]
1299 64 : DisSysCompDuctData(i).MThermal = 0.0; // Thermal capacity [J/K]
1300 64 : DisSysCompDuctData(i).MMoisture = 0.0; // Moisture capacity [kg]
1301 64 : DisSysCompDuctData(i).LamDynCoef = 64.0; // Laminar dynamic loss coefficient
1302 64 : DisSysCompDuctData(i).LamFriCoef = dlc; // Laminar friction loss coefficient
1303 64 : DisSysCompDuctData(i).InitLamCoef = 128.0; // Coefficient of linear initialization
1304 64 : DisSysCompDuctData(i).RelRough = e / D; // e/D: relative roughness
1305 64 : DisSysCompDuctData(i).RelL = L / D; // L/D: relative length
1306 64 : DisSysCompDuctData(i).A1 = 1.14 - 0.868589 * std::log(DisSysCompDuctData(i).RelRough); // 1.14 - 0.868589*ln(e/D)
1307 64 : DisSysCompDuctData(i).g = DisSysCompDuctData(i).A1; // 1/sqrt(Darcy friction factor)
1308 :
1309 : // Add the element to the lookup table, check for name overlaps
1310 64 : if (elements.find(thisObjectName) == elements.end()) {
1311 64 : elements[thisObjectName] = &DisSysCompDuctData(i); // Yet another workaround
1312 : } else {
1313 0 : ShowSevereError(
1314 : m_state,
1315 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1316 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1317 0 : success = false;
1318 : }
1319 :
1320 64 : ++i;
1321 64 : }
1322 : }
1323 :
1324 : // Read AirflowNetwork Distribution system component: constant volume fan
1325 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Fan";
1326 25 : DisSysNumOfCVFs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1327 25 : if (DisSysNumOfCVFs > 0 && DisSysNumOfCVFs != m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC")) {
1328 0 : ShowSevereError(m_state, format("The number of entered AirflowNetwork:Distribution:Component:Fan objects is {}", DisSysNumOfCVFs));
1329 0 : ShowSevereError(m_state,
1330 0 : format("The number of entered AirLoopHVAC objects is {}",
1331 0 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC")));
1332 0 : ShowContinueError(m_state, "Both numbers should be equal. Please check your inputs.");
1333 0 : success = false;
1334 : }
1335 :
1336 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1337 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1338 7 : int i = 1; // Temporary workaround
1339 7 : DisSysCompCVFData.allocate(DisSysNumOfCVFs); // Temporary workaround
1340 7 : auto &instancesValue = instances.value();
1341 15 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1342 8 : auto const &fields = instance.value();
1343 8 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1344 8 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1345 :
1346 8 : std::string fan_name = Util::makeUPPER(fields.at("fan_name").get<std::string>());
1347 :
1348 : int fanIndex;
1349 8 : Real64 flowRate = 0.0;
1350 : int inletNode;
1351 : int outletNode;
1352 :
1353 : HVAC::FanType fanType = static_cast<HVAC::FanType>(
1354 8 : getEnumValue(HVAC::fanTypeNamesUC, Util::makeUPPER(fields.at("supply_fan_object_type").get<std::string>())));
1355 :
1356 8 : HVAC::FanType fanType2 = HVAC::FanType::Invalid;
1357 :
1358 8 : if (fanType == HVAC::FanType::SystemModel) {
1359 2 : fanIndex = Fans::GetFanIndex(m_state, fan_name);
1360 2 : if (fanIndex < 0) {
1361 0 : ShowSevereError(m_state, "...occurs in " + CurrentModuleObject + " = " + DisSysCompCVFData(i).name);
1362 0 : success = false;
1363 : } else {
1364 2 : auto *fanSys = dynamic_cast<Fans::FanSystem *>(m_state.dataFans->fans(fanIndex));
1365 2 : assert(fanSys != nullptr);
1366 2 : flowRate = fanSys->maxAirFlowRate * m_state.dataEnvrn->StdRhoAir;
1367 2 : DisSysCompCVFData(i).FanModelFlag = true;
1368 2 : inletNode = fanSys->inletNodeNum;
1369 2 : outletNode = fanSys->outletNodeNum;
1370 2 : if (fanSys->speedControl == Fans::SpeedControl::Continuous) {
1371 0 : fanType2 = HVAC::FanType::VAV;
1372 0 : VAVSystem = true;
1373 : } else {
1374 2 : fanType2 = HVAC::FanType::OnOff;
1375 : }
1376 2 : supplyFanType = fanType2;
1377 : }
1378 :
1379 : } else {
1380 6 : fanIndex = GetFanIndex(m_state, fan_name);
1381 :
1382 6 : if (fanIndex == 0) {
1383 0 : ErrorObjectHeader eoh{RoutineName, CurrentModuleObject, DisSysCompCVFData(i).name};
1384 0 : ShowSevereItemNotFound(m_state, eoh, "Fan Name", fan_name);
1385 0 : success = false;
1386 : }
1387 :
1388 6 : auto *fan = m_state.dataFans->fans(fanIndex);
1389 6 : flowRate = fan->maxAirFlowRate * m_state.dataEnvrn->StdRhoAir;
1390 :
1391 6 : fanType2 = fan->type;
1392 6 : supplyFanType = fanType2;
1393 : }
1394 :
1395 8 : if (!(fanType2 == HVAC::FanType::Constant || fanType2 == HVAC::FanType::OnOff || fanType2 == HVAC::FanType::VAV)) {
1396 0 : ShowSevereError(
1397 : m_state,
1398 0 : format("{}The Supply Fan Object Type in {} = {} is not a valid fan type.", RoutineName, CurrentModuleObject, thisObjectName));
1399 0 : ShowContinueError(m_state, "Valid fan types are Fan:ConstantVolume, Fan:OnOff, Fan:VariableVolume, or Fan:SystemModel.");
1400 0 : success = false;
1401 : } else {
1402 8 : if (fanType == HVAC::FanType::Constant && fanType2 == HVAC::FanType::OnOff) {
1403 0 : ShowSevereError(m_state, "The Supply Fan Object Type defined in " + CurrentModuleObject + " is Fan:ConstantVolume");
1404 0 : ShowContinueError(m_state, "The Supply Fan Object Type defined in an AirLoopHVAC is Fan:OnOff");
1405 0 : success = false;
1406 8 : } else if (fanType == HVAC::FanType::OnOff && fanType2 == HVAC::FanType::Constant) {
1407 0 : ShowSevereError(m_state, "The Supply Fan Object Type defined in " + CurrentModuleObject + " is Fan:SimpleOnOff");
1408 0 : ShowContinueError(m_state, "The Supply Fan Object Type defined in an AirLoopHVAC is Fan:ConstantVolume");
1409 0 : success = false;
1410 : }
1411 : }
1412 8 : bool ErrorsFound{false};
1413 8 : auto *fan = m_state.dataFans->fans(fanIndex);
1414 8 : if (fanType2 == HVAC::FanType::Constant) {
1415 4 : inletNode = fan->inletNodeNum;
1416 4 : outletNode = fan->outletNodeNum;
1417 : }
1418 8 : if (fanType2 == HVAC::FanType::OnOff && !DisSysCompCVFData(i).FanModelFlag) {
1419 2 : inletNode = fan->inletNodeNum;
1420 2 : outletNode = fan->outletNodeNum;
1421 : }
1422 8 : if (fanType2 == HVAC::FanType::VAV && !DisSysCompCVFData(i).FanModelFlag) {
1423 0 : inletNode = fan->inletNodeNum;
1424 0 : outletNode = fan->outletNodeNum;
1425 0 : VAVSystem = true;
1426 : }
1427 :
1428 8 : if (ErrorsFound) {
1429 0 : success = false;
1430 : }
1431 :
1432 8 : DisSysCompCVFData(i).name = fan_name; // Name of duct effective leakage ratio component
1433 8 : DisSysCompCVFData(i).Ctrl = 1.0; // Control ratio
1434 8 : DisSysCompCVFData(i).FanIndex = fanIndex;
1435 8 : DisSysCompCVFData(i).FlowRate = flowRate;
1436 8 : DisSysCompCVFData(i).fanType = fanType2;
1437 8 : DisSysCompCVFData(i).InletNode = inletNode;
1438 8 : DisSysCompCVFData(i).OutletNode = outletNode;
1439 :
1440 : // Add the element to the lookup table, check for name overlaps
1441 8 : if (elements.find(fan_name) == elements.end()) {
1442 8 : elements[fan_name] = &DisSysCompCVFData(i); // Yet another workaround
1443 : } else {
1444 0 : ShowSevereError(
1445 0 : m_state, format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, fan_name));
1446 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1447 0 : success = false;
1448 : }
1449 :
1450 8 : ++i;
1451 8 : }
1452 : }
1453 :
1454 : // Read AirflowNetwork Distribution system component: coil
1455 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Coil";
1456 25 : DisSysNumOfCoils = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1457 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1458 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1459 7 : int i = 1; // Temporary workaround
1460 7 : DisSysCompCoilData.allocate(DisSysNumOfCoils); // Temporary workaround
1461 7 : auto &instancesValue = instances.value();
1462 27 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1463 20 : auto const &fields = instance.value();
1464 : // auto const &thisObjectName = Util::makeUPPER(instance.key());
1465 20 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1466 :
1467 40 : std::string coil_name = fields.at("coil_name").get<std::string>();
1468 40 : std::string coil_type = fields.at("coil_object_type").get<std::string>();
1469 40 : Real64 L{fields.at("air_path_length")};
1470 20 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1471 :
1472 20 : DisSysCompCoilData(i).name = Util::makeUPPER(coil_name); // Name of associated EPlus coil component
1473 20 : DisSysCompCoilData(i).EPlusType = coil_type; // coil type
1474 20 : DisSysCompCoilData(i).L = L; // Air path length
1475 20 : DisSysCompCoilData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1476 :
1477 : // Add the element to the lookup table, check for name overlaps
1478 20 : if (elements.find(DisSysCompCoilData(i).name) == elements.end()) {
1479 20 : elements[DisSysCompCoilData(i).name] = &DisSysCompCoilData(i); // Yet another workaround
1480 : } else {
1481 0 : ShowSevereError(m_state,
1482 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1483 : RoutineName,
1484 : CurrentModuleObject,
1485 0 : DisSysCompCoilData(i).name));
1486 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1487 0 : success = false;
1488 : }
1489 :
1490 20 : ++i;
1491 20 : }
1492 : }
1493 :
1494 : // Read AirflowNetwork Distribution system component: heat exchanger
1495 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:HeatExchanger";
1496 25 : DisSysNumOfHXs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1497 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1498 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1499 0 : int i = 1; // Temporary workaround
1500 0 : DisSysCompHXData.allocate(DisSysNumOfHXs); // Temporary workaround
1501 0 : auto &instancesValue = instances.value();
1502 0 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1503 0 : auto const &fields = instance.value();
1504 : // auto const &thisObjectName = Util::makeUPPER(instance.key());
1505 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1506 :
1507 0 : std::string hx_name = fields.at("heatexchanger_name").get<std::string>();
1508 0 : std::string hx_type = fields.at("heatexchanger_object_type").get<std::string>();
1509 0 : Real64 L{fields.at("air_path_length")};
1510 0 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1511 :
1512 0 : DisSysCompHXData(i).name = Util::makeUPPER(hx_name); // Name of associated EPlus heat exchange component
1513 0 : DisSysCompHXData(i).EPlusType = hx_type; // coil type
1514 0 : DisSysCompHXData(i).L = L; // Air path length
1515 0 : DisSysCompHXData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1516 0 : DisSysCompHXData(i).CoilParentExists = HVACHXAssistedCoolingCoil::VerifyHeatExchangerParent(m_state, hx_type, hx_name);
1517 :
1518 : // Add the element to the lookup table, check for name overlaps
1519 0 : if (elements.find(DisSysCompHXData(i).name) == elements.end()) {
1520 0 : elements[DisSysCompHXData(i).name] = &DisSysCompHXData(i); // Yet another workaround
1521 : } else {
1522 0 : ShowSevereError(m_state,
1523 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1524 : RoutineName,
1525 : CurrentModuleObject,
1526 0 : DisSysCompHXData(i).name));
1527 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1528 0 : success = false;
1529 : }
1530 0 : ++i;
1531 0 : }
1532 : }
1533 :
1534 : // Read AirflowNetwork Distribution system component: terminal unit
1535 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:TerminalUnit";
1536 25 : DisSysNumOfTermUnits = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1537 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1538 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1539 2 : int i = 1; // Temporary workaround
1540 2 : DisSysCompTermUnitData.allocate(DisSysNumOfTermUnits); // Temporary workaround
1541 2 : auto &instancesValue = instances.value();
1542 5 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1543 3 : auto const &fields = instance.value();
1544 : // auto const &thisObjectName = Util::makeUPPER(instance.key());
1545 3 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1546 :
1547 6 : std::string tu_name = fields.at("terminal_unit_name").get<std::string>();
1548 6 : std::string tu_type = fields.at("terminal_unit_object_type").get<std::string>();
1549 6 : Real64 L{fields.at("air_path_length")};
1550 3 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1551 :
1552 3 : DisSysCompTermUnitData(i).name = Util::makeUPPER(tu_name); // Name of associated EPlus coil component
1553 3 : DisSysCompTermUnitData(i).EPlusType = tu_type; // Terminal unit type
1554 3 : DisSysCompTermUnitData(i).L = L; // Air path length
1555 3 : DisSysCompTermUnitData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1556 :
1557 : // Add the element to the lookup table, check for name overlaps
1558 3 : if (elements.find(DisSysCompTermUnitData(i).name) == elements.end()) {
1559 3 : elements[DisSysCompTermUnitData(i).name] = &DisSysCompTermUnitData(i); // Yet another workaround
1560 : } else {
1561 0 : ShowSevereError(m_state,
1562 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1563 : RoutineName,
1564 : CurrentModuleObject,
1565 0 : DisSysCompTermUnitData(i).name));
1566 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1567 0 : success = false;
1568 : }
1569 :
1570 3 : ++i;
1571 3 : }
1572 : }
1573 :
1574 : // Get input data of constant pressure drop component
1575 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ConstantPressureDrop";
1576 25 : DisSysNumOfCPDs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1577 25 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1578 25 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1579 2 : int i = 1; // Temporary workaround
1580 2 : DisSysCompCPDData.allocate(DisSysNumOfCPDs); // Temporary workaround
1581 2 : auto &instancesValue = instances.value();
1582 4 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1583 2 : auto const &fields = instance.value();
1584 2 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1585 2 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1586 :
1587 2 : Real64 dp{fields.at("pressure_difference_across_the_component")};
1588 :
1589 2 : DisSysCompCPDData(i).name = thisObjectName; // Name of constant pressure drop component
1590 2 : DisSysCompCPDData(i).A = 1.0; // cross section area
1591 2 : DisSysCompCPDData(i).DP = dp; // Pressure difference across the component
1592 :
1593 : // Add the element to the lookup table, check for name overlaps
1594 2 : if (elements.find(thisObjectName) == elements.end()) {
1595 2 : elements[thisObjectName] = &DisSysCompCPDData(i); // Yet another workaround
1596 : } else {
1597 0 : ShowSevereError(
1598 : m_state,
1599 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1600 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1601 0 : success = false;
1602 : }
1603 :
1604 2 : ++i;
1605 2 : }
1606 : }
1607 :
1608 25 : return success;
1609 25 : }
1610 :
1611 127 : void Solver::get_input()
1612 : {
1613 :
1614 : // SUBROUTINE INFORMATION:
1615 : // AUTHOR Lixing Gu
1616 : // DATE WRITTEN Aug. 2003
1617 : // MODIFIED Aug. 2005
1618 : // RE-ENGINEERED na
1619 :
1620 : // PURPOSE OF THIS SUBROUTINE:
1621 : // This subroutine reads inputs of air distribution system
1622 :
1623 : // Using/Aliasing
1624 : using Curve::GetCurveIndex;
1625 : using DataLoopNode::ObjectIsParent;
1626 : using HVACHXAssistedCoolingCoil::VerifyHeatExchangerParent;
1627 : using MixedAir::GetOAMixerNumber;
1628 : using NodeInputManager::GetOnlySingleNode;
1629 : using OutAirNodeManager::SetOutAirNodes;
1630 : using RoomAir::GetRAFNNodeNum;
1631 :
1632 : // SUBROUTINE PARAMETER DEFINITIONS:
1633 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::get_input: "); // include trailing blank space
1634 :
1635 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1636 : int n;
1637 : int k;
1638 : int count;
1639 : bool NodeFound;
1640 : bool found;
1641 : int NumAPL;
1642 127 : Array1D_string CompName(2);
1643 127 : std::string SimAirNetworkKey;
1644 :
1645 : // Declare variables used in this subroutine for debug purpose
1646 127 : Array1D_int ZoneCheck;
1647 127 : Array1D_int ZoneBCCheck;
1648 :
1649 : int NumAlphas; // Number of Alphas for each GetObjectItem call
1650 : int NumNumbers; // Number of Numbers for each GetObjectItem call
1651 : int IOStatus; // Used in GetObjectItem
1652 127 : std::string CurrentModuleObject;
1653 127 : Array1D_string Alphas; // Alpha input items for object
1654 127 : Array1D_string cAlphaFields; // Alpha field names
1655 127 : Array1D_string cNumericFields; // Numeric field names
1656 127 : Array1D<Real64> Numbers; // Numeric input items for object
1657 127 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
1658 127 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
1659 127 : int MaxNums(0); // Maximum number of numeric input fields
1660 127 : int MaxAlphas(0); // Maximum number of alpha input fields
1661 127 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
1662 : Real64 minHeight;
1663 : Real64 maxHeight;
1664 : Real64 baseratio;
1665 :
1666 127 : auto &Node(m_state.dataLoopNodes->Node);
1667 :
1668 : // Formats
1669 : static constexpr std::string_view Format_110(
1670 : "! <AirflowNetwork Model:Control>, No Multizone or Distribution/Multizone with Distribution/Multizone "
1671 : "without Distribution/Multizone with Distribution only during Fan Operation\n");
1672 : static constexpr std::string_view Format_120("AirflowNetwork Model:Control,{}\n");
1673 :
1674 : // Set the maximum numbers of input fields
1675 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1676 : m_state, "AirflowNetwork:SimulationControl", TotalArgs, NumAlphas, NumNumbers);
1677 127 : MaxNums = max(MaxNums, NumNumbers);
1678 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1679 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(m_state, "AirflowNetwork:MultiZone:Zone", TotalArgs, NumAlphas, NumNumbers);
1680 127 : MaxNums = max(MaxNums, NumNumbers);
1681 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1682 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1683 : m_state, "AirflowNetwork:MultiZone:Surface", TotalArgs, NumAlphas, NumNumbers);
1684 127 : MaxNums = max(MaxNums, NumNumbers);
1685 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1686 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1687 : m_state, "AirflowNetwork:MultiZone:Component:DetailedOpening", TotalArgs, NumAlphas, NumNumbers);
1688 127 : MaxNums = max(MaxNums, NumNumbers);
1689 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1690 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1691 : m_state, "AirflowNetwork:MultiZone:ExternalNode", TotalArgs, NumAlphas, NumNumbers);
1692 127 : MaxNums = max(MaxNums, NumNumbers);
1693 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1694 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1695 : m_state, "AirflowNetwork:MultiZone:WindPressureCoefficientArray", TotalArgs, NumAlphas, NumNumbers);
1696 127 : MaxNums = max(MaxNums, NumNumbers);
1697 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1698 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1699 : m_state, "AirflowNetwork:MultiZone:WindPressureCoefficientValues", TotalArgs, NumAlphas, NumNumbers);
1700 127 : MaxNums = max(MaxNums, NumNumbers);
1701 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1702 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1703 : m_state, "AirflowNetwork:Distribution:Node", TotalArgs, NumAlphas, NumNumbers);
1704 127 : MaxNums = max(MaxNums, NumNumbers);
1705 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1706 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1707 : m_state, "AirflowNetwork:Distribution:DuctViewFactors", TotalArgs, NumAlphas, NumNumbers);
1708 127 : MaxNums = max(MaxNums, NumNumbers);
1709 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1710 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1711 : m_state, "AirflowNetwork:Distribution:Linkage", TotalArgs, NumAlphas, NumNumbers);
1712 127 : MaxNums = max(MaxNums, NumNumbers);
1713 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1714 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1715 : m_state, "AirflowNetwork:OccupantVentilationControl", TotalArgs, NumAlphas, NumNumbers);
1716 127 : MaxNums = max(MaxNums, NumNumbers);
1717 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1718 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(m_state, "AirflowNetwork:IntraZone:Node", TotalArgs, NumAlphas, NumNumbers);
1719 127 : MaxNums = max(MaxNums, NumNumbers);
1720 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1721 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1722 : m_state, "AirflowNetwork:IntraZone:Linkage", TotalArgs, NumAlphas, NumNumbers);
1723 127 : MaxNums = max(MaxNums, NumNumbers);
1724 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1725 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1726 : m_state, "AirflowNetwork:ZoneControl:PressureController", TotalArgs, NumAlphas, NumNumbers);
1727 127 : MaxNums = max(MaxNums, NumNumbers);
1728 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1729 127 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1730 : m_state, "AirflowNetwork:Distribution:DuctSizing", TotalArgs, NumAlphas, NumNumbers);
1731 127 : MaxNums = max(MaxNums, NumNumbers);
1732 127 : MaxAlphas = max(MaxAlphas, NumAlphas);
1733 :
1734 127 : Alphas.allocate(MaxAlphas);
1735 127 : cAlphaFields.allocate(MaxAlphas);
1736 127 : cNumericFields.allocate(MaxNums);
1737 127 : Numbers.dimension(MaxNums, 0.0);
1738 127 : lAlphaBlanks.dimension(MaxAlphas, true);
1739 127 : lNumericBlanks.dimension(MaxNums, true);
1740 :
1741 127 : bool ErrorsFound = false;
1742 :
1743 127 : auto &Zone(m_state.dataHeatBal->Zone);
1744 :
1745 : // Read AirflowNetwork OccupantVentilationControl before reading other AirflowNetwork objects, so that this object can be called by other
1746 : // simple ventilation objects
1747 127 : CurrentModuleObject = "AirflowNetwork:OccupantVentilationControl";
1748 127 : AirflowNetworkNumOfOccuVentCtrls = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1749 127 : if (AirflowNetworkNumOfOccuVentCtrls > 0) {
1750 0 : OccupantVentilationControl.allocate(AirflowNetworkNumOfOccuVentCtrls);
1751 0 : for (int i = 1; i <= AirflowNetworkNumOfOccuVentCtrls; ++i) {
1752 0 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
1753 : CurrentModuleObject,
1754 : i,
1755 : Alphas,
1756 : NumAlphas,
1757 : Numbers,
1758 : NumNumbers,
1759 : IOStatus,
1760 : lNumericBlanks,
1761 : lAlphaBlanks,
1762 : cAlphaFields,
1763 : cNumericFields);
1764 0 : OccupantVentilationControl(i).Name = Alphas(1); // Name of object
1765 0 : OccupantVentilationControl(i).MinOpeningTime = Numbers(1);
1766 0 : if (OccupantVentilationControl(i).MinOpeningTime < 0.0) {
1767 : // Code will never be executed, validation will catch invalid input
1768 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(1) + " < 0.0");
1769 0 : ShowContinueError(m_state,
1770 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", OccupantVentilationControl(i).MinOpeningTime));
1771 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1772 0 : OccupantVentilationControl(i).MinOpeningTime = 0.0;
1773 : }
1774 0 : OccupantVentilationControl(i).MinClosingTime = Numbers(2);
1775 0 : if (OccupantVentilationControl(i).MinClosingTime < 0.0) {
1776 : // Code will never be executed, validation will catch invalid input
1777 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " < 0.0");
1778 0 : ShowContinueError(m_state,
1779 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", OccupantVentilationControl(i).MinClosingTime));
1780 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1781 0 : OccupantVentilationControl(i).MinClosingTime = 0.0;
1782 : }
1783 0 : if (NumAlphas == 1 && NumNumbers == 2) {
1784 0 : OccupantVentilationControl(i).MinTimeControlOnly = true;
1785 : }
1786 0 : if (!lAlphaBlanks(2)) {
1787 0 : OccupantVentilationControl(i).ComfortLowTempCurveName = Alphas(2);
1788 0 : OccupantVentilationControl(i).ComfortLowTempCurveNum = GetCurveIndex(m_state, Alphas(2)); // convert curve name to number
1789 0 : if (OccupantVentilationControl(i).ComfortLowTempCurveNum == 0) {
1790 0 : OccupantVentilationControl(i).MinTimeControlOnly = true;
1791 0 : ShowWarningError(m_state,
1792 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(2) +
1793 0 : " not found = " + OccupantVentilationControl(i).ComfortLowTempCurveName);
1794 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1795 0 : ShowContinueError(
1796 : m_state,
1797 : "Thermal comfort will not be performed and minimum opening and closing times are checked only. Simulation continues.");
1798 : } else {
1799 0 : ErrorsFound |= Curve::CheckCurveDims(m_state,
1800 0 : OccupantVentilationControl(i).ComfortLowTempCurveNum, // Curve index
1801 : {1}, // Valid dimensions
1802 : RoutineName, // Routine name
1803 : CurrentModuleObject, // Object Type
1804 0 : OccupantVentilationControl(i).Name, // Object Name
1805 0 : cAlphaFields(2)); // Field Name
1806 : }
1807 : }
1808 0 : if (!lAlphaBlanks(3)) {
1809 0 : OccupantVentilationControl(i).ComfortHighTempCurveName = Alphas(3);
1810 0 : OccupantVentilationControl(i).ComfortHighTempCurveNum = GetCurveIndex(m_state, Alphas(3)); // convert curve name to number
1811 0 : if (OccupantVentilationControl(i).ComfortHighTempCurveNum > 0) {
1812 0 : ErrorsFound |= Curve::CheckCurveDims(m_state,
1813 0 : OccupantVentilationControl(i).ComfortHighTempCurveNum, // Curve index
1814 : {1}, // Valid dimensions
1815 : RoutineName, // Routine name
1816 : CurrentModuleObject, // Object Type
1817 0 : OccupantVentilationControl(i).Name, // Object Name
1818 0 : cAlphaFields(3)); // Field Name
1819 : } else {
1820 0 : ShowWarningError(m_state,
1821 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) +
1822 0 : " not found = " + OccupantVentilationControl(i).ComfortHighTempCurveName);
1823 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1824 0 : ShowContinueError(m_state, "A single curve of thermal comfort low temperature is used only. Simulation continues.");
1825 : }
1826 : }
1827 0 : if (OccupantVentilationControl(i).ComfortHighTempCurveNum > 0) {
1828 0 : OccupantVentilationControl(i).ComfortBouPoint = Numbers(3);
1829 0 : if (OccupantVentilationControl(i).ComfortBouPoint < 0.0) {
1830 : // Code will never be executed, validation will catch invalid input
1831 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(3) + " < 0.0");
1832 0 : ShowContinueError(
1833 : m_state,
1834 0 : format("..Input value = {:.1R}, Value will be reset to 10.0 as default", OccupantVentilationControl(i).ComfortBouPoint));
1835 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1836 0 : OccupantVentilationControl(i).ComfortBouPoint = 10.0;
1837 : }
1838 : }
1839 : // Check continuity of both curves at boundary point
1840 0 : if (OccupantVentilationControl(i).ComfortLowTempCurveNum > 0 && OccupantVentilationControl(i).ComfortHighTempCurveNum) {
1841 0 : if (std::abs(CurveValue(m_state, OccupantVentilationControl(i).ComfortLowTempCurveNum, Numbers(3)) -
1842 0 : CurveValue(m_state, OccupantVentilationControl(i).ComfortHighTempCurveNum, Numbers(3))) > 0.1) {
1843 0 : ShowSevereError(m_state,
1844 0 : format(RoutineName) + CurrentModuleObject +
1845 : " object: The difference of both curve values at boundary point > 0.1");
1846 0 : ShowContinueError(m_state, "Both curve names are = " + cAlphaFields(2) + " and " + cAlphaFields(3));
1847 0 : ShowContinueError(m_state,
1848 0 : format("The input value of {} = {:.1R}", cNumericFields(3), OccupantVentilationControl(i).ComfortBouPoint));
1849 0 : ErrorsFound = true;
1850 : }
1851 : }
1852 0 : if (!lNumericBlanks(4)) {
1853 0 : OccupantVentilationControl(i).MaxPPD = Numbers(4);
1854 0 : if (OccupantVentilationControl(i).MaxPPD < 0.0 || OccupantVentilationControl(i).MaxPPD > 100.0) {
1855 : // Code will never be executed, validation will catch invalid input
1856 0 : ShowWarningError(m_state,
1857 0 : format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " beyond 0.0 and 100.0");
1858 0 : ShowContinueError(
1859 0 : m_state, format("..Input value = {:.1R}, Value will be reset to 10.0 as default", OccupantVentilationControl(i).MaxPPD));
1860 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1861 0 : OccupantVentilationControl(i).MaxPPD = 10.0;
1862 : }
1863 : }
1864 0 : if (!lAlphaBlanks(4)) {
1865 0 : if (Util::SameString(Alphas(4), "Yes")) {
1866 0 : OccupantVentilationControl(i).OccupancyCheck = true;
1867 0 : } else if (Util::SameString(Alphas(4), "No")) {
1868 0 : OccupantVentilationControl(i).OccupancyCheck = false;
1869 : } else {
1870 : // Code will never be executed, validation will catch invalid input
1871 0 : ShowSevereError(m_state,
1872 0 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" invalid " + cAlphaFields(2) + "=\"" +
1873 0 : Alphas(2) + "\" illegal key.");
1874 0 : ShowContinueError(m_state, "Valid keys are: Yes or No");
1875 0 : ErrorsFound = true;
1876 : }
1877 : }
1878 0 : if (!lAlphaBlanks(5)) {
1879 0 : OccupantVentilationControl(i).OpeningProbSchName = Alphas(5); // a schedule name for opening probability
1880 0 : OccupantVentilationControl(i).openingProbSched = Sched::GetSchedule(m_state, OccupantVentilationControl(i).OpeningProbSchName);
1881 0 : if (OccupantVentilationControl(i).openingProbSched == nullptr) {
1882 0 : ShowSevereError(m_state,
1883 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(5) +
1884 0 : " not found = " + OccupantVentilationControl(i).OpeningProbSchName);
1885 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1886 0 : ErrorsFound = true;
1887 : }
1888 : }
1889 0 : if (!lAlphaBlanks(6)) {
1890 0 : OccupantVentilationControl(i).ClosingProbSchName = Alphas(6); // a schedule name for closing probability
1891 0 : OccupantVentilationControl(i).closingProbSched = Sched::GetSchedule(m_state, OccupantVentilationControl(i).ClosingProbSchName);
1892 0 : if (OccupantVentilationControl(i).closingProbSched == nullptr) {
1893 0 : ShowSevereError(m_state,
1894 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) +
1895 0 : " not found = " + OccupantVentilationControl(i).ClosingProbSchName);
1896 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1897 0 : ErrorsFound = true;
1898 : }
1899 : }
1900 : }
1901 : }
1902 :
1903 127 : if (ErrorsFound) {
1904 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
1905 : }
1906 :
1907 : // *** Read AirflowNetwork simulation parameters
1908 127 : CurrentModuleObject = "AirflowNetwork:SimulationControl";
1909 127 : NumAirflowNetwork = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1910 127 : if (NumAirflowNetwork == 0) {
1911 104 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:Zone") >= 1 &&
1912 104 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:Surface") >= 2) {
1913 1 : control_defaulted = true;
1914 1 : simulation_control.name = "AFNDefaultControl";
1915 1 : simulation_control.type = ControlType::MultizoneWithoutDistribution;
1916 1 : simulation_control.WPCCntr = "SURFACEAVERAGECALCULATION";
1917 1 : simulation_control.HeightOption = "OPENINGHEIGHT";
1918 1 : simulation_control.BldgType = "LOWRISE";
1919 1 : simulation_control.InitType = "ZERONODEPRESSURES";
1920 1 : simulation_control.temperature_height_dependence = false;
1921 1 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
1922 : // Use default values for numerical fields
1923 1 : simulation_control.maximum_iterations = 500;
1924 1 : simulation_control.relative_convergence_tolerance = 1.E-4;
1925 1 : simulation_control.absolute_convergence_tolerance = 1.E-6;
1926 1 : simulation_control.convergence_acceleration_limit = -0.5;
1927 1 : simulation_control.azimuth = 0.0;
1928 1 : simulation_control.aspect_ratio = 1.0;
1929 1 : simulation_control.MaxPressure = 500.0; // Maximum pressure difference by default
1930 1 : SimAirNetworkKey = "MultizoneWithoutDistribution";
1931 1 : simulation_control.InitFlag = 1;
1932 1 : ShowWarningError(m_state, format("{}{} object is not found ", RoutineName, CurrentModuleObject));
1933 3 : ShowContinueError(m_state, "..The default behaviour values are assigned. Please see details in Input Output Reference.");
1934 : } else {
1935 102 : simulation_control.type = ControlType::NoMultizoneOrDistribution;
1936 102 : print(m_state.files.eio, Format_110);
1937 102 : print(m_state.files.eio, Format_120, "NoMultizoneOrDistribution");
1938 102 : return;
1939 : }
1940 : }
1941 25 : if (NumAirflowNetwork > 1) {
1942 0 : ShowFatalError(m_state, format("{}Only one (\"1\") {} object per simulation is allowed.", RoutineName, CurrentModuleObject));
1943 : }
1944 :
1945 25 : if (!control_defaulted) {
1946 24 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
1947 : CurrentModuleObject,
1948 : NumAirflowNetwork,
1949 : Alphas,
1950 : NumAlphas,
1951 : Numbers,
1952 : NumNumbers,
1953 : IOStatus,
1954 : lNumericBlanks,
1955 : lAlphaBlanks,
1956 : cAlphaFields,
1957 : cNumericFields);
1958 :
1959 24 : simulation_control.name = Alphas(1);
1960 24 : simulation_control.WPCCntr = Alphas(3);
1961 24 : simulation_control.HeightOption = Alphas(4);
1962 24 : simulation_control.BldgType = Alphas(5);
1963 :
1964 : // Retrieve flag allowing the support of zone equipment
1965 24 : simulation_control.allow_unsupported_zone_equipment = false;
1966 24 : if (Util::SameString(Alphas(9), "Yes")) {
1967 1 : simulation_control.allow_unsupported_zone_equipment = true;
1968 : }
1969 :
1970 : // Find a flag for possible combination of vent and distribution system
1971 : // This SELECT_CASE_var will go on input refactor, no need to fix
1972 : {
1973 24 : auto const SELECT_CASE_var(Util::makeUPPER(Alphas(2)));
1974 24 : if (SELECT_CASE_var == "NOMULTIZONEORDISTRIBUTION") {
1975 0 : simulation_control.type = ControlType::NoMultizoneOrDistribution;
1976 0 : SimAirNetworkKey = "NoMultizoneOrDistribution";
1977 24 : } else if (SELECT_CASE_var == "MULTIZONEWITHOUTDISTRIBUTION") {
1978 17 : simulation_control.type = ControlType::MultizoneWithoutDistribution;
1979 17 : SimAirNetworkKey = "MultizoneWithoutDistribution";
1980 7 : } else if (SELECT_CASE_var == "MULTIZONEWITHDISTRIBUTIONONLYDURINGFANOPERATION") {
1981 0 : simulation_control.type = ControlType::MultizoneWithDistributionOnlyDuringFanOperation;
1982 0 : SimAirNetworkKey = "MultizoneWithDistributionOnlyDuringFanOperation";
1983 : } else { // if (SELECT_CASE_var == "MULTIZONEWITHDISTRIBUTION") {
1984 7 : simulation_control.type = ControlType::MultizoneWithDistribution;
1985 7 : SimAirNetworkKey = "MultizoneWithDistribution";
1986 : }
1987 24 : }
1988 : }
1989 :
1990 : // Determine a convenience boolean or two to simplify the checking
1991 : // The first one is true if distribution is simulated, replaces some > and >= comparisons
1992 : // SimulateAirflowNetwork > AirflowNetworkControlMultizone -> type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation
1993 : // type == ControlType::MultizoneWithDistribution
1994 : // SimulateAirflowNetwork >= AirflowNetworkControlSimpleADS -> type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation
1995 : // type == ControlType::MultizoneWithDistribution
1996 50 : distribution_simulated = simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation ||
1997 25 : simulation_control.type == ControlType::MultizoneWithDistribution;
1998 : // This one is true if the multizone simulation is ALWAYS done
1999 25 : multizone_always_simulated =
2000 25 : simulation_control.type == ControlType::MultizoneWithDistribution || simulation_control.type == ControlType::MultizoneWithoutDistribution;
2001 :
2002 : // Check the number of primary air loops
2003 25 : if (distribution_simulated) {
2004 7 : NumAPL = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC");
2005 7 : if (NumAPL > 0) {
2006 7 : LoopPartLoadRatio.allocate(NumAPL);
2007 7 : LoopOnOffFanRunTimeFraction.allocate(NumAPL);
2008 7 : LoopOnOffFlag.allocate(NumAPL);
2009 7 : LoopPartLoadRatio = 0.0;
2010 7 : LoopOnOffFanRunTimeFraction = 0.0;
2011 7 : LoopOnOffFlag = false;
2012 : }
2013 : }
2014 25 : print(m_state.files.eio, Format_110);
2015 25 : print(m_state.files.eio, Format_120, SimAirNetworkKey);
2016 :
2017 25 : if (control_defaulted) {
2018 1 : cAlphaFields(2) = "AirflowNetwork Control";
2019 : }
2020 :
2021 : // Check whether there are any objects from infiltration, ventilation, mixing and cross mixing
2022 25 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution ||
2023 25 : simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation) {
2024 0 : if (m_state.dataHeatBal->TotInfiltration + m_state.dataHeatBal->TotVentilation + m_state.dataHeatBal->TotMixing +
2025 0 : m_state.dataHeatBal->TotCrossMixing + m_state.dataHeatBal->TotZoneAirBalance +
2026 0 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneEarthtube") +
2027 0 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneThermalChimney") +
2028 0 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneCoolTower:Shower") ==
2029 : 0) {
2030 0 : ShowWarningError(m_state, format("{}{} = \"{}\"", RoutineName, cAlphaFields(2), SimAirNetworkKey));
2031 0 : ShowContinueError(
2032 : m_state,
2033 : "..but there are no Infiltration, Ventilation, Mixing, Cross Mixing or ZoneAirBalance objects. The simulation continues...");
2034 : }
2035 : }
2036 :
2037 : // Check whether a user wants to perform SIMPLE calculation only or not
2038 25 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) {
2039 0 : return;
2040 : }
2041 :
2042 25 : if (multizone_always_simulated) {
2043 25 : if (m_state.dataHeatBal->TotInfiltration > 0) {
2044 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2045 0 : ShowContinueError(m_state,
2046 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneInfiltration:* objects are present.");
2047 0 : ShowContinueError(m_state, "..ZoneInfiltration objects will not be simulated.");
2048 : }
2049 25 : if (m_state.dataHeatBal->TotVentilation > 0) {
2050 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2051 0 : ShowContinueError(m_state,
2052 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneVentilation:* objects are present.");
2053 0 : ShowContinueError(m_state, "..ZoneVentilation objects will not be simulated.");
2054 : }
2055 25 : if (m_state.dataHeatBal->TotMixing > 0) {
2056 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2057 0 : ShowContinueError(m_state, "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneMixing objects are present.");
2058 0 : ShowContinueError(m_state, "..ZoneMixing objects will not be simulated.");
2059 : }
2060 25 : if (m_state.dataHeatBal->TotCrossMixing > 0) {
2061 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2062 0 : ShowContinueError(m_state,
2063 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneCrossMixing objects are present.");
2064 0 : ShowContinueError(m_state, "..ZoneCrossMixing objects will not be simulated.");
2065 : }
2066 25 : if (m_state.dataHeatBal->TotZoneAirBalance > 0) {
2067 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2068 0 : ShowContinueError(
2069 0 : m_state, "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneAirBalance:OutdoorAir objects are present.");
2070 0 : ShowContinueError(m_state, "..ZoneAirBalance:OutdoorAir objects will not be simulated.");
2071 : }
2072 25 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneEarthtube") > 0) {
2073 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2074 0 : ShowContinueError(m_state,
2075 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneEarthtube objects are present.");
2076 0 : ShowContinueError(m_state, "..ZoneEarthtube objects will not be simulated.");
2077 : }
2078 25 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneThermalChimney") > 0) {
2079 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2080 0 : ShowContinueError(m_state,
2081 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneThermalChimney objects are present.");
2082 0 : ShowContinueError(m_state, "..ZoneThermalChimney objects will not be simulated.");
2083 : }
2084 25 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneCoolTower:Shower") > 0) {
2085 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2086 0 : ShowContinueError(m_state,
2087 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneCoolTower:Shower objects are present.");
2088 0 : ShowContinueError(m_state, "..ZoneCoolTower:Shower objects will not be simulated.");
2089 : }
2090 : }
2091 :
2092 25 : SetOutAirNodes(m_state);
2093 25 : if (!control_defaulted) {
2094 24 : bool SimObjectError = false;
2095 24 : if (Util::SameString(simulation_control.WPCCntr, "Input")) {
2096 10 : simulation_control.iWPCCnt = iWPCCntr::Input;
2097 10 : if (lAlphaBlanks(4)) {
2098 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) + " = INPUT.");
2099 0 : ShowContinueError(m_state, ".." + cAlphaFields(4) + " was not entered.");
2100 0 : ErrorsFound = true;
2101 0 : SimObjectError = true;
2102 : } else {
2103 10 : if (!(Util::SameString(simulation_control.HeightOption, "ExternalNode") ||
2104 10 : Util::SameString(simulation_control.HeightOption, "OpeningHeight"))) {
2105 0 : ShowSevereError(
2106 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(4) + " = " + Alphas(4) + " is invalid.");
2107 0 : ShowContinueError(m_state,
2108 0 : "Valid choices are ExternalNode or OpeningHeight. " + CurrentModuleObject + ": " + cAlphaFields(1) + " = " +
2109 0 : simulation_control.name);
2110 0 : ErrorsFound = true;
2111 0 : SimObjectError = true;
2112 : }
2113 : }
2114 14 : } else if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
2115 14 : simulation_control.iWPCCnt = iWPCCntr::SurfAvg;
2116 14 : if (!(Util::SameString(simulation_control.BldgType, "LowRise") || Util::SameString(simulation_control.BldgType, "HighRise"))) {
2117 0 : ShowSevereError(m_state,
2118 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(5) + " = " + Alphas(5) + " is invalid.");
2119 0 : ShowContinueError(m_state,
2120 0 : "Valid choices are LowRise or HighRise. " + CurrentModuleObject + ": " + cAlphaFields(1) + " = " +
2121 0 : simulation_control.name);
2122 0 : ErrorsFound = true;
2123 0 : SimObjectError = true;
2124 : }
2125 38 : for (k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
2126 24 : if (Node(k).IsLocalNode) {
2127 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(3) + "=" + Alphas(3));
2128 0 : ShowContinueError(m_state,
2129 : "A local air node is defined to INPUT the wind pressure coefficient curve, while Wind Pressure Coefficient "
2130 : "Type is set to SurfaceAverageCalculation.");
2131 0 : ShowContinueError(m_state, "It requires the Wind Pressure Coefficient Type be set to INPUT to use the local air node.");
2132 0 : ErrorsFound = true;
2133 0 : SimObjectError = true;
2134 0 : break;
2135 : }
2136 : }
2137 : } else {
2138 0 : ShowSevereError(m_state,
2139 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) + " = " + simulation_control.WPCCntr +
2140 : " is not valid.");
2141 0 : ShowContinueError(m_state,
2142 0 : "Valid choices are Input or SurfaceAverageCalculation. " + CurrentModuleObject + " = " + simulation_control.name);
2143 0 : ErrorsFound = true;
2144 0 : SimObjectError = true;
2145 : }
2146 :
2147 24 : simulation_control.InitType = Alphas(6);
2148 24 : if (Util::SameString(simulation_control.InitType, "LinearInitializationMethod")) {
2149 5 : simulation_control.InitFlag = 0;
2150 19 : } else if (Util::SameString(simulation_control.InitType, "ZeroNodePressures")) {
2151 19 : simulation_control.InitFlag = 1;
2152 0 : } else if (Util::SameString(simulation_control.InitType, "0")) {
2153 0 : simulation_control.InitFlag = 0;
2154 0 : } else if (Util::SameString(simulation_control.InitType, "1")) {
2155 0 : simulation_control.InitFlag = 1;
2156 : } else {
2157 : // Code will never be executed, validation will catch invalid input
2158 0 : ShowSevereError(m_state,
2159 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) + " = " + Alphas(6) + " is invalid.");
2160 0 : ShowContinueError(m_state,
2161 0 : "Valid choices are LinearInitializationMethod or ZeroNodePressures. " + CurrentModuleObject + " = " +
2162 0 : simulation_control.name);
2163 0 : ErrorsFound = true;
2164 0 : SimObjectError = true;
2165 : }
2166 :
2167 24 : if (!lAlphaBlanks(7) && Util::SameString(Alphas(7), "Yes")) simulation_control.temperature_height_dependence = true;
2168 :
2169 24 : if (lAlphaBlanks(8)) {
2170 23 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2171 1 : } else if (Util::SameString(Alphas(8), "SkylineLU")) {
2172 1 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2173 0 : } else if (Util::SameString(Alphas(8), "ConjugateGradient")) {
2174 0 : simulation_control.solver = SimulationControl::Solver::ConjugateGradient;
2175 : } else {
2176 0 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2177 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2178 0 : ShowContinueError(m_state, "..Specified " + cAlphaFields(8) + " = \"" + Alphas(8) + "\" is unrecognized.");
2179 0 : ShowContinueError(m_state, "..Default value \"SkylineLU\" will be used.");
2180 : }
2181 :
2182 : // Get inputs for duct sizing
2183 24 : simulation_control.autosize_ducts = false;
2184 24 : if (NumAlphas == 10) {
2185 24 : if (Util::SameString(Alphas(10), "YES")) {
2186 0 : simulation_control.autosize_ducts = true;
2187 0 : if (simulation_control.type == ControlType::MultizoneWithDistribution) {
2188 0 : if (NumAPL > 1) {
2189 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2190 0 : ShowContinueError(
2191 : m_state,
2192 0 : format("The number of AirLoopHAVC is greater than 1. The current requirement for Duct Sizing requires a "
2193 : "single AirLoopHVAC."));
2194 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2195 0 : simulation_control.autosize_ducts = false;
2196 : }
2197 : }
2198 : }
2199 : }
2200 :
2201 24 : if (SimObjectError) {
2202 0 : ShowFatalError(
2203 : m_state,
2204 0 : format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
2205 : }
2206 :
2207 24 : simulation_control.maximum_iterations = static_cast<int>(Numbers(1));
2208 24 : simulation_control.relative_convergence_tolerance = Numbers(2);
2209 24 : simulation_control.absolute_convergence_tolerance = Numbers(3);
2210 24 : simulation_control.convergence_acceleration_limit = Numbers(4);
2211 24 : simulation_control.azimuth = Numbers(5);
2212 24 : simulation_control.aspect_ratio = Numbers(6);
2213 24 : simulation_control.MaxPressure = 500.0; // Maximum pressure difference by default
2214 : }
2215 :
2216 25 : CurrentModuleObject = "AirflowNetwork:Distribution:DuctSizing";
2217 25 : int NumDuctSizing = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2218 25 : if (NumDuctSizing > 1) {
2219 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2220 0 : ShowContinueError(
2221 : m_state,
2222 0 : format("The number of AirflowNetwork:Distribution:DuctSizing is greater than 1. The current requirement for Duct Sizing requires a "
2223 : "single object."));
2224 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2225 0 : simulation_control.autosize_ducts = false;
2226 25 : } else if (simulation_control.autosize_ducts && NumDuctSizing == 0) {
2227 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2228 0 : ShowContinueError(
2229 : m_state,
2230 0 : format("The number of AirflowNetwork:Distribution:DuctSizing is not avalable. The current requirement for Duct Sizing requires a "
2231 : "single object."));
2232 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2233 0 : simulation_control.autosize_ducts = false;
2234 : }
2235 25 : if (simulation_control.autosize_ducts && NumDuctSizing == 1) {
2236 0 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2237 : CurrentModuleObject,
2238 : NumDuctSizing,
2239 : Alphas,
2240 : NumAlphas,
2241 : Numbers,
2242 : NumNumbers,
2243 : IOStatus,
2244 : lNumericBlanks,
2245 : lAlphaBlanks,
2246 : cAlphaFields,
2247 : cNumericFields);
2248 :
2249 0 : simulation_control.ductSizing.name = Alphas(1);
2250 0 : if (Util::SameString(Alphas(2), Util::makeUPPER("MaximumVelocity"))) {
2251 0 : simulation_control.ductSizing.method = DuctSizingMethod::MaxVelocity;
2252 0 : } else if (Util::SameString(Alphas(2), Util::makeUPPER("PressureLoss"))) {
2253 0 : simulation_control.ductSizing.method = DuctSizingMethod::PressureLoss;
2254 0 : } else if (Util::SameString(Alphas(2), Util::makeUPPER("PressureLossWithMaximumVelocity"))) {
2255 0 : simulation_control.ductSizing.method = DuctSizingMethod::VelocityAndLoss;
2256 : } else {
2257 0 : ShowSevereError(m_state, format("{} {} object, {} = {} is invalid.", RoutineName, CurrentModuleObject, cAlphaFields(2), Alphas(2)));
2258 0 : ShowContinueError(m_state,
2259 0 : format("Valid choices are MaximumVelocity, PressureLoss, and PressureLossWithMaximumVelocity. {}: {} = {}",
2260 : CurrentModuleObject,
2261 : cAlphaFields(1),
2262 : Alphas(1)));
2263 0 : ErrorsFound = true;
2264 : }
2265 0 : if (simulation_control.type != ControlType::MultizoneWithDistribution) {
2266 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2267 0 : ShowContinueError(m_state,
2268 0 : format("Although {} = \"{}\" is entered, but {} is not MultizoneWithoutDistribution.",
2269 : cAlphaFields(10),
2270 : Alphas(10),
2271 : cAlphaFields(2)));
2272 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2273 0 : simulation_control.autosize_ducts = false;
2274 : }
2275 0 : simulation_control.ductSizing.factor = Numbers(1);
2276 0 : simulation_control.ductSizing.max_velocity = Numbers(2);
2277 0 : simulation_control.ductSizing.supply_trunk_pressure_loss = Numbers(3);
2278 0 : simulation_control.ductSizing.supply_branch_pressure_loss = Numbers(4);
2279 0 : simulation_control.ductSizing.return_trunk_pressure_loss = Numbers(5);
2280 0 : simulation_control.ductSizing.return_branch_pressure_loss = Numbers(6);
2281 : }
2282 :
2283 : // *** Read AirflowNetwork simulation zone data
2284 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Zone";
2285 25 : AirflowNetworkNumOfZones = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2286 25 : if (AirflowNetworkNumOfZones > 0) {
2287 25 : MultizoneZoneData.allocate(AirflowNetworkNumOfZones);
2288 25 : AirflowNetworkZoneFlag.dimension(m_state.dataGlobal->NumOfZones, false); // AirflowNetwork zone flag
2289 77 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
2290 52 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2291 : CurrentModuleObject,
2292 : i,
2293 : Alphas,
2294 : NumAlphas,
2295 : Numbers,
2296 : NumNumbers,
2297 : IOStatus,
2298 : lNumericBlanks,
2299 : lAlphaBlanks,
2300 : cAlphaFields,
2301 : cNumericFields);
2302 :
2303 52 : ErrorObjectHeader eoh{RoutineName, CurrentModuleObject, Alphas(1)};
2304 :
2305 52 : MultizoneZoneData(i).ZoneName = Alphas(1); // Name of Associated EnergyPlus Thermal Zone
2306 52 : if (!lAlphaBlanks(2)) MultizoneZoneData(i).VentControl = Alphas(2); // Ventilation Control Mode: "Temperature", "Enthalpy",
2307 : // "ASHRAE55ADAPTIVE", "CEN15251AdaptiveComfort,
2308 : // "Constant", or "NoVent"
2309 52 : MultizoneZoneData(i).VentTempControlSchName = Alphas(3); // Name of ventilation temperature control schedule
2310 52 : MultizoneZoneData(i).OpenFactor = Numbers(1); // Limit Value on Multiplier for Modulating Venting Open Factor,
2311 : // Not applicable if Vent Control Mode = CONSTANT or NOVENT
2312 52 : MultizoneZoneData(i).LowValueTemp = Numbers(2); // Lower Value on Inside/Outside Temperature Difference
2313 : // for Modulating the Venting Open Factor with temp control
2314 52 : MultizoneZoneData(i).UpValueTemp = Numbers(3); // Upper Value on Inside/Outside Temperature Difference
2315 : // for Modulating the Venting Open Factor with temp control
2316 52 : MultizoneZoneData(i).LowValueEnth = Numbers(4); // Lower Value on Inside/Outside Temperature Difference
2317 : // for Modulating the Venting Open Factor with Enthalpy control
2318 52 : MultizoneZoneData(i).UpValueEnth = Numbers(5); // Upper Value on Inside/Outside Temperature Difference
2319 : // for Modulating the Venting Open Factor with Enthalpy control
2320 52 : MultizoneZoneData(i).VentCtrNum = VentControlType::None;
2321 52 : MultizoneZoneData(i).SingleSidedCpType = Alphas(5);
2322 52 : MultizoneZoneData(i).BuildWidth = Numbers(6);
2323 :
2324 52 : if (!lAlphaBlanks(6)) {
2325 0 : MultizoneZoneData(i).OccupantVentilationControlName = Alphas(6);
2326 0 : MultizoneZoneData(i).OccupantVentilationControlNum =
2327 0 : Util::FindItemInList(MultizoneZoneData(i).OccupantVentilationControlName, OccupantVentilationControl);
2328 0 : if (MultizoneZoneData(i).OccupantVentilationControlNum == 0) {
2329 0 : ShowSevereError(m_state,
2330 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) +
2331 0 : " not found = " + MultizoneZoneData(i).OccupantVentilationControlName);
2332 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
2333 0 : ErrorsFound = true;
2334 : }
2335 : }
2336 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Temperature")) MultizoneZoneData(i).VentCtrNum = VentControlType::Temp;
2337 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Enthalpy")) MultizoneZoneData(i).VentCtrNum = VentControlType::Enth;
2338 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Constant")) MultizoneZoneData(i).VentCtrNum = VentControlType::Const;
2339 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "ASHRAE55Adaptive")) MultizoneZoneData(i).VentCtrNum = VentControlType::ASH55;
2340 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "CEN15251Adaptive"))
2341 3 : MultizoneZoneData(i).VentCtrNum = VentControlType::CEN15251;
2342 52 : if (Util::SameString(MultizoneZoneData(i).VentControl, "NoVent")) MultizoneZoneData(i).VentCtrNum = VentControlType::NoVent;
2343 :
2344 52 : if (MultizoneZoneData(i).VentCtrNum < NumOfVentCtrTypes) {
2345 20 : if (NumAlphas >= 4 && (!lAlphaBlanks(4))) {
2346 15 : MultizoneZoneData(i).VentAvailSchName = Alphas(4);
2347 15 : if ((MultizoneZoneData(i).ventAvailSched = Sched::GetSchedule(m_state, MultizoneZoneData(i).VentAvailSchName)) == nullptr) {
2348 0 : ShowSevereItemNotFound(m_state, eoh, cAlphaFields(4), Alphas(4));
2349 0 : ErrorsFound = true;
2350 : }
2351 : }
2352 : } else {
2353 32 : MultizoneZoneData(i).VentAvailSchName = std::string();
2354 32 : MultizoneZoneData(i).ventAvailSched = Sched::GetScheduleAlwaysOn(m_state);
2355 : }
2356 : }
2357 : } else {
2358 0 : ShowSevereError(m_state,
2359 0 : format(RoutineName) + "For an AirflowNetwork Simulation, at least one " + CurrentModuleObject +
2360 : " object is required but none were found.");
2361 0 : ShowFatalError(
2362 0 : m_state, format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
2363 : }
2364 :
2365 : // ==> Zone data validation
2366 77 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
2367 : // Zone name validation
2368 52 : ErrorObjectHeader eoh{RoutineName, CurrentModuleObject, MultizoneZoneData(i).ZoneName};
2369 :
2370 52 : MultizoneZoneData(i).ZoneNum = Util::FindItemInList(MultizoneZoneData(i).ZoneName, Zone);
2371 52 : if (MultizoneZoneData(i).ZoneNum == 0) {
2372 0 : ShowSevereItemNotFound(m_state, eoh, "Zone Name", MultizoneZoneData(i).ZoneName);
2373 0 : ErrorsFound = true;
2374 : } else {
2375 52 : AirflowNetworkZoneFlag(MultizoneZoneData(i).ZoneNum) = true;
2376 52 : MultizoneZoneData(i).Height = Zone(MultizoneZoneData(i).ZoneNum).Centroid.z; // Nodal height
2377 : }
2378 52 : if (MultizoneZoneData(i).VentCtrNum == VentControlType::None) {
2379 0 : ShowSevereError(m_state,
2380 0 : format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(2) + " = " +
2381 0 : MultizoneZoneData(i).VentControl);
2382 0 : ShowContinueError(m_state, "Valid choices are Temperature, Enthalpy, Constant, or NoVent");
2383 0 : ShowContinueError(m_state, ".. in " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\"");
2384 0 : ErrorsFound = true;
2385 : }
2386 :
2387 91 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Temperature") ||
2388 91 : Util::SameString(MultizoneZoneData(i).VentControl, "Enthalpy")) { // Already converted this to an enum, why compare strings?
2389 : // .or. &
2390 : // Util::SameString(MultizoneZoneData(i)%VentControl,'ASHRAE55Adaptive') .or. &
2391 : // Util::SameString(MultizoneZoneData(i)%VentControl,'CEN15251Adaptive')) then
2392 13 : if (MultizoneZoneData(i).VentTempControlSchName.empty()) {
2393 0 : ShowSevereEmptyField(m_state, eoh, cAlphaFields(3), cAlphaFields(2), Alphas(2));
2394 0 : ErrorsFound = true;
2395 13 : } else if ((MultizoneZoneData(i).ventTempControlSched = Sched::GetSchedule(m_state, MultizoneZoneData(i).VentTempControlSchName)) ==
2396 : nullptr) {
2397 0 : ShowSevereItemNotFound(m_state, eoh, cAlphaFields(3), Alphas(3));
2398 0 : ErrorsFound = true;
2399 : }
2400 : } else {
2401 39 : MultizoneZoneData(i).ventTempControlSched = nullptr;
2402 39 : if (!MultizoneZoneData(i).VentTempControlSchName.empty()) {
2403 0 : ShowWarningNonEmptyField(m_state, eoh, cAlphaFields(3), cAlphaFields(2), Alphas(2));
2404 0 : MultizoneZoneData(i).VentTempControlSchName = std::string();
2405 : }
2406 : }
2407 52 : if (MultizoneZoneData(i).OpenFactor > 1.0 || MultizoneZoneData(i).OpenFactor < 0.0) {
2408 : // Code will never be executed, validation will catch invalid input
2409 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(1) + " is out of range [0.0,1.0]");
2410 0 : ShowContinueError(m_state, format("..Input value = {:.2R}, Value will be set to 1.0", MultizoneZoneData(i).OpenFactor));
2411 0 : MultizoneZoneData(i).OpenFactor = 1.0;
2412 : }
2413 :
2414 : {
2415 : // These SELECT_CASE_vars will go on input refactor, no need to fix
2416 52 : auto const SELECT_CASE_var(Util::makeUPPER(MultizoneZoneData(i).VentControl));
2417 52 : if (SELECT_CASE_var == "TEMPERATURE") { // checks on Temperature control
2418 13 : if (MultizoneZoneData(i).LowValueTemp < 0.0) {
2419 : // Code will never be executed, validation will catch invalid input
2420 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " < 0.0");
2421 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be set to 0.0", MultizoneZoneData(i).LowValueTemp));
2422 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2423 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
2424 : }
2425 13 : if (MultizoneZoneData(i).LowValueTemp >= 100.0) {
2426 : // Code will never be executed, validation will catch invalid input
2427 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " >= 100.0");
2428 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneZoneData(i).LowValueTemp));
2429 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2430 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
2431 : }
2432 13 : if (MultizoneZoneData(i).UpValueTemp <= MultizoneZoneData(i).LowValueTemp) {
2433 0 : ShowWarningError(m_state,
2434 0 : format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(3) + " <= " + cNumericFields(2));
2435 0 : ShowContinueError(m_state,
2436 0 : format("..Input value for {} = {:.1R}, Value will be reset to 100.0",
2437 : cNumericFields(3),
2438 0 : MultizoneZoneData(i).UpValueTemp));
2439 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2440 0 : MultizoneZoneData(i).UpValueTemp = 100.0;
2441 : }
2442 :
2443 39 : } else if (SELECT_CASE_var == "ENTHALPY") { // checks for Enthalpy control
2444 0 : if (MultizoneZoneData(i).LowValueEnth < 0.0) {
2445 : // Code will never be executed, validation will catch invalid input
2446 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " < 0.0");
2447 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneZoneData(i).LowValueEnth));
2448 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2449 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
2450 : }
2451 0 : if (MultizoneZoneData(i).LowValueEnth >= 300000.0) {
2452 : // Code will never be executed, validation will catch invalid input
2453 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " >= 300000.0");
2454 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0.", MultizoneZoneData(i).LowValueEnth));
2455 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2456 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
2457 : }
2458 0 : if (MultizoneZoneData(i).UpValueEnth <= MultizoneZoneData(i).LowValueEnth) {
2459 0 : ShowWarningError(m_state,
2460 0 : format("{}{} object, {} <= {}", RoutineName, CurrentModuleObject, cNumericFields(5), cNumericFields(4)));
2461 0 : ShowContinueError(m_state,
2462 0 : format("..Input value for {}= {:.1R}, Value will be reset to 300000.0",
2463 : cNumericFields(5),
2464 0 : MultizoneZoneData(i).UpValueEnth));
2465 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2466 0 : MultizoneZoneData(i).UpValueEnth = 300000.0;
2467 : }
2468 39 : } else if (SELECT_CASE_var == "ASHRAE55ADAPTIVE") {
2469 : // Check that for the given zone, there is a people object for which ASHRAE 55 calculations are carried out
2470 0 : int ZoneNum = MultizoneZoneData(i).ZoneNum;
2471 0 : for (int j = 1; j <= m_state.dataHeatBal->TotPeople; ++j) {
2472 0 : if (ZoneNum == m_state.dataHeatBal->People(j).ZonePtr && m_state.dataHeatBal->People(j).AdaptiveASH55) {
2473 0 : MultizoneZoneData(i).ASH55PeopleInd = j;
2474 : }
2475 : }
2476 0 : if (MultizoneZoneData(i).ASH55PeopleInd == 0) {
2477 0 : ShowFatalError(m_state,
2478 0 : "ASHRAE55 ventilation control for zone " + MultizoneZoneData(i).ZoneName +
2479 : " requires a people object with respective model calculations.");
2480 : }
2481 39 : } else if (SELECT_CASE_var == "CEN15251ADAPTIVE") {
2482 : // Check that for the given zone, there is a people object for which CEN-15251 calculations are carried out
2483 3 : int ZoneNum = MultizoneZoneData(i).ZoneNum;
2484 3 : for (int j = 1; j <= m_state.dataHeatBal->TotPeople; ++j) {
2485 3 : if (ZoneNum == m_state.dataHeatBal->People(j).ZonePtr && m_state.dataHeatBal->People(j).AdaptiveCEN15251) {
2486 3 : MultizoneZoneData(i).CEN15251PeopleInd = j;
2487 3 : break;
2488 : }
2489 : }
2490 3 : if (MultizoneZoneData(i).CEN15251PeopleInd == 0) {
2491 0 : ShowFatalError(m_state,
2492 0 : "CEN15251 ventilation control for zone " + MultizoneZoneData(i).ZoneName +
2493 : " requires a people object with respective model calculations.");
2494 : }
2495 : } else {
2496 : }
2497 52 : }
2498 : }
2499 :
2500 : // *** Read AirflowNetwork external node
2501 25 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
2502 : // Wind coefficient == Surface-Average does not need inputs of external nodes
2503 10 : AirflowNetworkNumOfExtNode =
2504 10 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:ExternalNode");
2505 10 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel) {
2506 1 : AirflowNetworkNumOfOutAirNode = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "OutdoorAir:Node");
2507 1 : AirflowNetworkNumOfExtNode += AirflowNetworkNumOfOutAirNode;
2508 : }
2509 :
2510 10 : if (AirflowNetworkNumOfExtNode > 0) {
2511 10 : MultizoneExternalNodeData.allocate(AirflowNetworkNumOfExtNode);
2512 10 : CurrentModuleObject = "AirflowNetwork:MultiZone:ExternalNode";
2513 41 : for (int i = 1; i <= AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode; ++i) {
2514 31 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2515 : CurrentModuleObject,
2516 : i,
2517 : Alphas,
2518 : NumAlphas,
2519 : Numbers,
2520 : NumNumbers,
2521 : IOStatus,
2522 : lNumericBlanks,
2523 : lAlphaBlanks,
2524 : cAlphaFields,
2525 : cNumericFields);
2526 31 : MultizoneExternalNodeData(i).Name = Alphas(1); // Name of external node
2527 31 : MultizoneExternalNodeData(i).height = Numbers(1); // Nodal height
2528 31 : if (Util::SameString(simulation_control.HeightOption, "ExternalNode") && lNumericBlanks(1)) {
2529 0 : ShowWarningError(m_state,
2530 0 : format(RoutineName) + CurrentModuleObject + " object =" + Alphas(1) + ". The input of " + cNumericFields(1) +
2531 : " is required, but a blank is found.");
2532 0 : ShowContinueError(m_state, format("The default value is assigned as {:.1R}", Numbers(1)));
2533 : }
2534 31 : MultizoneExternalNodeData(i).ExtNum = AirflowNetworkNumOfZones + i; // External node number
2535 31 : MultizoneExternalNodeData(i).curve = Curve::GetCurveIndex(m_state, Alphas(2)); // Wind pressure curve
2536 31 : if (MultizoneExternalNodeData(i).curve == 0) {
2537 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(2) + "=" + Alphas(2));
2538 0 : ShowContinueError(m_state, "Entered in " + CurrentModuleObject + '=' + Alphas(1));
2539 0 : ErrorsFound = true;
2540 : }
2541 31 : if (NumAlphas >= 3 && !lAlphaBlanks(3)) { // Symmetric curve
2542 6 : if (Util::SameString(Alphas(3), "Yes")) {
2543 4 : MultizoneExternalNodeData(i).symmetricCurve = true;
2544 2 : } else if (!Util::SameString(Alphas(3), "No")) {
2545 0 : ShowWarningError(
2546 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(3) + " = " + Alphas(3));
2547 0 : ShowContinueError(m_state, "The default value is assigned as No.");
2548 : }
2549 : }
2550 31 : if (NumAlphas == 4 && !lAlphaBlanks(4)) { // Relative or absolute wind angle
2551 4 : if (Util::SameString(Alphas(4), "Relative")) {
2552 2 : MultizoneExternalNodeData(i).useRelativeAngle = true;
2553 2 : } else if (!Util::SameString(Alphas(4), "Absolute")) {
2554 : // Code will never be executed, validation will catch invalid input
2555 0 : ShowWarningError(
2556 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(4) + " = " + Alphas(4));
2557 0 : ShowContinueError(m_state, "The default value is assigned as Absolute.");
2558 : }
2559 : }
2560 : }
2561 10 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel) {
2562 :
2563 1 : CurrentModuleObject = "OutdoorAir:Node";
2564 3 : for (int i = AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode + 1; i <= AirflowNetworkNumOfExtNode; ++i) {
2565 4 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2566 : CurrentModuleObject,
2567 2 : i - (AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode),
2568 : Alphas,
2569 : NumAlphas,
2570 : Numbers,
2571 : NumNumbers,
2572 : IOStatus,
2573 : lNumericBlanks,
2574 : lAlphaBlanks,
2575 : cAlphaFields,
2576 : cNumericFields);
2577 : // HACK: Need to verify name is unique between "OutdoorAir:Node" and "AirflowNetwork:MultiZone:ExternalNode"
2578 :
2579 2 : if (NumAlphas > 5 && !lAlphaBlanks(6)) { // Wind pressure curve
2580 1 : MultizoneExternalNodeData(i).curve = GetCurveIndex(m_state, Alphas(6));
2581 1 : if (MultizoneExternalNodeData(i).curve == 0) {
2582 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(6) + "=" + Alphas(6));
2583 0 : ShowContinueError(m_state, "Entered in " + CurrentModuleObject + '=' + Alphas(1));
2584 0 : ErrorsFound = true;
2585 : }
2586 : }
2587 :
2588 2 : if (NumAlphas > 6 && !lAlphaBlanks(7)) { // Symmetric curve
2589 1 : if (Util::SameString(Alphas(7), "Yes")) {
2590 0 : MultizoneExternalNodeData(i).symmetricCurve = true;
2591 1 : } else if (!Util::SameString(Alphas(7), "No")) {
2592 0 : ShowWarningError(m_state,
2593 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(7) + " = " +
2594 0 : Alphas(7));
2595 0 : ShowContinueError(m_state, "The default value is assigned as No.");
2596 : }
2597 : }
2598 :
2599 2 : if (NumAlphas > 7 && !lAlphaBlanks(8)) { // Relative or absolute wind angle
2600 1 : if (Util::SameString(Alphas(8), "Relative")) {
2601 0 : MultizoneExternalNodeData(i).useRelativeAngle = true;
2602 1 : } else if (!Util::SameString(Alphas(8), "Absolute")) {
2603 0 : ShowWarningError(m_state,
2604 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(8) + " = " +
2605 0 : Alphas(8));
2606 0 : ShowContinueError(m_state, "The default value is assigned as Absolute.");
2607 : }
2608 : }
2609 :
2610 2 : MultizoneExternalNodeData(i).Name = Alphas(1); // Name of external node
2611 6 : int NodeNum = GetOnlySingleNode(m_state,
2612 2 : Alphas(1),
2613 : ErrorsFound,
2614 : DataLoopNode::ConnectionObjectType::OutdoorAirNode,
2615 : "AirflowNetwork:Multizone:Surface",
2616 : DataLoopNode::NodeFluidType::Air,
2617 : DataLoopNode::ConnectionType::Inlet,
2618 : NodeInputManager::CompFluidStream::Primary,
2619 : ObjectIsParent);
2620 2 : MultizoneExternalNodeData(i).OutAirNodeNum = NodeNum; // Name of outdoor air node
2621 2 : MultizoneExternalNodeData(i).height = Node(NodeNum).Height; // Nodal height
2622 2 : MultizoneExternalNodeData(i).ExtNum = AirflowNetworkNumOfZones + i; // External node number
2623 : }
2624 : }
2625 : } else {
2626 0 : ShowSevereError(m_state,
2627 0 : format(RoutineName) + "An " + CurrentModuleObject +
2628 : " object is required but not found when Wind Pressure Coefficient Type = Input.");
2629 0 : ErrorsFound = true;
2630 : }
2631 : }
2632 :
2633 : // *** Read AirflowNetwork element data
2634 25 : ErrorsFound = ErrorsFound || !get_element_input();
2635 :
2636 : // *** Read AirflowNetwork simulation surface data
2637 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
2638 25 : AirflowNetworkNumOfSurfaces = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2639 25 : if (AirflowNetworkNumOfSurfaces > 0) {
2640 25 : MultizoneSurfaceData.allocate(AirflowNetworkNumOfSurfaces);
2641 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
2642 143 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2643 : CurrentModuleObject,
2644 : i,
2645 : Alphas,
2646 : NumAlphas,
2647 : Numbers,
2648 : NumNumbers,
2649 : IOStatus,
2650 : lNumericBlanks,
2651 : lAlphaBlanks,
2652 : cAlphaFields,
2653 : cNumericFields);
2654 143 : MultizoneSurfaceData(i).SurfName = Alphas(1); // Name of Associated EnergyPlus surface
2655 143 : MultizoneSurfaceData(i).OpeningName = Alphas(2); // Name of crack or opening component,
2656 : // either simple or detailed large opening, or crack
2657 143 : MultizoneSurfaceData(i).ExternalNodeName = Alphas(3); // Name of external node, but not used at WPC="INPUT"
2658 191 : if (Util::FindItemInList(Alphas(3), MultizoneExternalNodeData) &&
2659 48 : m_state.afn->MultizoneExternalNodeData(Util::FindItemInList(Alphas(3), MultizoneExternalNodeData)).curve == 0) {
2660 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(3) + "=" + Alphas(3));
2661 0 : ShowContinueError(m_state,
2662 : "A valid wind pressure coefficient curve name is required but not found when Wind Pressure "
2663 : "Coefficient Type = Input.");
2664 0 : ErrorsFound = true;
2665 : }
2666 143 : MultizoneSurfaceData(i).Factor = Numbers(1); // Crack Actual Value or Window Open Factor for Ventilation
2667 143 : if (MultizoneSurfaceData(i).Factor > 1.0 || MultizoneSurfaceData(i).Factor <= 0.0) {
2668 0 : ShowWarningError(m_state,
2669 0 : format(RoutineName) + CurrentModuleObject + " object=" + MultizoneSurfaceData(i).SurfName + ", " +
2670 0 : cNumericFields(1) + " is out of range (0.0,1.0]");
2671 0 : ShowContinueError(m_state, format("..Input value = {:.2R}, Value will be set to 1.0", MultizoneSurfaceData(i).Factor));
2672 0 : MultizoneSurfaceData(i).Factor = 1.0;
2673 : }
2674 : // Get input of ventilation control and associated data
2675 143 : if (NumAlphas >= 4) {
2676 : // Ventilation Control Mode: "TEMPERATURE", "ENTHALPY",
2677 : // "CONSTANT", "ZONELEVEL", "NOVENT", "ADJACENTTEMPERATURE",
2678 : // or "ADJACENTENTHALPY"
2679 40 : if (!lAlphaBlanks(4)) MultizoneSurfaceData(i).VentControl = Alphas(4);
2680 : // Name of ventilation temperature control schedule
2681 40 : if (!lAlphaBlanks(5)) MultizoneSurfaceData(i).VentTempControlSchName = Alphas(5);
2682 : {
2683 : // This SELECT_CASE_var will go on input refactor, no need to fix
2684 40 : auto const SELECT_CASE_var(Util::makeUPPER(MultizoneSurfaceData(i).VentControl));
2685 40 : if (SELECT_CASE_var == "TEMPERATURE") {
2686 6 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Temp;
2687 6 : MultizoneSurfaceData(i).IndVentControl = true;
2688 34 : } else if (SELECT_CASE_var == "ENTHALPY") {
2689 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Enth;
2690 0 : MultizoneSurfaceData(i).IndVentControl = true;
2691 34 : } else if (SELECT_CASE_var == "CONSTANT") {
2692 9 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Const;
2693 9 : MultizoneSurfaceData(i).IndVentControl = true;
2694 25 : } else if (SELECT_CASE_var == "ASHRAE55ADAPTIVE") {
2695 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::ASH55;
2696 0 : MultizoneSurfaceData(i).IndVentControl = true;
2697 25 : } else if (SELECT_CASE_var == "CEN15251ADAPTIVE") {
2698 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::CEN15251;
2699 0 : MultizoneSurfaceData(i).IndVentControl = true;
2700 25 : } else if (SELECT_CASE_var == "NOVENT") {
2701 10 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::NoVent;
2702 10 : MultizoneSurfaceData(i).IndVentControl = true;
2703 15 : } else if (SELECT_CASE_var == "ZONELEVEL") {
2704 15 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::ZoneLevel;
2705 15 : MultizoneSurfaceData(i).IndVentControl = false;
2706 0 : } else if (SELECT_CASE_var == "ADJACENTTEMPERATURE") {
2707 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::AdjTemp;
2708 0 : MultizoneSurfaceData(i).IndVentControl = true;
2709 0 : } else if (SELECT_CASE_var == "ADJACENTENTHALPY") {
2710 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::AdjEnth;
2711 0 : MultizoneSurfaceData(i).IndVentControl = true;
2712 : } else {
2713 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(4));
2714 0 : ShowContinueError(m_state,
2715 0 : ".." + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName + ", Specified " + cAlphaFields(4) +
2716 0 : " = " + Alphas(4));
2717 0 : ShowContinueError(m_state,
2718 : "..The valid choices are \"Temperature\", \"Enthalpy\", \"Constant\", \"NoVent\", \"ZoneLevel\", "
2719 : "\"AdjancentTemperature\" or \"AdjacentEnthalpy\"");
2720 0 : ErrorsFound = true;
2721 : }
2722 40 : }
2723 : }
2724 143 : MultizoneSurfaceData(i).ModulateFactor = Numbers(2); // Limit Value on Multiplier for Modulating Venting Open Factor
2725 143 : MultizoneSurfaceData(i).LowValueTemp = Numbers(3); // Lower temperature value for modulation of temperature control
2726 143 : MultizoneSurfaceData(i).UpValueTemp = Numbers(4); // Upper temperature value for modulation of temperature control
2727 143 : MultizoneSurfaceData(i).LowValueEnth = Numbers(5); // Lower Enthalpy value for modulation of Enthalpy control
2728 143 : MultizoneSurfaceData(i).UpValueEnth = Numbers(6); // Lower Enthalpy value for modulation of Enthalpy control
2729 168 : if (MultizoneSurfaceData(i).VentSurfCtrNum < 4 || MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjTemp ||
2730 25 : MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjEnth) {
2731 118 : if (!lAlphaBlanks(6)) {
2732 14 : MultizoneSurfaceData(i).VentAvailSchName = Alphas(6); // Name of ventilation availability schedule
2733 : }
2734 : }
2735 143 : if (!lAlphaBlanks(7)) {
2736 0 : MultizoneSurfaceData(i).OccupantVentilationControlName = Alphas(7);
2737 0 : MultizoneSurfaceData(i).OccupantVentilationControlNum =
2738 0 : Util::FindItemInList(MultizoneSurfaceData(i).OccupantVentilationControlName, OccupantVentilationControl);
2739 0 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) {
2740 0 : ShowSevereError(m_state,
2741 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(7) +
2742 0 : " not found = " + MultizoneSurfaceData(i).OccupantVentilationControlName);
2743 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
2744 0 : ErrorsFound = true;
2745 : }
2746 : }
2747 : // Get data of polygonal surface
2748 143 : if (!lAlphaBlanks(8)) {
2749 5 : if (Alphas(8) == "POLYGONHEIGHT") {
2750 0 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::Height;
2751 5 : } else if (Alphas(8) == "BASESURFACEASPECTRATIO") {
2752 4 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::BaseAspectRatio;
2753 1 : } else if (Alphas(8) == "USERDEFINEDASPECTRATIO") {
2754 1 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::UserAspectRatio;
2755 : } else {
2756 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(8));
2757 0 : ShowContinueError(m_state,
2758 0 : ".." + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName + ", Specified " + cAlphaFields(8) +
2759 0 : " = " + Alphas(8));
2760 0 : ShowContinueError(m_state,
2761 : "..The valid choices are \"PolygonHeight\", \"BaseSurfaceAspectRatio\", or \"UserDefinedAspectRatio\"");
2762 0 : ErrorsFound = true;
2763 : }
2764 : } else {
2765 138 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::Height;
2766 : }
2767 143 : if (!lNumericBlanks(7)) {
2768 1 : MultizoneSurfaceData(i).EquivRecUserAspectRatio = Numbers(7);
2769 : } else {
2770 142 : MultizoneSurfaceData(i).EquivRecUserAspectRatio = 1.0;
2771 : }
2772 : }
2773 : } else {
2774 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
2775 0 : ErrorsFound = true;
2776 : }
2777 :
2778 : // remove extra OutdoorAir:Node, not assigned to External Node Name
2779 25 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel && AirflowNetworkNumOfOutAirNode > 0) {
2780 3 : for (int i = AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode + 1; i <= AirflowNetworkNumOfExtNode; ++i) {
2781 2 : found = false;
2782 10 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
2783 8 : if (Util::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
2784 1 : found = true;
2785 : }
2786 : }
2787 2 : if (!found) {
2788 1 : if (i < AirflowNetworkNumOfExtNode) {
2789 0 : for (k = i; k <= AirflowNetworkNumOfExtNode - 1; ++k) {
2790 0 : MultizoneExternalNodeData(k).Name = MultizoneExternalNodeData(k + 1).Name;
2791 0 : MultizoneExternalNodeData(k).OutAirNodeNum = MultizoneExternalNodeData(k + 1).OutAirNodeNum;
2792 0 : MultizoneExternalNodeData(k).height = MultizoneExternalNodeData(k + 1).height;
2793 0 : MultizoneExternalNodeData(k).ExtNum = MultizoneExternalNodeData(k + 1).ExtNum - 1;
2794 : }
2795 0 : i -= 1;
2796 : }
2797 1 : AirflowNetworkNumOfOutAirNode -= 1;
2798 1 : AirflowNetworkNumOfExtNode -= 1;
2799 1 : MultizoneExternalNodeData.resize(AirflowNetworkNumOfExtNode);
2800 : }
2801 : }
2802 : }
2803 :
2804 : // ==> Validate AirflowNetwork simulation surface data
2805 25 : NumOfExtNodes = 0;
2806 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
2807 : // Check a valid surface defined earlier
2808 143 : MultizoneSurfaceData(i).SurfNum = Util::FindItemInList(MultizoneSurfaceData(i).SurfName, m_state.dataSurface->Surface);
2809 143 : if (MultizoneSurfaceData(i).SurfNum == 0) {
2810 0 : ShowSevereError(m_state,
2811 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(1) +
2812 0 : " given = " + MultizoneSurfaceData(i).SurfName);
2813 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
2814 : }
2815 144 : if (!m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).HeatTransSurf &&
2816 1 : !m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) {
2817 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2818 0 : ShowContinueError(m_state,
2819 0 : "..The surface specified must be a heat transfer surface. Invalid " + cAlphaFields(1) + " = " +
2820 0 : MultizoneSurfaceData(i).SurfName);
2821 0 : ErrorsFound = true;
2822 0 : continue;
2823 : }
2824 : // Ensure an interior surface does not face itself
2825 143 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1) {
2826 : // Check the surface is a subsurface or not
2827 37 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf == MultizoneSurfaceData(i).SurfNum) {
2828 35 : if (MultizoneSurfaceData(i).SurfNum == m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond) {
2829 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2830 0 : ShowContinueError(m_state,
2831 0 : "..The surface facing itself is not allowed. Invalid " + cAlphaFields(1) + " = " +
2832 0 : MultizoneSurfaceData(i).SurfName);
2833 0 : ErrorsFound = true;
2834 : }
2835 : } else {
2836 2 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf ==
2837 2 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).ExtBoundCond) {
2838 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2839 0 : ShowContinueError(m_state,
2840 0 : "..The base surface facing itself is not allowed. Invalid " + cAlphaFields(1) + " = " +
2841 0 : MultizoneSurfaceData(i).SurfName);
2842 0 : ErrorsFound = true;
2843 : }
2844 : }
2845 : }
2846 : // Ensure zones defined in inside and outside environment are used in the object of AIRFLOWNETWORK:MULTIZONE:ZONE
2847 143 : found = false;
2848 143 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone;
2849 : int j;
2850 247 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
2851 247 : if (MultizoneZoneData(j).ZoneNum == n) {
2852 143 : found = true;
2853 143 : break;
2854 : }
2855 : }
2856 : // find a surface geometry
2857 143 : MultizoneSurfaceData(i).Height = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Height;
2858 143 : MultizoneSurfaceData(i).Width = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Width;
2859 143 : MultizoneSurfaceData(i).CHeight = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Centroid.z;
2860 143 : if (found) {
2861 143 : MultizoneSurfaceData(i).NodeNums[0] = j;
2862 : } else {
2863 0 : ShowSevereError(m_state,
2864 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName);
2865 0 : ShowContinueError(m_state,
2866 0 : "..Zone for inside surface must be defined in a AirflowNetwork:MultiZone:Zone object. Could not find Zone = " +
2867 0 : Zone(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone).Name);
2868 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
2869 : }
2870 :
2871 : // Calculate equivalent width and height
2872 143 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides != 4) {
2873 12 : MultizoneSurfaceData(i).NonRectangular = true;
2874 12 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::Height) {
2875 12 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Tilt < 1.0 ||
2876 5 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Tilt > 179.0) { // horizontal surface
2877 : // check base surface shape
2878 2 : if (m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Sides == 4) {
2879 1 : baseratio = m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Width /
2880 1 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Height;
2881 1 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * baseratio);
2882 2 : MultizoneSurfaceData(i).Height =
2883 1 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2884 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2885 0 : ShowWarningError(m_state,
2886 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2887 0 : ShowContinueError(m_state,
2888 : "The entered choice of Equivalent Rectangle Method is PolygonHeight. This choice is not valid for "
2889 : "a horizontal surface.");
2890 0 : ShowContinueError(m_state, "The BaseSurfaceAspectRatio choice is used. Simulation continues.");
2891 : }
2892 : } else {
2893 1 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area *
2894 1 : MultizoneSurfaceData(i).EquivRecUserAspectRatio);
2895 2 : MultizoneSurfaceData(i).Height =
2896 1 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2897 : // add warning
2898 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2899 0 : ShowWarningError(m_state,
2900 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2901 0 : ShowContinueError(m_state,
2902 : "The entered choice of Equivalent Rectangle Method is PolygonHeight. This choice is not valid for "
2903 : "a horizontal surface with a polygonal base surface.");
2904 0 : ShowContinueError(m_state, "The default aspect ratio at 1 is used. Simulation continues.");
2905 : }
2906 : }
2907 : } else {
2908 5 : minHeight = min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2909 5 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2910 5 : maxHeight = max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2911 5 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2912 12 : for (j = 3; j <= m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides; ++j) {
2913 7 : minHeight = min(minHeight,
2914 7 : min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2915 7 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2916 7 : maxHeight = max(maxHeight,
2917 7 : max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2918 7 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2919 : }
2920 5 : if (maxHeight > minHeight) {
2921 5 : MultizoneSurfaceData(i).Height = maxHeight - minHeight;
2922 5 : MultizoneSurfaceData(i).Width =
2923 5 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / (maxHeight - minHeight);
2924 : }
2925 : }
2926 : }
2927 12 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::BaseAspectRatio) {
2928 4 : if (m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Sides == 4) {
2929 2 : baseratio = m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Width /
2930 2 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Height;
2931 2 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * baseratio);
2932 2 : MultizoneSurfaceData(i).Height =
2933 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2934 : } else {
2935 2 : minHeight = min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2936 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2937 2 : maxHeight = max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2938 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2939 4 : for (j = 3; j <= m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides; ++j) {
2940 2 : minHeight = min(minHeight,
2941 2 : min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2942 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2943 2 : maxHeight = max(maxHeight,
2944 2 : max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2945 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2946 : }
2947 2 : if (maxHeight > minHeight) {
2948 1 : MultizoneSurfaceData(i).Height = maxHeight - minHeight;
2949 2 : MultizoneSurfaceData(i).Width =
2950 1 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / (maxHeight - minHeight);
2951 : // add warning
2952 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2953 0 : ShowWarningError(m_state,
2954 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2955 0 : ShowContinueError(m_state,
2956 : "The entered choice of Equivalent Rectangle Method is BaseSurfaceAspectRatio. This choice is not "
2957 : "valid for a polygonal base surface.");
2958 0 : ShowContinueError(m_state, "The PolygonHeight choice is used. Simulation continues.");
2959 : }
2960 : } else {
2961 1 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area *
2962 1 : MultizoneSurfaceData(i).EquivRecUserAspectRatio);
2963 2 : MultizoneSurfaceData(i).Height =
2964 1 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2965 : // add warning
2966 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2967 0 : ShowWarningError(m_state,
2968 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2969 0 : ShowContinueError(m_state,
2970 : "The entered choice of Equivalent Rectangle Method is BaseSurfaceAspectRatio. This choice is not "
2971 : "valid for a horizontal surface with a polygonal base surface.");
2972 0 : ShowContinueError(m_state, "The default aspect ratio at 1 is used. Simulation continues.");
2973 : }
2974 : }
2975 : }
2976 : }
2977 12 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::UserAspectRatio) {
2978 2 : MultizoneSurfaceData(i).Width =
2979 1 : sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * MultizoneSurfaceData(i).EquivRecUserAspectRatio);
2980 1 : MultizoneSurfaceData(i).Height =
2981 1 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2982 : }
2983 : }
2984 :
2985 : // Get the number of external surfaces
2986 180 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == ExternalEnvironment ||
2987 37 : (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
2988 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
2989 106 : ++AirflowNetworkNumOfExtSurfaces;
2990 : }
2991 :
2992 : // Outside face environment
2993 143 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
2994 80 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond;
2995 112 : if (n == ExternalEnvironment ||
2996 32 : (n == OtherSideCoefNoCalcExt && m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
2997 48 : ++NumOfExtNodes;
2998 48 : if (AirflowNetworkNumOfExtNode > 0) {
2999 48 : found = false;
3000 123 : for (j = 1; j <= AirflowNetworkNumOfExtNode; ++j) {
3001 123 : if (Util::SameString(MultizoneSurfaceData(i).ExternalNodeName, MultizoneExternalNodeData(j).Name)) {
3002 48 : MultizoneSurfaceData(i).NodeNums[1] = MultizoneExternalNodeData(j).ExtNum;
3003 48 : found = true;
3004 48 : break;
3005 : }
3006 : }
3007 48 : if (!found) {
3008 0 : ShowSevereError(m_state,
3009 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(3) + " = " +
3010 0 : MultizoneSurfaceData(i).ExternalNodeName);
3011 0 : ShowContinueError(m_state, "A valid " + cAlphaFields(3) + " is required when Wind Pressure Coefficient Type = Input");
3012 0 : ErrorsFound = true;
3013 : }
3014 : } else {
3015 : // MultizoneSurfaceData(i)%NodeNums[1] =
3016 : // AirflowNetworkNumOfZones+NumOfExtNodes
3017 : }
3018 48 : continue;
3019 : } else {
3020 32 : if (n < ExternalEnvironment &&
3021 0 : !(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3022 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3023 0 : ShowSevereError(m_state,
3024 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(1) + " = " +
3025 0 : MultizoneSurfaceData(i).SurfName);
3026 0 : ShowContinueError(m_state, "This type of surface (has ground, etc exposure) cannot be used in the AiflowNetwork model.");
3027 0 : ErrorsFound = true;
3028 : }
3029 : }
3030 32 : found = false;
3031 96 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
3032 96 : if (MultizoneZoneData(j).ZoneNum == m_state.dataSurface->Surface(n).Zone) {
3033 32 : found = true;
3034 32 : break;
3035 : }
3036 : }
3037 32 : if (found) {
3038 32 : MultizoneSurfaceData(i).NodeNums[1] = j;
3039 : } else {
3040 0 : ShowSevereError(m_state,
3041 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3042 0 : MultizoneSurfaceData(i).SurfName);
3043 0 : ShowContinueError(
3044 : m_state,
3045 0 : "..Zone for outside surface must be defined in a AirflowNetwork:MultiZone:Zone object. Could not find Zone = " +
3046 0 : Zone(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone).Name);
3047 0 : ErrorsFound = true;
3048 0 : continue;
3049 : }
3050 : }
3051 95 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
3052 63 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond;
3053 63 : if (n >= 1) { // exterior boundary condition is a surface
3054 5 : found = false;
3055 10 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
3056 10 : if (MultizoneZoneData(j).ZoneNum == m_state.dataSurface->Surface(n).Zone) {
3057 5 : found = true;
3058 5 : break;
3059 : }
3060 : }
3061 5 : if (found) {
3062 5 : MultizoneSurfaceData(i).NodeNums[1] = j;
3063 : } else {
3064 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " = " + MultizoneSurfaceData(i).SurfName);
3065 0 : ShowContinueError(m_state,
3066 0 : "An adjacent zone = " + Zone(m_state.dataSurface->Surface(n).Zone).Name +
3067 : " is not described in AIRFLOWNETWORK:MULTIZONE:ZONE");
3068 0 : ErrorsFound = true;
3069 0 : continue;
3070 : }
3071 : }
3072 : }
3073 95 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == -2 &&
3074 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3075 95 : if (MultizoneSurfaceData(i).NodeNums[1] == 0 && m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond < 0) {
3076 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " = " + MultizoneSurfaceData(i).SurfName);
3077 0 : ShowContinueError(m_state,
3078 0 : "Outside boundary condition and object are " +
3079 0 : cExtBoundCondition(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond) + " and " +
3080 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCondName + ".");
3081 0 : ShowContinueError(m_state, "The outside boundary condition must be exposed to either the outside or an adjacent zone.");
3082 0 : ErrorsFound = true;
3083 0 : continue;
3084 : }
3085 : }
3086 : }
3087 :
3088 : // write outputs in eio file
3089 25 : found = true;
3090 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3091 143 : if (MultizoneSurfaceData(i).NonRectangular) {
3092 12 : if (found) {
3093 3 : print(m_state.files.eio,
3094 : "! <AirflowNetwork Model:Equivalent Rectangle Surface>, Name, Equivalent Height {{m}}, Equivalent Width {{m}} "
3095 : "AirflowNetwork "
3096 : "Model:Equivalent Rectangle\n");
3097 3 : found = false;
3098 : }
3099 12 : print(m_state.files.eio,
3100 : "AirflowNetwork Model:Equivalent Rectangle Surface, {}, {:.2R},{:.2R}\n",
3101 12 : MultizoneSurfaceData(i).SurfName,
3102 12 : MultizoneSurfaceData(i).Height,
3103 12 : MultizoneSurfaceData(i).Width);
3104 : }
3105 : }
3106 :
3107 : // Validate adjacent temperature and Enthalpy control for an interior surface only
3108 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3109 143 : if (MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjTemp) {
3110 0 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1)) {
3111 0 : ShowSevereError(m_state,
3112 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3113 0 : MultizoneSurfaceData(i).SurfName);
3114 0 : ShowContinueError(m_state, "..AdjacentTemperature venting control must be defined for an interzone surface.");
3115 0 : ErrorsFound = true;
3116 : }
3117 : }
3118 143 : if (MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjEnth) {
3119 0 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1)) {
3120 0 : ShowSevereError(m_state,
3121 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3122 0 : MultizoneSurfaceData(i).SurfName);
3123 0 : ShowContinueError(m_state, "..AdjacentEnthalpy venting control must be defined for an interzone surface.");
3124 0 : ErrorsFound = true;
3125 : }
3126 : }
3127 : }
3128 :
3129 : // Ensure the number of external node = the number of external surface with HeightOption choice = OpeningHeight
3130 25 : if (Util::SameString(simulation_control.HeightOption, "OpeningHeight") && simulation_control.iWPCCnt == iWPCCntr::Input) {
3131 0 : if (AirflowNetworkNumOfExtSurfaces != AirflowNetworkNumOfExtNode) {
3132 0 : ShowSevereError(m_state,
3133 0 : format(RoutineName) +
3134 : "When the choice of Height Selection for Local Wind Speed Calculation is OpeningHeight, the number of external "
3135 0 : "surfaces defined in " +
3136 0 : CurrentModuleObject + " objects ");
3137 0 : ShowContinueError(m_state, "has to be equal to the number of AirflowNetwork:MultiZone:ExternalNode objects.");
3138 0 : ShowContinueError(m_state,
3139 0 : format("The entered number of external nodes is {}. The entered number of external surfaces is {}.",
3140 0 : AirflowNetworkNumOfExtNode,
3141 0 : AirflowNetworkNumOfExtSurfaces));
3142 0 : ErrorsFound = true;
3143 : }
3144 : }
3145 :
3146 : // Read AirflowNetwork simulation detailed openings
3147 : // Moved into getAirflowElementInput
3148 :
3149 : // Validate opening component and assign opening dimension
3150 25 : if (AirflowNetworkNumOfDetOpenings > 0) {
3151 9 : for (int i = 1; i <= AirflowNetworkNumOfDetOpenings; ++i) {
3152 5 : found = false;
3153 48 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3154 43 : if (MultizoneCompDetOpeningData(i).name == MultizoneSurfaceData(j).OpeningName) {
3155 : // MultizoneCompDetOpeningData(i)%Width =
3156 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Width
3157 : // MultizoneCompDetOpeningData(i)%Height =
3158 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Height
3159 6 : found = true;
3160 : }
3161 : }
3162 : }
3163 : }
3164 :
3165 : // Read AirflowNetwork simulation simple openings
3166 : // Moved into getAirflowElementInput
3167 :
3168 : // Read AirflowNetwork simulation horizontal openings
3169 : // Moved into getAirflowElementInput
3170 :
3171 : // Check status of control level for each surface with an opening
3172 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
3173 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3174 143 : if (MultizoneSurfaceData(i).SurfNum == 0) continue;
3175 143 : bool has_Opening{false}; // Why use array constructor?
3176 :
3177 143 : ErrorObjectHeader eoh{RoutineName, CurrentModuleObject, MultizoneSurfaceData(i).SurfName};
3178 :
3179 : // This is terrible, should not do it this way
3180 143 : auto afe = elements.find(MultizoneSurfaceData(i).OpeningName);
3181 143 : if (afe != elements.end()) {
3182 143 : auto type = afe->second->type();
3183 143 : has_Opening = (type == ComponentType::DOP) || (type == ComponentType::SOP) || (type == ComponentType::HOP);
3184 : }
3185 : // Obtain schedule number and check surface shape
3186 143 : if (has_Opening) {
3187 24 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides == 3) {
3188 5 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName + "\".");
3189 15 : ShowContinueError(m_state,
3190 : "The opening is a Triangular subsurface. A rectangular subsurface will be used with equivalent "
3191 : "width and height.");
3192 : }
3193 : // Venting controls are not allowed for an air boundary surface
3194 25 : if ((m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) &&
3195 1 : (MultizoneSurfaceData(i).VentSurfCtrNum != VentControlType::Const)) {
3196 2 : ShowWarningError(m_state,
3197 2 : format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName +
3198 : "\" is an air boundary surface.");
3199 1 : ShowContinueError(m_state, "Ventilation Control Mode = " + Alphas(4) + " is not valid. Resetting to Constant.");
3200 1 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Const;
3201 1 : MultizoneSurfaceData(i).IndVentControl = true;
3202 : }
3203 :
3204 24 : if (MultizoneSurfaceData(i).VentAvailSchName.empty()) {
3205 18 : MultizoneSurfaceData(i).ventAvailSched = Sched::GetScheduleAlwaysOn(m_state);
3206 6 : } else if ((MultizoneSurfaceData(i).ventAvailSched = Sched::GetSchedule(m_state, MultizoneSurfaceData(i).VentAvailSchName)) ==
3207 : nullptr) {
3208 0 : ShowSevereItemNotFound(m_state, eoh, "Venting Schedule", MultizoneSurfaceData(i).VentAvailSchName);
3209 0 : ErrorsFound = true;
3210 6 : } else if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) {
3211 1 : ShowWarningNonEmptyField(m_state, eoh, "Venting Availbility Schedule");
3212 2 : ShowContinueError(m_state, "Venting is always available for air-boundary surfaces.");
3213 1 : MultizoneSurfaceData(i).ventAvailSched = Sched::GetScheduleAlwaysOn(m_state);
3214 1 : MultizoneSurfaceData(i).VentAvailSchName = "";
3215 : }
3216 :
3217 24 : switch (MultizoneSurfaceData(i).VentSurfCtrNum) {
3218 5 : case VentControlType::Temp:
3219 : case VentControlType::AdjTemp: {
3220 5 : if (MultizoneSurfaceData(i).VentTempControlSchName.empty()) {
3221 0 : ShowSevereEmptyField(m_state, eoh, "Ventilation Schedule", "Ventinlation Control", "Temperature");
3222 0 : ErrorsFound = true;
3223 10 : } else if ((MultizoneSurfaceData(i).ventTempControlSched =
3224 5 : Sched::GetSchedule(m_state, MultizoneSurfaceData(i).VentTempControlSchName)) == nullptr) {
3225 0 : ShowSevereItemNotFound(m_state, eoh, "Ventilation Schedule", MultizoneSurfaceData(i).VentTempControlSchName);
3226 0 : ErrorsFound = true;
3227 : }
3228 5 : if (MultizoneSurfaceData(i).LowValueTemp < 0.0) {
3229 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Temperature difference value < 0.0d0");
3230 0 : ShowContinueError(m_state, format("..Input value={:.1R}, Value will be reset to 0.0.", MultizoneSurfaceData(i).LowValueTemp));
3231 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3232 0 : MultizoneSurfaceData(i).LowValueTemp = 0.0;
3233 : }
3234 5 : if (MultizoneSurfaceData(i).LowValueTemp >= 100.0) {
3235 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Temperature difference value >= 100.0d0");
3236 0 : ShowContinueError(m_state,
3237 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueTemp));
3238 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3239 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
3240 : }
3241 5 : if (MultizoneSurfaceData(i).UpValueTemp <= MultizoneSurfaceData(i).LowValueTemp) {
3242 0 : ShowWarningError(
3243 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Upper Temperature <= Lower Temperature difference value.");
3244 0 : ShowContinueError(m_state,
3245 0 : format("..Input value = {:.1R}, Value will be reset to 100.0", MultizoneSurfaceData(i).UpValueTemp));
3246 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3247 0 : MultizoneSurfaceData(i).UpValueTemp = 100.0;
3248 : }
3249 :
3250 5 : } break;
3251 :
3252 0 : case VentControlType::Enth:
3253 : case VentControlType::AdjEnth: {
3254 0 : if (MultizoneSurfaceData(i).VentTempControlSchName.empty()) {
3255 0 : ShowSevereEmptyField(m_state, eoh, "Ventilation Schedule", "Ventilation Control", "Enthalpy");
3256 0 : ErrorsFound = true;
3257 0 : } else if ((MultizoneSurfaceData(i).ventTempControlSched =
3258 0 : Sched::GetSchedule(m_state, MultizoneSurfaceData(i).VentTempControlSchName)) == nullptr) {
3259 0 : ShowSevereItemNotFound(m_state, eoh, "Ventilation Schedule", MultizoneSurfaceData(i).VentTempControlSchName);
3260 0 : ErrorsFound = true;
3261 : }
3262 0 : if (MultizoneSurfaceData(i).LowValueEnth < 0.0) {
3263 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Enthalpy difference value < 0.0d0");
3264 0 : ShowContinueError(m_state,
3265 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueEnth));
3266 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3267 0 : MultizoneSurfaceData(i).LowValueEnth = 0.0;
3268 : }
3269 0 : if (MultizoneSurfaceData(i).LowValueEnth >= 300000.0) {
3270 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Enthalpy difference value >= 300000.0");
3271 0 : ShowContinueError(m_state,
3272 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueEnth));
3273 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3274 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
3275 : }
3276 0 : if (MultizoneSurfaceData(i).UpValueEnth <= MultizoneSurfaceData(i).LowValueEnth) {
3277 0 : ShowWarningError(m_state,
3278 0 : format(RoutineName) + CurrentModuleObject + " object, Upper Enthalpy <= Lower Enthalpy difference value.");
3279 0 : ShowContinueError(m_state,
3280 0 : format("..Input value = {:.1R}, Value will be set to 300000.0", MultizoneSurfaceData(i).UpValueEnth));
3281 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3282 0 : MultizoneSurfaceData(i).UpValueEnth = 300000.0;
3283 : }
3284 :
3285 0 : } break;
3286 12 : case VentControlType::Const:
3287 : case VentControlType::ASH55:
3288 : case VentControlType::CEN15251:
3289 : case VentControlType::NoVent:
3290 : case VentControlType::ZoneLevel: {
3291 12 : MultizoneSurfaceData(i).ventTempControlSched = nullptr;
3292 12 : MultizoneSurfaceData(i).VentTempControlSchName = "";
3293 12 : } break;
3294 7 : default:
3295 7 : break;
3296 : }
3297 : }
3298 : }
3299 :
3300 : // Validate opening component and assign opening dimension
3301 25 : if (AirflowNetworkNumOfSimOpenings > 0) {
3302 18 : for (int i = 1; i <= AirflowNetworkNumOfSimOpenings; ++i) {
3303 9 : found = false;
3304 54 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3305 45 : if (MultizoneCompSimpleOpeningData(i).name == MultizoneSurfaceData(j).OpeningName) {
3306 : // MultizoneCompSimpleOpeningData(i)%Width =
3307 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Width
3308 : // MultizoneCompSimpleOpeningData(i)%Height =
3309 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Height
3310 18 : found = true;
3311 : }
3312 : }
3313 : }
3314 : }
3315 :
3316 : // Calculate CP values
3317 25 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
3318 15 : calculate_Cps();
3319 : // Ensure automatic generation is OK
3320 15 : n = 0;
3321 90 : for (int j = 1; j <= 5; ++j) {
3322 75 : found = false;
3323 216 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3324 177 : if (MultizoneExternalNodeData(i).facadeNum == j) {
3325 36 : found = true;
3326 36 : break;
3327 : }
3328 : }
3329 75 : if (found) ++n;
3330 75 : if (j == 5 && (!found)) {
3331 13 : found = true;
3332 13 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3333 0 : ShowWarningError(m_state,
3334 0 : format(RoutineName) +
3335 : "SurfaceAverageCalculation is entered for field = Wind Pressure Coefficient Type, but no roof "
3336 : "surface is defined using an AirflowNetwork:MultiZone:Surface object.");
3337 0 : ShowContinueError(m_state, "Reconsider if this is your modeling intent. Simulation continues.");
3338 : }
3339 : }
3340 : }
3341 15 : if (n < 5 && m_state.dataGlobal->DisplayExtraWarnings) {
3342 0 : ShowWarningError(m_state, format(RoutineName) + "SurfaceAverageCalculation is entered for field = Wind Pressure Coefficient Type.");
3343 0 : ShowContinueError(m_state,
3344 : "The AirflowNetwork model provides wind pressure coefficients for 4 vertical exterior orientations and "
3345 : "1 horizontal roof.");
3346 0 : ShowContinueError(m_state,
3347 0 : format(" There are only {} exterior surface orientations defined in this input file using "
3348 : "AirflowNetwork:MultiZone:Surface objects.",
3349 : n));
3350 0 : ShowContinueError(m_state, "Reconsider if this is your modeling intent. Simulation continues.");
3351 : }
3352 : }
3353 :
3354 : // Assign external node height
3355 35 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation") ||
3356 35 : Util::SameString(simulation_control.HeightOption, "OpeningHeight")) {
3357 73 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3358 278 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3359 298 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == ExternalEnvironment ||
3360 20 : (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3361 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtWind)) {
3362 258 : if (Util::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
3363 58 : MultizoneExternalNodeData(i).height = m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Centroid.z;
3364 58 : break;
3365 : }
3366 : }
3367 : }
3368 : }
3369 : }
3370 :
3371 : // Assign external node azimuth, should consider combining this with the above to avoid the repeated search
3372 115 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3373 435 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3374 506 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == ExternalEnvironment ||
3375 74 : (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3376 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtWind)) {
3377 358 : if (Util::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
3378 87 : MultizoneExternalNodeData(i).azimuth = m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Azimuth;
3379 87 : break;
3380 : }
3381 : }
3382 : }
3383 : }
3384 :
3385 25 : if (ErrorsFound) {
3386 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3387 : }
3388 :
3389 : // Write wind pressure coefficients in the EIO file
3390 25 : print(m_state.files.eio, "! <AirflowNetwork Model:Wind Direction>, Wind Direction #1 to n (degree)\n");
3391 25 : print(m_state.files.eio, "AirflowNetwork Model:Wind Direction, ");
3392 :
3393 25 : int numWinDirs = 11;
3394 25 : Real64 angleDelta = 30.0;
3395 25 : if (AirflowNetworkNumOfSingleSideZones > 0) {
3396 2 : numWinDirs = 35;
3397 2 : angleDelta = 10.0;
3398 : }
3399 :
3400 348 : for (int i = 0; i < numWinDirs; ++i) {
3401 323 : print(m_state.files.eio, "{:.1R},", i * angleDelta);
3402 : }
3403 25 : print(m_state.files.eio, "{:.1R}\n", numWinDirs * angleDelta);
3404 :
3405 25 : print(m_state.files.eio, "! <AirflowNetwork Model:Wind Pressure Coefficients>, Name, Wind Pressure Coefficients #1 to n (dimensionless)\n");
3406 :
3407 : // The old version used to write info with single-sided natural ventilation specific labeling, this version no longer does that.
3408 50 : std::set<int> curves;
3409 115 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3410 90 : curves.insert(MultizoneExternalNodeData(i).curve);
3411 : }
3412 95 : for (auto index : curves) {
3413 70 : print(m_state.files.eio, "AirflowNetwork Model:Wind Pressure Coefficients, {}, ", Curve::GetCurveName(m_state, index));
3414 :
3415 984 : for (int j = 0; j < numWinDirs; ++j) {
3416 914 : print(m_state.files.eio, "{:.2R},", Curve::CurveValue(m_state, index, j * angleDelta));
3417 : }
3418 70 : print(m_state.files.eio, "{:.2R}\n", Curve::CurveValue(m_state, index, numWinDirs * angleDelta));
3419 : }
3420 :
3421 25 : if (AirflowNetworkNumOfSingleSideZones > 0) {
3422 4 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3423 2 : if (MultizoneZoneData(i).SingleSidedCpType == "ADVANCED") {
3424 2 : print(m_state.files.eio,
3425 : "AirflowNetwork: Advanced Single-Sided Model: Difference in Opening Wind Pressure Coefficients (DeltaCP), ");
3426 2 : print(m_state.files.eio, "{}, ", MultizoneZoneData(i).ZoneName);
3427 72 : for (unsigned j = 1; j <= EPDeltaCP(i).WindDir.size() - 1; ++j) {
3428 70 : print(m_state.files.eio, "{:.2R},", EPDeltaCP(i).WindDir(j));
3429 : }
3430 2 : print(m_state.files.eio, "{:.2R}\n", EPDeltaCP(i).WindDir(static_cast<int>(EPDeltaCP(i).WindDir.size())));
3431 : }
3432 : }
3433 : }
3434 :
3435 : // If no zone object, exit
3436 25 : if (AirflowNetworkNumOfZones == 0) {
3437 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3438 : }
3439 : // If zone node number =0, exit.
3440 168 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3441 143 : if (MultizoneSurfaceData(j).NodeNums[0] == 0 && ErrorsFound) {
3442 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3443 : }
3444 143 : if (MultizoneSurfaceData(j).NodeNums[1] == 0 && ErrorsFound) {
3445 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3446 : }
3447 : }
3448 :
3449 : // Ensure at least two surfaces are exposed to a zone
3450 25 : ZoneCheck.allocate(AirflowNetworkNumOfZones);
3451 25 : ZoneBCCheck.allocate(AirflowNetworkNumOfZones);
3452 25 : ZoneCheck = 0;
3453 25 : ZoneBCCheck = 0;
3454 25 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
3455 168 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3456 143 : if (MultizoneSurfaceData(j).NodeNums[0] <= AirflowNetworkNumOfZones) {
3457 143 : ++ZoneCheck(MultizoneSurfaceData(j).NodeNums[0]);
3458 143 : ZoneBCCheck(MultizoneSurfaceData(j).NodeNums[0]) = MultizoneSurfaceData(j).NodeNums[1];
3459 : }
3460 143 : if (MultizoneSurfaceData(j).NodeNums[1] <= AirflowNetworkNumOfZones) {
3461 37 : ++ZoneCheck(MultizoneSurfaceData(j).NodeNums[1]);
3462 37 : ZoneBCCheck(MultizoneSurfaceData(j).NodeNums[1]) = MultizoneSurfaceData(j).NodeNums[0];
3463 : }
3464 : }
3465 77 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3466 52 : if (ZoneCheck(i) == 0) {
3467 0 : ShowSevereError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3468 0 : ShowContinueError(m_state, " does not have any surfaces defined in " + CurrentModuleObject);
3469 0 : ShowContinueError(m_state, "Each zone should have at least two surfaces defined in " + CurrentModuleObject);
3470 0 : ErrorsFound = true;
3471 : }
3472 52 : if (ZoneCheck(i) == 1) {
3473 0 : ShowSevereError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3474 0 : ShowContinueError(m_state, " has only one surface defined in " + CurrentModuleObject);
3475 0 : ShowContinueError(m_state, " Each zone should have at least two surfaces defined in " + CurrentModuleObject);
3476 0 : ErrorsFound = true;
3477 : }
3478 52 : if (ZoneCheck(i) > 1) {
3479 52 : bool SurfaceFound = false;
3480 137 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3481 137 : if (MultizoneSurfaceData(j).NodeNums[0] == i) {
3482 31 : if (ZoneBCCheck(i) != MultizoneSurfaceData(j).NodeNums[1]) {
3483 31 : SurfaceFound = true;
3484 31 : break;
3485 : }
3486 : }
3487 106 : if (MultizoneSurfaceData(j).NodeNums[1] == i) {
3488 21 : if (ZoneBCCheck(i) != MultizoneSurfaceData(j).NodeNums[0]) {
3489 21 : SurfaceFound = true;
3490 21 : break;
3491 : }
3492 : }
3493 : }
3494 52 : if (!SurfaceFound) {
3495 0 : ShowWarningError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3496 0 : ShowContinueError(m_state,
3497 0 : "has more than one surface defined in " + CurrentModuleObject + ", but has the same boundary conditions");
3498 0 : ShowContinueError(m_state, "Please check inputs of " + CurrentModuleObject);
3499 : }
3500 : }
3501 : }
3502 25 : ZoneCheck.deallocate();
3503 25 : ZoneBCCheck.deallocate();
3504 :
3505 : // Validate CP Value number
3506 25 : if (simulation_control.iWPCCnt == iWPCCntr::Input) { // Surface-Average does not need inputs of external nodes
3507 : // Ensure different curve is used to avoid a single side boundary condition
3508 10 : found = false;
3509 10 : bool differentAngle = false;
3510 12 : for (int j = 2; j <= AirflowNetworkNumOfExtNode; ++j) {
3511 10 : if (MultizoneExternalNodeData(j - 1).curve != MultizoneExternalNodeData(j).curve) {
3512 8 : found = true;
3513 8 : break;
3514 : } else {
3515 : // If the curves are the same, then check to see if the azimuths are different
3516 2 : if (MultizoneExternalNodeData(j - 1).azimuth != MultizoneExternalNodeData(j).azimuth) {
3517 2 : differentAngle = MultizoneExternalNodeData(j - 1).symmetricCurve || MultizoneExternalNodeData(j).symmetricCurve;
3518 : }
3519 : }
3520 : }
3521 10 : if (!found && !differentAngle) {
3522 0 : ShowSevereError(m_state,
3523 : "The same Wind Pressure Coefficient Curve name is used in all AirflowNetwork:MultiZone:ExternalNode objects.");
3524 0 : ShowContinueError(
3525 : m_state, "Please input at least two different Wind Pressure Coefficient Curve names to avoid single side boundary condition.");
3526 0 : ErrorsFound = true;
3527 : }
3528 : }
3529 :
3530 : // Assign occupant ventilation control number from zone to surface
3531 168 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3532 143 : int j = MultizoneSurfaceData(i).SurfNum;
3533 143 : auto const &surf = m_state.dataSurface->Surface(j);
3534 143 : if (surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
3535 107 : surf.OriginalClass == SurfaceClass::GlassDoor) {
3536 93 : for (n = 1; n <= AirflowNetworkNumOfZones; ++n) {
3537 57 : if (MultizoneZoneData(n).ZoneNum == m_state.dataSurface->Surface(j).Zone) {
3538 36 : if (MultizoneZoneData(n).OccupantVentilationControlNum > 0 && MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) {
3539 0 : MultizoneSurfaceData(i).OccupantVentilationControlNum = MultizoneZoneData(n).OccupantVentilationControlNum;
3540 : }
3541 : }
3542 : }
3543 : }
3544 : }
3545 :
3546 : // Read AirflowNetwork Intra zone node
3547 25 : CurrentModuleObject = "AirflowNetwork:IntraZone:Node";
3548 25 : IntraZoneNumOfNodes = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3549 25 : if (IntraZoneNumOfNodes > 0) {
3550 1 : IntraZoneNodeData.allocate(IntraZoneNumOfNodes);
3551 6 : for (int i = 1; i <= IntraZoneNumOfNodes; ++i) {
3552 5 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3553 : CurrentModuleObject,
3554 : i,
3555 : Alphas,
3556 : NumAlphas,
3557 : Numbers,
3558 : NumNumbers,
3559 : IOStatus,
3560 : lNumericBlanks,
3561 : lAlphaBlanks,
3562 : cAlphaFields,
3563 : cNumericFields);
3564 5 : IntraZoneNodeData(i).Name = Alphas(1); // Name of node
3565 5 : IntraZoneNodeData(i).RAFNNodeName = Alphas(2); // Name of RoomAir node
3566 5 : IntraZoneNodeData(i).Height = Numbers(1); // Nodal height
3567 : // verify RoomAir model node names(May be too early to check and move to another subroutine)
3568 : bool Errorfound1;
3569 5 : GetRAFNNodeNum(
3570 5 : m_state, IntraZoneNodeData(i).RAFNNodeName, IntraZoneNodeData(i).ZoneNum, IntraZoneNodeData(i).RAFNNodeNum, Errorfound1);
3571 5 : if (Errorfound1) ErrorsFound = true;
3572 5 : if (IntraZoneNodeData(i).RAFNNodeNum == 0) {
3573 0 : ShowSevereError(m_state,
3574 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "' invalid name " + cAlphaFields(2) + "='" +
3575 0 : Alphas(2));
3576 0 : ErrorsFound = true;
3577 : }
3578 10 : IntraZoneNodeData(i).AFNZoneNum =
3579 5 : Util::FindItemInList(Alphas(3), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3580 5 : if (MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).RAFNNodeNum == 0) {
3581 1 : GetRAFNNodeNum(m_state,
3582 1 : MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).ZoneName,
3583 1 : IntraZoneNodeData(i).ZoneNum,
3584 1 : MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).RAFNNodeNum,
3585 : Errorfound1);
3586 : }
3587 5 : if (IntraZoneNodeData(i).ZoneNum == 0) {
3588 0 : ShowSevereError(m_state,
3589 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "' the Zone is not defined for " +
3590 0 : cAlphaFields(3) + "='" + Alphas(3));
3591 0 : ErrorsFound = true;
3592 : }
3593 : }
3594 : }
3595 :
3596 : // check model compatibility
3597 25 : if (IntraZoneNumOfNodes > 0) {
3598 1 : if (!Util::SameString(SimAirNetworkKey, "MultizoneWithoutDistribution")) {
3599 0 : ShowSevereError(m_state,
3600 0 : format(RoutineName) + CurrentModuleObject +
3601 0 : " model requires Simulation Control = MultizoneWithoutDistribution, while the input choice is " +
3602 0 : SimAirNetworkKey + ".");
3603 0 : ErrorsFound = true;
3604 0 : ShowFatalError(
3605 : m_state,
3606 0 : format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
3607 : }
3608 : }
3609 :
3610 25 : NumOfNodesIntraZone = IntraZoneNumOfNodes;
3611 : // check zone node
3612 25 : IntraZoneNumOfZones = 0;
3613 77 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3614 52 : if (MultizoneZoneData(i).RAFNNodeNum > 0) {
3615 1 : IntraZoneNumOfZones += 1;
3616 : }
3617 : }
3618 :
3619 : // Override error check due to RoomAirNode for the time being
3620 :
3621 : // Read AirflowNetwork Intra linkage
3622 25 : CurrentModuleObject = "AirflowNetwork:IntraZone:Linkage";
3623 25 : IntraZoneNumOfLinks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3624 25 : if (IntraZoneNumOfLinks > 0) {
3625 1 : IntraZoneLinkageData.allocate(IntraZoneNumOfLinks);
3626 1 : UniqueAirflowNetworkSurfaceName.reserve(IntraZoneNumOfLinks);
3627 7 : for (int i = 1; i <= IntraZoneNumOfLinks; ++i) {
3628 6 : 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 6 : IntraZoneLinkageData(i).Name = Alphas(1); // Name of linkage
3641 6 : IntraZoneLinkageData(i).NodeNames[0] = Alphas(2);
3642 6 : IntraZoneLinkageData(i).NodeHeights[0] = 0.0;
3643 6 : IntraZoneLinkageData(i).NodeNames[1] = Alphas(3);
3644 6 : IntraZoneLinkageData(i).NodeHeights[1] = 0.0;
3645 6 : IntraZoneLinkageData(i).CompName = Alphas(4);
3646 6 : if (!lAlphaBlanks(5)) {
3647 : // Perform simple test first.The comprehensive input validation will occur later
3648 : // Check valid surface name
3649 0 : IntraZoneLinkageData(i).SurfaceName = Alphas(5);
3650 0 : IntraZoneLinkageData(i).LinkNum =
3651 0 : Util::FindItemInList(Alphas(5), MultizoneSurfaceData, &MultizoneSurfaceProp::SurfName, AirflowNetworkNumOfSurfaces);
3652 0 : if (IntraZoneLinkageData(i).LinkNum == 0) {
3653 0 : ShowSevereError(m_state,
3654 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(5) +
3655 0 : " given = " + Alphas(5) + " in AirflowNetwork:MultiZone:Surface objects");
3656 0 : ErrorsFound = true;
3657 : }
3658 0 : GlobalNames::VerifyUniqueInterObjectName(
3659 0 : m_state, UniqueAirflowNetworkSurfaceName, Alphas(5), CurrentModuleObject, cAlphaFields(5), ErrorsFound);
3660 : }
3661 6 : if (Util::SameString(Alphas(2), Alphas(3))) {
3662 0 : ShowSevereError(m_state,
3663 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid inputs of both node name with " +
3664 0 : Alphas(2) + " = " + Alphas(3));
3665 0 : ErrorsFound = true;
3666 : }
3667 : // Check valid node names
3668 6 : IntraZoneLinkageData(i).NodeNums[0] = Util::FindItemInList(Alphas(2), IntraZoneNodeData, IntraZoneNumOfNodes);
3669 6 : if (IntraZoneLinkageData(i).NodeNums[0] == 0) {
3670 0 : IntraZoneLinkageData(i).NodeNums[0] =
3671 0 : Util::FindItemInList(Alphas(2), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3672 0 : IntraZoneLinkageData(i).NodeHeights[0] = Zone(MultizoneZoneData(IntraZoneLinkageData(i).NodeNums[0]).ZoneNum).Centroid.z;
3673 0 : if (IntraZoneLinkageData(i).NodeNums[0] == 0) {
3674 0 : ShowSevereError(m_state,
3675 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(2) +
3676 0 : " given = " + Alphas(2) + " in AirflowNetwork:IntraZone:Node and AirflowNetwork:MultiZone:Zone objects");
3677 0 : ErrorsFound = true;
3678 : }
3679 : } else {
3680 6 : IntraZoneLinkageData(i).NodeHeights[0] = IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0]).Height;
3681 6 : IntraZoneLinkageData(i).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0] + AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
3682 : }
3683 6 : IntraZoneLinkageData(i).NodeNums[1] = Util::FindItemInList(Alphas(3), IntraZoneNodeData, IntraZoneNumOfNodes);
3684 6 : if (IntraZoneLinkageData(i).NodeNums[1] == 0) {
3685 2 : IntraZoneLinkageData(i).NodeNums[1] =
3686 2 : Util::FindItemInList(Alphas(3), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3687 2 : if (IntraZoneLinkageData(i).NodeNums[1] > 0) {
3688 2 : IntraZoneLinkageData(i).NodeHeights[1] = Zone(MultizoneZoneData(IntraZoneLinkageData(i).NodeNums[1]).ZoneNum).Centroid.z;
3689 : } else {
3690 0 : if (simulation_control.iWPCCnt == iWPCCntr::Input) { // Surface-Average does not need inputs of external nodes
3691 0 : IntraZoneLinkageData(i).NodeNums[1] = MultizoneSurfaceData(IntraZoneLinkageData(i).LinkNum).NodeNums[1];
3692 0 : if (IntraZoneLinkageData(i).NodeNums[1] == 0) {
3693 0 : ShowSevereError(m_state,
3694 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(3) +
3695 0 : " given = " + Alphas(3) +
3696 : " in AirflowNetwork:IntraZone:Node or AirflowNetwork:MultiZone:Zone or "
3697 : "AirflowNetwork:MultiZone:ExternalNode objects");
3698 0 : ErrorsFound = true;
3699 : }
3700 : }
3701 0 : if (simulation_control.iWPCCnt == iWPCCntr::SurfAvg) {
3702 0 : if (!lAlphaBlanks(3)) {
3703 0 : ShowWarningError(m_state,
3704 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + " The input of " + cAlphaFields(3) +
3705 : " is not needed, ");
3706 0 : ShowContinueError(m_state,
3707 : " since AirflowNetwork Wind Pressure Coefficient Type = SURFACE-AVERAGE CALCULATION. The "
3708 : "simulation continues...");
3709 : }
3710 0 : IntraZoneLinkageData(i).NodeNums[1] = MultizoneSurfaceData(IntraZoneLinkageData(i).LinkNum).NodeNums[1];
3711 : }
3712 : }
3713 : } else {
3714 4 : IntraZoneLinkageData(i).NodeHeights[1] = IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1]).Height;
3715 4 : IntraZoneLinkageData(i).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1] + AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
3716 : }
3717 : // Ensure the both linked nodes for a surface are not zone nodes.One of nodes has to be an intrazone node
3718 8 : if (IntraZoneLinkageData(i).NodeNums[1] <= AirflowNetworkNumOfZones &&
3719 2 : IntraZoneLinkageData(i).NodeNums[0] <= AirflowNetworkNumOfZones) {
3720 0 : ShowSevereError(m_state,
3721 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid node inputs " + Alphas(2) + " and " +
3722 0 : Alphas(3) + " are zone nodes");
3723 0 : ErrorsFound = true;
3724 : }
3725 6 : if (IntraZoneLinkageData(i).NodeNums[0] <= AirflowNetworkNumOfZones &&
3726 6 : IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode && lAlphaBlanks(5)) {
3727 0 : if (IntraZoneLinkageData(i).NodeNums[0] !=
3728 0 : m_state.afn->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3729 0 : .AFNZoneNum) {
3730 0 : ShowSevereError(
3731 : m_state,
3732 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + ": Invalid zone inputs between Node and Link " +
3733 0 : Alphas(2) + " and " +
3734 0 : m_state.afn->MultizoneZoneData(IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0]).AFNZoneNum).ZoneName);
3735 0 : ErrorsFound = true;
3736 : }
3737 : }
3738 6 : if (IntraZoneLinkageData(i).NodeNums[1] <= AirflowNetworkNumOfZones &&
3739 6 : IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode && lAlphaBlanks(5)) {
3740 2 : if (IntraZoneLinkageData(i).NodeNums[1] !=
3741 2 : m_state.afn->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3742 2 : .AFNZoneNum) {
3743 0 : ShowSevereError(
3744 : m_state,
3745 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + ": Invalid zone inputs between Node and Link " +
3746 0 : Alphas(3) + " and " +
3747 0 : m_state.afn->MultizoneZoneData(IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1]).AFNZoneNum).ZoneName);
3748 0 : ErrorsFound = true;
3749 : }
3750 : }
3751 : }
3752 :
3753 : // Reset the number of intrazone links for a given surface
3754 1 : NumOfLinksIntraZone = IntraZoneNumOfLinks;
3755 7 : for (int i = 1; i <= IntraZoneNumOfLinks; ++i) {
3756 6 : int j = IntraZoneLinkageData(i).LinkNum;
3757 6 : if (j > 0) {
3758 : // Revise data in multizone object
3759 0 : NumOfLinksIntraZone = NumOfLinksIntraZone - 1;
3760 0 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == 0) {
3761 : // Exterior surface NodeNums[1] should be equal
3762 0 : if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3763 0 : MultizoneSurfaceData(j).RAFNflag = true;
3764 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3765 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3766 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3767 0 : MultizoneSurfaceData(j).RAFNflag = true;
3768 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3769 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3770 : } else {
3771 0 : ShowSevereError(m_state,
3772 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3773 0 : IntraZoneLinkageData(i).Name +
3774 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3775 0 : ErrorsFound = true;
3776 : }
3777 : } else {
3778 : // Interior surface
3779 0 : if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode &&
3780 0 : IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3781 0 : MultizoneSurfaceData(j).RAFNflag = true;
3782 0 : if (MultizoneZoneData(MultizoneSurfaceData(j).NodeNums[0]).ZoneNum ==
3783 0 : m_state.afn
3784 0 : ->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3785 0 : .ZoneNum) {
3786 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3787 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3788 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1];
3789 : } else {
3790 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3791 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3792 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[0];
3793 : }
3794 0 : } else if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3795 0 : MultizoneSurfaceData(j).RAFNflag = true;
3796 0 : if (IntraZoneLinkageData(i).NodeNums[1] == MultizoneSurfaceData(j).NodeNums[0]) {
3797 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[0];
3798 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] == MultizoneSurfaceData(j).NodeNums[1]) {
3799 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3800 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3801 : } else {
3802 0 : ShowSevereError(m_state,
3803 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3804 0 : IntraZoneLinkageData(i).Name +
3805 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3806 0 : ErrorsFound = true;
3807 : }
3808 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3809 0 : MultizoneSurfaceData(j).RAFNflag = true;
3810 0 : if (IntraZoneLinkageData(i).NodeNums[0] == MultizoneSurfaceData(j).NodeNums[0]) {
3811 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1];
3812 0 : } else if (IntraZoneLinkageData(i).NodeNums[0] == MultizoneSurfaceData(j).NodeNums[1]) {
3813 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3814 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3815 : } else {
3816 0 : ShowSevereError(m_state,
3817 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3818 0 : IntraZoneLinkageData(i).Name +
3819 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3820 0 : ErrorsFound = true;
3821 : }
3822 : }
3823 : }
3824 : }
3825 : }
3826 : // Remove links with surface defined in Multizone : Surface objects
3827 1 : if (NumOfLinksIntraZone < IntraZoneNumOfLinks) {
3828 0 : int link = 1;
3829 0 : while (link <= NumOfLinksIntraZone) {
3830 0 : if (IntraZoneLinkageData(link).LinkNum > 0) {
3831 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3832 0 : ShowWarningError(m_state,
3833 0 : format(RoutineName) + CurrentModuleObject + "='" + IntraZoneLinkageData(link).Name +
3834 : " is reomoved from the list due to the surface conncetion from Intrazone to Interzone.");
3835 : }
3836 0 : for (int j = link; j <= IntraZoneNumOfLinks - 1; ++j) {
3837 0 : IntraZoneLinkageData(j) = IntraZoneLinkageData(j + 1);
3838 : }
3839 : }
3840 0 : if (IntraZoneLinkageData(link).LinkNum == 0) link = link + 1;
3841 : }
3842 0 : if (IntraZoneLinkageData(link).LinkNum > 0) {
3843 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3844 0 : ShowWarningError(m_state,
3845 0 : format(RoutineName) + CurrentModuleObject + "='" + IntraZoneLinkageData(link).Name +
3846 : " is removed from the list due to the surface connection from Intrazone to Interzone.");
3847 : }
3848 : }
3849 : }
3850 : }
3851 :
3852 : // Read AirflowNetwork Distribution system node
3853 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Node";
3854 25 : DisSysNumOfNodes = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3855 25 : if (DisSysNumOfNodes > 0) {
3856 7 : DisSysNodeData.allocate(DisSysNumOfNodes);
3857 142 : for (int i = 1; i <= DisSysNumOfNodes; ++i) {
3858 135 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3859 : CurrentModuleObject,
3860 : i,
3861 : Alphas,
3862 : NumAlphas,
3863 : Numbers,
3864 : NumNumbers,
3865 : IOStatus,
3866 : lNumericBlanks,
3867 : lAlphaBlanks,
3868 : cAlphaFields,
3869 : cNumericFields);
3870 135 : DisSysNodeData(i).Name = Alphas(1); // Name of node
3871 135 : DisSysNodeData(i).EPlusName = Alphas(2); // Name of associated EnergyPlus node
3872 135 : DisSysNodeData(i).EPlusType = Alphas(3); // Name of associated EnergyPlus type
3873 135 : DisSysNodeData(i).Height = Numbers(1); // Nodal height
3874 135 : DisSysNodeData(i).EPlusNodeNum = 0; // EPlus node number
3875 : // verify EnergyPlus object type
3876 381 : if (Util::SameString(Alphas(3), "AirLoopHVAC:ZoneMixer") || Util::SameString(Alphas(3), "AirLoopHVAC:ZoneSplitter") ||
3877 348 : Util::SameString(Alphas(3), "AirLoopHVAC:OutdoorAirSystem") || Util::SameString(Alphas(3), "OAMixerOutdoorAirStreamNode") ||
3878 339 : Util::SameString(Alphas(3), "OutdoorAir:NodeList") || Util::SameString(Alphas(3), "OutdoorAir:Node") ||
3879 375 : Util::SameString(Alphas(3), "Other") || lAlphaBlanks(3)) {
3880 : } else {
3881 0 : ShowSevereError(m_state,
3882 0 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" invalid " + cAlphaFields(3) + "=\"" +
3883 0 : Alphas(3) + "\" illegal key.");
3884 0 : ShowContinueError(m_state,
3885 : "Valid keys are: AirLoopHVAC:ZoneMixer, AirLoopHVAC:ZoneSplitter, AirLoopHVAC:OutdoorAirSystem, "
3886 : "OAMixerOutdoorAirStreamNode, OutdoorAir:NodeList, OutdoorAir:Node or Other.");
3887 0 : ErrorsFound = true;
3888 : }
3889 : // Avoid duplication of EPlusName
3890 1695 : for (int j = 1; j < i; ++j) {
3891 1560 : if (!Util::SameString(Alphas(2), "")) {
3892 1088 : if (Util::SameString(DisSysNodeData(j).EPlusName, Alphas(2))) {
3893 2 : ShowSevereError(m_state,
3894 2 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" Duplicated " + cAlphaFields(2) +
3895 3 : "=\"" + Alphas(2) + "\". Please make a correction.");
3896 1 : ErrorsFound = true;
3897 : }
3898 : }
3899 : }
3900 : }
3901 : } else {
3902 18 : if (distribution_simulated) {
3903 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
3904 0 : ErrorsFound = true;
3905 : }
3906 : }
3907 :
3908 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Duct";
3909 25 : if (DisSysNumOfDucts == 0) {
3910 18 : if (distribution_simulated) {
3911 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
3912 0 : ErrorsFound = true;
3913 : }
3914 : }
3915 :
3916 : // Read AirflowNetwork distribution system component: DuctViewFactors
3917 25 : CurrentModuleObject = "AirflowNetwork:Distribution:DuctViewFactors";
3918 25 : DisSysNumOfDuctViewFactors = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3919 25 : if (DisSysNumOfDuctViewFactors > 0) {
3920 2 : AirflowNetworkLinkageViewFactorData.allocate(DisSysNumOfDuctViewFactors);
3921 4 : for (int i = 1; i <= DisSysNumOfDuctViewFactors; ++i) {
3922 2 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3923 : CurrentModuleObject,
3924 : i,
3925 : Alphas,
3926 : NumAlphas,
3927 : Numbers,
3928 : NumNumbers,
3929 : IOStatus,
3930 : lNumericBlanks,
3931 : lAlphaBlanks,
3932 : cAlphaFields,
3933 : cNumericFields);
3934 :
3935 2 : auto &this_VF_object(AirflowNetworkLinkageViewFactorData(i));
3936 :
3937 2 : this_VF_object.LinkageName = Alphas(1); // Name of linkage
3938 :
3939 : // Surface exposure fraction
3940 2 : if (Numbers(2) > 1) {
3941 0 : ShowWarningError(m_state,
3942 0 : "Duct surface exposure fraction greater than 1. Check input in: " + CurrentModuleObject + " " +
3943 0 : this_VF_object.LinkageName);
3944 0 : ShowContinueError(m_state, "Using value of 1 for surface exposure fraction");
3945 0 : this_VF_object.DuctExposureFraction = 1;
3946 2 : } else if (Numbers(2) < 0) {
3947 0 : ShowWarningError(
3948 0 : m_state, "Surface exposure fraction less than 0. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
3949 0 : ShowContinueError(m_state, "Using value of 0 for surface exposure fraction");
3950 0 : this_VF_object.DuctExposureFraction = 0;
3951 : } else {
3952 2 : this_VF_object.DuctExposureFraction = Numbers(1);
3953 : }
3954 :
3955 : // Duct surface emittance
3956 2 : if (Numbers(2) > 1) {
3957 0 : ShowWarningError(
3958 0 : m_state, "Duct surface emittance greater than 1. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
3959 0 : ShowContinueError(m_state, "Using value of 1 for surface emittance");
3960 0 : this_VF_object.DuctEmittance = 1;
3961 2 : } else if (Numbers(2) < 0) {
3962 0 : ShowWarningError(
3963 0 : m_state, "Surface exposure fraction less than 0. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
3964 0 : ShowContinueError(m_state, "Using value of 0 for surface exposure fraction");
3965 0 : this_VF_object.DuctEmittance = 0;
3966 : } else {
3967 2 : this_VF_object.DuctEmittance = Numbers(2);
3968 : }
3969 :
3970 2 : this_VF_object.ObjectNum = i;
3971 :
3972 2 : int numSurfaces = NumAlphas - 1;
3973 :
3974 2 : this_VF_object.LinkageSurfaceData.allocate(numSurfaces);
3975 :
3976 12 : for (int surfNum = 1; surfNum < NumAlphas; ++surfNum) {
3977 10 : this_VF_object.LinkageSurfaceData(surfNum).SurfaceName = Alphas(surfNum + 1); // Surface name
3978 10 : this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum = Util::FindItemInList(Alphas(surfNum + 1), m_state.dataSurface->Surface);
3979 :
3980 10 : if (this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum == 0) {
3981 0 : ShowFatalError(
3982 0 : m_state, "Surface " + Alphas(surfNum + 1) + " not found. See: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
3983 : }
3984 :
3985 : // Surface view factor
3986 10 : if (!m_state.dataSurface->Surface(this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum).HeatTransSurf) {
3987 0 : ShowWarningError(m_state,
3988 0 : "Surface=" + Alphas(surfNum + 1) + " is not a heat transfer surface. Check input in: " +
3989 0 : CurrentModuleObject + " " + this_VF_object.LinkageName);
3990 0 : ShowContinueError(m_state, "Using value of 0 for view factor");
3991 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 0;
3992 10 : } else if (Numbers(surfNum + 2) > 1) {
3993 0 : ShowWarningError(m_state,
3994 0 : "View factor for surface " + Alphas(surfNum + 1) +
3995 0 : " greater than 1. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
3996 0 : ShowContinueError(m_state, "Using value of 1 for view factor");
3997 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 1;
3998 10 : } else if (Numbers(surfNum + 2) < 0) {
3999 0 : ShowWarningError(m_state,
4000 0 : "View factor for surface " + Alphas(surfNum + 1) + " less than 0. Check input in: " + CurrentModuleObject +
4001 0 : " " + this_VF_object.LinkageName);
4002 0 : ShowContinueError(m_state, "Using value of 0 for view factor");
4003 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 0;
4004 : } else {
4005 10 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = Numbers(surfNum + 2);
4006 : }
4007 : }
4008 : }
4009 : }
4010 :
4011 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Fan";
4012 25 : if (DisSysNumOfCVFs == 0) {
4013 18 : if (distribution_simulated) {
4014 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
4015 0 : ErrorsFound = true;
4016 : }
4017 : }
4018 :
4019 : // Read PressureController
4020 25 : CurrentModuleObject = "AirflowNetwork:ZoneControl:PressureController";
4021 25 : NumOfPressureControllers = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
4022 25 : if (NumOfPressureControllers > 1) {
4023 0 : ShowSevereError(m_state,
4024 0 : format(RoutineName) + "More " + CurrentModuleObject + " are found. Currently only one( \"1\") " + CurrentModuleObject +
4025 : " object per simulation is allowed when using AirflowNetwork Distribution Systems.");
4026 0 : ShowFatalError(
4027 0 : m_state, format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
4028 : }
4029 :
4030 25 : if (NumOfPressureControllers > 0) {
4031 1 : PressureControllerData.allocate(NumOfPressureControllers);
4032 2 : for (int i = 1; i <= NumOfPressureControllers; ++i) {
4033 1 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
4034 : CurrentModuleObject,
4035 : i,
4036 : Alphas,
4037 : NumAlphas,
4038 : Numbers,
4039 : NumNumbers,
4040 : IOStatus,
4041 : lNumericBlanks,
4042 : lAlphaBlanks,
4043 : cAlphaFields,
4044 : cNumericFields);
4045 :
4046 1 : ErrorObjectHeader eoh{RoutineName, CurrentModuleObject, Alphas(1)};
4047 :
4048 1 : PressureControllerData(i).Name = Alphas(1); // Object Name
4049 1 : PressureControllerData(i).ZoneName = Alphas(2); // Zone name
4050 1 : PressureControllerData(i).ZoneNum = Util::FindItemInList(Alphas(2), Zone);
4051 2 : PressureControllerData(i).AFNNodeNum =
4052 1 : Util::FindItemInList(Alphas(2), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
4053 1 : if (PressureControllerData(i).ZoneNum == 0) {
4054 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(2) + " given.");
4055 0 : ShowContinueError(m_state, "..invalid " + cAlphaFields(2) + " = \"" + PressureControllerData(i).ZoneName + "\"");
4056 0 : ErrorsFound = true;
4057 : }
4058 :
4059 1 : PressureControllerData(i).ControlObjectType = Alphas(3); // Control Object Type
4060 1 : PressureControllerData(i).ControlObjectName = Alphas(4); // Control Object Name
4061 :
4062 : {
4063 : // This SELECT_CASE_var will go on input refactor, no need to fix
4064 1 : auto const SELECT_CASE_var(Util::makeUPPER(Alphas(3)));
4065 1 : if (SELECT_CASE_var == "AIRFLOWNETWORK:MULTIZONE:COMPONENT:ZONEEXHAUSTFAN") {
4066 0 : PressureControllerData(i).ControlTypeSet = PressureCtrlExhaust;
4067 1 : } else if (SELECT_CASE_var == "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT:RELIEFAIRFLOW") {
4068 1 : PressureControllerData(i).ControlTypeSet = PressureCtrlRelief;
4069 : } else { // Error
4070 0 : ShowSevereError(m_state,
4071 0 : format(RoutineName) + CurrentModuleObject + " object, The entered choice for " + cAlphaFields(3) +
4072 0 : " is not valid = \"" + PressureControllerData(i).Name + "\"");
4073 0 : ShowContinueError(m_state,
4074 : "Valid choices are "
4075 : "\"AirflowNetwork:MultiZone:Component:ZoneExhaustFan\",\"AirflowNetwork:Distribution:Component:"
4076 : "ReliefAirFlow\"");
4077 0 : ShowContinueError(m_state, "The input choice is " + Alphas(3));
4078 0 : ErrorsFound = true;
4079 : }
4080 1 : }
4081 :
4082 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlExhaust) {
4083 : // This is not great
4084 0 : bool is_EXF{false};
4085 0 : auto afe = elements.find(Alphas(4));
4086 0 : if (afe != elements.end()) {
4087 0 : is_EXF = afe->second->type() == ComponentType::EXF;
4088 : }
4089 0 : if (!is_EXF) {
4090 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, an invalid name is given:");
4091 0 : ShowContinueError(m_state, ".. invalid " + cAlphaFields(4) + " = \"" + Alphas(4) + "\".");
4092 0 : ErrorsFound = true;
4093 : }
4094 : }
4095 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlRelief) {
4096 : // This is not great
4097 1 : bool is_REL{false};
4098 1 : auto afe = elements.find(Alphas(4));
4099 1 : if (afe != elements.end()) {
4100 1 : is_REL = afe->second->type() == ComponentType::REL;
4101 : }
4102 1 : if (!is_REL) {
4103 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, an invalid name is given:");
4104 0 : ShowContinueError(m_state, ".. invalid " + cAlphaFields(4) + " = \"" + Alphas(4) + "\".");
4105 0 : ErrorsFound = true;
4106 : }
4107 : }
4108 :
4109 1 : if (lAlphaBlanks(5)) {
4110 1 : PressureControllerData(i).availSched = Sched::GetScheduleAlwaysOn(m_state);
4111 0 : } else if ((PressureControllerData(i).availSched = Sched::GetSchedule(m_state, Alphas(5))) == nullptr) {
4112 0 : ShowSevereItemNotFound(m_state, eoh, cAlphaFields(5), Alphas(5));
4113 0 : ErrorsFound = true;
4114 : }
4115 :
4116 1 : if ((PressureControllerData(i).presSetpointSched = Sched::GetSchedule(m_state, Alphas(6))) == nullptr) {
4117 0 : ShowSevereItemNotFound(m_state, eoh, cAlphaFields(6), Alphas(6));
4118 0 : ErrorsFound = true;
4119 : }
4120 : }
4121 : }
4122 :
4123 : // Assign numbers of nodes and linkages
4124 25 : if (simulation_control.type != ControlType::NoMultizoneOrDistribution) {
4125 25 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
4126 10 : NumOfNodesMultiZone = AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
4127 : } else {
4128 15 : NumOfNodesMultiZone = AirflowNetworkNumOfZones + NumOfExtNodes;
4129 : }
4130 25 : NumOfLinksMultiZone = AirflowNetworkNumOfSurfaces;
4131 25 : AirflowNetworkNumOfNodes = NumOfNodesMultiZone;
4132 25 : if (NumOfNodesIntraZone > 0) AirflowNetworkNumOfNodes = AirflowNetworkNumOfNodes + NumOfNodesIntraZone;
4133 25 : AirflowNetworkNumOfLinks = NumOfLinksMultiZone;
4134 25 : if (NumOfLinksIntraZone > 0) AirflowNetworkNumOfLinks = AirflowNetworkNumOfLinks + NumOfLinksIntraZone;
4135 : }
4136 25 : if (distribution_simulated) {
4137 7 : AirflowNetworkNumOfNodes = NumOfNodesMultiZone + DisSysNumOfNodes + NumOfNodesIntraZone;
4138 : }
4139 :
4140 : // Assign node data
4141 25 : AirflowNetworkNodeData.allocate(AirflowNetworkNumOfNodes);
4142 : // Zone node
4143 77 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
4144 52 : AirflowNetworkNodeData(i).Name = MultizoneZoneData(i).ZoneName;
4145 52 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4146 52 : AirflowNetworkNodeData(i).EPlusZoneNum = MultizoneZoneData(i).ZoneNum;
4147 52 : AirflowNetworkNodeData(i).NodeHeight = MultizoneZoneData(i).Height;
4148 : }
4149 : // External node
4150 25 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
4151 42 : for (int i = AirflowNetworkNumOfZones + 1; i <= NumOfNodesMultiZone; ++i) {
4152 32 : AirflowNetworkNodeData(i).Name = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).Name;
4153 32 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4154 32 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4155 32 : AirflowNetworkNodeData(i).NodeHeight = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).height;
4156 32 : AirflowNetworkNodeData(i).ExtNodeNum = i - AirflowNetworkNumOfZones;
4157 32 : AirflowNetworkNodeData(i).OutAirNodeNum = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).OutAirNodeNum;
4158 : }
4159 : } else { // Surface-Average input
4160 73 : for (int i = AirflowNetworkNumOfZones + 1; i <= NumOfNodesMultiZone; ++i) {
4161 58 : n = i - AirflowNetworkNumOfZones;
4162 58 : AirflowNetworkNodeData(i).Name = MultizoneExternalNodeData(n).Name;
4163 58 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4164 58 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4165 58 : AirflowNetworkNodeData(i).ExtNodeNum = n;
4166 : }
4167 : }
4168 :
4169 : // Intrazone node
4170 25 : if (NumOfNodesIntraZone > 0) {
4171 6 : for (int i = NumOfNodesMultiZone + 1; i <= NumOfNodesMultiZone + NumOfNodesIntraZone; ++i) {
4172 5 : n = i - NumOfNodesMultiZone;
4173 5 : AirflowNetworkNodeData(i).Name = IntraZoneNodeData(n).Name;
4174 5 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4175 5 : AirflowNetworkNodeData(i).EPlusZoneNum = IntraZoneNodeData(n).ZoneNum;
4176 5 : AirflowNetworkNodeData(i).NodeHeight = IntraZoneNodeData(n).Height;
4177 5 : AirflowNetworkNodeData(i).RAFNNodeNum = IntraZoneNodeData(n).RAFNNodeNum;
4178 : }
4179 2 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
4180 1 : if (MultizoneZoneData(i).RAFNNodeNum > 0) {
4181 1 : AirflowNetworkNodeData(i).RAFNNodeNum = MultizoneZoneData(i).RAFNNodeNum;
4182 : }
4183 : }
4184 : }
4185 25 : NumOfNodesMultiZone = NumOfNodesMultiZone + NumOfNodesIntraZone;
4186 :
4187 : // Check whether Distribution system is simulated
4188 25 : if (AirflowNetworkNumOfNodes > NumOfNodesMultiZone) {
4189 : // Search node types: OAMixerOutdoorAirStreamNode, OutdoorAir:NodeList, and OutdoorAir:Node
4190 7 : int j = 0;
4191 142 : for (int i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
4192 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
4193 3 : ++j;
4194 : }
4195 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:NodeList")) {
4196 0 : ++j;
4197 : }
4198 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:Node")) {
4199 0 : ++j;
4200 : }
4201 : }
4202 :
4203 142 : for (int i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
4204 135 : AirflowNetworkNodeData(i).Name = DisSysNodeData(i - NumOfNodesMultiZone).Name;
4205 135 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4206 135 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4207 135 : AirflowNetworkNodeData(i).NodeHeight = DisSysNodeData(i - NumOfNodesMultiZone).Height;
4208 135 : AirflowNetworkNodeData(i).EPlusNodeNum = DisSysNodeData(i - NumOfNodesMultiZone).EPlusNodeNum;
4209 : // Get mixer information
4210 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:ZoneMixer")) {
4211 8 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::MIX;
4212 : }
4213 : // Get splitter information
4214 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:ZoneSplitter")) {
4215 8 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPL;
4216 : }
4217 : // Get outside air system information
4218 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
4219 3 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::OAN;
4220 : }
4221 : // Get OA system inlet information 'OAMixerOutdoorAirStreamNode' was specified as an outdoor air node implicitly
4222 135 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
4223 3 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::EXT;
4224 3 : AirflowNetworkNodeData(i).ExtNodeNum = AirflowNetworkNumOfExtNode + 1;
4225 3 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4226 : }
4227 270 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:NodeList") ||
4228 270 : Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:Node")) {
4229 0 : if (j > 1) {
4230 0 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::EXT;
4231 0 : AirflowNetworkNodeData(i).ExtNodeNum = AirflowNetworkNumOfExtNode + 1;
4232 0 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4233 : } else {
4234 0 : ShowSevereError(m_state,
4235 0 : format(RoutineName) + "AirflowNetwork:Distribution:Node: The outdoor air node is found at " +
4236 0 : AirflowNetworkNodeData(i).Name);
4237 0 : ShowContinueError(m_state,
4238 : "The node with Component Object Type = OAMixerOutdoorAirStreamNode is not found. Please check inputs.");
4239 0 : ErrorsFound = true;
4240 : }
4241 : }
4242 : }
4243 : }
4244 :
4245 : // Start to assembly AirflowNetwork Components
4246 25 : AirflowNetworkNumOfComps = AirflowNetworkNumOfDetOpenings + AirflowNetworkNumOfSimOpenings + AirflowNetworkNumOfSurCracks +
4247 25 : AirflowNetworkNumOfSurELA + DisSysNumOfLeaks + DisSysNumOfELRs + DisSysNumOfDucts + DisSysNumOfDampers +
4248 25 : DisSysNumOfCVFs + DisSysNumOfDetFans + DisSysNumOfCPDs + DisSysNumOfCoils + DisSysNumOfTermUnits +
4249 25 : AirflowNetworkNumOfExhFan + DisSysNumOfHXs + AirflowNetworkNumOfHorOpenings + NumOfOAFans + NumOfReliefFans +
4250 25 : AirflowNetworkNumOfSFR;
4251 25 : AirflowNetworkCompData.allocate(AirflowNetworkNumOfComps);
4252 :
4253 30 : for (int i = 1; i <= AirflowNetworkNumOfDetOpenings; ++i) { // Detailed opening component
4254 5 : AirflowNetworkCompData(i).Name = MultizoneCompDetOpeningData(i).name;
4255 5 : compnum[AirflowNetworkCompData(i).Name] = i;
4256 5 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DOP;
4257 5 : AirflowNetworkCompData(i).TypeNum = i;
4258 5 : AirflowNetworkCompData(i).EPlusName = "";
4259 5 : AirflowNetworkCompData(i).EPlusCompName = "";
4260 5 : AirflowNetworkCompData(i).EPlusType = "";
4261 5 : AirflowNetworkCompData(i).CompNum = i;
4262 : }
4263 :
4264 25 : int j = AirflowNetworkNumOfDetOpenings;
4265 34 : for (int i = 1 + j; i <= AirflowNetworkNumOfSimOpenings + j; ++i) { // Simple opening component
4266 9 : n = i - j;
4267 9 : AirflowNetworkCompData(i).Name = MultizoneCompSimpleOpeningData(n).name;
4268 9 : compnum[AirflowNetworkCompData(i).Name] = i;
4269 9 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SOP;
4270 9 : AirflowNetworkCompData(i).TypeNum = n;
4271 9 : AirflowNetworkCompData(i).EPlusName = "";
4272 9 : AirflowNetworkCompData(i).EPlusCompName = "";
4273 9 : AirflowNetworkCompData(i).EPlusType = "";
4274 9 : AirflowNetworkCompData(i).CompNum = i;
4275 : }
4276 :
4277 25 : j += AirflowNetworkNumOfSimOpenings;
4278 61 : for (int i = 1 + j; i <= AirflowNetworkNumOfSurCracks + j; ++i) { // Surface crack component
4279 36 : n = i - j;
4280 36 : AirflowNetworkCompData(i).Name = MultizoneSurfaceCrackData(n).name;
4281 36 : compnum[AirflowNetworkCompData(i).Name] = i;
4282 36 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SCR;
4283 36 : AirflowNetworkCompData(i).TypeNum = n;
4284 36 : AirflowNetworkCompData(i).EPlusName = "";
4285 36 : AirflowNetworkCompData(i).EPlusCompName = "";
4286 36 : AirflowNetworkCompData(i).EPlusType = "";
4287 36 : AirflowNetworkCompData(i).CompNum = i;
4288 : }
4289 :
4290 25 : j += AirflowNetworkNumOfSurCracks;
4291 33 : for (int i = 1 + j; i <= AirflowNetworkNumOfSurELA + j; ++i) { // Surface crack component
4292 8 : n = i - j;
4293 8 : AirflowNetworkCompData(i).Name = MultizoneSurfaceELAData(n).name;
4294 8 : compnum[AirflowNetworkCompData(i).Name] = i;
4295 8 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SEL;
4296 8 : AirflowNetworkCompData(i).TypeNum = n;
4297 8 : AirflowNetworkCompData(i).EPlusName = "";
4298 8 : AirflowNetworkCompData(i).EPlusCompName = "";
4299 8 : AirflowNetworkCompData(i).EPlusType = "";
4300 8 : AirflowNetworkCompData(i).CompNum = i;
4301 : }
4302 :
4303 25 : j += AirflowNetworkNumOfSurELA;
4304 28 : for (int i = 1 + j; i <= AirflowNetworkNumOfExhFan + j; ++i) { // Zone exhaust fan component
4305 3 : n = i - j;
4306 3 : AirflowNetworkCompData(i).Name = MultizoneCompExhaustFanData(n).name;
4307 3 : compnum[AirflowNetworkCompData(i).Name] = i;
4308 3 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::EXF;
4309 3 : AirflowNetworkCompData(i).TypeNum = n;
4310 3 : AirflowNetworkCompData(i).EPlusName = "";
4311 3 : AirflowNetworkCompData(i).EPlusCompName = "";
4312 3 : AirflowNetworkCompData(i).EPlusType = "";
4313 3 : AirflowNetworkCompData(i).CompNum = i;
4314 : }
4315 :
4316 25 : j += AirflowNetworkNumOfExhFan;
4317 26 : for (int i = 1 + j; i <= AirflowNetworkNumOfHorOpenings + j; ++i) { // Distribution system crack component
4318 1 : n = i - j;
4319 1 : AirflowNetworkCompData(i).Name = MultizoneCompHorOpeningData(n).name;
4320 1 : compnum[AirflowNetworkCompData(i).Name] = i;
4321 1 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::HOP;
4322 1 : AirflowNetworkCompData(i).TypeNum = n;
4323 1 : AirflowNetworkCompData(i).EPlusName = "";
4324 1 : AirflowNetworkCompData(i).EPlusCompName = "";
4325 1 : AirflowNetworkCompData(i).EPlusType = "";
4326 1 : AirflowNetworkCompData(i).CompNum = i;
4327 : }
4328 :
4329 25 : j += AirflowNetworkNumOfHorOpenings;
4330 30 : for (int i = 1 + j; i <= DisSysNumOfLeaks + j; ++i) { // Distribution system crack component
4331 5 : n = i - j;
4332 5 : AirflowNetworkCompData(i).Name = DisSysCompLeakData(n).name;
4333 5 : compnum[AirflowNetworkCompData(i).Name] = i;
4334 5 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::PLR;
4335 5 : AirflowNetworkCompData(i).TypeNum = n;
4336 5 : AirflowNetworkCompData(i).EPlusName = "";
4337 5 : AirflowNetworkCompData(i).EPlusCompName = "";
4338 5 : AirflowNetworkCompData(i).EPlusType = "";
4339 5 : AirflowNetworkCompData(i).CompNum = i;
4340 : }
4341 :
4342 25 : j += DisSysNumOfLeaks;
4343 45 : for (int i = 1 + j; i <= DisSysNumOfELRs + j; ++i) { // Distribution system effective leakage ratio component
4344 20 : n = i - j;
4345 20 : AirflowNetworkCompData(i).Name = DisSysCompELRData(n).name;
4346 20 : compnum[AirflowNetworkCompData(i).Name] = i;
4347 20 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::ELR;
4348 20 : AirflowNetworkCompData(i).TypeNum = n;
4349 20 : AirflowNetworkCompData(i).EPlusName = "";
4350 20 : AirflowNetworkCompData(i).EPlusCompName = "";
4351 20 : AirflowNetworkCompData(i).EPlusType = "";
4352 20 : AirflowNetworkCompData(i).CompNum = i;
4353 : }
4354 :
4355 25 : j += DisSysNumOfELRs;
4356 89 : for (int i = 1 + j; i <= DisSysNumOfDucts + j; ++i) { // Distribution system effective leakage ratio component
4357 64 : n = i - j;
4358 64 : AirflowNetworkCompData(i).Name = DisSysCompDuctData(n).name;
4359 64 : compnum[AirflowNetworkCompData(i).Name] = i;
4360 64 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DWC;
4361 64 : AirflowNetworkCompData(i).TypeNum = n;
4362 64 : AirflowNetworkCompData(i).EPlusName = "";
4363 64 : AirflowNetworkCompData(i).EPlusCompName = "";
4364 64 : AirflowNetworkCompData(i).EPlusType = "";
4365 64 : AirflowNetworkCompData(i).CompNum = i;
4366 : }
4367 :
4368 25 : j += DisSysNumOfDucts;
4369 25 : for (int i = 1 + j; i <= DisSysNumOfDampers + j; ++i) { // Distribution system effective leakage ratio component
4370 0 : n = i - j;
4371 0 : AirflowNetworkCompData(i).Name = DisSysCompDamperData(n).name;
4372 0 : compnum[AirflowNetworkCompData(i).Name] = i;
4373 0 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DMP;
4374 0 : AirflowNetworkCompData(i).TypeNum = n;
4375 0 : AirflowNetworkCompData(i).EPlusName = "";
4376 0 : AirflowNetworkCompData(i).EPlusCompName = "";
4377 0 : AirflowNetworkCompData(i).EPlusType = "";
4378 0 : AirflowNetworkCompData(i).CompNum = i;
4379 : }
4380 :
4381 25 : j += DisSysNumOfDampers;
4382 33 : for (int i = 1 + j; i <= DisSysNumOfCVFs + j; ++i) { // Distribution system constant volume fan component
4383 8 : n = i - j;
4384 8 : AirflowNetworkCompData(i).Name = DisSysCompCVFData(n).name;
4385 8 : compnum[AirflowNetworkCompData(i).Name] = i;
4386 8 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::CVF;
4387 8 : AirflowNetworkCompData(i).TypeNum = n;
4388 8 : AirflowNetworkCompData(i).EPlusName = "";
4389 8 : AirflowNetworkCompData(i).EPlusCompName = "";
4390 8 : AirflowNetworkCompData(i).EPlusType = "";
4391 8 : AirflowNetworkCompData(i).CompNum = i;
4392 8 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::FAN;
4393 : }
4394 :
4395 25 : j += DisSysNumOfCVFs;
4396 25 : for (int i = 1 + j; i <= DisSysNumOfDetFans + j; ++i) { // Distribution system fan component
4397 0 : n = i - j;
4398 0 : AirflowNetworkCompData(i).Name = DisSysCompDetFanData(n).name;
4399 0 : compnum[AirflowNetworkCompData(i).Name] = i;
4400 0 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::FAN;
4401 0 : AirflowNetworkCompData(i).TypeNum = n;
4402 0 : AirflowNetworkCompData(i).EPlusName = "";
4403 0 : AirflowNetworkCompData(i).EPlusCompName = "";
4404 0 : AirflowNetworkCompData(i).EPlusType = "";
4405 0 : AirflowNetworkCompData(i).CompNum = i;
4406 0 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::FAN;
4407 : }
4408 :
4409 25 : j += DisSysNumOfDetFans;
4410 27 : for (int i = 1 + j; i <= DisSysNumOfCPDs + j; ++i) { // Distribution system constant pressure drop component
4411 2 : n = i - j;
4412 2 : AirflowNetworkCompData(i).Name = DisSysCompCPDData(n).name;
4413 2 : compnum[AirflowNetworkCompData(i).Name] = i;
4414 2 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::CPD;
4415 2 : AirflowNetworkCompData(i).TypeNum = n;
4416 2 : AirflowNetworkCompData(i).EPlusName = "";
4417 2 : AirflowNetworkCompData(i).EPlusCompName = "";
4418 2 : AirflowNetworkCompData(i).EPlusType = "";
4419 2 : AirflowNetworkCompData(i).CompNum = i;
4420 : }
4421 :
4422 25 : j += DisSysNumOfCPDs;
4423 45 : for (int i = 1 + j; i <= DisSysNumOfCoils + j; ++i) { // Distribution system coil component
4424 20 : n = i - j;
4425 20 : AirflowNetworkCompData(i).Name = DisSysCompCoilData(n).name;
4426 20 : compnum[AirflowNetworkCompData(i).Name] = i;
4427 20 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::COI;
4428 20 : AirflowNetworkCompData(i).TypeNum = n;
4429 20 : AirflowNetworkCompData(i).EPlusName = "";
4430 20 : AirflowNetworkCompData(i).EPlusCompName = "";
4431 20 : AirflowNetworkCompData(i).EPlusType = "";
4432 20 : AirflowNetworkCompData(i).CompNum = i;
4433 20 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::COI;
4434 : }
4435 :
4436 25 : j += DisSysNumOfCoils;
4437 28 : for (int i = 1 + j; i <= DisSysNumOfTermUnits + j; ++i) { // Terminal unit component
4438 3 : n = i - j;
4439 3 : AirflowNetworkCompData(i).Name = DisSysCompTermUnitData(n).name;
4440 3 : compnum[AirflowNetworkCompData(i).Name] = i;
4441 3 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::TMU;
4442 3 : AirflowNetworkCompData(i).TypeNum = n;
4443 3 : AirflowNetworkCompData(i).EPlusName = "";
4444 3 : AirflowNetworkCompData(i).EPlusCompName = "";
4445 3 : AirflowNetworkCompData(i).EPlusType = "";
4446 3 : AirflowNetworkCompData(i).CompNum = i;
4447 3 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::RHT;
4448 : }
4449 :
4450 25 : j += DisSysNumOfTermUnits;
4451 25 : for (int i = 1 + j; i <= DisSysNumOfHXs + j; ++i) { // Distribution system heat exchanger component
4452 0 : n = i - j;
4453 0 : AirflowNetworkCompData(i).Name = DisSysCompHXData(n).name;
4454 0 : compnum[AirflowNetworkCompData(i).Name] = i;
4455 0 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::HEX;
4456 0 : AirflowNetworkCompData(i).TypeNum = n;
4457 0 : AirflowNetworkCompData(i).EPlusName = "";
4458 0 : AirflowNetworkCompData(i).EPlusCompName = "";
4459 0 : AirflowNetworkCompData(i).EPlusType = "";
4460 0 : AirflowNetworkCompData(i).CompNum = i;
4461 0 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::HEX;
4462 : }
4463 :
4464 25 : j += DisSysNumOfHXs;
4465 28 : for (int i = 1 + j; i <= NumOfOAFans + j; ++i) { // OA fan component
4466 3 : n = i - j;
4467 3 : AirflowNetworkCompData(i).Name = DisSysCompOutdoorAirData(n).name;
4468 3 : compnum[AirflowNetworkCompData(i).Name] = i;
4469 3 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::OAF;
4470 3 : AirflowNetworkCompData(i).TypeNum = n;
4471 3 : AirflowNetworkCompData(i).EPlusName = "";
4472 3 : AirflowNetworkCompData(i).EPlusCompName = "";
4473 3 : AirflowNetworkCompData(i).EPlusType = "";
4474 3 : AirflowNetworkCompData(i).CompNum = i;
4475 : }
4476 :
4477 25 : j += NumOfOAFans;
4478 27 : for (int i = 1 + j; i <= NumOfReliefFans + j; ++i) { // OA fan component
4479 2 : n = i - j;
4480 2 : AirflowNetworkCompData(i).Name = DisSysCompReliefAirData(n).name;
4481 2 : compnum[AirflowNetworkCompData(i).Name] = i;
4482 2 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::REL;
4483 2 : AirflowNetworkCompData(i).TypeNum = n;
4484 2 : AirflowNetworkCompData(i).EPlusName = "";
4485 2 : AirflowNetworkCompData(i).EPlusCompName = "";
4486 2 : AirflowNetworkCompData(i).EPlusType = "";
4487 2 : AirflowNetworkCompData(i).CompNum = i;
4488 : }
4489 :
4490 : // This is also a bit of a hack to keep things working, this needs to be removed ASAP
4491 25 : j += NumOfReliefFans;
4492 25 : int ii = 1 + j;
4493 25 : int type_i = 1;
4494 25 : for (auto const &el : SpecifiedMassFlowData) {
4495 0 : AirflowNetworkCompData(ii).Name = el.name;
4496 0 : compnum[el.name] = ii;
4497 0 : AirflowNetworkCompData(ii).CompTypeNum = iComponentTypeNum::SMF;
4498 0 : AirflowNetworkCompData(ii).TypeNum = type_i;
4499 0 : AirflowNetworkCompData(ii).EPlusName = "";
4500 0 : AirflowNetworkCompData(ii).EPlusCompName = "";
4501 0 : AirflowNetworkCompData(ii).EPlusType = "";
4502 0 : AirflowNetworkCompData(ii).CompNum = ii;
4503 0 : ++ii;
4504 0 : ++type_i;
4505 : }
4506 :
4507 25 : type_i = 1;
4508 25 : for (auto const &el : SpecifiedVolumeFlowData) {
4509 0 : AirflowNetworkCompData(ii).Name = el.name;
4510 0 : compnum[el.name] = ii;
4511 0 : AirflowNetworkCompData(ii).CompTypeNum = iComponentTypeNum::SVF;
4512 0 : AirflowNetworkCompData(ii).TypeNum = type_i;
4513 0 : AirflowNetworkCompData(ii).EPlusName = "";
4514 0 : AirflowNetworkCompData(ii).EPlusCompName = "";
4515 0 : AirflowNetworkCompData(ii).EPlusType = "";
4516 0 : AirflowNetworkCompData(ii).CompNum = ii;
4517 0 : ++ii;
4518 0 : ++type_i;
4519 : }
4520 :
4521 : // Assign linkage data
4522 :
4523 : // Read AirflowNetwork linkage data
4524 25 : CurrentModuleObject = "AirflowNetwork:Distribution:Linkage";
4525 25 : DisSysNumOfLinks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
4526 25 : if (DisSysNumOfLinks > 0 && distribution_simulated) { // Multizone + Distribution
4527 7 : AirflowNetworkNumOfLinks = NumOfLinksMultiZone + DisSysNumOfLinks;
4528 7 : AirflowNetworkLinkageData.allocate(DisSysNumOfLinks + AirflowNetworkNumOfSurfaces);
4529 : } else { // Multizone + IntraZone only
4530 : // AirflowNetworkLinkageData.allocate( AirflowNetworkNumOfSurfaces );
4531 18 : AirflowNetworkLinkageData.allocate(AirflowNetworkNumOfLinks);
4532 : }
4533 :
4534 : // Assign Multizone linkage based on surfaces, by assuming every surface has a crack or opening
4535 25 : j = 0;
4536 168 : for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
4537 143 : if (MultizoneSurfaceData(count).SurfNum == 0) continue;
4538 143 : AirflowNetworkLinkageData(count).Name = MultizoneSurfaceData(count).SurfName;
4539 143 : AirflowNetworkLinkageData(count).NodeNums[0] = MultizoneSurfaceData(count).NodeNums[0];
4540 143 : AirflowNetworkLinkageData(count).NodeNums[1] = MultizoneSurfaceData(count).NodeNums[1];
4541 143 : AirflowNetworkLinkageData(count).CompName = MultizoneSurfaceData(count).OpeningName;
4542 143 : AirflowNetworkLinkageData(count).ZoneNum = 0;
4543 143 : AirflowNetworkLinkageData(count).LinkNum = count;
4544 143 : AirflowNetworkLinkageData(count).NodeHeights[0] = MultizoneSurfaceData(count).CHeight;
4545 143 : AirflowNetworkLinkageData(count).NodeHeights[1] = MultizoneSurfaceData(count).CHeight;
4546 143 : if (!m_state.dataSurface->WorldCoordSystem) {
4547 45 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum > 0) {
4548 45 : AirflowNetworkLinkageData(count).NodeHeights[0] -=
4549 45 : Zone(AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum).OriginZ;
4550 : }
4551 45 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum > 0) {
4552 3 : AirflowNetworkLinkageData(count).NodeHeights[1] -=
4553 3 : Zone(AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum).OriginZ;
4554 : }
4555 : }
4556 : // Find component number
4557 143 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4558 143 : if (afe != elements.end()) {
4559 : // found = false;
4560 : // for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
4561 143 : AirflowNetworkLinkageData(count).element = afe->second;
4562 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4563 143 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4564 143 : assert(compnum_iter != compnum.end());
4565 143 : int compnum = compnum_iter->second;
4566 143 : AirflowNetworkLinkageData(count).CompNum = compnum;
4567 :
4568 143 : auto const &surf = m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum);
4569 :
4570 143 : switch (AirflowNetworkLinkageData(count).element->type()) {
4571 6 : case ComponentType::DOP: {
4572 : // if (AirflowNetworkLinkageData(count).CompName ==
4573 : // AirflowNetworkCompData(i).Name) {
4574 : // AirflowNetworkLinkageData(count).CompNum = i;
4575 : // found = true;
4576 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::DOP) {
4577 6 : ++j;
4578 6 : AirflowNetworkLinkageData(count).DetOpenNum = j;
4579 6 : MultizoneSurfaceData(count).Multiplier = surf.Multiplier;
4580 6 : if (surf.Tilt < 10.0 || surf.Tilt > 170.0) {
4581 0 : ShowWarningError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4582 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is within ");
4583 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through large horizontal openings are poorly");
4584 0 : ShowContinueError(m_state, "modeled in the AirflowNetwork model resulting in only one-way airflow.");
4585 : }
4586 6 : if (!(surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::GlassDoor ||
4587 0 : surf.OriginalClass == SurfaceClass::Door || surf.IsAirBoundarySurf)) {
4588 0 : ShowSevereError(m_state,
4589 0 : format(RoutineName) +
4590 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4591 0 : AirflowNetworkLinkageData(count).Name);
4592 0 : ErrorsFound = true;
4593 : }
4594 :
4595 6 : if (surf.OriginalClass == SurfaceClass::Door || surf.OriginalClass == SurfaceClass::GlassDoor) {
4596 0 : if (MultizoneCompDetOpeningData(AirflowNetworkCompData(compnum).TypeNum).LVOType == 2) {
4597 0 : ShowSevereError(m_state,
4598 0 : format(RoutineName) +
4599 : "AirflowNetworkComponent: The opening with horizontally pivoted type must be assigned to a "
4600 0 : "window surface at " +
4601 0 : AirflowNetworkLinkageData(count).Name);
4602 0 : ErrorsFound = true;
4603 : }
4604 : }
4605 6 : } break;
4606 18 : case ComponentType::SOP: {
4607 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SOP) {
4608 18 : MultizoneSurfaceData(count).Multiplier = surf.Multiplier;
4609 18 : if (surf.Tilt < 10.0 || surf.Tilt > 170.0) {
4610 0 : ShowSevereError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4611 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is within");
4612 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through horizontal openings are not allowed.");
4613 0 : ShowContinueError(m_state, "AirflowNetwork:Multizone:Component:SimpleOpening = " + AirflowNetworkCompData(compnum).Name);
4614 0 : ErrorsFound = true;
4615 : }
4616 :
4617 18 : if (!(surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::GlassDoor ||
4618 0 : surf.OriginalClass == SurfaceClass::Door || surf.IsAirBoundarySurf)) {
4619 0 : ShowSevereError(m_state,
4620 0 : format(RoutineName) +
4621 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4622 0 : AirflowNetworkLinkageData(count).Name);
4623 0 : ErrorsFound = true;
4624 : }
4625 18 : } break;
4626 0 : case ComponentType::HOP: {
4627 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::HOP) {
4628 0 : MultizoneSurfaceData(count).Multiplier = surf.Multiplier;
4629 : // Get linkage height from upper and lower zones
4630 0 : if (MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum > 0) {
4631 0 : AirflowNetworkLinkageData(count).NodeHeights[0] =
4632 0 : Zone(MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum).Centroid.z;
4633 : }
4634 0 : if (AirflowNetworkLinkageData(count).NodeNums[1] <= AirflowNetworkNumOfZones) {
4635 0 : if (MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum > 0) {
4636 0 : AirflowNetworkLinkageData(count).NodeHeights[1] =
4637 0 : Zone(m_state.afn->MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum).Centroid.z;
4638 : }
4639 : }
4640 0 : if (AirflowNetworkLinkageData(count).NodeNums[1] > AirflowNetworkNumOfZones) {
4641 0 : ShowSevereError(m_state,
4642 0 : format(RoutineName) +
4643 0 : "AirflowNetworkComponent: The horizontal opening must be located between two thermal zones at " +
4644 0 : AirflowNetworkLinkageData(count).Name);
4645 0 : ShowContinueError(m_state, "This component is exposed to outdoors.");
4646 0 : ErrorsFound = true;
4647 : } else {
4648 0 : if (!(MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum > 0 &&
4649 0 : MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum > 0)) {
4650 0 : ShowSevereError(m_state,
4651 0 : format(RoutineName) +
4652 0 : "AirflowNetworkComponent: The horizontal opening must be located between two thermal zones at " +
4653 0 : AirflowNetworkLinkageData(count).Name);
4654 0 : ErrorsFound = true;
4655 : }
4656 : }
4657 0 : if (!(surf.Tilt > 170.0 && surf.Tilt < 190.0) && !(surf.Tilt > -10.0 && surf.Tilt < 10.0)) {
4658 0 : ShowWarningError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4659 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is above");
4660 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through non-horizontal openings are not modeled");
4661 0 : ShowContinueError(m_state,
4662 0 : "with the object of AirflowNetwork:Multizone:Component:HorizontalOpening = " +
4663 0 : AirflowNetworkCompData(compnum).Name);
4664 : }
4665 0 : if (!(surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::GlassDoor ||
4666 0 : surf.OriginalClass == SurfaceClass::Door || surf.IsAirBoundarySurf)) {
4667 0 : ShowSevereError(m_state,
4668 0 : format(RoutineName) +
4669 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4670 0 : AirflowNetworkLinkageData(count).Name);
4671 0 : ErrorsFound = true;
4672 : }
4673 0 : } break;
4674 119 : default:
4675 : // Nothing to do here
4676 119 : break;
4677 : }
4678 : } else {
4679 0 : ShowSevereError(m_state,
4680 0 : format(RoutineName) + CurrentModuleObject + ": The component is not defined in " +
4681 0 : AirflowNetworkLinkageData(count).Name);
4682 0 : ErrorsFound = true;
4683 : }
4684 : }
4685 :
4686 : // Assign intrazone links
4687 31 : for (count = 1 + AirflowNetworkNumOfSurfaces; count <= NumOfLinksIntraZone + AirflowNetworkNumOfSurfaces; ++count) {
4688 6 : AirflowNetworkLinkageData(count).Name = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).Name;
4689 6 : AirflowNetworkLinkageData(count).NodeNums[0] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeNums[0];
4690 6 : AirflowNetworkLinkageData(count).NodeNums[1] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeNums[1];
4691 6 : AirflowNetworkLinkageData(count).CompName = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).CompName;
4692 6 : AirflowNetworkLinkageData(count).ZoneNum = 0;
4693 6 : AirflowNetworkLinkageData(count).LinkNum = count;
4694 6 : AirflowNetworkLinkageData(count).NodeHeights[0] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeHeights[0];
4695 6 : AirflowNetworkLinkageData(count).NodeHeights[1] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeHeights[1];
4696 : // Find component number
4697 6 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4698 6 : if (afe != elements.end()) {
4699 6 : AirflowNetworkLinkageData(count).element = afe->second;
4700 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4701 6 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4702 6 : assert(compnum_iter != compnum.end());
4703 6 : int compnum = compnum_iter->second;
4704 6 : AirflowNetworkLinkageData(count).CompNum = compnum;
4705 6 : if (AirflowNetworkLinkageData(count).element->type() != ComponentType::SCR &&
4706 0 : AirflowNetworkLinkageData(count).element->type() != ComponentType::SEL) {
4707 :
4708 0 : ShowSevereError(m_state,
4709 0 : format(RoutineName) + AirflowNetworkLinkageData(count).CompName + ": The component is not allowed in " +
4710 0 : AirflowNetworkLinkageData(count).Name);
4711 0 : ShowContinueError(m_state,
4712 : "The allowed component type is either AirflowNetwork:MultiZone:Surface:Crack or "
4713 : "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea.");
4714 0 : ErrorsFound = true;
4715 : }
4716 : } else {
4717 0 : ShowSevereError(m_state,
4718 0 : format(RoutineName) + AirflowNetworkLinkageData(count).CompName + ": The component is not defined in " +
4719 0 : AirflowNetworkLinkageData(count).Name);
4720 0 : ErrorsFound = true;
4721 : }
4722 : }
4723 :
4724 : // Reset AirflowNetworkNumOfSurfaces by including NumOfLinksIntraZone
4725 25 : AirflowNetworkNumOfSurfaces = AirflowNetworkNumOfSurfaces + NumOfLinksIntraZone;
4726 25 : if (NumOfLinksIntraZone > 0) NumOfLinksMultiZone = AirflowNetworkNumOfSurfaces;
4727 :
4728 : // Assign AirflowNetwork info in RoomAirflowNetworkZoneInfo
4729 25 : if (NumOfNodesIntraZone > 0) {
4730 11 : for (int i = 1; i <= NumOfNodesMultiZone; ++i) {
4731 10 : n = AirflowNetworkNodeData(i).EPlusZoneNum;
4732 10 : AirflowNetworkNodeData(i).NumOfLinks = 0;
4733 10 : if (n > 0 && AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
4734 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID = i;
4735 90 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
4736 84 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i) {
4737 14 : AirflowNetworkNodeData(i).NumOfLinks = AirflowNetworkNodeData(i).NumOfLinks + 1;
4738 70 : } else if (AirflowNetworkLinkageData(j).NodeNums[1] == i) {
4739 6 : AirflowNetworkNodeData(i).NumOfLinks = AirflowNetworkNodeData(i).NumOfLinks + 1;
4740 : } else {
4741 : }
4742 : }
4743 : }
4744 10 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
4745 42 : for (j = 1; j <= m_state.dataRoomAir->AFNZoneInfo(n).NumOfAirNodes; ++j) {
4746 36 : if (m_state.dataRoomAir->AFNZoneInfo(n).Node(j).AFNNodeID == i) {
4747 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).NumOfAirflowLinks = AirflowNetworkNodeData(i).NumOfLinks;
4748 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link.allocate(AirflowNetworkNodeData(i).NumOfLinks);
4749 6 : k = 1;
4750 74 : for (int m = 1; m <= AirflowNetworkNumOfSurfaces; ++m) {
4751 74 : if (AirflowNetworkLinkageData(m).NodeNums[0] == i) {
4752 14 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNSimuID = m;
4753 14 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNDataID = m;
4754 14 : k = k + 1;
4755 14 : if (k > AirflowNetworkNodeData(i).NumOfLinks) break;
4756 : }
4757 70 : if (AirflowNetworkLinkageData(m).NodeNums[1] == i) {
4758 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNSimuID = m;
4759 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNDataID = m;
4760 6 : k = k + 1;
4761 6 : if (k > AirflowNetworkNodeData(i).NumOfLinks) break;
4762 : }
4763 : }
4764 : }
4765 : }
4766 : }
4767 : }
4768 : }
4769 :
4770 25 : if (DisSysNumOfLinks > 0 && distribution_simulated) { // Distribution
4771 :
4772 259 : for (auto &e : AirflowNetworkLinkageData)
4773 252 : e.ZoneNum = 0;
4774 :
4775 180 : for (count = AirflowNetworkNumOfSurfaces + 1; count <= AirflowNetworkNumOfLinks; ++count) {
4776 :
4777 346 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
4778 : CurrentModuleObject,
4779 173 : count - AirflowNetworkNumOfSurfaces,
4780 : Alphas,
4781 : NumAlphas,
4782 : Numbers,
4783 : NumNumbers,
4784 : IOStatus,
4785 : lNumericBlanks,
4786 : lAlphaBlanks,
4787 : cAlphaFields,
4788 : cNumericFields);
4789 173 : AirflowNetworkLinkageData(count).Name = Alphas(1);
4790 173 : AirflowNetworkLinkageData(count).NodeNames[0] = Alphas(2);
4791 173 : AirflowNetworkLinkageData(count).NodeHeights[0] = 0.0;
4792 173 : AirflowNetworkLinkageData(count).NodeNames[1] = Alphas(3);
4793 173 : AirflowNetworkLinkageData(count).NodeHeights[1] = 0.0;
4794 173 : AirflowNetworkLinkageData(count).CompName = Alphas(4);
4795 173 : AirflowNetworkLinkageData(count).ZoneName = Alphas(5);
4796 173 : AirflowNetworkLinkageData(count).LinkNum = count;
4797 :
4798 199 : for (int i = 1; i <= DisSysNumOfDuctViewFactors; ++i) {
4799 28 : if (AirflowNetworkLinkageData(count).Name == AirflowNetworkLinkageViewFactorData(i).LinkageName) {
4800 2 : AirflowNetworkLinkageData(count).LinkageViewFactorObjectNum = AirflowNetworkLinkageViewFactorData(i).ObjectNum;
4801 2 : break;
4802 : }
4803 : }
4804 :
4805 173 : if (!lAlphaBlanks(5)) {
4806 69 : AirflowNetworkLinkageData(count).ZoneNum = Util::FindItemInList(AirflowNetworkLinkageData(count).ZoneName, Zone);
4807 69 : if (AirflowNetworkLinkageData(count).ZoneNum == 0) {
4808 0 : ShowSevereError(m_state,
4809 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(5) +
4810 0 : " given = " + AirflowNetworkLinkageData(count).ZoneName);
4811 0 : ErrorsFound = true;
4812 : }
4813 : }
4814 173 : if (Alphas(2) == Alphas(3)) {
4815 0 : ShowSevereError(m_state,
4816 0 : format(RoutineName) + CurrentModuleObject + ", " + cAlphaFields(2) + " = " + cAlphaFields(3) + " in " +
4817 0 : AirflowNetworkLinkageData(count).Name);
4818 0 : ErrorsFound = true;
4819 : }
4820 : // Find component number
4821 173 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4822 173 : if (afe != elements.end()) {
4823 173 : AirflowNetworkLinkageData(count).element = afe->second;
4824 :
4825 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4826 173 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4827 173 : assert(compnum_iter != compnum.end());
4828 173 : int compnum = compnum_iter->second;
4829 173 : AirflowNetworkLinkageData(count).CompNum = compnum;
4830 : } else {
4831 0 : ShowSevereError(m_state,
4832 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(4) + " is not defined in " +
4833 0 : AirflowNetworkLinkageData(count).Name);
4834 0 : ErrorsFound = true;
4835 : }
4836 : // Find Node number
4837 173 : found = false;
4838 3470 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4839 3470 : if (AirflowNetworkLinkageData(count).NodeNames[0] == AirflowNetworkNodeData(i).Name) {
4840 173 : AirflowNetworkLinkageData(count).NodeNums[0] = i;
4841 173 : AirflowNetworkLinkageData(count).NodeHeights[0] += AirflowNetworkNodeData(i).NodeHeight;
4842 173 : found = true;
4843 173 : break;
4844 : }
4845 : }
4846 173 : if (!found) {
4847 0 : ShowSevereError(m_state,
4848 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(2) + " is not found in the node data " +
4849 0 : AirflowNetworkLinkageData(count).Name);
4850 0 : ErrorsFound = true;
4851 : }
4852 3444 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4853 3444 : if (AirflowNetworkLinkageData(count).NodeNames[1] == AirflowNetworkNodeData(i).Name) {
4854 173 : AirflowNetworkLinkageData(count).NodeNums[1] = i;
4855 173 : AirflowNetworkLinkageData(count).NodeHeights[1] += AirflowNetworkNodeData(i).NodeHeight;
4856 173 : found = true;
4857 173 : break;
4858 : }
4859 : }
4860 173 : if (!found) {
4861 0 : ShowSevereError(m_state,
4862 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(3) + " is not found in the node data " +
4863 0 : AirflowNetworkLinkageData(count).Name);
4864 0 : ErrorsFound = true;
4865 : }
4866 : }
4867 7 : } else {
4868 :
4869 18 : if (distribution_simulated) {
4870 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
4871 0 : ErrorsFound = true;
4872 : }
4873 : }
4874 :
4875 : // Ensure no duplicated names in AirflowNetwork component objects
4876 : // for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
4877 : // for (j = i + 1; j <= AirflowNetworkNumOfComps; ++j) {
4878 : // if (Util::SameString(AirflowNetworkCompData(i).Name,
4879 : // AirflowNetworkCompData(j).Name)) {
4880 : // // SurfaceAirflowLeakageNames
4881 : // if (i <= 4 && j <= 4) {
4882 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::DOP)
4883 : // CompName(1) = "AirflowNetwork:MultiZone:Component:DetailedOpening";
4884 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SOP)
4885 : // CompName(1) = "AirflowNetwork:MultiZone:Component:SimpleOpening";
4886 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SCR) CompName(1) =
4887 : // "AirflowNetwork:MultiZone:Surface:Crack"; if (AirflowNetworkCompData(i).CompTypeNum ==
4888 : // iComponentTypeNum::SEL) CompName(1) = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea"; if
4889 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DOP) CompName(2) =
4890 : // "AirflowNetwork:MultiZone:Component:DetailedOpening"; if (AirflowNetworkCompData(j).CompTypeNum ==
4891 : // iComponentTypeNum::SOP) CompName(2) = "AirflowNetwork:MultiZone:Component:SimpleOpening"; if
4892 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::SCR) CompName(2) =
4893 : // "AirflowNetwork:MultiZone:Surface:Crack"; if (AirflowNetworkCompData(j).CompTypeNum ==
4894 : // iComponentTypeNum::SEL) CompName(2) = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea"; ShowSevereError(m_state, RoutineName
4895 : // + "Duplicated component names are found = " + AirflowNetworkCompData(i).Name); ShowContinueError(m_state,
4896 : // "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2)); ErrorsFound = true;
4897 : // }
4898 : // // Distribution component
4899 : // if (i > 4 && j > 4) {
4900 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::PLR) CompName(1) =
4901 : // "AirflowNetwork:Distribution:Component:Leak"; if (AirflowNetworkCompData(i).CompTypeNum ==
4902 : // iComponentTypeNum::DWC) CompName(1) = "AirflowNetwork:Distribution:Component:Duct"; if
4903 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::ELR) CompName(1) =
4904 : // "AirflowNetwork:Distribution:Component:LeakageRatio"; if (AirflowNetworkCompData(i).CompTypeNum ==
4905 : // iComponentTypeNum::DMP) CompName(1) = "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT DAMPER"; if
4906 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::CVF) CompName(1) =
4907 : // "AirflowNetwork:Distribution:Component:Fan"; if (AirflowNetworkCompData(i).CompTypeNum ==
4908 : // iComponentTypeNum::CPD) CompName(1) = "AirflowNetwork:Distribution:Component:ConstantPressureDrop"; if
4909 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::COI) CompName(1) =
4910 : // "AirflowNetwork:Distribution:Component:Coil"; if (AirflowNetworkCompData(i).CompTypeNum ==
4911 : // iComponentTypeNum::TMU) CompName(1) = "AirflowNetwork:Distribution:Component:TerminalUnit"; if
4912 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::HEX) CompName(1) =
4913 : // "AirflowNetwork:Distribution:Component:HeatExchanger"; if (AirflowNetworkCompData(j).CompTypeNum ==
4914 : // iComponentTypeNum::PLR) CompName(2) = "AirflowNetwork:Distribution:Component:Leak"; if
4915 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DWC) CompName(2) =
4916 : // "AirflowNetwork:Distribution:Component:Duct"; if (AirflowNetworkCompData(j).CompTypeNum ==
4917 : // iComponentTypeNum::ELR) CompName(2) = "AirflowNetwork:Distribution:Component:LeakageRatio"; if
4918 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DMP) CompName(2) =
4919 : // "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT DAMPER"; if (AirflowNetworkCompData(j).CompTypeNum ==
4920 : // iComponentTypeNum::CVF) CompName(2) = "AirflowNetwork:Distribution:Component:Fan"; if
4921 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::CPD) CompName(2) =
4922 : // "AirflowNetwork:Distribution:Component:ConstantPressureDrop"; if (AirflowNetworkCompData(j).CompTypeNum
4923 : // == iComponentTypeNum::COI) CompName(2) = "AirflowNetwork:Distribution:Component:Coil"; if
4924 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::TMU) CompName(2) =
4925 : // "AirflowNetwork:Distribution:Component:TerminalUnit"; if (AirflowNetworkCompData(j).CompTypeNum ==
4926 : // iComponentTypeNum::HEX) CompName(2) = "AirflowNetwork:Distribution:Component:HeatExchanger"; ShowSevereError(m_state,
4927 : // format(RoutineName) + "Duplicated component names are found = " + AirflowNetworkCompData(i).Name);
4928 : // ShowContinueError(m_state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
4929 : // ErrorsFound = true;
4930 : // }
4931 : // }
4932 : // }
4933 : // }
4934 :
4935 : // Node and component validation
4936 347 : for (count = 1; count <= AirflowNetworkNumOfLinks; ++count) {
4937 322 : NodeFound = false;
4938 3764 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4939 3764 : if (i == AirflowNetworkLinkageData(count).NodeNums[0]) {
4940 322 : NodeFound = true;
4941 322 : break;
4942 : }
4943 : }
4944 322 : if (!NodeFound) {
4945 0 : if (count <= AirflowNetworkNumOfSurfaces) {
4946 0 : ShowSevereError(m_state,
4947 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
4948 0 : " in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name + " is not found");
4949 : } else {
4950 0 : ShowSevereError(m_state,
4951 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
4952 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
4953 : " is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE objects.");
4954 : }
4955 0 : ErrorsFound = true;
4956 : }
4957 322 : NodeFound = false;
4958 4234 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4959 4234 : if (i == AirflowNetworkLinkageData(count).NodeNums[1]) {
4960 322 : NodeFound = true;
4961 322 : break;
4962 : }
4963 : }
4964 322 : if (!NodeFound) {
4965 0 : if (count <= AirflowNetworkNumOfSurfaces) {
4966 0 : ShowSevereError(m_state,
4967 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
4968 0 : " in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name + " is not found");
4969 : } else {
4970 0 : ShowSevereError(m_state,
4971 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[1] +
4972 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
4973 : " is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE objects.");
4974 : }
4975 0 : ErrorsFound = true;
4976 : }
4977 322 : bool CompFound = false;
4978 7617 : for (int i = 1; i <= AirflowNetworkNumOfComps; ++i) {
4979 7295 : if (i == AirflowNetworkLinkageData(count).CompNum) {
4980 322 : CompFound = true;
4981 : }
4982 : }
4983 322 : if (!CompFound) {
4984 0 : ShowSevereError(m_state,
4985 0 : format(RoutineName) + "Component = " + AirflowNetworkLinkageData(count).CompName +
4986 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
4987 : " is not found in AirflowNetwork Component Data objects.");
4988 0 : ErrorsFound = true;
4989 : }
4990 : }
4991 :
4992 : // Ensure every AirflowNetworkNode is used in AirflowNetworkLinkage
4993 307 : for (count = 1; count <= AirflowNetworkNumOfNodes; ++count) {
4994 282 : bool NodeFound1 = false;
4995 282 : bool NodeFound2 = false;
4996 9424 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
4997 9142 : if (count == AirflowNetworkLinkageData(i).NodeNums[0]) {
4998 322 : NodeFound1 = true;
4999 : }
5000 9142 : if (count == AirflowNetworkLinkageData(i).NodeNums[1]) {
5001 322 : NodeFound2 = true;
5002 : }
5003 : }
5004 282 : if ((!NodeFound1) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum == 0) {
5005 0 : ShowSevereError(m_state,
5006 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5007 : " is not found as Node 1 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5008 0 : ShowContinueError(m_state,
5009 : "Each non-external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined as Node 1 once in "
5010 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5011 0 : ErrorsFound = true;
5012 : }
5013 282 : if ((!NodeFound2) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum == 0) {
5014 0 : ShowSevereError(m_state,
5015 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5016 : " is not found as Node 2 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5017 0 : ShowContinueError(m_state,
5018 : "Each non-external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined as Node 2 once in "
5019 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5020 0 : ErrorsFound = true;
5021 : }
5022 282 : if ((!NodeFound1) && (!NodeFound2) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum > 0) {
5023 0 : ShowSevereError(m_state,
5024 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5025 : " is not found as Node 1 Name or Node 2 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5026 0 : ShowContinueError(m_state, "This external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5027 0 : ErrorsFound = true;
5028 : }
5029 : }
5030 :
5031 : // Ensure there is at least one node defined as EXTERNAL node
5032 25 : NodeFound = false;
5033 307 : for (count = 1; count <= AirflowNetworkNumOfNodes; ++count) {
5034 282 : if (AirflowNetworkNodeData(count).ExtNodeNum > 0) {
5035 93 : NodeFound = true;
5036 : }
5037 : }
5038 25 : if (!NodeFound) {
5039 0 : ShowSevereError(m_state,
5040 0 : format(RoutineName) +
5041 : "No External Nodes found in AirflowNetwork:Multizone:ExternalNode. There must be at least 1 external node defined.");
5042 0 : ErrorsFound = true;
5043 : }
5044 :
5045 25 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
5046 96 : for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
5047 86 : if (AirflowNetworkLinkageData(count).NodeNums[0] == 0) {
5048 0 : ShowSevereError(m_state,
5049 0 : "The surface is not found in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name);
5050 0 : ErrorsFound = true;
5051 : }
5052 86 : if (AirflowNetworkLinkageData(count).NodeNums[1] == 0) {
5053 0 : ShowSevereError(m_state,
5054 0 : "The external node is not found in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name);
5055 0 : ErrorsFound = true;
5056 : }
5057 : }
5058 : }
5059 :
5060 : // Provide a warning when a door component is assigned as envelope leakage
5061 : // if (!ErrorsFound) {
5062 : // for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
5063 : // if
5064 : // (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).ExtNodeNum
5065 : // > 0 &&
5066 : // AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum
5067 : // > 0 && AirflowNetworkLinkageData(count).CompNum > 0) { if
5068 : // (AirflowNetworkCompData(AirflowNetworkLinkageData(count).CompNum).CompTypeNum
5069 : // == iComponentTypeNum::SOP) {
5070 : // }
5071 : // }
5072 : // if
5073 : // (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).ExtNodeNum
5074 : // > 0 &&
5075 : // AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum
5076 : // > 0 && AirflowNetworkLinkageData(count).CompNum > 0) { if
5077 : // (AirflowNetworkCompData(AirflowNetworkLinkageData(count).CompNum).CompTypeNum
5078 : // == iComponentTypeNum::SOP) {
5079 : // }
5080 : // }
5081 : // }
5082 : // }
5083 :
5084 : // Ensure the name of each heat exchanger is shown either once or twice in the field of
5085 25 : if (distribution_simulated) {
5086 7 : for (int i = 1; i <= DisSysNumOfHXs; ++i) {
5087 0 : count = 0;
5088 0 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
5089 0 : if (Util::SameString(AirflowNetworkLinkageData(j).CompName, DisSysCompHXData(i).name)) {
5090 0 : ++count;
5091 : }
5092 : }
5093 :
5094 0 : if (DisSysCompHXData(i).CoilParentExists && count != 2) {
5095 0 : ShowSevereError(m_state,
5096 0 : format(RoutineName) + "The inputs of component name field as a heat exchanger in "
5097 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE is not correct");
5098 0 : ShowContinueError(m_state,
5099 0 : "The entered name of heat exchanger is " + DisSysCompHXData(i).name +
5100 : " in AirflowNetwork:Distribution:Component:HeatExchanger objects");
5101 0 : ShowContinueError(m_state, format("The correct appearance number is 2. The entered appearance number is {}", count));
5102 0 : ErrorsFound = true;
5103 : }
5104 0 : if ((!DisSysCompHXData(i).CoilParentExists) && count != 1) {
5105 0 : ShowSevereError(m_state,
5106 0 : format(RoutineName) + "The inputs of component name field as a heat exchanger in "
5107 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE is not correct");
5108 0 : ShowContinueError(m_state,
5109 0 : "The entered name of heat exchanger is " + DisSysCompHXData(i).name +
5110 : " in AirflowNetwork:Distribution:Component:HeatExchanger objects");
5111 0 : ShowContinueError(m_state, format("The correct appearance number is 1. The entered appearance number is {}", count));
5112 0 : ErrorsFound = true;
5113 : }
5114 : }
5115 : }
5116 :
5117 : // Check node assignments using AirflowNetwork:Distribution:Component:OutdoorAirFlow or
5118 : // AirflowNetwork:Distribution:Component:ReliefAirFlow
5119 198 : for (count = AirflowNetworkNumOfSurfaces + 1; count <= AirflowNetworkNumOfLinks; ++count) {
5120 173 : int i = AirflowNetworkLinkageData(count).CompNum;
5121 173 : j = AirflowNetworkLinkageData(count).NodeNums[0];
5122 173 : k = AirflowNetworkLinkageData(count).NodeNums[1];
5123 :
5124 173 : if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::OAF) {
5125 3 : if (!Util::SameString(DisSysNodeData(j - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
5126 0 : ShowSevereError(m_state,
5127 0 : format(RoutineName) +
5128 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5129 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5130 0 : AirflowNetworkNodeData(j).Name + ",");
5131 0 : ShowContinueError(
5132 0 : m_state, "the component type in the first node should be OAMixerOutdoorAirStreamNode at " + AirflowNetworkNodeData(j).Name);
5133 0 : ErrorsFound = true;
5134 : }
5135 3 : if (!Util::SameString(DisSysNodeData(k - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
5136 0 : ShowSevereError(m_state,
5137 0 : format(RoutineName) +
5138 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5139 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5140 0 : AirflowNetworkNodeData(k).Name + ",");
5141 0 : ShowContinueError(m_state,
5142 0 : "the component object type in the second node should be AirLoopHVAC:OutdoorAirSystem at " +
5143 0 : AirflowNetworkNodeData(k).Name);
5144 0 : ErrorsFound = true;
5145 : }
5146 : }
5147 :
5148 173 : if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::REL) {
5149 2 : if (!Util::SameString(DisSysNodeData(j - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
5150 0 : ShowSevereError(m_state,
5151 0 : format(RoutineName) +
5152 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5153 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5154 0 : AirflowNetworkNodeData(j).Name + ",");
5155 0 : ShowContinueError(m_state,
5156 0 : "the component object type in the first node should be AirLoopHVAC:OutdoorAirSystem at " +
5157 0 : AirflowNetworkNodeData(j).Name);
5158 0 : ErrorsFound = true;
5159 : }
5160 2 : if (!Util::SameString(DisSysNodeData(k - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
5161 0 : ShowSevereError(m_state,
5162 0 : format(RoutineName) +
5163 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5164 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5165 0 : AirflowNetworkNodeData(k).Name + ",");
5166 0 : ShowContinueError(
5167 0 : m_state, "the component type in the second node should be OAMixerOutdoorAirStreamNode at " + AirflowNetworkNodeData(k).Name);
5168 0 : ErrorsFound = true;
5169 : }
5170 : }
5171 : }
5172 :
5173 25 : if (ErrorsFound) {
5174 2 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
5175 : }
5176 :
5177 24 : Alphas.deallocate();
5178 24 : cAlphaFields.deallocate();
5179 24 : cNumericFields.deallocate();
5180 24 : Numbers.deallocate();
5181 24 : lAlphaBlanks.deallocate();
5182 24 : lNumericBlanks.deallocate();
5183 :
5184 24 : if (!ErrorsFound) {
5185 24 : allocate_and_initialize();
5186 : }
5187 1157 : }
5188 :
5189 16855 : void Solver::initialize()
5190 : {
5191 : // SUBROUTINE INFORMATION:
5192 : // AUTHOR Lixing Gu
5193 : // DATE WRITTEN Aug. 2003
5194 : // MODIFIED na
5195 : // RE-ENGINEERED na
5196 :
5197 : // PURPOSE OF THIS SUBROUTINE:
5198 : // This subroutine initializes variables of additional zone loads caused by ADS.
5199 :
5200 : // USE STATEMENTS:
5201 16855 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
5202 :
5203 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5204 : int i;
5205 : int ZoneNum;
5206 16855 : auto &Zone(m_state.dataHeatBal->Zone);
5207 :
5208 16855 : if (initializeOneTimeFlag) {
5209 4 : exchangeData.allocate(m_state.dataGlobal->NumOfZones); // AirflowNetwork exchange data due to air-forced system
5210 5 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5211 2 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
5212 1 : multiExchangeData.allocate(m_state.dataGlobal->NumOfZones);
5213 1 : break;
5214 : }
5215 : }
5216 :
5217 4 : initializeOneTimeFlag = false;
5218 4 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5219 0 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5220 0 : SetupOutputVariable(m_state,
5221 : "AFN Zone Outdoor Air Mass Flow Rate",
5222 : Constant::Units::kg_s,
5223 0 : exchangeData(i).SumMHr,
5224 : OutputProcessor::TimeStepType::System,
5225 : OutputProcessor::StoreType::Average,
5226 0 : Zone(i).Name);
5227 0 : SetupOutputVariable(m_state,
5228 : "AFN Zone Mixing Mass Flow Rate",
5229 : Constant::Units::kg_s,
5230 0 : exchangeData(i).SumMMHr,
5231 : OutputProcessor::TimeStepType::System,
5232 : OutputProcessor::StoreType::Average,
5233 0 : Zone(i).Name);
5234 0 : SetupOutputVariable(m_state,
5235 : "AFN Zone Outdoor Air CO2 Mass Flow Rate",
5236 : Constant::Units::kg_s,
5237 0 : exchangeData(i).SumMHrCO,
5238 : OutputProcessor::TimeStepType::System,
5239 : OutputProcessor::StoreType::Average,
5240 0 : Zone(i).Name);
5241 0 : SetupOutputVariable(m_state,
5242 : "AFN Zone Mixing CO2 Mass Flow Rate",
5243 : Constant::Units::kg_s,
5244 0 : exchangeData(i).SumMMHrCO,
5245 : OutputProcessor::TimeStepType::System,
5246 : OutputProcessor::StoreType::Average,
5247 0 : Zone(i).Name);
5248 0 : SetupOutputVariable(m_state,
5249 : "AFN Zone Total CO2 Mass Flow Rate",
5250 : Constant::Units::kg_s,
5251 0 : exchangeData(i).TotalCO2,
5252 : OutputProcessor::TimeStepType::System,
5253 : OutputProcessor::StoreType::Average,
5254 0 : Zone(i).Name);
5255 : }
5256 : }
5257 4 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5258 0 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5259 0 : if (!m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5260 0 : SetupOutputVariable(m_state,
5261 : "AFN Zone Outdoor Air Mass Flow Rate",
5262 : Constant::Units::kg_s,
5263 0 : exchangeData(i).SumMHr,
5264 : OutputProcessor::TimeStepType::System,
5265 : OutputProcessor::StoreType::Average,
5266 0 : Zone(i).Name);
5267 0 : SetupOutputVariable(m_state,
5268 : "AFN Zone Mixing Mass Flow Rate",
5269 : Constant::Units::kg_s,
5270 0 : exchangeData(i).SumMMHr,
5271 : OutputProcessor::TimeStepType::System,
5272 : OutputProcessor::StoreType::Average,
5273 0 : Zone(i).Name);
5274 : }
5275 0 : SetupOutputVariable(m_state,
5276 : "AFN Zone Outdoor Air Generic Air Contaminant Mass Flow Rate",
5277 : Constant::Units::kg_s,
5278 0 : exchangeData(i).SumMHrGC,
5279 : OutputProcessor::TimeStepType::System,
5280 : OutputProcessor::StoreType::Average,
5281 0 : Zone(i).Name);
5282 0 : SetupOutputVariable(m_state,
5283 : "AFN Zone Mixing Generic Air Contaminant Mass Flow Rate",
5284 : Constant::Units::kg_s,
5285 0 : exchangeData(i).SumMMHrGC,
5286 : OutputProcessor::TimeStepType::System,
5287 : OutputProcessor::StoreType::Average,
5288 0 : Zone(i).Name);
5289 0 : SetupOutputVariable(m_state,
5290 : "AFN Zone Total Generic Air Contaminant Mass Flow Rate",
5291 : Constant::Units::kg_s,
5292 0 : exchangeData(i).TotalGC,
5293 : OutputProcessor::TimeStepType::System,
5294 : OutputProcessor::StoreType::Average,
5295 0 : Zone(i).Name);
5296 : }
5297 : }
5298 : }
5299 :
5300 16855 : if (m_state.dataGlobal->BeginEnvrnFlag && initializeMyEnvrnFlag) {
5301 : // Assign node values
5302 280 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5303 272 : AirflowNetworkNodeSimu(i).TZ = 23.0;
5304 272 : AirflowNetworkNodeSimu(i).WZ = 0.00084;
5305 272 : AirflowNetworkNodeSimu(i).PZ = 0.0;
5306 272 : AirflowNetworkNodeSimu(i).TZlast = AirflowNetworkNodeSimu(i).TZ;
5307 272 : AirflowNetworkNodeSimu(i).WZlast = AirflowNetworkNodeSimu(i).WZ;
5308 272 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5309 0 : AirflowNetworkNodeSimu(i).CO2Z = m_state.dataContaminantBalance->OutdoorCO2;
5310 0 : AirflowNetworkNodeSimu(i).CO2Zlast = AirflowNetworkNodeSimu(i).CO2Z;
5311 : }
5312 272 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5313 0 : AirflowNetworkNodeSimu(i).GCZ = m_state.dataContaminantBalance->OutdoorGC;
5314 0 : AirflowNetworkNodeSimu(i).GCZlast = AirflowNetworkNodeSimu(i).GCZ;
5315 : }
5316 272 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
5317 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
5318 0 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp = 23.0;
5319 0 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat = 0.0;
5320 : }
5321 : }
5322 :
5323 312 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
5324 304 : AirflowNetworkLinkSimu(i).FLOW = 0.0;
5325 304 : AirflowNetworkLinkSimu(i).FLOW2 = 0.0;
5326 : }
5327 :
5328 32 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5329 24 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT;
5330 24 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).airHumRat;
5331 24 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5332 0 : ANCO(i) = m_state.dataContaminantBalance->ZoneAirCO2(i);
5333 : }
5334 24 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5335 0 : ANGC(i) = m_state.dataContaminantBalance->ZoneAirGC(i);
5336 : }
5337 : }
5338 8 : if (AirflowNetworkNumOfOccuVentCtrls > 0) {
5339 0 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5340 0 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5341 0 : MultizoneSurfaceData(i).PrevOpeningstatus = AirflowNetwork::OpenStatus::FreeOperation;
5342 0 : MultizoneSurfaceData(i).CloseElapsedTime = 0.0;
5343 0 : MultizoneSurfaceData(i).OpenElapsedTime = 0.0;
5344 0 : MultizoneSurfaceData(i).OpeningStatus = AirflowNetwork::OpenStatus::FreeOperation;
5345 0 : MultizoneSurfaceData(i).OpeningProbStatus = AirflowNetwork::ProbabilityCheck::NoAction;
5346 0 : MultizoneSurfaceData(i).ClosingProbStatus = 0;
5347 : }
5348 : }
5349 : }
5350 :
5351 8 : initializeMyEnvrnFlag = false;
5352 : }
5353 16855 : if (!m_state.dataGlobal->BeginEnvrnFlag) {
5354 16717 : initializeMyEnvrnFlag = true;
5355 16717 : if (simulation_control.type != ControlType::NoMultizoneOrDistribution) {
5356 16717 : if (RollBackFlag) {
5357 0 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5358 0 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).XMAT[0];
5359 0 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).WPrevZoneTS[0];
5360 0 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) ANCO(i) = m_state.dataContaminantBalance->CO2ZoneTimeMinus1(i);
5361 0 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5362 0 : ANGC(i) = m_state.dataContaminantBalance->GCZoneTimeMinus1(i);
5363 : }
5364 : } else {
5365 66865 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5366 50148 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT;
5367 50148 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).airHumRat;
5368 50148 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) ANCO(i) = m_state.dataContaminantBalance->ZoneAirCO2(i);
5369 50148 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5370 0 : ANGC(i) = m_state.dataContaminantBalance->ZoneAirGC(i);
5371 : }
5372 : }
5373 :
5374 585021 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5375 568304 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0) {
5376 50148 : AirflowNetworkNodeSimu(i).TZ = ANZT(AirflowNetworkNodeData(i).EPlusZoneNum);
5377 50148 : AirflowNetworkNodeSimu(i).WZ = ANZW(AirflowNetworkNodeData(i).EPlusZoneNum);
5378 50148 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5379 0 : AirflowNetworkNodeSimu(i).CO2Z = ANCO(AirflowNetworkNodeData(i).EPlusZoneNum);
5380 50148 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5381 0 : AirflowNetworkNodeSimu(i).GCZ = ANGC(AirflowNetworkNodeData(i).EPlusZoneNum);
5382 : }
5383 568304 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
5384 284148 : if (AirflowNetworkNodeData(i).OutAirNodeNum > 0 &&
5385 1 : m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).IsLocalNode) {
5386 0 : AirflowNetworkNodeSimu(i).TZ = m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).OutAirDryBulb;
5387 0 : AirflowNetworkNodeSimu(i).WZ = m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).HumRat;
5388 : } else {
5389 284147 : AirflowNetworkNodeSimu(i).TZ = AirflowNetwork::OutDryBulbTempAt(m_state, AirflowNetworkNodeData(i).NodeHeight);
5390 284147 : AirflowNetworkNodeSimu(i).WZ = m_state.dataEnvrn->OutHumRat;
5391 : }
5392 :
5393 284147 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5394 0 : AirflowNetworkNodeSimu(i).CO2Z = m_state.dataContaminantBalance->OutdoorCO2;
5395 284147 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5396 0 : AirflowNetworkNodeSimu(i).GCZ = m_state.dataContaminantBalance->OutdoorGC;
5397 : }
5398 :
5399 568304 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
5400 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
5401 0 : if (m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID == i) {
5402 0 : AirflowNetworkNodeSimu(i).TZ =
5403 0 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp;
5404 0 : AirflowNetworkNodeSimu(i).WZ =
5405 0 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat;
5406 : }
5407 : }
5408 : }
5409 : }
5410 : }
5411 :
5412 67417 : for (auto &e : exchangeData) {
5413 50562 : e.TotalSen = 0.0;
5414 50562 : e.TotalLat = 0.0;
5415 50562 : e.MultiZoneSen = 0.0;
5416 50562 : e.MultiZoneLat = 0.0;
5417 50562 : e.LeakSen = 0.0;
5418 50562 : e.LeakLat = 0.0;
5419 50562 : e.CondSen = 0.0;
5420 50562 : e.DiffLat = 0.0;
5421 50562 : e.RadGain = 0.0;
5422 : }
5423 16855 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5424 0 : for (auto &e : exchangeData)
5425 0 : e.TotalCO2 = 0.0;
5426 16855 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5427 0 : for (auto &e : exchangeData)
5428 0 : e.TotalGC = 0.0;
5429 :
5430 : // Occupant ventilation control
5431 16855 : Real64 CurrentEndTime = m_state.dataGlobal->CurrentTime + m_state.dataHVACGlobal->SysTimeElapsed;
5432 16855 : if (CurrentEndTime > CurrentEndTimeLast && TimeStepSys >= TimeStepSysLast) {
5433 97820 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5434 92929 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) continue;
5435 92929 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5436 0 : MultizoneSurfaceData(i).PrevOpeningstatus = MultizoneSurfaceData(i).OpeningStatus;
5437 0 : MultizoneSurfaceData(i).OpenFactorLast = MultizoneSurfaceData(i).OpenFactor;
5438 0 : if (MultizoneSurfaceData(i).OpenFactor > 0.0) {
5439 0 : MultizoneSurfaceData(i).OpenElapsedTime += (CurrentEndTime - CurrentEndTimeLast) * 60.0;
5440 0 : MultizoneSurfaceData(i).CloseElapsedTime = 0.0;
5441 : } else {
5442 0 : MultizoneSurfaceData(i).OpenElapsedTime = 0.0;
5443 0 : MultizoneSurfaceData(i).CloseElapsedTime += (CurrentEndTime - CurrentEndTimeLast) * 60.0;
5444 : }
5445 0 : int j = MultizoneSurfaceData(i).SurfNum;
5446 0 : OccupantVentilationControl(MultizoneSurfaceData(i).OccupantVentilationControlNum)
5447 0 : .calc(m_state,
5448 0 : m_state.dataSurface->Surface(j).Zone,
5449 0 : MultizoneSurfaceData(i).OpenElapsedTime,
5450 0 : MultizoneSurfaceData(i).CloseElapsedTime,
5451 0 : MultizoneSurfaceData(i).OpeningStatus,
5452 0 : MultizoneSurfaceData(i).OpeningProbStatus,
5453 0 : MultizoneSurfaceData(i).ClosingProbStatus);
5454 0 : if (MultizoneSurfaceData(i).OpeningStatus == AirflowNetwork::OpenStatus::MinCheckForceOpen) {
5455 0 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).OpenFactorLast;
5456 : }
5457 0 : if (MultizoneSurfaceData(i).OpeningStatus == AirflowNetwork::OpenStatus::MinCheckForceClose) {
5458 0 : MultizoneSurfaceData(i).OpenFactor = 0.0;
5459 : }
5460 : }
5461 : }
5462 : }
5463 16855 : TimeStepSysLast = TimeStepSys;
5464 16855 : CurrentEndTimeLast = CurrentEndTime;
5465 16855 : }
5466 :
5467 24 : void Solver::allocate_and_initialize()
5468 : {
5469 :
5470 : // SUBROUTINE INFORMATION:
5471 : // AUTHOR Lixing Gu
5472 : // DATE WRITTEN Aug. 2003
5473 : // MODIFIED na
5474 : // RE-ENGINEERED na
5475 :
5476 : // PURPOSE OF THIS SUBROUTINE:
5477 : // This subroutine initializes variables and allocates dynamic arrays.
5478 :
5479 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5480 : int i;
5481 : int SurfNum;
5482 24 : auto &Zone(m_state.dataHeatBal->Zone);
5483 :
5484 24 : AirflowNetworkNodeSimu.allocate(AirflowNetworkNumOfNodes); // Node simulation variable in air distribution system
5485 24 : AirflowNetworkLinkSimu.allocate(AirflowNetworkNumOfLinks); // Link simulation variable in air distribution system
5486 24 : linkReport.allocate(AirflowNetworkNumOfLinks); // Report link simulation variable in air distribution system
5487 :
5488 27 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5489 7 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
5490 4 : nodeReport.allocate(AirflowNetworkNumOfZones);
5491 4 : linkReport1.allocate(AirflowNetworkNumOfSurfaces);
5492 4 : break;
5493 : }
5494 : }
5495 :
5496 24 : MA.allocate(AirflowNetworkNumOfNodes * AirflowNetworkNumOfNodes);
5497 24 : MV.allocate(AirflowNetworkNumOfNodes);
5498 24 : IVEC.allocate(AirflowNetworkNumOfNodes + 20);
5499 :
5500 24 : AirflowNetworkReportData.allocate(m_state.dataGlobal->NumOfZones); // Report variables
5501 24 : AirflowNetworkZnRpt.allocate(m_state.dataGlobal->NumOfZones); // Report variables
5502 :
5503 24 : ANZT.allocate(m_state.dataGlobal->NumOfZones); // Local zone air temperature for rollback use
5504 24 : ANZW.allocate(m_state.dataGlobal->NumOfZones); // Local zone humidity ratio for rollback use
5505 24 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5506 0 : ANCO.allocate(m_state.dataGlobal->NumOfZones); // Local zone CO2 for rollback use
5507 24 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5508 0 : ANGC.allocate(m_state.dataGlobal->NumOfZones); // Local zone generic contaminant for rollback use
5509 24 : allocate();
5510 :
5511 24 : bool OnOffFanFlag = false;
5512 31 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5513 7 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
5514 4 : OnOffFanFlag = true;
5515 : }
5516 : }
5517 :
5518 : // CurrentModuleObject='AirflowNetwork Simulations'
5519 287 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5520 526 : SetupOutputVariable(m_state,
5521 : "AFN Node Temperature",
5522 : Constant::Units::C,
5523 263 : AirflowNetworkNodeSimu(i).TZ,
5524 : OutputProcessor::TimeStepType::System,
5525 : OutputProcessor::StoreType::Average,
5526 263 : AirflowNetworkNodeData(i).Name);
5527 526 : SetupOutputVariable(m_state,
5528 : "AFN Node Humidity Ratio",
5529 : Constant::Units::kgWater_kgDryAir,
5530 263 : AirflowNetworkNodeSimu(i).WZ,
5531 : OutputProcessor::TimeStepType::System,
5532 : OutputProcessor::StoreType::Average,
5533 263 : AirflowNetworkNodeData(i).Name);
5534 263 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5535 0 : SetupOutputVariable(m_state,
5536 : "AFN Node CO2 Concentration",
5537 : Constant::Units::ppm,
5538 0 : AirflowNetworkNodeSimu(i).CO2Z,
5539 : OutputProcessor::TimeStepType::System,
5540 : OutputProcessor::StoreType::Average,
5541 0 : AirflowNetworkNodeData(i).Name);
5542 : }
5543 263 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5544 0 : SetupOutputVariable(m_state,
5545 : "AFN Node Generic Air Contaminant Concentration",
5546 : Constant::Units::ppm,
5547 0 : AirflowNetworkNodeSimu(i).GCZ,
5548 : OutputProcessor::TimeStepType::System,
5549 : OutputProcessor::StoreType::Average,
5550 0 : AirflowNetworkNodeData(i).Name);
5551 : }
5552 263 : if (!(supplyFanType == HVAC::FanType::OnOff && i <= AirflowNetworkNumOfZones)) {
5553 498 : SetupOutputVariable(m_state,
5554 : "AFN Node Total Pressure",
5555 : Constant::Units::Pa,
5556 249 : AirflowNetworkNodeSimu(i).PZ,
5557 : OutputProcessor::TimeStepType::System,
5558 : OutputProcessor::StoreType::Average,
5559 249 : AirflowNetworkNodeData(i).Name);
5560 : }
5561 263 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
5562 178 : SetupOutputVariable(m_state,
5563 : "AFN Node Wind Pressure",
5564 : Constant::Units::Pa,
5565 89 : AirflowNetworkNodeSimu(i).PZ,
5566 : OutputProcessor::TimeStepType::System,
5567 : OutputProcessor::StoreType::Average,
5568 89 : AirflowNetworkNodeData(i).Name);
5569 : }
5570 : }
5571 :
5572 328 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
5573 304 : if (!(supplyFanType == HVAC::FanType::OnOff && i <= AirflowNetworkNumOfSurfaces)) {
5574 504 : SetupOutputVariable(m_state,
5575 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
5576 : Constant::Units::kg_s,
5577 252 : linkReport(i).FLOW,
5578 : OutputProcessor::TimeStepType::System,
5579 : OutputProcessor::StoreType::Average,
5580 252 : AirflowNetworkLinkageData(i).Name);
5581 504 : SetupOutputVariable(m_state,
5582 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
5583 : Constant::Units::kg_s,
5584 252 : linkReport(i).FLOW2,
5585 : OutputProcessor::TimeStepType::System,
5586 : OutputProcessor::StoreType::Average,
5587 252 : AirflowNetworkLinkageData(i).Name);
5588 504 : SetupOutputVariable(m_state,
5589 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
5590 : Constant::Units::m3_s,
5591 252 : linkReport(i).VolFLOW,
5592 : OutputProcessor::TimeStepType::System,
5593 : OutputProcessor::StoreType::Average,
5594 252 : AirflowNetworkLinkageData(i).Name);
5595 504 : SetupOutputVariable(m_state,
5596 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
5597 : Constant::Units::m3_s,
5598 252 : linkReport(i).VolFLOW2,
5599 : OutputProcessor::TimeStepType::System,
5600 : OutputProcessor::StoreType::Average,
5601 252 : AirflowNetworkLinkageData(i).Name);
5602 504 : SetupOutputVariable(m_state,
5603 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
5604 : Constant::Units::Pa,
5605 252 : AirflowNetworkLinkSimu(i).DP,
5606 : OutputProcessor::TimeStepType::System,
5607 : OutputProcessor::StoreType::Average,
5608 252 : AirflowNetworkLinkageData(i).Name);
5609 : }
5610 : }
5611 :
5612 169 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5613 145 : if (AirflowNetworkLinkageData(i).element == nullptr) {
5614 : // This is not great
5615 0 : continue;
5616 : }
5617 145 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::DOP ||
5618 266 : AirflowNetworkLinkageData(i).element->type() == ComponentType::SOP ||
5619 121 : AirflowNetworkLinkageData(i).element->type() == ComponentType::HOP) {
5620 24 : SurfNum = MultizoneSurfaceData(i).SurfNum;
5621 48 : SetupOutputVariable(m_state,
5622 : "AFN Surface Venting Window or Door Opening Factor",
5623 : Constant::Units::None,
5624 24 : MultizoneSurfaceData(i).OpenFactor,
5625 : OutputProcessor::TimeStepType::System,
5626 : OutputProcessor::StoreType::Average,
5627 24 : MultizoneSurfaceData(i).SurfName);
5628 24 : if (m_state.dataGlobal->AnyEnergyManagementSystemInModel) {
5629 0 : SetupEMSActuator(m_state,
5630 : "AirFlow Network Window/Door Opening",
5631 0 : MultizoneSurfaceData(i).SurfName,
5632 : "Venting Opening Factor",
5633 : "[Fraction]",
5634 0 : MultizoneSurfaceData(i).EMSOpenFactorActuated,
5635 0 : MultizoneSurfaceData(i).EMSOpenFactor);
5636 : }
5637 48 : SetupOutputVariable(m_state,
5638 : "AFN Surface Venting Window or Door Opening Modulation Multiplier",
5639 : Constant::Units::None,
5640 24 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum),
5641 : OutputProcessor::TimeStepType::System,
5642 : OutputProcessor::StoreType::Average,
5643 24 : m_state.dataSurface->Surface(SurfNum).Name);
5644 48 : SetupOutputVariable(m_state,
5645 : "AFN Surface Venting Inside Setpoint Temperature",
5646 : Constant::Units::C,
5647 24 : m_state.dataSurface->SurfWinInsideTempForVentingRep(SurfNum),
5648 : OutputProcessor::TimeStepType::System,
5649 : OutputProcessor::StoreType::Average,
5650 24 : m_state.dataSurface->Surface(SurfNum).Name);
5651 48 : SetupOutputVariable(m_state,
5652 : "AFN Surface Venting Availability Status",
5653 : Constant::Units::None,
5654 24 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum),
5655 : OutputProcessor::TimeStepType::System,
5656 : OutputProcessor::StoreType::Average,
5657 24 : m_state.dataSurface->Surface(SurfNum).Name);
5658 24 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5659 0 : SetupOutputVariable(m_state,
5660 : "AFN Surface Venting Window or Door Opening Factor at Previous Time Step",
5661 : Constant::Units::None,
5662 0 : MultizoneSurfaceData(i).OpenFactorLast,
5663 : OutputProcessor::TimeStepType::System,
5664 : OutputProcessor::StoreType::Average,
5665 0 : MultizoneSurfaceData(i).SurfName);
5666 0 : SetupOutputVariable(m_state,
5667 : "AFN Surface Opening Elapsed Time",
5668 : Constant::Units::min,
5669 0 : MultizoneSurfaceData(i).OpenElapsedTime,
5670 : OutputProcessor::TimeStepType::System,
5671 : OutputProcessor::StoreType::Average,
5672 0 : MultizoneSurfaceData(i).SurfName);
5673 0 : SetupOutputVariable(m_state,
5674 : "AFN Surface Closing Elapsed Time",
5675 : Constant::Units::min,
5676 0 : MultizoneSurfaceData(i).CloseElapsedTime,
5677 : OutputProcessor::TimeStepType::System,
5678 : OutputProcessor::StoreType::Average,
5679 0 : MultizoneSurfaceData(i).SurfName);
5680 0 : SetupOutputVariable(m_state,
5681 : "AFN Surface Opening Status at Previous Time Step",
5682 : Constant::Units::None,
5683 0 : MultizoneSurfaceData(i).PrevOpeningstatus,
5684 : OutputProcessor::TimeStepType::System,
5685 : OutputProcessor::StoreType::Average,
5686 0 : MultizoneSurfaceData(i).SurfName);
5687 0 : SetupOutputVariable(m_state,
5688 : "AFN Surface Opening Status",
5689 : Constant::Units::None,
5690 0 : MultizoneSurfaceData(i).OpeningStatus,
5691 : OutputProcessor::TimeStepType::System,
5692 : OutputProcessor::StoreType::Average,
5693 0 : MultizoneSurfaceData(i).SurfName);
5694 0 : SetupOutputVariable(m_state,
5695 : "AFN Surface Opening Probability Status",
5696 : Constant::Units::None,
5697 0 : MultizoneSurfaceData(i).OpeningProbStatus,
5698 : OutputProcessor::TimeStepType::System,
5699 : OutputProcessor::StoreType::Average,
5700 0 : MultizoneSurfaceData(i).SurfName);
5701 0 : SetupOutputVariable(m_state,
5702 : "AFN Surface Closing Probability Status",
5703 : Constant::Units::None,
5704 0 : MultizoneSurfaceData(i).ClosingProbStatus,
5705 : OutputProcessor::TimeStepType::System,
5706 : OutputProcessor::StoreType::Average,
5707 0 : MultizoneSurfaceData(i).SurfName);
5708 : }
5709 : }
5710 : }
5711 :
5712 78 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5713 : // Multizone losses due to force air systems
5714 108 : SetupOutputVariable(m_state,
5715 : "AFN Zone Infiltration Sensible Heat Gain Rate",
5716 : Constant::Units::W,
5717 54 : AirflowNetworkReportData(i).MultiZoneInfiSenGainW,
5718 : OutputProcessor::TimeStepType::System,
5719 : OutputProcessor::StoreType::Average,
5720 54 : Zone(i).Name);
5721 108 : SetupOutputVariable(m_state,
5722 : "AFN Zone Infiltration Sensible Heat Gain Energy",
5723 : Constant::Units::J,
5724 54 : AirflowNetworkReportData(i).MultiZoneInfiSenGainJ,
5725 : OutputProcessor::TimeStepType::System,
5726 : OutputProcessor::StoreType::Sum,
5727 54 : Zone(i).Name);
5728 108 : SetupOutputVariable(m_state,
5729 : "AFN Zone Ventilation Sensible Heat Gain Rate",
5730 : Constant::Units::W,
5731 54 : AirflowNetworkReportData(i).MultiZoneVentSenGainW,
5732 : OutputProcessor::TimeStepType::System,
5733 : OutputProcessor::StoreType::Average,
5734 54 : Zone(i).Name);
5735 108 : SetupOutputVariable(m_state,
5736 : "AFN Zone Ventilation Sensible Heat Gain Energy",
5737 : Constant::Units::J,
5738 54 : AirflowNetworkReportData(i).MultiZoneVentSenGainJ,
5739 : OutputProcessor::TimeStepType::System,
5740 : OutputProcessor::StoreType::Sum,
5741 54 : Zone(i).Name);
5742 108 : SetupOutputVariable(m_state,
5743 : "AFN Zone Mixing Sensible Heat Gain Rate",
5744 : Constant::Units::W,
5745 54 : AirflowNetworkReportData(i).MultiZoneMixSenGainW,
5746 : OutputProcessor::TimeStepType::System,
5747 : OutputProcessor::StoreType::Average,
5748 54 : Zone(i).Name);
5749 108 : SetupOutputVariable(m_state,
5750 : "AFN Zone Mixing Sensible Heat Gain Energy",
5751 : Constant::Units::J,
5752 54 : AirflowNetworkReportData(i).MultiZoneMixSenGainJ,
5753 : OutputProcessor::TimeStepType::System,
5754 : OutputProcessor::StoreType::Sum,
5755 54 : Zone(i).Name);
5756 108 : SetupOutputVariable(m_state,
5757 : "AFN Zone Infiltration Sensible Heat Loss Rate",
5758 : Constant::Units::W,
5759 54 : AirflowNetworkReportData(i).MultiZoneInfiSenLossW,
5760 : OutputProcessor::TimeStepType::System,
5761 : OutputProcessor::StoreType::Average,
5762 54 : Zone(i).Name);
5763 108 : SetupOutputVariable(m_state,
5764 : "AFN Zone Infiltration Sensible Heat Loss Energy",
5765 : Constant::Units::J,
5766 54 : AirflowNetworkReportData(i).MultiZoneInfiSenLossJ,
5767 : OutputProcessor::TimeStepType::System,
5768 : OutputProcessor::StoreType::Sum,
5769 54 : Zone(i).Name);
5770 108 : SetupOutputVariable(m_state,
5771 : "AFN Zone Ventilation Sensible Heat Loss Rate",
5772 : Constant::Units::W,
5773 54 : AirflowNetworkReportData(i).MultiZoneVentSenLossW,
5774 : OutputProcessor::TimeStepType::System,
5775 : OutputProcessor::StoreType::Average,
5776 54 : Zone(i).Name);
5777 108 : SetupOutputVariable(m_state,
5778 : "AFN Zone Ventilation Sensible Heat Loss Energy",
5779 : Constant::Units::J,
5780 54 : AirflowNetworkReportData(i).MultiZoneVentSenLossJ,
5781 : OutputProcessor::TimeStepType::System,
5782 : OutputProcessor::StoreType::Sum,
5783 54 : Zone(i).Name);
5784 108 : SetupOutputVariable(m_state,
5785 : "AFN Zone Mixing Sensible Heat Loss Rate",
5786 : Constant::Units::W,
5787 54 : AirflowNetworkReportData(i).MultiZoneMixSenLossW,
5788 : OutputProcessor::TimeStepType::System,
5789 : OutputProcessor::StoreType::Average,
5790 54 : Zone(i).Name);
5791 108 : SetupOutputVariable(m_state,
5792 : "AFN Zone Mixing Sensible Heat Loss Energy",
5793 : Constant::Units::J,
5794 54 : AirflowNetworkReportData(i).MultiZoneMixSenLossJ,
5795 : OutputProcessor::TimeStepType::System,
5796 : OutputProcessor::StoreType::Sum,
5797 54 : Zone(i).Name);
5798 108 : SetupOutputVariable(m_state,
5799 : "AFN Zone Infiltration Latent Heat Gain Rate",
5800 : Constant::Units::W,
5801 54 : AirflowNetworkReportData(i).MultiZoneInfiLatGainW,
5802 : OutputProcessor::TimeStepType::System,
5803 : OutputProcessor::StoreType::Average,
5804 54 : Zone(i).Name);
5805 108 : SetupOutputVariable(m_state,
5806 : "AFN Zone Infiltration Latent Heat Gain Energy",
5807 : Constant::Units::J,
5808 54 : AirflowNetworkReportData(i).MultiZoneInfiLatGainJ,
5809 : OutputProcessor::TimeStepType::System,
5810 : OutputProcessor::StoreType::Sum,
5811 54 : Zone(i).Name);
5812 108 : SetupOutputVariable(m_state,
5813 : "AFN Zone Infiltration Latent Heat Loss Rate",
5814 : Constant::Units::W,
5815 54 : AirflowNetworkReportData(i).MultiZoneInfiLatLossW,
5816 : OutputProcessor::TimeStepType::System,
5817 : OutputProcessor::StoreType::Average,
5818 54 : Zone(i).Name);
5819 108 : SetupOutputVariable(m_state,
5820 : "AFN Zone Infiltration Latent Heat Loss Energy",
5821 : Constant::Units::J,
5822 54 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ,
5823 : OutputProcessor::TimeStepType::System,
5824 : OutputProcessor::StoreType::Sum,
5825 54 : Zone(i).Name);
5826 108 : SetupOutputVariable(m_state,
5827 : "AFN Zone Ventilation Latent Heat Gain Rate",
5828 : Constant::Units::W,
5829 54 : AirflowNetworkReportData(i).MultiZoneVentLatGainW,
5830 : OutputProcessor::TimeStepType::System,
5831 : OutputProcessor::StoreType::Average,
5832 54 : Zone(i).Name);
5833 108 : SetupOutputVariable(m_state,
5834 : "AFN Zone Ventilation Latent Heat Gain Energy",
5835 : Constant::Units::J,
5836 54 : AirflowNetworkReportData(i).MultiZoneVentLatGainJ,
5837 : OutputProcessor::TimeStepType::System,
5838 : OutputProcessor::StoreType::Sum,
5839 54 : Zone(i).Name);
5840 108 : SetupOutputVariable(m_state,
5841 : "AFN Zone Ventilation Latent Heat Loss Rate",
5842 : Constant::Units::W,
5843 54 : AirflowNetworkReportData(i).MultiZoneVentLatLossW,
5844 : OutputProcessor::TimeStepType::System,
5845 : OutputProcessor::StoreType::Average,
5846 54 : Zone(i).Name);
5847 108 : SetupOutputVariable(m_state,
5848 : "AFN Zone Ventilation Latent Heat Loss Energy",
5849 : Constant::Units::J,
5850 54 : AirflowNetworkReportData(i).MultiZoneVentLatLossJ,
5851 : OutputProcessor::TimeStepType::System,
5852 : OutputProcessor::StoreType::Sum,
5853 54 : Zone(i).Name);
5854 108 : SetupOutputVariable(m_state,
5855 : "AFN Zone Mixing Latent Heat Gain Rate",
5856 : Constant::Units::W,
5857 54 : AirflowNetworkReportData(i).MultiZoneMixLatGainW,
5858 : OutputProcessor::TimeStepType::System,
5859 : OutputProcessor::StoreType::Average,
5860 54 : Zone(i).Name);
5861 108 : SetupOutputVariable(m_state,
5862 : "AFN Zone Mixing Latent Heat Gain Energy",
5863 : Constant::Units::J,
5864 54 : AirflowNetworkReportData(i).MultiZoneMixLatGainJ,
5865 : OutputProcessor::TimeStepType::System,
5866 : OutputProcessor::StoreType::Sum,
5867 54 : Zone(i).Name);
5868 108 : SetupOutputVariable(m_state,
5869 : "AFN Zone Mixing Latent Heat Loss Rate",
5870 : Constant::Units::W,
5871 54 : AirflowNetworkReportData(i).MultiZoneMixLatLossW,
5872 : OutputProcessor::TimeStepType::System,
5873 : OutputProcessor::StoreType::Average,
5874 54 : Zone(i).Name);
5875 108 : SetupOutputVariable(m_state,
5876 : "AFN Zone Mixing Latent Heat Loss Energy",
5877 : Constant::Units::J,
5878 54 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ,
5879 : OutputProcessor::TimeStepType::System,
5880 : OutputProcessor::StoreType::Sum,
5881 54 : Zone(i).Name);
5882 : // Supply leak losses due to force air systems
5883 108 : SetupOutputVariable(m_state,
5884 : "AFN Zone Duct Leaked Air Sensible Heat Gain Rate",
5885 : Constant::Units::W,
5886 54 : AirflowNetworkReportData(i).LeakSenGainW,
5887 : OutputProcessor::TimeStepType::System,
5888 : OutputProcessor::StoreType::Average,
5889 54 : Zone(i).Name);
5890 108 : SetupOutputVariable(m_state,
5891 : "AFN Zone Duct Leaked Air Sensible Heat Gain Energy",
5892 : Constant::Units::J,
5893 54 : AirflowNetworkReportData(i).LeakSenGainJ,
5894 : OutputProcessor::TimeStepType::System,
5895 : OutputProcessor::StoreType::Sum,
5896 54 : Zone(i).Name);
5897 108 : SetupOutputVariable(m_state,
5898 : "AFN Zone Duct Leaked Air Sensible Heat Loss Rate",
5899 : Constant::Units::W,
5900 54 : AirflowNetworkReportData(i).LeakSenLossW,
5901 : OutputProcessor::TimeStepType::System,
5902 : OutputProcessor::StoreType::Average,
5903 54 : Zone(i).Name);
5904 108 : SetupOutputVariable(m_state,
5905 : "AFN Zone Duct Leaked Air Sensible Heat Loss Energy",
5906 : Constant::Units::J,
5907 54 : AirflowNetworkReportData(i).LeakSenLossJ,
5908 : OutputProcessor::TimeStepType::System,
5909 : OutputProcessor::StoreType::Sum,
5910 54 : Zone(i).Name);
5911 108 : SetupOutputVariable(m_state,
5912 : "AFN Zone Duct Leaked Air Latent Heat Gain Rate",
5913 : Constant::Units::W,
5914 54 : AirflowNetworkReportData(i).LeakLatGainW,
5915 : OutputProcessor::TimeStepType::System,
5916 : OutputProcessor::StoreType::Average,
5917 54 : Zone(i).Name);
5918 108 : SetupOutputVariable(m_state,
5919 : "AFN Zone Duct Leaked Air Latent Heat Gain Energy",
5920 : Constant::Units::J,
5921 54 : AirflowNetworkReportData(i).LeakLatGainJ,
5922 : OutputProcessor::TimeStepType::System,
5923 : OutputProcessor::StoreType::Sum,
5924 54 : Zone(i).Name);
5925 108 : SetupOutputVariable(m_state,
5926 : "AFN Zone Duct Leaked Air Latent Heat Loss Rate",
5927 : Constant::Units::W,
5928 54 : AirflowNetworkReportData(i).LeakLatLossW,
5929 : OutputProcessor::TimeStepType::System,
5930 : OutputProcessor::StoreType::Average,
5931 54 : Zone(i).Name);
5932 108 : SetupOutputVariable(m_state,
5933 : "AFN Zone Duct Leaked Air Latent Heat Loss Energy",
5934 : Constant::Units::J,
5935 54 : AirflowNetworkReportData(i).LeakLatLossJ,
5936 : OutputProcessor::TimeStepType::System,
5937 : OutputProcessor::StoreType::Sum,
5938 54 : Zone(i).Name);
5939 : // Conduction losses due to force air systems
5940 108 : SetupOutputVariable(m_state,
5941 : "AFN Zone Duct Conduction Sensible Heat Gain Rate",
5942 : Constant::Units::W,
5943 54 : AirflowNetworkReportData(i).CondSenGainW,
5944 : OutputProcessor::TimeStepType::System,
5945 : OutputProcessor::StoreType::Average,
5946 54 : Zone(i).Name);
5947 108 : SetupOutputVariable(m_state,
5948 : "AFN Zone Duct Conduction Sensible Heat Gain Energy",
5949 : Constant::Units::J,
5950 54 : AirflowNetworkReportData(i).CondSenGainJ,
5951 : OutputProcessor::TimeStepType::System,
5952 : OutputProcessor::StoreType::Sum,
5953 54 : Zone(i).Name);
5954 108 : SetupOutputVariable(m_state,
5955 : "AFN Zone Duct Conduction Sensible Heat Loss Rate",
5956 : Constant::Units::W,
5957 54 : AirflowNetworkReportData(i).CondSenLossW,
5958 : OutputProcessor::TimeStepType::System,
5959 : OutputProcessor::StoreType::Average,
5960 54 : Zone(i).Name);
5961 108 : SetupOutputVariable(m_state,
5962 : "AFN Zone Duct Conduction Sensible Heat Loss Energy",
5963 : Constant::Units::J,
5964 54 : AirflowNetworkReportData(i).CondSenLossJ,
5965 : OutputProcessor::TimeStepType::System,
5966 : OutputProcessor::StoreType::Sum,
5967 54 : Zone(i).Name);
5968 108 : SetupOutputVariable(m_state,
5969 : "AFN Zone Duct Diffusion Latent Heat Gain Rate",
5970 : Constant::Units::W,
5971 54 : AirflowNetworkReportData(i).DiffLatGainW,
5972 : OutputProcessor::TimeStepType::System,
5973 : OutputProcessor::StoreType::Average,
5974 54 : Zone(i).Name);
5975 108 : SetupOutputVariable(m_state,
5976 : "AFN Zone Duct Diffusion Latent Heat Gain Energy",
5977 : Constant::Units::J,
5978 54 : AirflowNetworkReportData(i).DiffLatGainJ,
5979 : OutputProcessor::TimeStepType::System,
5980 : OutputProcessor::StoreType::Sum,
5981 54 : Zone(i).Name);
5982 108 : SetupOutputVariable(m_state,
5983 : "AFN Zone Duct Diffusion Latent Heat Loss Rate",
5984 : Constant::Units::W,
5985 54 : AirflowNetworkReportData(i).DiffLatLossW,
5986 : OutputProcessor::TimeStepType::System,
5987 : OutputProcessor::StoreType::Average,
5988 54 : Zone(i).Name);
5989 108 : SetupOutputVariable(m_state,
5990 : "AFN Zone Duct Diffusion Latent Heat Loss Energy",
5991 : Constant::Units::J,
5992 54 : AirflowNetworkReportData(i).DiffLatLossJ,
5993 : OutputProcessor::TimeStepType::System,
5994 : OutputProcessor::StoreType::Sum,
5995 54 : Zone(i).Name);
5996 : // Radiation losses due to forced air systems
5997 108 : SetupOutputVariable(m_state,
5998 : "AFN Zone Duct Radiation Heat Gain Rate",
5999 : Constant::Units::W,
6000 54 : AirflowNetworkReportData(i).RadGainW,
6001 : OutputProcessor::TimeStepType::System,
6002 : OutputProcessor::StoreType::Average,
6003 54 : Zone(i).Name);
6004 108 : SetupOutputVariable(m_state,
6005 : "AFN Zone Duct Radiation Sensible Heat Gain Energy",
6006 : Constant::Units::J,
6007 54 : AirflowNetworkReportData(i).RadGainJ,
6008 : OutputProcessor::TimeStepType::System,
6009 : OutputProcessor::StoreType::Sum,
6010 54 : Zone(i).Name);
6011 108 : SetupOutputVariable(m_state,
6012 : "AFN Zone Duct Radiation Heat Loss Rate",
6013 : Constant::Units::W,
6014 54 : AirflowNetworkReportData(i).RadLossW,
6015 : OutputProcessor::TimeStepType::System,
6016 : OutputProcessor::StoreType::Average,
6017 54 : Zone(i).Name);
6018 108 : SetupOutputVariable(m_state,
6019 : "AFN Zone Duct Radiation Sensible Heat Loss Energy",
6020 : Constant::Units::J,
6021 54 : AirflowNetworkReportData(i).RadLossJ,
6022 : OutputProcessor::TimeStepType::System,
6023 : OutputProcessor::StoreType::Sum,
6024 54 : Zone(i).Name);
6025 : // Total losses due to force air systems
6026 108 : SetupOutputVariable(m_state,
6027 : "AFN Distribution Sensible Heat Gain Rate",
6028 : Constant::Units::W,
6029 54 : AirflowNetworkReportData(i).TotalSenGainW,
6030 : OutputProcessor::TimeStepType::System,
6031 : OutputProcessor::StoreType::Average,
6032 54 : Zone(i).Name);
6033 108 : SetupOutputVariable(m_state,
6034 : "AFN Distribution Sensible Heat Gain Energy",
6035 : Constant::Units::J,
6036 54 : AirflowNetworkReportData(i).TotalSenGainJ,
6037 : OutputProcessor::TimeStepType::System,
6038 : OutputProcessor::StoreType::Sum,
6039 54 : Zone(i).Name);
6040 108 : SetupOutputVariable(m_state,
6041 : "AFN Distribution Sensible Heat Loss Rate",
6042 : Constant::Units::W,
6043 54 : AirflowNetworkReportData(i).TotalSenLossW,
6044 : OutputProcessor::TimeStepType::System,
6045 : OutputProcessor::StoreType::Average,
6046 54 : Zone(i).Name);
6047 108 : SetupOutputVariable(m_state,
6048 : "AFN Distribution Sensible Heat Loss Energy",
6049 : Constant::Units::J,
6050 54 : AirflowNetworkReportData(i).TotalSenLossJ,
6051 : OutputProcessor::TimeStepType::System,
6052 : OutputProcessor::StoreType::Sum,
6053 54 : Zone(i).Name);
6054 108 : SetupOutputVariable(m_state,
6055 : "AFN Distribution Latent Heat Gain Rate",
6056 : Constant::Units::W,
6057 54 : AirflowNetworkReportData(i).TotalLatGainW,
6058 : OutputProcessor::TimeStepType::System,
6059 : OutputProcessor::StoreType::Average,
6060 54 : Zone(i).Name);
6061 108 : SetupOutputVariable(m_state,
6062 : "AFN Distribution Latent Heat Gain Energy",
6063 : Constant::Units::J,
6064 54 : AirflowNetworkReportData(i).TotalLatGainJ,
6065 : OutputProcessor::TimeStepType::System,
6066 : OutputProcessor::StoreType::Sum,
6067 54 : Zone(i).Name);
6068 108 : SetupOutputVariable(m_state,
6069 : "AFN Distribution Latent Heat Loss Rate",
6070 : Constant::Units::W,
6071 54 : AirflowNetworkReportData(i).TotalLatLossW,
6072 : OutputProcessor::TimeStepType::System,
6073 : OutputProcessor::StoreType::Average,
6074 54 : Zone(i).Name);
6075 108 : SetupOutputVariable(m_state,
6076 : "AFN Distribution Latent Heat Loss Energy",
6077 : Constant::Units::J,
6078 54 : AirflowNetworkReportData(i).TotalLatLossJ,
6079 : OutputProcessor::TimeStepType::System,
6080 : OutputProcessor::StoreType::Sum,
6081 54 : Zone(i).Name);
6082 : }
6083 :
6084 78 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
6085 108 : SetupOutputVariable(m_state,
6086 : "AFN Zone Infiltration Volume",
6087 : Constant::Units::m3,
6088 54 : AirflowNetworkZnRpt(i).InfilVolume,
6089 : OutputProcessor::TimeStepType::System,
6090 : OutputProcessor::StoreType::Sum,
6091 54 : Zone(i).Name);
6092 108 : SetupOutputVariable(m_state,
6093 : "AFN Zone Infiltration Mass",
6094 : Constant::Units::kg,
6095 54 : AirflowNetworkZnRpt(i).InfilMass,
6096 : OutputProcessor::TimeStepType::System,
6097 : OutputProcessor::StoreType::Sum,
6098 54 : Zone(i).Name);
6099 108 : SetupOutputVariable(m_state,
6100 : "AFN Zone Infiltration Air Change Rate",
6101 : Constant::Units::ach,
6102 54 : AirflowNetworkZnRpt(i).InfilAirChangeRate,
6103 : OutputProcessor::TimeStepType::System,
6104 : OutputProcessor::StoreType::Average,
6105 54 : Zone(i).Name);
6106 108 : SetupOutputVariable(m_state,
6107 : "AFN Zone Ventilation Volume",
6108 : Constant::Units::m3,
6109 54 : AirflowNetworkZnRpt(i).VentilVolume,
6110 : OutputProcessor::TimeStepType::System,
6111 : OutputProcessor::StoreType::Sum,
6112 54 : Zone(i).Name);
6113 108 : SetupOutputVariable(m_state,
6114 : "AFN Zone Ventilation Mass",
6115 : Constant::Units::kg,
6116 54 : AirflowNetworkZnRpt(i).VentilMass,
6117 : OutputProcessor::TimeStepType::System,
6118 : OutputProcessor::StoreType::Sum,
6119 54 : Zone(i).Name);
6120 108 : SetupOutputVariable(m_state,
6121 : "AFN Zone Ventilation Air Change Rate",
6122 : Constant::Units::ach,
6123 54 : AirflowNetworkZnRpt(i).VentilAirChangeRate,
6124 : OutputProcessor::TimeStepType::System,
6125 : OutputProcessor::StoreType::Average,
6126 54 : Zone(i).Name);
6127 108 : SetupOutputVariable(m_state,
6128 : "AFN Zone Mixing Volume",
6129 : Constant::Units::m3,
6130 54 : AirflowNetworkZnRpt(i).MixVolume,
6131 : OutputProcessor::TimeStepType::System,
6132 : OutputProcessor::StoreType::Sum,
6133 54 : Zone(i).Name);
6134 108 : SetupOutputVariable(m_state,
6135 : "AFN Zone Mixing Mass",
6136 : Constant::Units::kg,
6137 54 : AirflowNetworkZnRpt(i).MixMass,
6138 : OutputProcessor::TimeStepType::System,
6139 : OutputProcessor::StoreType::Sum,
6140 54 : Zone(i).Name);
6141 :
6142 108 : SetupOutputVariable(m_state,
6143 : "AFN Zone Exfiltration Heat Transfer Rate",
6144 : Constant::Units::W,
6145 54 : AirflowNetworkZnRpt(i).ExfilTotalLoss,
6146 : OutputProcessor::TimeStepType::System,
6147 : OutputProcessor::StoreType::Average,
6148 54 : Zone(i).Name);
6149 108 : SetupOutputVariable(m_state,
6150 : "AFN Zone Exfiltration Sensible Heat Transfer Rate",
6151 : Constant::Units::W,
6152 54 : AirflowNetworkZnRpt(i).ExfilSensiLoss,
6153 : OutputProcessor::TimeStepType::System,
6154 : OutputProcessor::StoreType::Average,
6155 54 : Zone(i).Name);
6156 108 : SetupOutputVariable(m_state,
6157 : "AFN Zone Exfiltration Latent Heat Transfer Rate",
6158 : Constant::Units::W,
6159 54 : AirflowNetworkZnRpt(i).ExfilLatentLoss,
6160 : OutputProcessor::TimeStepType::System,
6161 : OutputProcessor::StoreType::Average,
6162 54 : Zone(i).Name);
6163 : }
6164 :
6165 24 : if (OnOffFanFlag) {
6166 18 : for (i = 1; i <= AirflowNetworkNumOfZones; ++i) {
6167 28 : SetupOutputVariable(m_state,
6168 : "AFN Zone Average Pressure",
6169 : Constant::Units::Pa,
6170 14 : nodeReport(i).PZ,
6171 : OutputProcessor::TimeStepType::System,
6172 : OutputProcessor::StoreType::Average,
6173 14 : Zone(i).Name);
6174 28 : SetupOutputVariable(m_state,
6175 : "AFN Zone On Cycle Pressure",
6176 : Constant::Units::Pa,
6177 14 : nodeReport(i).PZON,
6178 : OutputProcessor::TimeStepType::System,
6179 : OutputProcessor::StoreType::Average,
6180 14 : Zone(i).Name);
6181 28 : SetupOutputVariable(m_state,
6182 : "AFN Zone Off Cycle Pressure",
6183 : Constant::Units::Pa,
6184 14 : nodeReport(i).PZOFF,
6185 : OutputProcessor::TimeStepType::System,
6186 : OutputProcessor::StoreType::Average,
6187 14 : Zone(i).Name);
6188 : }
6189 56 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6190 104 : SetupOutputVariable(m_state,
6191 : "AFN Linkage Node 1 to 2 Average Mass Flow Rate",
6192 : Constant::Units::kg_s,
6193 52 : linkReport1(i).FLOW,
6194 : OutputProcessor::TimeStepType::System,
6195 : OutputProcessor::StoreType::Average,
6196 52 : MultizoneSurfaceData(i).SurfName);
6197 104 : SetupOutputVariable(m_state,
6198 : "AFN Linkage Node 2 to 1 Average Mass Flow Rate",
6199 : Constant::Units::kg_s,
6200 52 : linkReport1(i).FLOW2,
6201 : OutputProcessor::TimeStepType::System,
6202 : OutputProcessor::StoreType::Average,
6203 52 : MultizoneSurfaceData(i).SurfName);
6204 104 : SetupOutputVariable(m_state,
6205 : "AFN Linkage Node 1 to 2 Average Volume Flow Rate",
6206 : Constant::Units::m3_s,
6207 52 : linkReport1(i).VolFLOW,
6208 : OutputProcessor::TimeStepType::System,
6209 : OutputProcessor::StoreType::Average,
6210 52 : MultizoneSurfaceData(i).SurfName);
6211 104 : SetupOutputVariable(m_state,
6212 : "AFN Linkage Node 2 to 1 Average Volume Flow Rate",
6213 : Constant::Units::m3_s,
6214 52 : linkReport1(i).VolFLOW2,
6215 : OutputProcessor::TimeStepType::System,
6216 : OutputProcessor::StoreType::Average,
6217 52 : MultizoneSurfaceData(i).SurfName);
6218 104 : SetupOutputVariable(m_state,
6219 : "AFN Surface Average Pressure Difference",
6220 : Constant::Units::Pa,
6221 52 : linkReport1(i).DP,
6222 : OutputProcessor::TimeStepType::System,
6223 : OutputProcessor::StoreType::Average,
6224 52 : MultizoneSurfaceData(i).SurfName);
6225 104 : SetupOutputVariable(m_state,
6226 : "AFN Surface On Cycle Pressure Difference",
6227 : Constant::Units::Pa,
6228 52 : linkReport1(i).DPON,
6229 : OutputProcessor::TimeStepType::System,
6230 : OutputProcessor::StoreType::Average,
6231 52 : MultizoneSurfaceData(i).SurfName);
6232 104 : SetupOutputVariable(m_state,
6233 : "AFN Surface Off Cycle Pressure Difference",
6234 : Constant::Units::Pa,
6235 52 : linkReport1(i).DPOFF,
6236 : OutputProcessor::TimeStepType::System,
6237 : OutputProcessor::StoreType::Average,
6238 52 : MultizoneSurfaceData(i).SurfName);
6239 : }
6240 : }
6241 :
6242 : // Assign node reference height
6243 287 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
6244 263 : if (!simulation_control.temperature_height_dependence) AirflowNetworkNodeData(i).NodeHeight = 0.0;
6245 263 : int ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
6246 263 : if (ZoneNum > 0) {
6247 55 : if (m_state.dataSurface->WorldCoordSystem) {
6248 43 : AirflowNetworkNodeData(i).NodeHeight = 0.0;
6249 : } else {
6250 12 : AirflowNetworkNodeData(i).NodeHeight = Zone(ZoneNum).OriginZ;
6251 : }
6252 : }
6253 : }
6254 24 : }
6255 :
6256 16865 : void Solver::calculate_balance()
6257 : {
6258 : // SUBROUTINE INFORMATION:
6259 : // AUTHOR Lixing Gu
6260 : // DATE WRITTEN Oct. 2005
6261 : // MODIFIED na
6262 : // RE-ENGINEERED na
6263 :
6264 : // PURPOSE OF THIS SUBROUTINE:
6265 : // This subroutine performs simulations of nodal pressures and linkage airflows.
6266 :
6267 : // Using/Aliasing
6268 : using General::SolveRoot;
6269 : using HVAC::VerySmallMassFlow;
6270 :
6271 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6272 : int i;
6273 : int j;
6274 : int n;
6275 : int NodeNum;
6276 : Real64 GlobalOpenFactor;
6277 : Real64 ZonePressure1;
6278 : Real64 ZonePressure2;
6279 : Real64 PressureSet;
6280 : Real64 LocalAzimuth;
6281 : Real64 LocalWindSpeed;
6282 : Real64 LocalWindDir;
6283 : Real64 LocalHumRat;
6284 : Real64 LocalDryBulb;
6285 16865 : Array1D<Real64> Par; // Pressure setpoint
6286 16865 : Real64 constexpr ErrorToler(0.00001);
6287 16865 : int constexpr MaxIte(20);
6288 : int SolFla;
6289 : Real64 MinExhaustMassFlowrate;
6290 : Real64 MaxExhaustMassFlowrate;
6291 : Real64 MinReliefMassFlowrate;
6292 : Real64 MaxReliefMassFlowrate;
6293 : int AirLoopNum;
6294 :
6295 16865 : auto &Node(m_state.dataLoopNodes->Node);
6296 :
6297 : // Validate supply and return connections
6298 16865 : if (CalcAirflowNetworkAirBalanceOneTimeFlag) {
6299 11 : CalcAirflowNetworkAirBalanceOneTimeFlag = false;
6300 11 : if (CalcAirflowNetworkAirBalanceErrorsFound) {
6301 0 : ShowFatalError(m_state, "GetAirflowNetworkInput: Program terminates for preceding reason(s).");
6302 : }
6303 : }
6304 :
6305 508909 : for (n = 1; n <= ActualNumOfNodes; ++n) {
6306 492044 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
6307 205511 : AirflowNetworkNodeSimu(n).PZ = 0.0;
6308 : } else {
6309 : // Assigning ambient conditions to external nodes
6310 286533 : i = AirflowNetworkNodeData(n).ExtNodeNum;
6311 286533 : if (i > 0) {
6312 286533 : AirflowNetworkNodeSimu(n).TZ = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(n).NodeHeight);
6313 286533 : AirflowNetworkNodeSimu(n).WZ = m_state.dataEnvrn->OutHumRat;
6314 286533 : if (i <= AirflowNetworkNumOfExtNode) {
6315 286527 : if (MultizoneExternalNodeData(i).OutAirNodeNum == 0) {
6316 286526 : LocalWindSpeed = DataEnvironment::WindSpeedAt(m_state, MultizoneExternalNodeData(i).height);
6317 286526 : LocalDryBulb = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(n).NodeHeight);
6318 286526 : LocalAzimuth = MultizoneExternalNodeData(i).azimuth;
6319 286526 : AirflowNetworkNodeSimu(n).PZ = calculate_wind_pressure(MultizoneExternalNodeData(i).curve,
6320 286526 : MultizoneExternalNodeData(i).symmetricCurve,
6321 286526 : MultizoneExternalNodeData(i).useRelativeAngle,
6322 : LocalAzimuth,
6323 : LocalWindSpeed,
6324 286526 : m_state.dataEnvrn->WindDir,
6325 : LocalDryBulb,
6326 286526 : m_state.dataEnvrn->OutHumRat);
6327 : } else {
6328 : // If and outdoor air node object is defined as the External Node Name in AirflowNetwork:MultiZone:Surface,
6329 : // the node object requires to define the Wind Pressure Coefficient Curve Name.
6330 1 : NodeNum = MultizoneExternalNodeData(i).OutAirNodeNum;
6331 1 : LocalWindSpeed = Node((NodeNum)).OutAirWindSpeed;
6332 1 : LocalWindDir = Node((NodeNum)).OutAirWindDir;
6333 1 : LocalHumRat = Node((NodeNum)).HumRat;
6334 1 : LocalDryBulb = Node((NodeNum)).OutAirDryBulb;
6335 1 : LocalAzimuth = MultizoneExternalNodeData(i).azimuth;
6336 1 : AirflowNetworkNodeSimu(n).PZ = calculate_wind_pressure(MultizoneExternalNodeData(i).curve,
6337 1 : MultizoneExternalNodeData(i).symmetricCurve,
6338 1 : MultizoneExternalNodeData(i).useRelativeAngle,
6339 : LocalAzimuth,
6340 : LocalWindSpeed,
6341 : LocalWindDir,
6342 : LocalDryBulb,
6343 : LocalHumRat);
6344 1 : AirflowNetworkNodeSimu(n).TZ = LocalDryBulb;
6345 1 : AirflowNetworkNodeSimu(n).WZ = LocalHumRat;
6346 : }
6347 : }
6348 :
6349 : } else {
6350 0 : ShowSevereError(m_state,
6351 0 : "GetAirflowNetworkInput: AIRFLOWNETWORK:DISTRIBUTION:NODE: Invalid external node = " +
6352 0 : AirflowNetworkNodeData(n).Name);
6353 0 : CalcAirflowNetworkAirBalanceErrorsFound = true;
6354 : }
6355 : }
6356 : }
6357 :
6358 337172 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6359 320307 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) {
6360 0 : continue;
6361 : }
6362 320307 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::SCR) {
6363 109 : AirflowNetworkLinkageData(i).control = MultizoneSurfaceData(i).Factor;
6364 : }
6365 320307 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) MultizoneSurfaceData(i).OpenFactor = 0.0;
6366 320307 : j = MultizoneSurfaceData(i).SurfNum;
6367 320307 : auto const &surf = m_state.dataSurface->Surface(j);
6368 320307 : if (surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
6369 320293 : surf.OriginalClass == SurfaceClass::GlassDoor || surf.IsAirBoundarySurf) {
6370 14 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
6371 0 : if (MultizoneSurfaceData(i).OpeningStatus == OpenStatus::FreeOperation) {
6372 0 : if (MultizoneSurfaceData(i).OpeningProbStatus == ProbabilityCheck::ForceChange) {
6373 0 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).Factor;
6374 0 : } else if (MultizoneSurfaceData(i).ClosingProbStatus == ProbabilityCheck::ForceChange) {
6375 0 : MultizoneSurfaceData(i).OpenFactor = 0.0;
6376 0 : } else if (MultizoneSurfaceData(i).ClosingProbStatus == ProbabilityCheck::KeepStatus ||
6377 0 : MultizoneSurfaceData(i).OpeningProbStatus == ProbabilityCheck::KeepStatus) {
6378 0 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).OpenFactorLast;
6379 : } else {
6380 0 : venting_control(i, MultizoneSurfaceData(i).OpenFactor);
6381 : }
6382 : }
6383 : } else {
6384 14 : venting_control(i, MultizoneSurfaceData(i).OpenFactor);
6385 : }
6386 14 : MultizoneSurfaceData(i).OpenFactor *= MultizoneSurfaceData(i).WindModifier;
6387 14 : if (MultizoneSurfaceData(i).HybridVentClose) {
6388 3 : MultizoneSurfaceData(i).OpenFactor = 0.0;
6389 3 : if (m_state.dataSurface->SurfWinVentingOpenFactorMultRep(j) > 0.0) m_state.dataSurface->SurfWinVentingOpenFactorMultRep(j) = 0.0;
6390 : }
6391 14 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DOP ||
6392 26 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SOP ||
6393 12 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
6394 0 : if (AirflowNetworkFanActivated && distribution_simulated && MultizoneSurfaceData(i).OpenFactor > 0.0 &&
6395 0 : (m_state.dataSurface->Surface(j).ExtBoundCond == ExternalEnvironment ||
6396 0 : (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
6397 2 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) &&
6398 0 : !m_state.dataGlobal->WarmupFlag) {
6399 : // Exterior Large opening only
6400 0 : ++MultizoneSurfaceData(i).ExtLargeOpeningErrCount;
6401 0 : if (MultizoneSurfaceData(i).ExtLargeOpeningErrCount < 2) {
6402 0 : ShowWarningError(m_state,
6403 0 : "AirflowNetwork: The window or door is open during HVAC system operation " +
6404 0 : MultizoneSurfaceData(i).SurfName);
6405 0 : ShowContinueError(m_state, format("The window or door opening factor is {:.2R}", MultizoneSurfaceData(i).OpenFactor));
6406 0 : ShowContinueErrorTimeStamp(m_state, "");
6407 : } else {
6408 0 : ShowRecurringWarningErrorAtEnd(m_state,
6409 0 : "AirFlowNetwork: " + MultizoneSurfaceData(i).SurfName +
6410 : " The window or door is open during HVAC system operation error continues...",
6411 0 : MultizoneSurfaceData(i).ExtLargeOpeningErrIndex,
6412 0 : MultizoneSurfaceData(i).OpenFactor,
6413 0 : MultizoneSurfaceData(i).OpenFactor);
6414 : }
6415 : }
6416 : }
6417 14 : if (MultizoneSurfaceData(i).OpenFactor > 1.0) {
6418 0 : ++MultizoneSurfaceData(i).OpenFactorErrCount;
6419 0 : if (MultizoneSurfaceData(i).OpenFactorErrCount < 2) {
6420 0 : ShowWarningError(m_state,
6421 0 : "AirflowNetwork: The window or door opening factor is greater than 1.0 " + MultizoneSurfaceData(i).SurfName);
6422 0 : ShowContinueErrorTimeStamp(m_state, "");
6423 : } else {
6424 0 : ShowRecurringWarningErrorAtEnd(m_state,
6425 0 : "AirFlowNetwork: " + MultizoneSurfaceData(i).SurfName +
6426 : " The window or door opening factor is greater than 1.0 error continues...",
6427 0 : MultizoneSurfaceData(i).OpenFactorErrIndex,
6428 0 : MultizoneSurfaceData(i).OpenFactor,
6429 0 : MultizoneSurfaceData(i).OpenFactor);
6430 : }
6431 : }
6432 : }
6433 : }
6434 :
6435 : // Check if the global ventilation control is applied or not
6436 16865 : GlobalOpenFactor = -1.0;
6437 337172 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6438 320307 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) continue;
6439 320307 : if (MultizoneSurfaceData(i).HybridCtrlMaster) {
6440 0 : GlobalOpenFactor = MultizoneSurfaceData(i).OpenFactor;
6441 0 : break;
6442 : }
6443 : }
6444 16865 : if (GlobalOpenFactor >= 0.0) {
6445 0 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6446 0 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) continue;
6447 0 : j = MultizoneSurfaceData(i).SurfNum;
6448 0 : auto const &surf = m_state.dataSurface->Surface(j);
6449 0 : if (surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
6450 0 : surf.OriginalClass == SurfaceClass::GlassDoor) {
6451 0 : if (MultizoneSurfaceData(i).HybridCtrlGlobal) {
6452 0 : MultizoneSurfaceData(i).OpenFactor = GlobalOpenFactor;
6453 : }
6454 : }
6455 : }
6456 : }
6457 :
6458 16865 : if (!Par.allocated()) {
6459 16865 : Par.allocate(1);
6460 16865 : Par = 0.0;
6461 : }
6462 :
6463 16865 : PressureSetFlag = 0;
6464 :
6465 16865 : if (NumOfPressureControllers == 1) {
6466 2 : if (PressureControllerData(1).availSched == nullptr) {
6467 0 : PressureSetFlag = PressureControllerData(1).ControlTypeSet;
6468 2 : } else if (PressureControllerData(1).availSched->getCurrentVal() > 0.0) {
6469 2 : PressureSetFlag = PressureControllerData(1).ControlTypeSet;
6470 : }
6471 2 : if (PressureSetFlag > 0) {
6472 2 : PressureSet = PressureControllerData(1).presSetpointSched->getCurrentVal();
6473 : }
6474 : }
6475 :
6476 16865 : initialize_calculation();
6477 :
6478 16865 : if (!(PressureSetFlag > 0 && AirflowNetworkFanActivated)) {
6479 16864 : airmov();
6480 1 : } else if (PressureSetFlag == PressureCtrlExhaust) {
6481 0 : AirLoopNum = AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).AirLoopNum;
6482 0 : MinExhaustMassFlowrate = 2.0 * VerySmallMassFlow;
6483 0 : MaxExhaustMassFlowrate = Node(PressureControllerData(1).OANodeNum).MassFlowRate;
6484 0 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling &&
6485 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio > 0.0) {
6486 0 : MaxExhaustMassFlowrate = MaxExhaustMassFlowrate / m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
6487 : }
6488 0 : ExhaustFanMassFlowRate = MinExhaustMassFlowrate;
6489 0 : airmov();
6490 0 : ZonePressure1 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6491 0 : if (ZonePressure1 <= PressureSet) {
6492 : // The highest pressure due to minimum flow rate could not reach Pressure set, bypass pressure set calculation
6493 0 : if (!m_state.dataGlobal->WarmupFlag) {
6494 0 : if (ErrCountLowPre == 0) {
6495 0 : ++ErrCountLowPre;
6496 0 : ShowWarningError(m_state,
6497 : "The calculated pressure with minimum exhaust fan rate is lower than the pressure setpoint. The pressure "
6498 : "control is unable to perform.");
6499 0 : ShowContinueErrorTimeStamp(m_state,
6500 0 : format("Calculated pressure = {:.2R}[Pa], Pressure setpoint ={:.2R}", ZonePressure1, PressureSet));
6501 : } else {
6502 0 : ++ErrCountLowPre;
6503 0 : ShowRecurringWarningErrorAtEnd(m_state,
6504 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6505 : ": The AFN model continues not to perform pressure control due to lower zone pressure...",
6506 0 : ErrIndexLowPre,
6507 : ZonePressure1,
6508 : ZonePressure1);
6509 : }
6510 : }
6511 : } else {
6512 0 : ExhaustFanMassFlowRate = MaxExhaustMassFlowrate;
6513 0 : airmov();
6514 0 : ZonePressure2 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6515 0 : if (ZonePressure2 >= PressureSet) {
6516 : // The lowest pressure due to maximum flow rate is still higher than Pressure set, bypass pressure set calculation
6517 0 : if (!m_state.dataGlobal->WarmupFlag) {
6518 0 : if (ErrCountHighPre == 0) {
6519 0 : ++ErrCountHighPre;
6520 0 : ShowWarningError(m_state,
6521 : "The calculated pressure with maximum exhaust fan rate is higher than the pressure setpoint. The "
6522 : "pressure control is unable to perform.");
6523 0 : ShowContinueErrorTimeStamp(
6524 0 : m_state, format("Calculated pressure = {:.2R}[Pa], Pressure setpoint = {:.2R}", ZonePressure2, PressureSet));
6525 : } else {
6526 0 : ++ErrCountHighPre;
6527 0 : ShowRecurringWarningErrorAtEnd(
6528 : m_state,
6529 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6530 : ": The AFN model continues not to perform pressure control due to higher zone pressure...",
6531 0 : ErrIndexHighPre,
6532 : ZonePressure2,
6533 : ZonePressure2);
6534 : }
6535 : }
6536 : } else {
6537 : // if ( ZonePressure1 > PressureSet && ZonePressure2 < PressureSet ) {
6538 0 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
6539 0 : auto f = [&thisState, PressureSet](Real64 const ControllerMassFlowRate) {
6540 0 : return AFNPressureResidual(thisState, ControllerMassFlowRate, PressureSet);
6541 0 : };
6542 0 : General::SolveRoot(
6543 0 : m_state, ErrorToler, MaxIte, SolFla, ExhaustFanMassFlowRate, f, MinExhaustMassFlowrate, MaxExhaustMassFlowrate);
6544 0 : if (SolFla == -1) {
6545 0 : if (!m_state.dataGlobal->WarmupFlag) {
6546 0 : if (ErrCountVar == 0) {
6547 0 : ++ErrCountVar;
6548 0 : ShowWarningError(m_state, "Iteration limit exceeded pressure setpoint using an exhaust fan. Simulation continues.");
6549 0 : ShowContinueErrorTimeStamp(m_state, format("Exhaust fan flow rate = {:.4R}", ExhaustFanMassFlowRate));
6550 : } else {
6551 0 : ++ErrCountVar;
6552 0 : ShowRecurringWarningErrorAtEnd(m_state,
6553 0 : PressureControllerData(1).Name +
6554 : "\": Iteration limit warning exceeding pressure setpoint continues...",
6555 0 : ErrIndexVar,
6556 0 : ExhaustFanMassFlowRate,
6557 0 : ExhaustFanMassFlowRate);
6558 : }
6559 : }
6560 0 : } else if (SolFla == -2) {
6561 0 : ShowFatalError(m_state,
6562 0 : "Zone pressure control failed using an exhaust fan: no solution is reached, for " +
6563 0 : PressureControllerData(1).Name);
6564 : }
6565 : }
6566 : }
6567 : } else { // PressureCtrlRelief - Pressure control type is Relief Flow
6568 1 : AirLoopNum = AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).AirLoopNum;
6569 1 : MinReliefMassFlowrate = 2.0 * VerySmallMassFlow;
6570 1 : MaxReliefMassFlowrate = Node(PressureControllerData(1).OANodeNum).MassFlowRate;
6571 1 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling &&
6572 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio > 0.0) {
6573 0 : MaxReliefMassFlowrate = MaxReliefMassFlowrate / m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
6574 : }
6575 1 : ReliefMassFlowRate = MinReliefMassFlowrate;
6576 1 : initialize_calculation();
6577 1 : airmov();
6578 1 : ZonePressure1 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6579 :
6580 1 : if (ZonePressure1 <= PressureSet) {
6581 : // The highest pressure due to minimum flow rate could not reach Pressure set, bypass pressure set calculation
6582 0 : if (!m_state.dataGlobal->WarmupFlag) {
6583 0 : if (ErrCountLowPre == 0) {
6584 0 : ++ErrCountLowPre;
6585 0 : ShowWarningError(m_state,
6586 : "The calculated pressure with minimum relief air rate is lower than the pressure setpoint. The pressure "
6587 : "control is unable to perform.");
6588 0 : ShowContinueErrorTimeStamp(m_state,
6589 0 : format("Calculated pressure = {:.2R}[Pa], Pressure setpoint ={:.2R}", ZonePressure1, PressureSet));
6590 : } else {
6591 0 : ++ErrCountLowPre;
6592 0 : ShowRecurringWarningErrorAtEnd(m_state,
6593 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6594 : ": The AFN model continues not to perform pressure control due to lower zone pressure...",
6595 0 : ErrIndexLowPre,
6596 : ZonePressure1,
6597 : ZonePressure1);
6598 : }
6599 : }
6600 : } else {
6601 1 : ReliefMassFlowRate = MaxReliefMassFlowrate;
6602 1 : initialize_calculation();
6603 1 : airmov();
6604 1 : ZonePressure2 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6605 1 : if (ZonePressure2 >= PressureSet) {
6606 : // The lowest pressure due to maximum flow rate is still higher than Pressure set, bypass pressure set calculation
6607 0 : if (!m_state.dataGlobal->WarmupFlag) {
6608 0 : if (ErrCountHighPre == 0) {
6609 0 : ++ErrCountHighPre;
6610 0 : ShowWarningError(m_state,
6611 : "The calculated pressure with maximum relief air rate is higher than the pressure setpoint. The "
6612 : "pressure control is unable to perform.");
6613 0 : ShowContinueErrorTimeStamp(
6614 0 : m_state, format("Calculated pressure = {:.2R}[Pa], Pressure setpoint = {:.2R}", ZonePressure2, PressureSet));
6615 : } else {
6616 0 : ++ErrCountHighPre;
6617 0 : ShowRecurringWarningErrorAtEnd(
6618 : m_state,
6619 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6620 : ": The AFN model continues not to perform pressure control due to higher zone pressure...",
6621 0 : ErrIndexHighPre,
6622 : ZonePressure2,
6623 : ZonePressure2);
6624 : }
6625 : }
6626 : } else {
6627 : // if ( ZonePressure1 > PressureSet && ZonePressure2 < PressureSet ) {
6628 1 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
6629 7 : auto f = [&thisState, PressureSet](Real64 const ControllerMassFlowRate) {
6630 7 : return AFNPressureResidual(thisState, ControllerMassFlowRate, PressureSet);
6631 1 : };
6632 1 : General::SolveRoot(m_state, ErrorToler, MaxIte, SolFla, ReliefMassFlowRate, f, MinReliefMassFlowrate, MaxReliefMassFlowrate);
6633 1 : if (SolFla == -1) {
6634 0 : if (!m_state.dataGlobal->WarmupFlag) {
6635 0 : if (ErrCountVar == 0) {
6636 0 : ++ErrCountVar;
6637 0 : ShowWarningError(m_state, "Iteration limit exceeded pressure setpoint using relief air. Simulation continues.");
6638 0 : ShowContinueErrorTimeStamp(m_state, format("Relief air flow rate = {:.4R}", ReliefMassFlowRate));
6639 : } else {
6640 0 : ++ErrCountVar;
6641 0 : ShowRecurringWarningErrorAtEnd(m_state,
6642 0 : PressureControllerData(1).Name +
6643 : "\": Iteration limit warning exceeding pressure setpoint continues...",
6644 0 : ErrIndexVar,
6645 0 : ReliefMassFlowRate,
6646 0 : ReliefMassFlowRate);
6647 : }
6648 : }
6649 1 : } else if (SolFla == -2) {
6650 0 : ShowFatalError(
6651 0 : m_state, "Zone pressure control failed using relief air: no solution is reached, for " + PressureControllerData(1).Name);
6652 : }
6653 : }
6654 : }
6655 : }
6656 16865 : }
6657 :
6658 7 : Real64 AFNPressureResidual(EnergyPlusData &state,
6659 : Real64 const ControllerMassFlowRate, // Pressure setpoint
6660 : Real64 PressureSet)
6661 : {
6662 : // FUNCTION INFORMATION:
6663 : // AUTHOR Lixing Gu
6664 : // DATE WRITTEN April 2016
6665 : // MODIFIED NA
6666 : // RE-ENGINEERED NA
6667 :
6668 : // PURPOSE OF THIS FUNCTION:
6669 : // Calculates residual function ((ZonePressure - PressureSet)/PressureSet)
6670 :
6671 : // METHODOLOGY EMPLOYED:
6672 : // Calls AIRMOV to get the pressure in the controlled zone and calculates the residual as defined above
6673 :
6674 : // Return value
6675 : Real64 AFNPressureResidual;
6676 :
6677 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
6678 : Real64 ZonePressure;
6679 :
6680 7 : if (state.afn->PressureSetFlag == PressureCtrlExhaust) {
6681 0 : state.afn->ExhaustFanMassFlowRate = ControllerMassFlowRate;
6682 : }
6683 :
6684 7 : if (state.afn->PressureSetFlag == PressureCtrlRelief) {
6685 7 : state.afn->ReliefMassFlowRate = ControllerMassFlowRate;
6686 : }
6687 7 : auto &solver = state.afn;
6688 7 : solver->initialize_calculation();
6689 7 : solver->airmov();
6690 :
6691 7 : ZonePressure = state.afn->AirflowNetworkNodeSimu(state.afn->PressureControllerData(1).AFNNodeNum).PZ;
6692 :
6693 7 : if (PressureSet != 0.0) {
6694 7 : AFNPressureResidual = (ZonePressure - PressureSet) / PressureSet;
6695 : } else {
6696 0 : AFNPressureResidual = (ZonePressure - PressureSet);
6697 : }
6698 7 : return AFNPressureResidual;
6699 : }
6700 :
6701 84 : static int makeTable(EnergyPlusData &state, const std::string &name, const int gridIndex, const std::vector<Real64> &y)
6702 : {
6703 : // Add a new table and performance curve
6704 84 : std::string contextString = "CalcWindPressureCoeffs: Creating table \"" + name + "\"";
6705 84 : std::pair<EnergyPlusData *, std::string> callbackPair{&state, contextString};
6706 84 : state.dataCurveManager->btwxtManager.setLoggingContext(&callbackPair);
6707 :
6708 84 : Curve::Curve *curve = Curve::AddCurve(state, name);
6709 :
6710 84 : curve->numDims = 1;
6711 :
6712 84 : curve->curveType = Curve::CurveType::BtwxtTableLookup;
6713 :
6714 84 : curve->inputLimits[0].min = 0.0;
6715 84 : curve->inputLimits[0].minPresent = true;
6716 84 : curve->inputLimits[0].max = 360.0;
6717 84 : curve->inputLimits[0].maxPresent = true;
6718 :
6719 84 : curve->TableIndex = gridIndex;
6720 84 : curve->GridValueIndex = state.dataCurveManager->btwxtManager.addOutputValues(gridIndex, y);
6721 :
6722 84 : return curve->Num;
6723 84 : }
6724 :
6725 16 : void Solver::calculate_Cps()
6726 : {
6727 :
6728 : // SUBROUTINE INFORMATION:
6729 : // AUTHOR Fred Winkelmann
6730 : // DATE WRITTEN May 2003
6731 : // MODIFIED Revised by L. Gu, Nov. 2005, to meet requirements of AirflowNetwork
6732 : // MODIFIED Revised by L. Gu, Dec. 2008, to set the number of external nodes based on
6733 : // the number of external surfaces
6734 : // MODIFIED Revised by J. DeGraw, Feb. 2017, to use tables
6735 : // RE-ENGINEERED na
6736 :
6737 : // PURPOSE OF THIS SUBROUTINE:
6738 : // Calculates surface-average wind pressure coefficients for
6739 : // the walls and roof of a rectangular building.
6740 :
6741 : // METHODOLOGY EMPLOYED:
6742 : // Interpolates correlations between surface-average wind pressure coefficient and wind direction based on
6743 : // measurements (see REFERENCES). Applicable only to rectangular buildings.
6744 :
6745 : // REFERENCES:
6746 : // For low-rise buildings: M.V. Swami and S. Chandra, Correlations for Pressure Distribution
6747 : // on Buildings and Calculation of Natural-Ventilation Airflow. ASHRAE Transactions 94 (1): 243-266.
6748 : // For high-rise buildings: 2001 ASHRAE Fundamentals Handbook, p. 16.5, Fig. 7, "Surface Averaged
6749 : // Wall Pressure Coefficients for Tall Buildings" and p.16.6, Fig. 9, "Surface Averaged Roof Pressure
6750 : // Coefficients for Tall Buildings; from R.E. Akins, J.A. Peterka, and J.E. Cermak. 1979.
6751 : // Averaged Pressure Coefficients for Rectangular Buildings. Wind Engineering. Proc. Fifth
6752 : // International Conference 7:369-80, Fort Collins, CO. Pergamon Press, NY.
6753 :
6754 : // Using/Aliasing
6755 : using namespace DataSurfaces;
6756 :
6757 : // index 1 is wind incidence angle (0,30,60,...,300,330 deg)
6758 : // index 2 is side ratio (0.25,1.0,4.0)
6759 : // Surface-averaged wind-pressure coefficient array for walls
6760 : static constexpr std::array<std::array<Real64, 12>, 3> CPHighRiseWall = {{
6761 : {0.60, 0.54, 0.23, -0.25, -0.61, -0.55, -0.51, -0.55, -0.61, -0.25, 0.23, 0.54},
6762 : {0.60, 0.48, 0.04, -0.56, -0.56, -0.42, -0.37, -0.42, -0.56, -0.56, 0.04, 0.48},
6763 : {0.60, 0.44, -0.26, -0.70, -0.53, -0.32, -0.22, -0.32, -0.53, -0.70, -0.26, 0.44},
6764 : }};
6765 :
6766 : // index 1 is wind incidence angle (0,30,60,...,300,330 deg)
6767 : // index 2 is side ratio (0.25,0.5,1.0)
6768 : // Surface-averaged wind-pressure coefficient array for roof
6769 : static constexpr std::array<std::array<Real64, 12>, 3> CPHighRiseRoof = {{
6770 : {-0.28, -0.69, -0.72, -0.76, -0.72, -0.69, -0.28, -0.69, -0.72, -0.76, -0.72, -0.69},
6771 : {-0.47, -0.52, -0.70, -0.76, -0.70, -0.52, -0.47, -0.52, -0.70, -0.76, -0.70, -0.52},
6772 : {-0.70, -0.55, -0.55, -0.70, -0.55, -0.55, -0.70, -0.55, -0.55, -0.70, -0.55, -0.55},
6773 : }};
6774 :
6775 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6776 : int FacadeNum; // Facade number
6777 : int ExtNum; // External number
6778 : int AFNZnNum; // Zone number
6779 : Real64 SideRatio; // For vertical facades, width of facade / width of adjacent facade
6780 : Real64 SR; // SideRatio restricted to 0.25 to 4.0 range
6781 : Real64 SideRatioFac; // LOG(SideRatio)
6782 : Real64 IncRad; // IncAng in radians
6783 : int IAng; // Incidence angle index; used in interpolation
6784 : Real64 DelAng; // Incidence angle difference; used in interpolation
6785 : Real64 WtAng; // Incidence angle weighting factor; used in interpolation
6786 : int ISR; // Side ratio index, for interpolation
6787 : Real64 WtSR; // Side ratio weighting factor; used in interpolation
6788 : int SurfNum; // Surface number
6789 : int SurfDatNum; // Surface data number
6790 : Real64 SurfAng; // Azimuth angle of surface normal (degrees clockwise from North)
6791 : int FacadeNumThisSurf; // Facade number for a particular surface
6792 : Real64 AngDiff; // Angle difference between wind and surface direction (deg)
6793 : Real64 AngDiffMin; // Minimum angle difference between wind and surface direction (deg)
6794 32 : std::vector<int> curveIndex = {0, 0, 0, 0, 0};
6795 :
6796 : // Facade azimuth angle
6797 80 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
6798 64 : FacadeAng(FacadeNum) = m_state.afn->simulation_control.azimuth + (FacadeNum - 1) * 90.0;
6799 64 : if (FacadeAng(FacadeNum) >= 360.0) {
6800 10 : FacadeAng(FacadeNum) -= 360.0;
6801 : }
6802 : }
6803 :
6804 16 : FacadeAng(5) = simulation_control.azimuth + 90.0;
6805 :
6806 : // Create AirflowNetwork external node objects -- one for each of the external surfaces
6807 :
6808 16 : MultizoneExternalNodeData.allocate(AirflowNetworkNumOfExtSurfaces);
6809 16 : AirflowNetworkNumOfExtNode = AirflowNetworkNumOfExtSurfaces;
6810 16 : NumOfExtNodes = AirflowNetworkNumOfExtSurfaces;
6811 76 : for (ExtNum = 1; ExtNum <= NumOfExtNodes; ++ExtNum) {
6812 60 : MultizoneExternalNodeData(ExtNum).ExtNum = AirflowNetworkNumOfZones + ExtNum;
6813 60 : MultizoneExternalNodeData(ExtNum).Name = format("ExtNode{:4}", ExtNum);
6814 : }
6815 :
6816 : // Associate each external node with SurfaceData
6817 :
6818 16 : ExtNum = 0;
6819 81 : for (SurfDatNum = 1; SurfDatNum <= AirflowNetworkNumOfSurfaces; ++SurfDatNum) {
6820 65 : if (SurfDatNum > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) {
6821 0 : continue;
6822 : }
6823 65 : SurfNum = MultizoneSurfaceData(SurfDatNum).SurfNum;
6824 65 : if (SurfNum == 0) {
6825 0 : continue; // Error caught earlier
6826 : }
6827 72 : if (m_state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment ||
6828 7 : (m_state.dataSurface->Surface(SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt && m_state.dataSurface->Surface(SurfNum).ExtWind)) {
6829 60 : ++ExtNum;
6830 60 : if (m_state.dataSurface->Surface(SurfNum).Tilt >= 45.0) { // "Vertical" surface
6831 54 : SurfAng = m_state.dataSurface->Surface(SurfNum).Azimuth;
6832 54 : FacadeNumThisSurf = 1;
6833 54 : AngDiffMin = std::abs(SurfAng - FacadeAng(1));
6834 54 : if (AngDiffMin > 359.0) {
6835 0 : AngDiffMin = std::abs(AngDiffMin - 360.0);
6836 : }
6837 216 : for (FacadeNum = 2; FacadeNum <= 4; ++FacadeNum) {
6838 162 : AngDiff = std::abs(SurfAng - FacadeAng(FacadeNum));
6839 162 : if (AngDiff > 359.0) {
6840 0 : AngDiff = std::abs(AngDiff - 360.0);
6841 : }
6842 162 : if (AngDiff < AngDiffMin) {
6843 71 : AngDiffMin = AngDiff;
6844 71 : FacadeNumThisSurf = FacadeNum;
6845 : }
6846 : }
6847 54 : MultizoneExternalNodeData(ExtNum).facadeNum = FacadeNumThisSurf;
6848 : } else { // "Roof" surface
6849 6 : MultizoneExternalNodeData(ExtNum).facadeNum = 5;
6850 : }
6851 60 : MultizoneSurfaceData(SurfDatNum).NodeNums[1] = MultizoneExternalNodeData(ExtNum).ExtNum;
6852 60 : MultizoneSurfaceData(SurfDatNum).ExternalNodeName = MultizoneExternalNodeData(ExtNum).Name;
6853 : }
6854 : }
6855 :
6856 : // Check if using the advanced single sided model
6857 37 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
6858 21 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
6859 2 : ++AirflowNetworkNumOfSingleSideZones;
6860 : }
6861 : }
6862 :
6863 32 : std::vector<Real64> dirs30 = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360};
6864 16 : std::vector<Btwxt::GridAxis> dirs30Axes;
6865 16 : dirs30Axes.emplace_back(dirs30,
6866 : "30 Degree Increment",
6867 0 : Btwxt::InterpolationMethod::linear,
6868 16 : Btwxt::ExtrapolationMethod::linear,
6869 16 : std::pair<double, double>{0.0, 360.0});
6870 :
6871 48 : auto dirs30GridIndex = m_state.dataCurveManager->btwxtManager.addGrid("30 Degree Increments", dirs30Axes);
6872 :
6873 16 : if (AirflowNetworkNumOfSingleSideZones == 0) { // do the standard surface average coefficient calculation
6874 : // Create the array of wind directions
6875 :
6876 : // Create a curve for each facade
6877 84 : for (FacadeNum = 1; FacadeNum <= 5; ++FacadeNum) {
6878 70 : if (FacadeNum == 1 || FacadeNum == 3 || FacadeNum == 5) {
6879 42 : SideRatio = simulation_control.aspect_ratio;
6880 : } else { // FacadeNum = 2 or 4
6881 28 : SideRatio = 1.0 / simulation_control.aspect_ratio;
6882 : }
6883 70 : if (Util::SameString(simulation_control.BldgType, "HighRise") && FacadeNum != 5) {
6884 0 : SideRatio = 1.0 / SideRatio;
6885 : }
6886 70 : SideRatioFac = std::log(SideRatio);
6887 70 : std::vector<Real64> vals(13);
6888 910 : for (int windDirNum = 1; windDirNum <= 12; ++windDirNum) {
6889 840 : Real64 WindAng = (windDirNum - 1) * 30.0;
6890 840 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
6891 840 : if (IncAng > 180.0) IncAng = 360.0 - IncAng;
6892 840 : IAng = int(IncAng / 30.0) + 1;
6893 840 : DelAng = mod(IncAng, 30.0);
6894 840 : WtAng = 1.0 - DelAng / 30.0;
6895 :
6896 : // Wind-pressure coefficients for vertical facades, low-rise building
6897 :
6898 840 : if (Util::SameString(simulation_control.BldgType, "LowRise") && FacadeNum <= 4) {
6899 672 : IncRad = IncAng * Constant::DegToRad;
6900 672 : Real64 const cos_IncRad_over_2(std::cos(IncRad / 2.0));
6901 1344 : vals[windDirNum - 1] = 0.6 * std::log(1.248 - 0.703 * std::sin(IncRad / 2.0) - 1.175 * pow_2(std::sin(IncRad)) +
6902 672 : 0.131 * pow_3(std::sin(2.0 * IncRad * SideRatioFac)) + 0.769 * cos_IncRad_over_2 +
6903 672 : 0.07 * pow_2(SideRatioFac * std::sin(IncRad / 2.0)) + 0.717 * pow_2(cos_IncRad_over_2));
6904 : }
6905 :
6906 : // Wind-pressure coefficients for vertical facades, high-rise building
6907 :
6908 168 : else if (Util::SameString(simulation_control.BldgType, "HighRise") && FacadeNum <= 4) {
6909 0 : SR = min(max(SideRatio, 0.25), 4.0);
6910 0 : if (SR >= 0.25 && SR < 1.0) {
6911 0 : ISR = 1;
6912 0 : WtSR = (1.0 - SR) / 0.75;
6913 : } else { // 1.0 <= SR <= 4.0
6914 0 : ISR = 2;
6915 0 : WtSR = (4.0 - SR) / 3.0;
6916 : }
6917 0 : vals[windDirNum - 1] = WtSR * (WtAng * CPHighRiseWall[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseWall[ISR - 1][IAng]) +
6918 0 : (1.0 - WtSR) * (WtAng * CPHighRiseWall[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseWall[ISR][IAng]);
6919 : }
6920 :
6921 : // Wind-pressure coefficients for roof (assumed same for low-rise and high-rise buildings)
6922 :
6923 336 : else if ((Util::SameString(simulation_control.BldgType, "HighRise") ||
6924 336 : Util::SameString(simulation_control.BldgType, "LowRise")) &&
6925 168 : FacadeNum == 5) {
6926 168 : SR = min(max(SideRatio, 0.25), 1.0);
6927 168 : if (SR >= 0.25 && SR < 0.5) {
6928 84 : ISR = 1;
6929 84 : WtSR = (0.5 - SR) / 0.25;
6930 : } else { // 0.5 <= SR <= 1.0
6931 84 : ISR = 2;
6932 84 : WtSR = (1.0 - SR) / 0.5;
6933 : }
6934 336 : vals[windDirNum - 1] = WtSR * (WtAng * CPHighRiseRoof[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR - 1][IAng]) +
6935 168 : (1.0 - WtSR) * (WtAng * CPHighRiseRoof[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR][IAng]);
6936 : }
6937 :
6938 : } // End of wind direction loop
6939 : // Add new table
6940 70 : vals[12] = vals[0]; // Enforce periodicity
6941 70 : curveIndex[FacadeNum - 1] = AirflowNetwork::makeTable(m_state, format("!WPCTABLE{}", FacadeNum), dirs30GridIndex, vals);
6942 70 : } // End of facade number loop
6943 :
6944 : } else { //-calculate the advanced single sided wind pressure coefficients
6945 :
6946 : // Calculate the wind pressure coefficients vs. wind direction for each external node
6947 : // The wind pressure coeffients are stored temporarily in the "valsByFacade" vector and then
6948 : // converted into a table near the end of this else. There will be at least seven profiles
6949 : // (four sides plus one roof plus two for each pair of windows). The name is thus a little
6950 : // misleading, as it isn't really the values by facade once you get beyond the first five.
6951 2 : std::vector<std::vector<Real64>> valsByFacade(5);
6952 10 : for (FacadeNum = 0; FacadeNum < 4; ++FacadeNum) {
6953 16 : valsByFacade[FacadeNum] = std::vector<Real64>(36);
6954 : }
6955 2 : FacadeNum = 4;
6956 2 : valsByFacade[FacadeNum] = std::vector<Real64>(12);
6957 10 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
6958 8 : if (FacadeNum == 1 || FacadeNum == 3) {
6959 4 : SideRatio = simulation_control.aspect_ratio;
6960 : } else { // FacadeNum = 2 or 4
6961 4 : SideRatio = 1.0 / simulation_control.aspect_ratio;
6962 : }
6963 8 : if (Util::SameString(simulation_control.BldgType, "HighRise")) {
6964 0 : SideRatio = 1.0 / SideRatio;
6965 : }
6966 8 : SideRatioFac = std::log(SideRatio);
6967 296 : for (int windDirNum = 1; windDirNum <= 36; ++windDirNum) {
6968 288 : Real64 WindAng = (windDirNum - 1) * 10.0;
6969 288 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
6970 288 : if (IncAng > 180.0) IncAng = 360.0 - IncAng;
6971 : // IAng = int(IncAng / 10.0) + 1;
6972 288 : DelAng = mod(IncAng, 10.0);
6973 288 : WtAng = 1.0 - DelAng / 10.0;
6974 : // Wind-pressure coefficients for vertical facades, low-rise building
6975 288 : IncRad = IncAng * Constant::DegToRad;
6976 288 : valsByFacade[FacadeNum - 1][windDirNum - 1] =
6977 288 : 0.6 * std::log(1.248 - 0.703 * std::sin(IncRad / 2.0) - 1.175 * pow_2(std::sin(IncRad)) +
6978 288 : 0.131 * pow_3(std::sin(2.0 * IncRad * SideRatioFac)) + 0.769 * std::cos(IncRad / 2.0) +
6979 288 : 0.07 * pow_2(SideRatioFac * std::sin(IncRad / 2.0)) + 0.717 * pow_2(std::cos(IncRad / 2.0)));
6980 : } // End of wind direction loop
6981 : } // End of facade number loop
6982 : // Add a roof
6983 2 : FacadeNum = 5;
6984 2 : SR = min(max(SideRatio, 0.25), 1.0);
6985 2 : if (SR >= 0.25 && SR < 0.5) {
6986 0 : ISR = 1;
6987 0 : WtSR = (0.5 - SR) / 0.25;
6988 : } else { // 0.5 <= SR <= 1.0
6989 2 : ISR = 2;
6990 2 : WtSR = (1.0 - SR) / 0.5;
6991 : }
6992 26 : for (int windDirNum = 1; windDirNum <= 12; ++windDirNum) {
6993 24 : Real64 WindAng = (windDirNum - 1) * 30.0;
6994 24 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
6995 24 : if (IncAng > 180.0) IncAng = 360.0 - IncAng;
6996 24 : IAng = int(IncAng / 30.0) + 1;
6997 24 : DelAng = mod(IncAng, 30.0);
6998 24 : WtAng = 1.0 - DelAng / 30.0;
6999 : // Wind-pressure coefficients for roof (assumed same for low-rise and high-rise buildings)
7000 24 : valsByFacade[FacadeNum - 1][windDirNum - 1] =
7001 24 : WtSR * (WtAng * CPHighRiseRoof[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR - 1][IAng]) +
7002 24 : (1.0 - WtSR) * (WtAng * CPHighRiseRoof[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR][IAng]);
7003 : }
7004 2 : single_sided_Cps(valsByFacade); // run the advanced single sided subroutine if at least one zone calls for it
7005 : // Resize the curve index array
7006 2 : curveIndex.resize(valsByFacade.size());
7007 : // Create the curves
7008 :
7009 : std::vector<Real64> dirs10 = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180,
7010 4 : 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360};
7011 :
7012 2 : std::vector<Btwxt::GridAxis> dirs10Axes;
7013 2 : dirs10Axes.emplace_back(dirs10,
7014 : "10 Degree Increments",
7015 0 : Btwxt::InterpolationMethod::linear,
7016 2 : Btwxt::ExtrapolationMethod::linear,
7017 2 : std::pair<double, double>{0.0, 360.0});
7018 :
7019 6 : auto dirs10GridIndex = m_state.dataCurveManager->btwxtManager.addGrid("10 Degree Increments", dirs10Axes);
7020 :
7021 10 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
7022 8 : valsByFacade[FacadeNum - 1].push_back(valsByFacade[FacadeNum - 1][0]); // Enforce periodicity
7023 16 : curveIndex[FacadeNum - 1] =
7024 8 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLEFACADE{}", FacadeNum), dirs10GridIndex, valsByFacade[FacadeNum - 1]);
7025 : }
7026 2 : FacadeNum = 5;
7027 2 : valsByFacade[FacadeNum - 1].push_back(valsByFacade[FacadeNum - 1][0]); // Enforce periodicity
7028 4 : curveIndex[FacadeNum - 1] =
7029 2 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLEFACADE{}", FacadeNum), dirs30GridIndex, valsByFacade[FacadeNum - 1]);
7030 6 : for (unsigned facadeNum = 6; facadeNum <= valsByFacade.size(); ++facadeNum) {
7031 4 : valsByFacade[facadeNum - 1].push_back(valsByFacade[facadeNum - 1][0]); // Enforce periodicity
7032 8 : curveIndex[facadeNum - 1] =
7033 4 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLE{}", facadeNum), dirs10GridIndex, valsByFacade[facadeNum - 1]);
7034 : }
7035 2 : }
7036 : // Connect the external nodes to the new curves
7037 76 : for (ExtNum = 1; ExtNum <= NumOfExtNodes; ++ExtNum) {
7038 60 : MultizoneExternalNodeData(ExtNum).curve = curveIndex[MultizoneExternalNodeData(ExtNum).facadeNum - 1];
7039 : }
7040 16 : }
7041 :
7042 286540 : Real64 Solver::calculate_wind_pressure(int const curve, // Curve index, change this to pointer after curve refactor
7043 : bool const symmetricCurve, // True if the curve is symmetric (0 to 180)
7044 : bool const relativeAngle, // True if the Cp curve angle is measured relative to the surface
7045 : Real64 const azimuth, // Azimuthal angle of surface
7046 : Real64 const windSpeed, // Wind velocity
7047 : Real64 const windDir, // Wind direction
7048 : Real64 const dryBulbTemp, // Air node dry bulb temperature
7049 : Real64 const humRat // Air node humidity ratio
7050 : )
7051 : {
7052 :
7053 : // SUBROUTINE INFORMATION:
7054 : // AUTHOR Lixing Gu
7055 : // DATE WRITTEN Oct. 2005
7056 : // MODIFIED Jason DeGraw, Feb. 2017, modify to use curves
7057 : // MODIFIED Xuan Luo, Aug. 2017, modify to use local air condition
7058 : // RE-ENGINEERED na
7059 :
7060 : // PURPOSE OF THIS SUBROUTINE:
7061 : // Calculates surface wind pressure based on given CP values
7062 :
7063 : // REFERENCES:
7064 : // COMIS Fundamentals
7065 :
7066 : // Return value is wind pressure[Pa]
7067 :
7068 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
7069 286540 : Real64 angle(windDir);
7070 : Real64 rho; // Outdoor air density
7071 : Real64 Cp; // Cp value at given wind direction
7072 :
7073 : // Calculate outdoor density
7074 286540 : rho = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, dryBulbTemp, humRat);
7075 :
7076 : // Calculate pressure coefficient
7077 286540 : if (relativeAngle) {
7078 6 : angle = angle - azimuth;
7079 6 : if (angle < 0.0) {
7080 2 : angle += 360.0;
7081 : }
7082 : }
7083 286540 : if (symmetricCurve) {
7084 4 : if (angle > 180.0) {
7085 2 : angle = 360.0 - angle;
7086 : }
7087 : }
7088 286540 : Cp = Curve::CurveValue(m_state, curve, angle);
7089 :
7090 286540 : return Cp * 0.5 * rho * windSpeed * windSpeed;
7091 : }
7092 :
7093 399344 : Real64 Solver::duct_inside_convection_resistance(Real64 const Tair, // Average air temperature
7094 : Real64 const mdot, // Mass flow rate
7095 : Real64 const Dh, // Hydraulic diameter
7096 : Real64 const hIn // User defined convection coefficient
7097 : )
7098 : {
7099 : // SUBROUTINE INFORMATION:
7100 : // AUTHOR Matt Mitchell, Tony Fontanini
7101 : // DATE WRITTEN Feb. 2017
7102 : // MODIFIED na
7103 : // RE-ENGINEERED na
7104 :
7105 : // PURPOSE OF THIS SUBROUTINE:
7106 : // Calculates duct inside convection coefficients
7107 :
7108 : // REFERENCES:
7109 : // ASTM C1340
7110 : // Jakob, F.E., Fischer, R.D., Flanigan, L.J. 1987. "Experimental Validation of the Duct Submodel for the SP43 Simulation Model."
7111 : // ASHRAE Trans. pp 1499-1514.
7112 :
7113 399344 : Real64 hIn_final = 0;
7114 :
7115 399344 : if (hIn == 0) {
7116 :
7117 399341 : Real64 Tair_IP = Tair * 1.8 + 32.0; // Convert C to F
7118 399341 : Real64 mdot_IP = mdot * 2.20462 * 3600; // Convert kg/s to lb/hr
7119 399341 : Real64 Dh_IP = Dh * 3.28084; // Convert m to ft
7120 399341 : Real64 Ai_IP = pow_2(Dh_IP) * Constant::Pi / 4;
7121 :
7122 399341 : Real64 CorrelationCoeff = 0.00368 + 1.5e-6 * (Tair_IP - 80);
7123 399341 : Real64 MassFlux = mdot_IP / Ai_IP; // lb/hr-ft2
7124 :
7125 399341 : Real64 DuctInsideConvCoeff_IP = CorrelationCoeff * pow(MassFlux, 0.8) / pow(Dh_IP, 0.2); // BTU/hr-ft2-F
7126 :
7127 399341 : hIn_final = DuctInsideConvCoeff_IP * pow_2(3.28084) * 1.8 * 1055.06 / 3600; // Convert BTU/hr-ft2-F to W/m2-K
7128 :
7129 : } else {
7130 3 : hIn_final = hIn;
7131 : }
7132 :
7133 399344 : if (hIn_final == 0) {
7134 0 : return 0;
7135 : } else {
7136 399344 : return 1 / hIn_final;
7137 : }
7138 : }
7139 :
7140 399346 : Real64 Solver::duct_outside_convection_resistance(Real64 const Ts, // Surface temperature
7141 : Real64 const Tamb, // Free air temperature
7142 : Real64 const Wamb, // Free air humidity ratio
7143 : Real64 const Pamb, // Free air barometric pressure
7144 : Real64 const Dh, // Hydraulic diameter
7145 : int const ZoneNum, // Zone number
7146 : Real64 const hOut // User defined convection coefficient
7147 : )
7148 : {
7149 : // SUBROUTINE INFORMATION:
7150 : // AUTHOR Matt Mitchell, Tony Fontanini
7151 : // DATE WRITTEN Feb. 2017
7152 : // MODIFIED na
7153 : // RE-ENGINEERED na
7154 :
7155 : // PURPOSE OF THIS SUBROUTINE:
7156 : // Calculates duct outside convection coefficients
7157 :
7158 : // REFERENCES:
7159 : // ASTM C1340
7160 :
7161 399346 : Real64 k = properties.thermal_conductivity(Ts);
7162 399346 : auto &Zone(m_state.dataHeatBal->Zone);
7163 :
7164 399346 : Real64 hOut_final = 0;
7165 :
7166 399346 : if (hOut == 0) {
7167 :
7168 : // Free convection
7169 399343 : Real64 Pr = properties.prandtl_number(Pamb, (Ts + Tamb) / 2, Wamb);
7170 399343 : Real64 KinVisc = properties.kinematic_viscosity(Pamb, (Ts + Tamb) / 2, Wamb);
7171 399343 : Real64 Beta = 2.0 / ((Tamb + Constant::Kelvin) + (Ts + Constant::Kelvin));
7172 399343 : Real64 Gr = Constant::Gravity * Beta * std::abs(Ts - Tamb) * pow_3(Dh) / pow_2(KinVisc);
7173 399343 : Real64 Ra = Gr * Pr;
7174 399343 : Real64 Nu_free(0);
7175 :
7176 399343 : if (Ra < 10e9) {
7177 399343 : Nu_free = 0.53 * pow(Ra, 0.25);
7178 : } else {
7179 0 : Nu_free = 0.13 * pow(Ra, 0.333);
7180 : }
7181 :
7182 399343 : Real64 V = 0;
7183 : // Forced convection
7184 399343 : if (ZoneNum > 0) {
7185 306607 : Real64 ACH = zone_OA_change_rate(ZoneNum); // Zone air change rate [1/hr]
7186 306607 : Real64 Vol = Zone(ZoneNum).Volume; // Zone volume [m3]
7187 306607 : V = pow(Vol, 0.333) * ACH / 3600; // Average air speed in zone [m/s]
7188 : } else {
7189 92736 : V = m_state.dataEnvrn->WindSpeed;
7190 : }
7191 :
7192 399343 : Real64 Re = V * Dh / KinVisc; // Reynolds number
7193 399343 : Real64 c = 0;
7194 399343 : Real64 n = 0;
7195 :
7196 399343 : if (Re <= 4) {
7197 6 : c = 0.989;
7198 6 : n = 0.33;
7199 399337 : } else if (4 < Re && Re <= 40) {
7200 169307 : c = 0.911;
7201 169307 : n = 0.385;
7202 230030 : } else if (40 < Re && Re <= 4000) {
7203 137294 : c = 0.683;
7204 137294 : n = 0.466;
7205 92736 : } else if (4000 < Re && Re <= 40000) {
7206 38752 : c = 0.193;
7207 38752 : n = 0.618;
7208 53984 : } else if (40000 < Re) {
7209 53984 : c = 0.0266;
7210 53984 : n = 0.805;
7211 : }
7212 :
7213 399343 : Real64 Nu_forced = c * pow(Re, n) * pow(Pr, 0.333);
7214 :
7215 399343 : Real64 Nu_combined = pow(pow_3(Nu_free) + pow_3(Nu_forced), 0.333);
7216 399343 : hOut_final = Nu_combined * k / Dh;
7217 :
7218 : } else {
7219 3 : hOut_final = hOut;
7220 : }
7221 :
7222 399346 : if (hOut_final == 0) {
7223 0 : return 0;
7224 : } else {
7225 399346 : return 1 / hOut_final;
7226 : }
7227 : }
7228 :
7229 11054 : void Solver::calculate_heat_balance()
7230 : {
7231 : // SUBROUTINE INFORMATION:
7232 : // AUTHOR Lixing Gu
7233 : // DATE WRITTEN Oct. 2005
7234 : // MODIFIED na
7235 : // RE-ENGINEERED Revised based on Subroutine CalcADSHeatBalance
7236 :
7237 : // PURPOSE OF THIS SUBROUTINE:
7238 : // This subroutine performs AirflowNetwork thermal simulations.
7239 :
7240 : // USE STATEMENTS:
7241 11054 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
7242 :
7243 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7244 : int i;
7245 : int LF;
7246 : int LT;
7247 : int CompNum;
7248 : int NF;
7249 : int NT;
7250 : iComponentTypeNum CompTypeNum;
7251 : int ExtNodeNum;
7252 : Real64 Ei;
7253 : Real64 DirSign;
7254 : Real64 Tamb;
7255 : Real64 Wamb;
7256 : Real64 Pamb;
7257 : Real64 CpAir;
7258 : Real64 TZON;
7259 : Real64 load;
7260 : int ZoneNum;
7261 :
7262 11054 : auto &Node(m_state.dataLoopNodes->Node);
7263 :
7264 11054 : MA = 0.0;
7265 11054 : MV = 0.0;
7266 :
7267 431106 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
7268 420052 : CompNum = AirflowNetworkLinkageData(i).CompNum;
7269 420052 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
7270 420052 : std::string CompName = AirflowNetworkCompData(CompNum).EPlusName;
7271 420052 : CpAir = PsyCpAirFnW((AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i).NodeNums[0]).WZ +
7272 420052 : AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i).NodeNums[1]).WZ) /
7273 : 2.0);
7274 : // Calculate duct conduction loss
7275 420052 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct element only
7276 121594 : int TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7277 121594 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7278 121594 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7279 121594 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7280 121594 : DirSign = 1.0;
7281 : } else { // flow direction is the opposite as input from node 2 to node 1
7282 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7283 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7284 0 : DirSign = -1.0;
7285 : }
7286 : // Fatal error when return flow is opposite to the desired direction
7287 121594 : if (AirflowNetworkLinkSimu(i).FLOW == 0.0 && AirflowNetworkLinkSimu(i).FLOW2 > 0.0) {
7288 0 : if (LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
7289 0 : ShowSevereError(m_state,
7290 : "AirflowNetwork: The airflow direction is opposite to the intended direction (from node 1 to node 2) in "
7291 0 : "AirflowNetwork:Distribution:Linkage = " +
7292 0 : AirflowNetworkLinkageData(i).Name);
7293 0 : ShowContinueErrorTimeStamp(m_state, "");
7294 0 : ShowContinueError(m_state,
7295 : "The sum of the airflows entering the zone is greater than the airflows leaving the zone (e.g., wind "
7296 : "and stack effect).");
7297 0 : ShowContinueError(m_state,
7298 : "Please check wind speed or reduce values of \"Window/Door Opening Factor, or Crack Factor\" defined in "
7299 : "AirflowNetwork:MultiZone:Surface objects.");
7300 : // ShowFatalError(state, "AirflowNetwork: The previous error causes termination." );
7301 : }
7302 : }
7303 :
7304 121594 : if (AirflowNetworkLinkageData(i).ZoneNum < 0) {
7305 0 : ExtNodeNum = AirflowNetworkLinkageData(i).NodeNums[1];
7306 0 : if (AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum > 0 && Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).IsLocalNode) {
7307 0 : Tamb = Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).OutAirDryBulb;
7308 0 : Wamb = Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).HumRat;
7309 : } else {
7310 0 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(ExtNodeNum).NodeHeight);
7311 0 : Wamb = m_state.dataEnvrn->OutHumRat;
7312 : }
7313 121594 : } else if (AirflowNetworkLinkageData(i).ZoneNum == 0) {
7314 44216 : Tamb = AirflowNetworkNodeSimu(LT).TZ;
7315 44216 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7316 : } else {
7317 77378 : Tamb = ANZT(AirflowNetworkLinkageData(i).ZoneNum);
7318 77378 : Wamb = ANZW(AirflowNetworkLinkageData(i).ZoneNum);
7319 : }
7320 :
7321 121594 : Pamb = m_state.dataEnvrn->OutBaroPress;
7322 :
7323 121594 : Real64 constexpr tolerance = 0.001;
7324 121594 : Real64 UThermal(10); // Initialize. This will get updated.
7325 121594 : Real64 UThermal_iter = 0;
7326 121594 : Real64 Tsurr = Tamb;
7327 121594 : Real64 Tsurr_K = Tsurr + Constant::Kelvin;
7328 121594 : Real64 Tin = AirflowNetworkNodeSimu(LF).TZ;
7329 121594 : Real64 TDuctSurf = (Tamb + Tin) / 2.0;
7330 121594 : Real64 TDuctSurf_K = TDuctSurf + Constant::Kelvin;
7331 121594 : Real64 DuctSurfArea = DisSysCompDuctData(TypeNum).L * DisSysCompDuctData(TypeNum).hydraulicDiameter * Constant::Pi;
7332 :
7333 : // If user defined view factors not present, calculate air-to-air heat transfer
7334 121594 : if (AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum == 0) {
7335 :
7336 : // Calculate convection coefficient if one or both not present
7337 121594 : if (DisSysCompDuctData(TypeNum).InsideConvCoeff == 0 && DisSysCompDuctData(TypeNum).OutsideConvCoeff == 0) {
7338 520931 : while (std::abs(UThermal - UThermal_iter) > tolerance) {
7339 399337 : UThermal_iter = UThermal;
7340 :
7341 1597348 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin,
7342 399337 : AirflowNetworkLinkSimu(i).FLOW,
7343 399337 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7344 399337 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7345 1597348 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7346 : Tamb,
7347 : Wamb,
7348 : Pamb,
7349 399337 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7350 399337 : AirflowNetworkLinkageData(i).ZoneNum,
7351 399337 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7352 399337 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7353 399337 : Real64 RThermTotal = RThermConvIn + RThermConvOut + RThermConduct;
7354 399337 : UThermal = pow(RThermTotal, -1);
7355 :
7356 : // Duct conduction, assuming effectiveness = 1 - exp(-NTU)
7357 399337 : Ei = General::epexp(-UThermal * DuctSurfArea, (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7358 399337 : Real64 QCondDuct = std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * (Tamb - Tin) * (1 - Ei);
7359 :
7360 399337 : TDuctSurf = Tamb - QCondDuct * RThermConvOut / DuctSurfArea;
7361 : }
7362 : } else { // Air-to-air only. U and h values are all known
7363 0 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin,
7364 0 : AirflowNetworkLinkSimu(i).FLOW,
7365 0 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7366 0 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7367 0 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7368 : Tamb,
7369 : Wamb,
7370 : Pamb,
7371 0 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7372 0 : AirflowNetworkLinkageData(i).ZoneNum,
7373 0 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7374 0 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7375 0 : Real64 RThermTotal = RThermConvIn + RThermConvOut + RThermConduct;
7376 0 : UThermal = pow(RThermTotal, -1);
7377 : }
7378 :
7379 121594 : Tsurr = Tamb;
7380 :
7381 : } else { // Air-to-air + radiation heat transfer
7382 :
7383 0 : auto &VFObj(AirflowNetworkLinkageViewFactorData(AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum));
7384 0 : VFObj.QRad = 0;
7385 0 : VFObj.QConv = 0;
7386 :
7387 0 : Real64 Tin_ave = Tin;
7388 0 : Real64 hOut = 0;
7389 :
7390 0 : while (std::abs(UThermal - UThermal_iter) > tolerance) {
7391 0 : UThermal_iter = UThermal;
7392 :
7393 0 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin_ave,
7394 0 : AirflowNetworkLinkSimu(i).FLOW,
7395 0 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7396 0 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7397 0 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7398 : Tamb,
7399 : Wamb,
7400 : Pamb,
7401 0 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7402 0 : AirflowNetworkLinkageData(i).ZoneNum,
7403 0 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7404 :
7405 0 : if (RThermConvOut > 0.0) {
7406 0 : hOut = 1 / RThermConvOut;
7407 : }
7408 :
7409 0 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7410 :
7411 0 : Real64 hrjTj_sum = 0;
7412 0 : Real64 hrj_sum = 0;
7413 :
7414 0 : for (int j = 1; j <= VFObj.LinkageSurfaceData.u(); ++j) {
7415 :
7416 0 : int ZoneSurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7417 :
7418 0 : Real64 TSurfj = m_state.dataHeatBalSurf->SurfOutsideTempHist(1)(ZoneSurfNum);
7419 0 : Real64 TSurfj_K = TSurfj + Constant::Kelvin;
7420 :
7421 : Real64 ZoneSurfEmissivity =
7422 0 : m_state.dataConstruction->Construct(m_state.dataSurface->Surface(ZoneSurfNum).Construction).InsideAbsorpThermal;
7423 0 : Real64 ZoneSurfArea = m_state.dataSurface->Surface(ZoneSurfNum).Area;
7424 :
7425 0 : Real64 DuctEmissivity = VFObj.DuctEmittance;
7426 0 : Real64 DuctExposureFrac = VFObj.DuctExposureFraction;
7427 0 : Real64 DuctToZoneSurfViewFactor = VFObj.LinkageSurfaceData(j).ViewFactor;
7428 :
7429 0 : Real64 DuctSurfResistance = (1 - DuctEmissivity) / (DuctExposureFrac * DuctSurfArea * DuctEmissivity);
7430 0 : Real64 SpaceResistance = 1 / (DuctExposureFrac * DuctSurfArea * DuctToZoneSurfViewFactor);
7431 0 : Real64 ZoneSurfResistance = (1 - ZoneSurfEmissivity) / (ZoneSurfArea * ZoneSurfEmissivity);
7432 :
7433 0 : VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor =
7434 0 : Constant::StefanBoltzmann / (DuctSurfResistance + SpaceResistance + ZoneSurfResistance);
7435 :
7436 0 : Real64 hrj = VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor * (TDuctSurf_K + TSurfj_K) *
7437 0 : (pow_2(TDuctSurf_K) + pow_2(TSurfj_K)) / DuctSurfArea;
7438 :
7439 0 : hrjTj_sum += hrj * TSurfj;
7440 0 : hrj_sum += hrj;
7441 : }
7442 :
7443 0 : Tsurr = (hOut * Tamb + hrjTj_sum) / (hOut + hrj_sum); // Surroundings temperature [C]
7444 0 : Tsurr_K = Tsurr + Constant::Kelvin;
7445 :
7446 0 : Real64 RThermTotal = RThermConvIn + RThermConduct + 1 / (hOut + hrj_sum);
7447 0 : UThermal = pow(RThermTotal, -1);
7448 :
7449 0 : Real64 NTU = UThermal * DuctSurfArea / (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir);
7450 0 : Tin_ave = Tsurr + (Tin - Tsurr) * (1 / NTU) * (1 - exp(-NTU));
7451 :
7452 0 : TDuctSurf = Tin_ave - UThermal * (RThermConvIn + RThermConduct) * (Tin_ave - Tsurr);
7453 0 : TDuctSurf_K = TDuctSurf + Constant::Kelvin;
7454 : }
7455 :
7456 0 : for (int j = 1; j <= VFObj.LinkageSurfaceData.u(); ++j) {
7457 0 : int ZoneSurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7458 0 : Real64 TSurfj = m_state.dataHeatBalSurf->SurfOutsideTempHist(1)(ZoneSurfNum);
7459 0 : Real64 TSurfj_K = TSurfj + Constant::Kelvin;
7460 0 : VFObj.LinkageSurfaceData(j).SurfaceRadLoad = VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor *
7461 0 : (pow_4(TDuctSurf_K) - pow_4(TSurfj_K)); // Radiant load for this surface [W]
7462 0 : int SurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7463 0 : Real64 ZoneSurfaceArea = m_state.dataSurface->Surface(SurfNum).Area;
7464 0 : m_state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) += VFObj.LinkageSurfaceData(j).SurfaceRadLoad * TimeStepSys *
7465 0 : Constant::rSecsInHour /
7466 : ZoneSurfaceArea; // Energy to each surface per unit area [J/m2]
7467 0 : VFObj.QRad += VFObj.LinkageSurfaceData(j).SurfaceRadLoad; // Total radiant load from all surfaces for this system timestep [W]
7468 : }
7469 :
7470 0 : VFObj.QConv = hOut * DuctSurfArea * (TDuctSurf - Tamb);
7471 0 : UThermal = (VFObj.QRad + VFObj.QConv) / (DuctSurfArea * std::abs(Tsurr - Tin));
7472 : }
7473 :
7474 121594 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7475 0 : Ei = General::epexp(-UThermal * DuctSurfArea, (AirflowNetworkLinkSimu(i).FLOW2 * CpAir));
7476 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7477 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * Ei;
7478 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Tsurr * (1.0 - Ei) * CpAir;
7479 : } else {
7480 121594 : Ei = General::epexp(-UThermal * DuctSurfArea, (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7481 121594 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7482 121594 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * Ei;
7483 121594 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Tsurr * (1.0 - Ei) * CpAir;
7484 : }
7485 : }
7486 420052 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
7487 0 : int TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7488 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7489 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7490 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7491 0 : DirSign = 1.0;
7492 : } else { // flow direction is the opposite as input from node 2 to node 1
7493 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7494 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7495 0 : DirSign = -1.0;
7496 : }
7497 0 : Ei = General::epexp(-0.001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7498 0 : (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7499 0 : Tamb = AirflowNetworkNodeSimu(LT).TZ;
7500 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7501 0 : Ei = General::epexp(-0.001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7502 0 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir));
7503 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7504 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * Ei;
7505 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Tamb * (1.0 - Ei) * CpAir;
7506 : } else {
7507 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7508 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * Ei;
7509 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Tamb * (1.0 - Ei) * CpAir;
7510 : }
7511 : }
7512 420052 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
7513 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7514 33162 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7515 33162 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7516 33162 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7517 33162 : DirSign = 1.0;
7518 : } else { // flow direction is the opposite as input from node 2 to node 1
7519 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7520 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7521 0 : DirSign = -1.0;
7522 : }
7523 : }
7524 : // Calculate temp in a constant pressure drop element
7525 420052 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
7526 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7527 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7528 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7529 : } else { // flow direction is the opposite as input from node 2 to node 1
7530 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7531 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7532 : }
7533 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7534 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7535 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7536 : } else {
7537 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7538 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7539 : }
7540 0 : MV(LT) = 0.0;
7541 : }
7542 : // Calculate return leak
7543 420052 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
7544 : // Return leak element only
7545 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
7546 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7547 22108 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7548 22108 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7549 22108 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7550 22108 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7551 : }
7552 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
7553 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7554 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7555 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7556 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7557 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7558 : }
7559 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
7560 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7561 4308 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7562 4308 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7563 4308 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7564 4308 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7565 : }
7566 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
7567 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7568 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7569 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7570 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7571 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7572 : }
7573 : }
7574 : // Check reheat unit or coil
7575 420052 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(i).VAVTermDamper)) {
7576 0 : NF = 0;
7577 0 : NT = 0;
7578 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
7579 0 : NF = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum;
7580 : }
7581 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
7582 0 : NT = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum;
7583 : }
7584 0 : if ((NF == 0) || (NT == 0)) {
7585 0 : ShowFatalError(m_state,
7586 0 : "Node number in the primary air loop is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " +
7587 0 : AirflowNetworkLinkageData(i).Name);
7588 : }
7589 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) {
7590 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7591 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7592 0 : load = Node(NT).Temp - Node(NF).Temp;
7593 : } else {
7594 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7595 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7596 0 : load = Node(NF).Temp - Node(NT).Temp;
7597 : }
7598 0 : CpAir = PsyCpAirFnW(Node(NT).HumRat);
7599 0 : MV(LT) += AirflowNetworkLinkSimu(i).FLOW * CpAir * load;
7600 : }
7601 420052 : }
7602 :
7603 : // Prescribe temperature for EPlus nodes
7604 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7605 375836 : bool found = false;
7606 375836 : bool OANode = false;
7607 14259660 : for (int j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
7608 13928040 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7609 817996 : CompNum = AirflowNetworkLinkageData(j).CompNum;
7610 817996 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
7611 0 : found = true;
7612 0 : break;
7613 : }
7614 : // Overwrite fan outlet node
7615 817996 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7616 11054 : found = false;
7617 11054 : break;
7618 : }
7619 : // Overwrite return connection outlet
7620 806942 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
7621 22108 : found = true;
7622 22108 : break;
7623 : }
7624 806942 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
7625 22108 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
7626 11054 : found = true;
7627 11054 : break;
7628 : }
7629 : }
7630 14270714 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
7631 386890 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
7632 0 : OANode = true;
7633 0 : break;
7634 : }
7635 : }
7636 375836 : if (found) continue;
7637 342674 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
7638 331620 : int j = AirflowNetworkNodeData(i).EPlusNodeNum;
7639 :
7640 408998 : if (j > 0 &&
7641 77378 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
7642 55270 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
7643 55270 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7644 55270 : MV(i) = Node(j).Temp * 1.0e10;
7645 : }
7646 331620 : if (j > 0 && OANode) {
7647 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7648 0 : MV(i) = Node(j).Temp * 1.0e10;
7649 : }
7650 331620 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7651 22108 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
7652 22108 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7653 22108 : MV(i) = ANZT(ZoneNum) * 1.0e10;
7654 : }
7655 331620 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7656 187918 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7657 187918 : if (AirflowNetworkNodeData(i).OutAirNodeNum > 0) {
7658 0 : MV(i) = Node(AirflowNetworkNodeData(i).OutAirNodeNum).OutAirDryBulb * 1.0e10;
7659 : } else {
7660 187918 : MV(i) = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(i).NodeHeight) * 1.0e10;
7661 : }
7662 : }
7663 331620 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7664 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7665 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
7666 0 : if (m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID == i) {
7667 0 : MV(i) = m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp * 1.0e10;
7668 : }
7669 : }
7670 : }
7671 :
7672 : // Assign node value to distribution nodes with fan off
7673 165810 : for (i = 1 + NumOfNodesMultiZone; i <= AirflowNetworkNumOfNodes; ++i) {
7674 154756 : int j = AirflowNetworkNodeData(i).EPlusNodeNum;
7675 154756 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
7676 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7677 0 : MV(i) = Node(j).Temp * 1.0e10;
7678 : }
7679 154756 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
7680 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7681 0 : MV(i) = AirflowNetworkNodeSimu(i).TZlast * 1.0e10;
7682 : }
7683 : }
7684 :
7685 : // Check singularity
7686 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7687 375836 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
7688 0 : if (i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
7689 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7690 0 : MV(i) = AirflowNetworkNodeSimu(i).TZlast * 1.0e10;
7691 : } else {
7692 0 : ShowFatalError(m_state,
7693 0 : "CalcAirflowNetworkHeatBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
7694 0 : AirflowNetworkNodeData(i).Name);
7695 : }
7696 : }
7697 : }
7698 :
7699 : // Get an inverse matrix
7700 11054 : mrxinv(AirflowNetworkNumOfNodes);
7701 :
7702 : // Calculate node temperatures
7703 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7704 375836 : TZON = 0.0;
7705 13154260 : for (int j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
7706 12778424 : TZON += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
7707 : }
7708 375836 : AirflowNetworkNodeSimu(i).TZ = TZON;
7709 : }
7710 11054 : }
7711 :
7712 11054 : void Solver::calculate_moisture_balance()
7713 : {
7714 : // SUBROUTINE INFORMATION:
7715 : // AUTHOR Lixing Gu
7716 : // DATE WRITTEN Oct. 2005
7717 : // MODIFIED na
7718 : // RE-ENGINEERED Revised based on Subroutine CalcADSMoistureBalance
7719 :
7720 : // PURPOSE OF THIS SUBROUTINE:
7721 : // This subroutine performs AirflowNetwork moisture simulations.
7722 :
7723 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7724 : int i;
7725 : int j;
7726 : int LF;
7727 : int LT;
7728 : int CompNum;
7729 : int NF;
7730 : int NT;
7731 : iComponentTypeNum CompTypeNum;
7732 : int TypeNum;
7733 : Real64 Ei;
7734 : Real64 DirSign;
7735 : Real64 Wamb;
7736 : Real64 WZON;
7737 : Real64 load;
7738 : int ZoneNum;
7739 :
7740 11054 : auto &Node(m_state.dataLoopNodes->Node);
7741 :
7742 11054 : MA = 0.0;
7743 11054 : MV = 0.0;
7744 431106 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
7745 420052 : CompNum = AirflowNetworkLinkageData(i).CompNum;
7746 420052 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
7747 420052 : std::string CompName = AirflowNetworkCompData(CompNum).EPlusName;
7748 : // Calculate duct moisture diffusion loss
7749 420052 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct component only
7750 121594 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7751 121594 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7752 121594 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7753 121594 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7754 121594 : DirSign = 1.0;
7755 : } else { // flow direction is the opposite as input from node 2 to node 1
7756 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7757 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7758 0 : DirSign = -1.0;
7759 : }
7760 121594 : Ei = General::epexp(-DisSysCompDuctData(TypeNum).UMoisture * DisSysCompDuctData(TypeNum).L *
7761 121594 : DisSysCompDuctData(TypeNum).hydraulicDiameter * Constant::Pi,
7762 121594 : (DirSign * AirflowNetworkLinkSimu(i).FLOW));
7763 121594 : if (AirflowNetworkLinkageData(i).ZoneNum < 0) {
7764 0 : Wamb = m_state.dataEnvrn->OutHumRat;
7765 121594 : } else if (AirflowNetworkLinkageData(i).ZoneNum == 0) {
7766 44216 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7767 : } else {
7768 77378 : Wamb = ANZW(AirflowNetworkLinkageData(i).ZoneNum);
7769 : }
7770 121594 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7771 0 : Ei = General::epexp(-DisSysCompDuctData(TypeNum).UMoisture * DisSysCompDuctData(TypeNum).L *
7772 0 : DisSysCompDuctData(TypeNum).hydraulicDiameter * Constant::Pi,
7773 0 : (AirflowNetworkLinkSimu(i).FLOW2));
7774 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7775 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Ei;
7776 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Wamb * (1.0 - Ei);
7777 : } else {
7778 121594 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7779 121594 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * Ei;
7780 121594 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Wamb * (1.0 - Ei);
7781 : }
7782 : }
7783 420052 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
7784 0 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7785 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7786 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7787 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7788 0 : DirSign = 1.0;
7789 : } else { // flow direction is the opposite as input from node 2 to node 1
7790 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7791 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7792 0 : DirSign = -1.0;
7793 : }
7794 0 : Ei = General::epexp(-0.0001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7795 0 : (DirSign * AirflowNetworkLinkSimu(i).FLOW));
7796 0 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7797 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7798 :
7799 : Ei =
7800 0 : General::epexp(-0.0001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7801 0 : (AirflowNetworkLinkSimu(i).FLOW2));
7802 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7803 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Ei;
7804 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Wamb * (1.0 - Ei);
7805 : } else {
7806 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7807 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * Ei;
7808 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Wamb * (1.0 - Ei);
7809 : }
7810 : }
7811 420052 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
7812 33162 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7813 33162 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7814 33162 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7815 33162 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7816 33162 : DirSign = 1.0;
7817 : } else { // flow direction is the opposite as input from node 2 to node 1
7818 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7819 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7820 0 : DirSign = -1.0;
7821 : }
7822 : }
7823 : // Calculate temp in a constant pressure drop component
7824 420052 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
7825 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7826 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7827 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7828 : } else { // flow direction is the opposite as input from node 2 to node 1
7829 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7830 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7831 : }
7832 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7833 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7834 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7835 : } else {
7836 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7837 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7838 : }
7839 0 : MV(LT) = 0.0;
7840 : }
7841 : // Calculate return leak
7842 420052 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
7843 : // Return leak component only
7844 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
7845 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7846 22108 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7847 22108 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7848 22108 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7849 22108 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7850 : }
7851 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
7852 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7853 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7854 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7855 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7856 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7857 : }
7858 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
7859 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7860 4308 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7861 4308 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7862 4308 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7863 4308 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7864 : }
7865 44216 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
7866 44216 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7867 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7868 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7869 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7870 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7871 : }
7872 : }
7873 : // Check reheat unit
7874 420052 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(i).VAVTermDamper)) {
7875 0 : NF = 0;
7876 0 : NT = 0;
7877 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
7878 0 : NF = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum;
7879 : }
7880 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
7881 0 : NT = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum;
7882 : }
7883 0 : if ((NF == 0) || (NT == 0)) {
7884 0 : ShowFatalError(m_state,
7885 0 : "Node number in the primary air loop is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " +
7886 0 : AirflowNetworkLinkageData(i).Name);
7887 : }
7888 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) {
7889 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7890 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7891 0 : load = Node(NT).HumRat - Node(NF).HumRat;
7892 : } else {
7893 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7894 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7895 0 : load = Node(NF).HumRat - Node(NT).HumRat;
7896 : }
7897 0 : MV(LT) += AirflowNetworkLinkSimu(i).FLOW * load;
7898 : }
7899 420052 : }
7900 :
7901 : // Prescribe temperature for EPlus nodes
7902 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7903 375836 : bool found = false;
7904 375836 : bool OANode = false;
7905 14259660 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
7906 13928040 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7907 817996 : CompNum = AirflowNetworkLinkageData(j).CompNum;
7908 817996 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
7909 0 : found = true;
7910 0 : break;
7911 : }
7912 : // Overwrite fan outlet node
7913 817996 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7914 11054 : found = false;
7915 11054 : break;
7916 : }
7917 : // Overwrite return connection outlet
7918 806942 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
7919 22108 : found = true;
7920 22108 : break;
7921 : }
7922 806942 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
7923 22108 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
7924 11054 : found = true;
7925 11054 : break;
7926 : }
7927 : }
7928 14270714 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
7929 386890 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
7930 0 : OANode = true;
7931 0 : break;
7932 : }
7933 : }
7934 375836 : if (found) continue;
7935 342674 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
7936 331620 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
7937 408998 : if (j > 0 &&
7938 77378 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
7939 55270 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
7940 55270 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7941 55270 : MV(i) = Node(j).HumRat * 1.0e10;
7942 : }
7943 331620 : if (j > 0 && OANode) {
7944 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7945 0 : MV(i) = Node(j).HumRat * 1.0e10;
7946 : }
7947 331620 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7948 22108 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
7949 22108 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7950 22108 : MV(i) = ANZW(ZoneNum) * 1.0e10;
7951 : }
7952 331620 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
7953 187918 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7954 187918 : MV(i) = m_state.dataEnvrn->OutHumRat * 1.0e10;
7955 : }
7956 331620 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7957 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7958 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
7959 0 : if (m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID == i) {
7960 0 : MV(i) = m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat * 1.0e10;
7961 : }
7962 : }
7963 : }
7964 :
7965 : // Assign node value to distribution nodes with fan off
7966 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7967 375836 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
7968 375836 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
7969 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7970 0 : MV(i) = Node(j).HumRat * 1.0e10;
7971 : }
7972 375836 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
7973 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7974 0 : MV(i) = AirflowNetworkNodeSimu(i).WZlast * 1.0e10;
7975 : }
7976 : }
7977 :
7978 : // Check singularity
7979 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7980 375836 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-8) {
7981 0 : ShowFatalError(m_state,
7982 0 : "CalcAirflowNetworkMoisBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
7983 0 : AirflowNetworkNodeData(i).Name);
7984 : }
7985 : }
7986 :
7987 : // Get an inverse matrix
7988 11054 : mrxinv(AirflowNetworkNumOfNodes);
7989 :
7990 : // Calculate node temperatures
7991 386890 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7992 375836 : WZON = 0.0;
7993 13154260 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
7994 12778424 : WZON += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
7995 : }
7996 375836 : AirflowNetworkNodeSimu(i).WZ = WZON;
7997 : }
7998 11054 : }
7999 :
8000 0 : void Solver::calculate_CO2_balance()
8001 : {
8002 : // SUBROUTINE INFORMATION:
8003 : // AUTHOR Lixing Gu
8004 : // DATE WRITTEN June. 2010
8005 : // MODIFIED na
8006 : // RE-ENGINEERED Revised based on Subroutine CalcAirflowNetworkMoisBalance
8007 :
8008 : // PURPOSE OF THIS SUBROUTINE:
8009 : // This subroutine performs AirflowNetwork CO2 simulations.
8010 :
8011 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8012 : int i;
8013 : int j;
8014 : int LF;
8015 : int LT;
8016 : int CompNum;
8017 : iComponentTypeNum CompTypeNum;
8018 : Real64 DirSign;
8019 : Real64 COZN;
8020 : int ZoneNum;
8021 :
8022 0 : MA = 0.0;
8023 0 : MV = 0.0;
8024 0 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
8025 0 : CompNum = AirflowNetworkLinkageData(i).CompNum;
8026 0 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
8027 0 : std::string CompName = AirflowNetworkCompData(CompNum).EPlusName;
8028 : // Calculate duct moisture diffusion loss
8029 0 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct component only
8030 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8031 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8032 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8033 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8034 0 : DirSign = 1.0;
8035 : } else { // flow direction is the opposite as input from node 2 to node 1
8036 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8037 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8038 0 : DirSign = -1.0;
8039 : }
8040 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8041 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8042 : }
8043 0 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
8044 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8045 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8046 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8047 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8048 0 : DirSign = 1.0;
8049 : } else { // flow direction is the opposite as input from node 2 to node 1
8050 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8051 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8052 0 : DirSign = -1.0;
8053 : }
8054 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8055 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8056 : }
8057 0 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
8058 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8059 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8060 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8061 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8062 0 : DirSign = 1.0;
8063 : } else { // flow direction is the opposite as input from node 2 to node 1
8064 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8065 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8066 0 : DirSign = -1.0;
8067 : }
8068 : }
8069 : // Calculate temp in a constant pressure drop component
8070 0 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
8071 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8072 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8073 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8074 : } else { // flow direction is the opposite as input from node 2 to node 1
8075 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8076 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8077 : }
8078 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8079 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8080 0 : MV(LT) = 0.0;
8081 : }
8082 : // Calculate return leak
8083 0 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
8084 : // Return leak component only
8085 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
8086 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8087 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8088 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8089 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8090 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8091 : }
8092 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
8093 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8094 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8095 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8096 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8097 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8098 : }
8099 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
8100 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8101 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8102 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8103 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8104 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8105 : }
8106 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
8107 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8108 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8109 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8110 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8111 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8112 : }
8113 : }
8114 0 : }
8115 :
8116 : // Prescribe temperature for EPlus nodes
8117 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8118 0 : bool found = false;
8119 0 : bool OANode = false;
8120 0 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
8121 0 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8122 0 : CompNum = AirflowNetworkLinkageData(j).CompNum;
8123 0 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
8124 0 : found = true;
8125 0 : break;
8126 : }
8127 : // Overwrite fan outlet node
8128 0 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8129 0 : found = false;
8130 0 : break;
8131 : }
8132 : // Overwrite return connection outlet
8133 0 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
8134 0 : found = true;
8135 0 : break;
8136 : }
8137 0 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
8138 0 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
8139 0 : found = true;
8140 0 : break;
8141 : }
8142 : }
8143 0 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
8144 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
8145 0 : OANode = true;
8146 0 : break;
8147 : }
8148 : }
8149 0 : if (found) continue;
8150 0 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
8151 0 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8152 0 : if (j > 0 &&
8153 0 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
8154 0 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
8155 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8156 0 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8157 : }
8158 0 : if (j > 0 && OANode) {
8159 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8160 0 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8161 : }
8162 0 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8163 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8164 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8165 0 : MV(i) = ANCO(ZoneNum) * 1.0e10;
8166 : }
8167 0 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
8168 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8169 0 : MV(i) = m_state.dataContaminantBalance->OutdoorCO2 * 1.0e10;
8170 : }
8171 : }
8172 :
8173 : // Assign node value to distribution nodes with fan off
8174 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8175 0 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8176 0 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
8177 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8178 0 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8179 : }
8180 0 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
8181 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8182 0 : MV(i) = AirflowNetworkNodeSimu(i).CO2Zlast * 1.0e10;
8183 : }
8184 : }
8185 :
8186 : // Check singularity
8187 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8188 0 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
8189 0 : ShowFatalError(m_state,
8190 0 : "CalcAirflowNetworkCO2Balance: A diagonal entity is zero in AirflowNetwork matrix at node " +
8191 0 : AirflowNetworkNodeData(i).Name);
8192 : }
8193 : }
8194 :
8195 : // Get an inverse matrix
8196 0 : mrxinv(AirflowNetworkNumOfNodes);
8197 :
8198 : // Calculate node temperatures
8199 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8200 0 : COZN = 0.0;
8201 0 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
8202 0 : COZN += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
8203 : }
8204 0 : AirflowNetworkNodeSimu(i).CO2Z = COZN;
8205 : }
8206 0 : }
8207 :
8208 0 : void Solver::calculate_GC_balance()
8209 : {
8210 : // SUBROUTINE INFORMATION:
8211 : // AUTHOR Lixing Gu
8212 : // DATE WRITTEN Jan. 2012
8213 : // MODIFIED na
8214 : // RE-ENGINEERED Revised based on Subroutine CalcAirflowNetworkCO2Balance
8215 :
8216 : // PURPOSE OF THIS SUBROUTINE:
8217 : // This subroutine performs AirflowNetwork generic contaminant simulations.
8218 :
8219 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8220 : int i;
8221 : int j;
8222 : int LF;
8223 : int LT;
8224 : int CompNum;
8225 : iComponentTypeNum CompTypeNum;
8226 : Real64 DirSign;
8227 : Real64 COZN;
8228 : int ZoneNum;
8229 :
8230 0 : MA = 0.0;
8231 0 : MV = 0.0;
8232 0 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
8233 0 : CompNum = AirflowNetworkLinkageData(i).CompNum;
8234 0 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
8235 0 : std::string_view CompName = AirflowNetworkCompData(CompNum).EPlusName;
8236 : // Calculate duct moisture diffusion loss
8237 0 : if (CompTypeNum == iComponentTypeNum::DWC && CompName.empty()) { // Duct component only
8238 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8239 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8240 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8241 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8242 0 : DirSign = 1.0;
8243 : } else { // flow direction is the opposite as input from node 2 to node 1
8244 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8245 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8246 0 : DirSign = -1.0;
8247 : }
8248 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8249 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8250 : }
8251 0 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
8252 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8253 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8254 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8255 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8256 0 : DirSign = 1.0;
8257 : } else { // flow direction is the opposite as input from node 2 to node 1
8258 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8259 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8260 0 : DirSign = -1.0;
8261 : }
8262 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8263 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8264 : }
8265 0 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
8266 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8267 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8268 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8269 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8270 0 : DirSign = 1.0;
8271 : } else { // flow direction is the opposite as input from node 2 to node 1
8272 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8273 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8274 0 : DirSign = -1.0;
8275 : }
8276 : }
8277 : // Calculate temp in a constant pressure drop component
8278 0 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
8279 0 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8280 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8281 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8282 : } else { // flow direction is the opposite as input from node 2 to node 1
8283 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8284 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8285 : }
8286 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8287 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8288 0 : MV(LT) = 0.0;
8289 : }
8290 : // Calculate return leak
8291 0 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
8292 : // Return leak component only
8293 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
8294 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8295 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8296 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8297 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8298 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8299 : }
8300 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
8301 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8302 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8303 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8304 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8305 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8306 : }
8307 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
8308 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8309 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8310 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8311 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8312 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8313 : }
8314 0 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
8315 0 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8316 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8317 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8318 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8319 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8320 : }
8321 : }
8322 : }
8323 :
8324 : // Prescribe temperature for EPlus nodes
8325 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8326 0 : bool found = false;
8327 0 : bool OANode = false;
8328 0 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
8329 0 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8330 0 : CompNum = AirflowNetworkLinkageData(j).CompNum;
8331 0 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
8332 0 : found = true;
8333 0 : break;
8334 : }
8335 : // Overwrite fan outlet node
8336 0 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8337 0 : found = false;
8338 0 : break;
8339 : }
8340 : // Overwrite return connection outlet
8341 0 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
8342 0 : found = true;
8343 0 : break;
8344 : }
8345 0 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
8346 0 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
8347 0 : found = true;
8348 0 : break;
8349 : }
8350 : }
8351 0 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
8352 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
8353 0 : OANode = true;
8354 0 : break;
8355 : }
8356 : }
8357 0 : if (found) continue;
8358 0 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
8359 0 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8360 0 : if (j > 0 &&
8361 0 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
8362 0 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
8363 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8364 0 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8365 : }
8366 0 : if (j > 0 && OANode) {
8367 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8368 0 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8369 : }
8370 0 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8371 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8372 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8373 0 : MV(i) = ANGC(ZoneNum) * 1.0e10;
8374 : }
8375 0 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
8376 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8377 0 : MV(i) = m_state.dataContaminantBalance->OutdoorGC * 1.0e10;
8378 : }
8379 : }
8380 :
8381 : // Assign node value to distribution nodes with fan off
8382 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8383 0 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8384 0 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
8385 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8386 0 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8387 : }
8388 0 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
8389 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8390 0 : MV(i) = AirflowNetworkNodeSimu(i).GCZlast * 1.0e10;
8391 : }
8392 : }
8393 :
8394 : // Check singularity
8395 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8396 0 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
8397 0 : ShowFatalError(m_state,
8398 0 : "CalcAirflowNetworkGCBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
8399 0 : AirflowNetworkNodeData(i).Name);
8400 : }
8401 : }
8402 :
8403 : // Get an inverse matrix
8404 0 : mrxinv(AirflowNetworkNumOfNodes);
8405 :
8406 : // Calculate node temperatures
8407 0 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8408 0 : COZN = 0.0;
8409 0 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
8410 0 : COZN += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
8411 : }
8412 0 : AirflowNetworkNodeSimu(i).GCZ = COZN;
8413 : }
8414 0 : }
8415 :
8416 22108 : void Solver::mrxinv(int const NORDER)
8417 : {
8418 :
8419 : // SUBROUTINE INFORMATION:
8420 : // AUTHOR Lixing Gu
8421 : // DATE WRITTEN Oct. 2005
8422 : // MODIFIED na
8423 : // RE-ENGINEERED Revised based on Subroutine ADSINV
8424 :
8425 : // PURPOSE OF THIS SUBROUTINE:
8426 : // This subroutine inverses a matrix
8427 :
8428 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8429 : int i;
8430 : int j;
8431 : int K;
8432 : int M;
8433 : Real64 R1;
8434 : Real64 S;
8435 :
8436 22108 : IVEC = 0;
8437 773780 : for (i = 1; i <= NORDER; ++i) {
8438 751672 : IVEC(i + 20) = i;
8439 : }
8440 773780 : for (i = 1; i <= NORDER; ++i) {
8441 751672 : R1 = 0.0;
8442 751672 : M = i;
8443 13905932 : for (j = i; j <= NORDER; ++j) {
8444 13154260 : if (std::abs(R1) < std::abs(MA((i - 1) * NORDER + j))) {
8445 751672 : M = j;
8446 751672 : R1 = MA((i - 1) * NORDER + j);
8447 : }
8448 : }
8449 751672 : if (i != M) {
8450 0 : K = IVEC(M + 20);
8451 0 : IVEC(M + 20) = IVEC(i + 20);
8452 0 : IVEC(i + 20) = K;
8453 0 : for (j = 1; j <= NORDER; ++j) {
8454 0 : S = MA((j - 1) * NORDER + i);
8455 0 : MA((j - 1) * NORDER + i) = MA((j - 1) * NORDER + M);
8456 0 : MA((j - 1) * NORDER + M) = S;
8457 : }
8458 : }
8459 751672 : MA((i - 1) * NORDER + i) = 1.0;
8460 26308520 : for (j = 1; j <= NORDER; ++j) {
8461 25556848 : MA((i - 1) * NORDER + j) /= R1;
8462 : }
8463 26308520 : for (j = 1; j <= NORDER; ++j) {
8464 25556848 : if (i == j) continue;
8465 24805176 : R1 = MA((j - 1) * NORDER + i);
8466 24805176 : if (std::abs(R1) <= 1.0E-20) continue;
8467 561316 : MA((j - 1) * NORDER + i) = 0.0;
8468 19646060 : for (K = 1; K <= NORDER; ++K) {
8469 19084744 : MA((j - 1) * NORDER + K) -= R1 * MA((i - 1) * NORDER + K);
8470 : }
8471 : }
8472 : }
8473 773780 : for (i = 1; i <= NORDER; ++i) {
8474 751672 : if (IVEC(i + 20) == i) continue;
8475 0 : M = i;
8476 0 : while (NORDER > M) {
8477 0 : ++M;
8478 0 : if (IVEC(M + 20) == i) break;
8479 : }
8480 0 : IVEC(M + 20) = IVEC(i + 20);
8481 0 : for (j = 1; j <= NORDER; ++j) {
8482 0 : R1 = MA((i - 1) * NORDER + j);
8483 0 : MA((i - 1) * NORDER + j) = MA((M - 1) * NORDER + j);
8484 0 : MA((M - 1) * NORDER + j) = R1;
8485 : }
8486 0 : IVEC(i + 20) = i;
8487 : }
8488 22108 : }
8489 :
8490 344 : void Solver::report()
8491 : {
8492 :
8493 : // SUBROUTINE INFORMATION:
8494 : // AUTHOR Lixing Gu
8495 : // DATE WRITTEN 2/1/04
8496 : // MODIFIED na
8497 : // RE-ENGINEERED na
8498 :
8499 : // PURPOSE OF THIS SUBROUTINE:
8500 : // This subroutine reports outputs of air distribution systems
8501 :
8502 : // Using/Aliasing
8503 344 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
8504 344 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
8505 :
8506 344 : auto &Zone(m_state.dataHeatBal->Zone);
8507 :
8508 : // SUBROUTINE PARAMETER DEFINITIONS:
8509 344 : constexpr Real64 Lam(2.5e6); // Heat of vaporization (J/kg)
8510 :
8511 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8512 : int i;
8513 : int n;
8514 : int M;
8515 : int ZN1;
8516 : int ZN2;
8517 : Real64 AirDensity;
8518 : Real64 CpAir;
8519 : Real64 Tamb;
8520 : Real64 hg; // latent heat of vaporization
8521 : Real64 ReportingConstant;
8522 : Real64 ReportingFraction;
8523 : int AirLoopNum;
8524 : int FanNum;
8525 : Real64 RepOnOffFanRunTimeFraction;
8526 :
8527 344 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) return;
8528 :
8529 344 : if (!onetime) {
8530 3 : onceZoneFlag.dimension(m_state.dataGlobal->NumOfZones, false);
8531 3 : onceSurfFlag.dimension(AirflowNetworkNumOfLinks, false);
8532 3 : onetime = true;
8533 : }
8534 344 : ReportingConstant = TimeStepSys * Constant::rSecsInHour;
8535 :
8536 344 : m_state.dataHeatBal->ZoneTotalExfiltrationHeatLoss = 0.0;
8537 :
8538 1385 : for (auto &e : AirflowNetworkReportData) {
8539 1041 : e.MultiZoneInfiSenGainW = 0.0;
8540 1041 : e.MultiZoneInfiSenGainJ = 0.0;
8541 1041 : e.MultiZoneInfiSenLossW = 0.0;
8542 1041 : e.MultiZoneInfiSenLossJ = 0.0;
8543 1041 : e.MultiZoneInfiLatGainW = 0.0;
8544 1041 : e.MultiZoneInfiLatGainJ = 0.0;
8545 1041 : e.MultiZoneInfiLatLossW = 0.0;
8546 1041 : e.MultiZoneInfiLatLossJ = 0.0;
8547 1041 : e.MultiZoneVentSenGainW = 0.0;
8548 1041 : e.MultiZoneVentSenGainJ = 0.0;
8549 1041 : e.MultiZoneVentSenLossW = 0.0;
8550 1041 : e.MultiZoneVentSenLossJ = 0.0;
8551 1041 : e.MultiZoneVentLatGainW = 0.0;
8552 1041 : e.MultiZoneVentLatGainJ = 0.0;
8553 1041 : e.MultiZoneVentLatLossW = 0.0;
8554 1041 : e.MultiZoneVentLatLossJ = 0.0;
8555 1041 : e.MultiZoneMixSenGainW = 0.0;
8556 1041 : e.MultiZoneMixSenGainJ = 0.0;
8557 1041 : e.MultiZoneMixSenLossW = 0.0;
8558 1041 : e.MultiZoneMixSenLossJ = 0.0;
8559 1041 : e.MultiZoneMixLatGainW = 0.0;
8560 1041 : e.MultiZoneMixLatGainJ = 0.0;
8561 1041 : e.MultiZoneMixLatLossW = 0.0;
8562 1041 : e.MultiZoneMixLatLossJ = 0.0;
8563 1041 : e.LeakSenGainW = 0.0;
8564 1041 : e.LeakSenGainJ = 0.0;
8565 1041 : e.LeakSenLossW = 0.0;
8566 1041 : e.LeakSenLossJ = 0.0;
8567 1041 : e.LeakLatGainW = 0.0;
8568 1041 : e.LeakLatGainJ = 0.0;
8569 1041 : e.LeakLatLossW = 0.0;
8570 1041 : e.LeakLatLossJ = 0.0;
8571 1041 : e.CondSenGainW = 0.0;
8572 1041 : e.CondSenGainJ = 0.0;
8573 1041 : e.CondSenLossW = 0.0;
8574 1041 : e.CondSenLossJ = 0.0;
8575 1041 : e.DiffLatGainW = 0.0;
8576 1041 : e.DiffLatGainJ = 0.0;
8577 1041 : e.DiffLatLossW = 0.0;
8578 1041 : e.DiffLatLossJ = 0.0;
8579 1041 : e.RadGainW = 0.0;
8580 1041 : e.RadGainJ = 0.0;
8581 1041 : e.RadLossW = 0.0;
8582 1041 : e.RadLossJ = 0.0;
8583 1041 : e.TotalSenGainW = 0.0;
8584 1041 : e.TotalSenGainJ = 0.0;
8585 1041 : e.TotalSenLossW = 0.0;
8586 1041 : e.TotalSenLossJ = 0.0;
8587 1041 : e.TotalLatGainW = 0.0;
8588 1041 : e.TotalLatGainJ = 0.0;
8589 1041 : e.TotalLatLossW = 0.0;
8590 1041 : e.TotalLatLossJ = 0.0;
8591 : }
8592 :
8593 : // Calculate sensible and latent loads in each zone from multizone airflows
8594 344 : if (multizone_always_simulated ||
8595 0 : (simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation && AirflowNetworkFanActivated)) {
8596 6888 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
8597 6544 : n = AirflowNetworkLinkageData(i).NodeNums[0];
8598 6544 : M = AirflowNetworkLinkageData(i).NodeNums[1];
8599 6544 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
8600 6544 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
8601 : // Find a linkage from a zone to outdoors
8602 6544 : if (ZN1 > 0 && ZN2 == 0) {
8603 5823 : auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
8604 5823 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfLinkedOutAirNode > 0) {
8605 0 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(MultizoneSurfaceData(i).SurfNum);
8606 0 : CpAir = PsyCpAirFnW(Psychrometrics::PsyWFnTdbTwbPb(m_state,
8607 : Tamb,
8608 0 : m_state.dataSurface->SurfOutWetBulbTemp(MultizoneSurfaceData(i).SurfNum),
8609 0 : m_state.dataEnvrn->OutBaroPress));
8610 : } else {
8611 5823 : Tamb = Zone(ZN1).OutDryBulbTemp;
8612 5823 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
8613 : }
8614 5823 : hg = Psychrometrics::PsyHgAirFnWTdb(zn1HB.airHumRat, zn1HB.MAT);
8615 :
8616 11616 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
8617 5793 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
8618 5459 : if (Tamb > zn1HB.MAT) {
8619 1256 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT));
8620 1256 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainJ +=
8621 1256 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant;
8622 : } else {
8623 4203 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb));
8624 4203 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossJ +=
8625 4203 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant;
8626 : }
8627 5459 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
8628 12 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainW +=
8629 6 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg;
8630 6 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainJ +=
8631 6 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8632 : } else {
8633 10906 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossW +=
8634 5453 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8635 5453 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossJ +=
8636 5453 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8637 : }
8638 : } else {
8639 364 : if (Tamb > zn1HB.MAT) {
8640 69 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT));
8641 69 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainJ +=
8642 69 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant;
8643 : } else {
8644 295 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb));
8645 295 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossJ +=
8646 295 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant;
8647 : }
8648 364 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
8649 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainW +=
8650 0 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg;
8651 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainJ +=
8652 0 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8653 : } else {
8654 728 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossW +=
8655 364 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8656 364 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossJ +=
8657 364 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8658 : }
8659 : }
8660 : }
8661 6544 : if (ZN1 == 0 && ZN2 > 0) {
8662 0 : auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
8663 0 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfLinkedOutAirNode > 0) {
8664 0 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(MultizoneSurfaceData(i).SurfNum);
8665 0 : CpAir = PsyCpAirFnW(Psychrometrics::PsyWFnTdbTwbPb(m_state,
8666 : Tamb,
8667 0 : m_state.dataSurface->SurfOutWetBulbTemp(MultizoneSurfaceData(i).SurfNum),
8668 0 : m_state.dataEnvrn->OutBaroPress));
8669 : } else {
8670 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
8671 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
8672 : }
8673 0 : hg = Psychrometrics::PsyHgAirFnWTdb(zn2HB.airHumRat, zn2HB.MAT);
8674 :
8675 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
8676 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
8677 0 : if (Tamb > zn2HB.MAT) {
8678 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT));
8679 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainJ +=
8680 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant;
8681 : } else {
8682 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb));
8683 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossJ +=
8684 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant;
8685 : }
8686 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
8687 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainW +=
8688 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg;
8689 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainJ +=
8690 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8691 : } else {
8692 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossW +=
8693 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8694 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossJ +=
8695 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8696 : }
8697 : } else {
8698 0 : if (Tamb > zn2HB.MAT) {
8699 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT));
8700 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainJ +=
8701 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant;
8702 : } else {
8703 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb));
8704 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossJ +=
8705 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant;
8706 : }
8707 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
8708 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainW +=
8709 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg;
8710 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainJ +=
8711 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8712 : } else {
8713 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossW +=
8714 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8715 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossJ +=
8716 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8717 : }
8718 : }
8719 : }
8720 :
8721 6544 : if (ZN1 > 0 && ZN2 > 0) {
8722 721 : auto const &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
8723 721 : auto const &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
8724 721 : CpAir = PsyCpAirFnW((zn1HB.airHumRat + zn2HB.airHumRat) / 2.0);
8725 721 : hg = Psychrometrics::PsyHgAirFnWTdb((zn1HB.airHumRat + zn2HB.airHumRat) / 2.0, (zn1HB.MAT + zn2HB.MAT) / 2.0);
8726 721 : if (zn1HB.MAT > zn2HB.MAT) {
8727 545 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn1HB.MAT - zn2HB.MAT));
8728 545 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainJ +=
8729 545 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant;
8730 : } else {
8731 176 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - zn1HB.MAT));
8732 176 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossJ +=
8733 176 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant;
8734 : }
8735 721 : if (zn1HB.airHumRat > zn2HB.airHumRat) {
8736 1360 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainW +=
8737 680 : (AirflowNetworkLinkSimu(i).FLOW * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg;
8738 680 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainJ +=
8739 680 : (AirflowNetworkLinkSimu(i).FLOW * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8740 : } else {
8741 82 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossW +=
8742 41 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg;
8743 41 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossJ +=
8744 41 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8745 : }
8746 721 : if (zn2HB.MAT > zn1HB.MAT) {
8747 136 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn2HB.MAT - zn1HB.MAT));
8748 136 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainJ +=
8749 136 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant;
8750 : } else {
8751 585 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - zn2HB.MAT));
8752 585 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossJ +=
8753 585 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant;
8754 : }
8755 721 : if (zn2HB.airHumRat > zn1HB.airHumRat) {
8756 10 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainW +=
8757 5 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg;
8758 5 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainJ +=
8759 5 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8760 : } else {
8761 1432 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossW +=
8762 716 : std::abs(AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg;
8763 716 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossJ +=
8764 716 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8765 : }
8766 : }
8767 : }
8768 : }
8769 :
8770 : // Assign data for report
8771 344 : if (distribution_simulated) {
8772 1385 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
8773 1041 : if (exchangeData(i).LeakSen > 0.0) {
8774 144 : AirflowNetworkReportData(i).LeakSenGainW = exchangeData(i).LeakSen;
8775 144 : AirflowNetworkReportData(i).LeakSenGainJ = exchangeData(i).LeakSen * ReportingConstant;
8776 : } else {
8777 897 : AirflowNetworkReportData(i).LeakSenLossW = -exchangeData(i).LeakSen;
8778 897 : AirflowNetworkReportData(i).LeakSenLossJ = -exchangeData(i).LeakSen * ReportingConstant;
8779 : }
8780 1041 : if (exchangeData(i).LeakLat > 0.0) {
8781 0 : AirflowNetworkReportData(i).LeakLatGainW = exchangeData(i).LeakLat * Lam;
8782 0 : AirflowNetworkReportData(i).LeakLatGainJ = exchangeData(i).LeakLat * Lam * ReportingConstant;
8783 : } else {
8784 1041 : AirflowNetworkReportData(i).LeakLatLossW = -exchangeData(i).LeakLat * Lam;
8785 1041 : AirflowNetworkReportData(i).LeakLatLossJ = -exchangeData(i).LeakLat * Lam * ReportingConstant;
8786 : }
8787 1041 : if (exchangeData(i).CondSen > 0.0) {
8788 380 : AirflowNetworkReportData(i).CondSenGainW = exchangeData(i).CondSen;
8789 380 : AirflowNetworkReportData(i).CondSenGainJ = exchangeData(i).CondSen * ReportingConstant;
8790 : } else {
8791 661 : AirflowNetworkReportData(i).CondSenLossW = -exchangeData(i).CondSen;
8792 661 : AirflowNetworkReportData(i).CondSenLossJ = -exchangeData(i).CondSen * ReportingConstant;
8793 : }
8794 1041 : if (exchangeData(i).DiffLat > 0.0) {
8795 339 : AirflowNetworkReportData(i).DiffLatGainW = exchangeData(i).DiffLat * Lam;
8796 339 : AirflowNetworkReportData(i).DiffLatGainJ = exchangeData(i).DiffLat * Lam * ReportingConstant;
8797 : } else {
8798 702 : AirflowNetworkReportData(i).DiffLatLossW = -exchangeData(i).DiffLat * Lam;
8799 702 : AirflowNetworkReportData(i).DiffLatLossJ = -exchangeData(i).DiffLat * Lam * ReportingConstant;
8800 : }
8801 1041 : if (exchangeData(i).RadGain < 0.0) {
8802 0 : AirflowNetworkReportData(i).RadGainW = -exchangeData(i).RadGain;
8803 0 : AirflowNetworkReportData(i).RadGainJ = -exchangeData(i).RadGain * ReportingConstant;
8804 : } else {
8805 1041 : AirflowNetworkReportData(i).RadLossW = exchangeData(i).RadGain;
8806 1041 : AirflowNetworkReportData(i).RadLossJ = exchangeData(i).RadGain * ReportingConstant;
8807 : }
8808 1041 : if (exchangeData(i).TotalSen > 0.0) {
8809 380 : AirflowNetworkReportData(i).TotalSenGainW = exchangeData(i).TotalSen;
8810 380 : AirflowNetworkReportData(i).TotalSenGainJ = exchangeData(i).TotalSen * ReportingConstant;
8811 : } else {
8812 661 : AirflowNetworkReportData(i).TotalSenLossW = -exchangeData(i).TotalSen;
8813 661 : AirflowNetworkReportData(i).TotalSenLossJ = -exchangeData(i).TotalSen * ReportingConstant;
8814 : }
8815 1041 : if (exchangeData(i).TotalLat > 0.0) {
8816 339 : AirflowNetworkReportData(i).TotalLatGainW = exchangeData(i).TotalLat * Lam;
8817 339 : AirflowNetworkReportData(i).TotalLatGainJ = exchangeData(i).TotalLat * Lam * ReportingConstant;
8818 : } else {
8819 702 : AirflowNetworkReportData(i).TotalLatLossW = -exchangeData(i).TotalLat * Lam;
8820 702 : AirflowNetworkReportData(i).TotalLatLossJ = -exchangeData(i).TotalLat * Lam * ReportingConstant;
8821 : }
8822 : }
8823 : }
8824 :
8825 : // Zone report
8826 :
8827 1385 : for (auto &e : AirflowNetworkZnRpt) {
8828 1041 : e.InfilVolume = 0.0;
8829 1041 : e.InfilMass = 0.0;
8830 1041 : e.InfilAirChangeRate = 0.0;
8831 1041 : e.VentilVolume = 0.0;
8832 1041 : e.VentilMass = 0.0;
8833 1041 : e.VentilAirChangeRate = 0.0;
8834 1041 : e.MixVolume = 0.0;
8835 1041 : e.MixMass = 0.0;
8836 : }
8837 :
8838 683 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
8839 339 : if (DisSysNumOfCVFs == 0) continue;
8840 339 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
8841 339 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
8842 : }
8843 534 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
8844 195 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
8845 : // ON Cycle calculation
8846 195 : onceZoneFlag = false;
8847 780 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
8848 585 : if (AirflowNetworkNodeData(i).AirLoopNum > 0 && AirflowNetworkNodeData(i).AirLoopNum != AirLoopNum) continue;
8849 585 : if (AirflowNetworkNodeData(i).AirLoopNum == AirLoopNum) {
8850 390 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
8851 : }
8852 585 : if (AirflowNetworkNodeData(i).AirLoopNum == 0) {
8853 195 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
8854 : }
8855 585 : if (AirflowNetworkNodeData(i).AirLoopNum == 0 && onceZoneFlag(i)) continue;
8856 585 : AirflowNetworkReportData(i).MultiZoneInfiSenGainW *= RepOnOffFanRunTimeFraction;
8857 585 : AirflowNetworkReportData(i).MultiZoneInfiSenGainJ *= RepOnOffFanRunTimeFraction;
8858 585 : AirflowNetworkReportData(i).MultiZoneInfiSenLossW *= RepOnOffFanRunTimeFraction;
8859 585 : AirflowNetworkReportData(i).MultiZoneInfiSenLossJ *= RepOnOffFanRunTimeFraction;
8860 585 : AirflowNetworkReportData(i).MultiZoneInfiLatGainW *= RepOnOffFanRunTimeFraction;
8861 585 : AirflowNetworkReportData(i).MultiZoneInfiLatGainJ *= RepOnOffFanRunTimeFraction;
8862 585 : AirflowNetworkReportData(i).MultiZoneInfiLatLossW *= RepOnOffFanRunTimeFraction;
8863 585 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ *= RepOnOffFanRunTimeFraction;
8864 585 : AirflowNetworkReportData(i).MultiZoneVentSenGainW *= RepOnOffFanRunTimeFraction;
8865 585 : AirflowNetworkReportData(i).MultiZoneVentSenGainJ *= RepOnOffFanRunTimeFraction;
8866 585 : AirflowNetworkReportData(i).MultiZoneVentSenLossW *= RepOnOffFanRunTimeFraction;
8867 585 : AirflowNetworkReportData(i).MultiZoneVentSenLossJ *= RepOnOffFanRunTimeFraction;
8868 585 : AirflowNetworkReportData(i).MultiZoneVentLatGainW *= RepOnOffFanRunTimeFraction;
8869 585 : AirflowNetworkReportData(i).MultiZoneVentLatGainJ *= RepOnOffFanRunTimeFraction;
8870 585 : AirflowNetworkReportData(i).MultiZoneVentLatLossW *= RepOnOffFanRunTimeFraction;
8871 585 : AirflowNetworkReportData(i).MultiZoneVentLatLossJ *= RepOnOffFanRunTimeFraction;
8872 585 : AirflowNetworkReportData(i).MultiZoneMixSenGainW *= RepOnOffFanRunTimeFraction;
8873 585 : AirflowNetworkReportData(i).MultiZoneMixSenGainJ *= RepOnOffFanRunTimeFraction;
8874 585 : AirflowNetworkReportData(i).MultiZoneMixSenLossW *= RepOnOffFanRunTimeFraction;
8875 585 : AirflowNetworkReportData(i).MultiZoneMixSenLossJ *= RepOnOffFanRunTimeFraction;
8876 585 : AirflowNetworkReportData(i).MultiZoneMixLatGainW *= RepOnOffFanRunTimeFraction;
8877 585 : AirflowNetworkReportData(i).MultiZoneMixLatGainJ *= RepOnOffFanRunTimeFraction;
8878 585 : AirflowNetworkReportData(i).MultiZoneMixLatLossW *= RepOnOffFanRunTimeFraction;
8879 585 : AirflowNetworkReportData(i).MultiZoneMixLatLossJ *= RepOnOffFanRunTimeFraction;
8880 585 : if (AirflowNetworkNodeData(i).AirLoopNum == 0) {
8881 195 : onceZoneFlag(i) = true;
8882 : }
8883 : }
8884 : // Off Cycle addon
8885 195 : onceSurfFlag = false;
8886 3900 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
8887 3705 : n = AirflowNetworkLinkageData(i).NodeNums[0];
8888 3705 : M = AirflowNetworkLinkageData(i).NodeNums[1];
8889 3705 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
8890 3705 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
8891 : // Find a linkage from a zone to outdoors
8892 3705 : if (ZN1 > 0 && ZN2 == 0) {
8893 3315 : auto const &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
8894 3315 : if (AirflowNetworkNodeData(n).AirLoopNum > 0 && AirflowNetworkNodeData(n).AirLoopNum != AirLoopNum) continue;
8895 3315 : if (AirflowNetworkNodeData(n).AirLoopNum == AirLoopNum) {
8896 2535 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
8897 : }
8898 3315 : if (AirflowNetworkNodeData(n).AirLoopNum == 0) {
8899 780 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
8900 : }
8901 3315 : if (AirflowNetworkNodeData(n).AirLoopNum == 0 && onceSurfFlag(i)) continue;
8902 3315 : ReportingFraction = (1.0 - RepOnOffFanRunTimeFraction);
8903 3315 : Tamb = Zone(ZN1).OutDryBulbTemp;
8904 3315 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
8905 6630 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
8906 3315 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
8907 3120 : if (Tamb > zn1HB.MAT) {
8908 2512 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainW +=
8909 1256 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * (1.0 - RepOnOffFanRunTimeFraction);
8910 1256 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainJ +=
8911 1256 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
8912 : } else {
8913 3728 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossW +=
8914 1864 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * (1.0 - RepOnOffFanRunTimeFraction);
8915 1864 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossJ +=
8916 1864 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
8917 : }
8918 3120 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
8919 0 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainW +=
8920 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingFraction;
8921 0 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainJ +=
8922 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingConstant *
8923 : ReportingFraction;
8924 : } else {
8925 6240 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossW +=
8926 3120 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
8927 3120 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossJ +=
8928 3120 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
8929 : ReportingFraction;
8930 : }
8931 : } else {
8932 195 : if (Tamb > zn1HB.MAT) {
8933 138 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainW +=
8934 69 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * (1.0 - RepOnOffFanRunTimeFraction);
8935 69 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainJ +=
8936 69 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
8937 : } else {
8938 252 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossW +=
8939 126 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * (1.0 - RepOnOffFanRunTimeFraction);
8940 126 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossJ +=
8941 126 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
8942 : }
8943 195 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
8944 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainW +=
8945 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingFraction;
8946 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainJ +=
8947 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingConstant *
8948 : ReportingFraction;
8949 : } else {
8950 390 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossW +=
8951 195 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
8952 195 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossJ +=
8953 195 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
8954 : ReportingFraction;
8955 : }
8956 : }
8957 3315 : if (AirflowNetworkNodeData(n).AirLoopNum == 0) {
8958 780 : onceSurfFlag(i) = true;
8959 : }
8960 : }
8961 3705 : if (ZN1 == 0 && ZN2 > 0) {
8962 0 : auto const &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
8963 0 : if (AirflowNetworkNodeData(M).AirLoopNum > 0 && AirflowNetworkNodeData(M).AirLoopNum != AirLoopNum) continue;
8964 0 : if (AirflowNetworkNodeData(M).AirLoopNum == AirLoopNum) {
8965 0 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
8966 : }
8967 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0) {
8968 0 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
8969 : }
8970 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0 && onceSurfFlag(i)) continue;
8971 0 : ReportingFraction = (1.0 - RepOnOffFanRunTimeFraction);
8972 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
8973 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
8974 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
8975 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
8976 0 : if (Tamb > zn2HB.MAT) {
8977 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainW +=
8978 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingFraction;
8979 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainJ +=
8980 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
8981 : } else {
8982 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossW +=
8983 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingFraction;
8984 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossJ +=
8985 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
8986 : }
8987 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
8988 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainW +=
8989 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingFraction;
8990 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainJ +=
8991 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingConstant *
8992 : ReportingFraction;
8993 : } else {
8994 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossW +=
8995 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
8996 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossJ +=
8997 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
8998 : ReportingFraction;
8999 : }
9000 : } else {
9001 0 : if (Tamb > zn2HB.MAT) {
9002 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainW +=
9003 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingFraction;
9004 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainJ +=
9005 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9006 : } else {
9007 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossW +=
9008 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingFraction;
9009 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossJ +=
9010 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
9011 : }
9012 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
9013 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainW +=
9014 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingFraction;
9015 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainJ +=
9016 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingConstant *
9017 : ReportingFraction;
9018 : } else {
9019 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossW +=
9020 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
9021 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossJ +=
9022 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9023 : ReportingFraction;
9024 : }
9025 : }
9026 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0) {
9027 0 : onceSurfFlag(i) = true;
9028 : }
9029 : }
9030 :
9031 3705 : if (ZN1 > 0 && ZN2 > 0) {
9032 390 : auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
9033 390 : auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
9034 390 : ReportingFraction = (1.0 - MaxOnOffFanRunTimeFraction);
9035 390 : CpAir = PsyCpAirFnW(zn1HB.airHumRat);
9036 390 : if (zn1HB.MAT > zn2HB.MAT) {
9037 508 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainW +=
9038 254 : (linkReport1(i).FLOWOFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingFraction;
9039 254 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainJ +=
9040 254 : (linkReport1(i).FLOWOFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9041 : } else {
9042 272 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossW +=
9043 136 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingFraction;
9044 136 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossJ +=
9045 136 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9046 : }
9047 390 : if (zn1HB.airHumRat > zn2HB.airHumRat) {
9048 780 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainW +=
9049 390 : (linkReport1(i).FLOWOFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingFraction;
9050 390 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainJ +=
9051 390 : (linkReport1(i).FLOWOFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingConstant * ReportingFraction;
9052 : } else {
9053 0 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossW +=
9054 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingFraction;
9055 0 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossJ +=
9056 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingConstant * ReportingFraction;
9057 : }
9058 390 : CpAir = PsyCpAirFnW(zn2HB.airHumRat);
9059 390 : if (zn2HB.MAT > zn1HB.MAT) {
9060 272 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainW +=
9061 136 : (linkReport1(i).FLOW2OFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingFraction;
9062 136 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainJ +=
9063 136 : (linkReport1(i).FLOW2OFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9064 : } else {
9065 508 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossW +=
9066 254 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingFraction;
9067 254 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossJ +=
9068 254 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9069 : }
9070 :
9071 390 : if (zn2HB.airHumRat > zn1HB.airHumRat) {
9072 0 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainW +=
9073 0 : (linkReport1(i).FLOW2OFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingFraction;
9074 0 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainJ +=
9075 0 : (linkReport1(i).FLOW2OFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingConstant * ReportingFraction;
9076 : } else {
9077 780 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossW +=
9078 390 : std::abs(linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingFraction;
9079 390 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossJ +=
9080 390 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingConstant * ReportingFraction;
9081 : }
9082 : }
9083 : }
9084 : }
9085 : }
9086 :
9087 344 : if (!multizone_always_simulated) {
9088 0 : return;
9089 : }
9090 :
9091 1385 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) { // Start of zone loads report variable update loop ...
9092 1041 : auto &thisZoneHB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i);
9093 1041 : Tamb = Zone(i).OutDryBulbTemp;
9094 1041 : CpAir = PsyCpAirFnW(thisZoneHB.airHumRatAvg);
9095 1041 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.airHumRatAvg);
9096 :
9097 1041 : AirflowNetworkZnRpt(i).InfilMass = (exchangeData(i).SumMCp / CpAir) * ReportingConstant;
9098 1041 : AirflowNetworkZnRpt(i).InfilVolume = AirflowNetworkZnRpt(i).InfilMass / AirDensity;
9099 1041 : AirflowNetworkZnRpt(i).InfilAirChangeRate = AirflowNetworkZnRpt(i).InfilVolume / (TimeStepSys * Zone(i).Volume);
9100 1041 : AirflowNetworkZnRpt(i).VentilMass = (exchangeData(i).SumMVCp / CpAir) * ReportingConstant;
9101 1041 : AirflowNetworkZnRpt(i).VentilVolume = AirflowNetworkZnRpt(i).VentilMass / AirDensity;
9102 1041 : AirflowNetworkZnRpt(i).VentilAirChangeRate = AirflowNetworkZnRpt(i).VentilVolume / (TimeStepSys * Zone(i).Volume);
9103 1041 : AirflowNetworkZnRpt(i).MixMass = (exchangeData(i).SumMMCp / CpAir) * ReportingConstant;
9104 1041 : AirflowNetworkZnRpt(i).MixVolume = AirflowNetworkZnRpt(i).MixMass / AirDensity;
9105 : // save values for predefined report
9106 1041 : Real64 stdDensAFNInfilVolume = AirflowNetworkZnRpt(i).InfilMass / m_state.dataEnvrn->StdRhoAir;
9107 1041 : Real64 stdDensAFNNatVentVolume = AirflowNetworkZnRpt(i).VentilMass / m_state.dataEnvrn->StdRhoAir;
9108 1041 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolStdDen = stdDensAFNNatVentVolume;
9109 1041 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolTotalStdDen += stdDensAFNNatVentVolume;
9110 1041 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalStdDen += stdDensAFNInfilVolume;
9111 1041 : if (m_state.dataHeatBal->ZonePreDefRep(i).isOccupied) {
9112 339 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolTotalOccStdDen += stdDensAFNNatVentVolume;
9113 339 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalOccStdDen += stdDensAFNInfilVolume;
9114 339 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalOcc +=
9115 339 : (AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) * Zone(i).Multiplier * Zone(i).ListMultiplier;
9116 339 : if ((AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) <
9117 339 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolMin) {
9118 64 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolMin =
9119 64 : (AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) * Zone(i).Multiplier * Zone(i).ListMultiplier;
9120 : }
9121 : }
9122 :
9123 1041 : Real64 H2OHtOfVap = Psychrometrics::PsyHgAirFnWTdb(m_state.dataEnvrn->OutHumRat, Zone(i).OutDryBulbTemp);
9124 1041 : AirflowNetworkZnRpt(i).InletMass = 0;
9125 1041 : AirflowNetworkZnRpt(i).OutletMass = 0;
9126 1041 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).IsControlled) {
9127 1017 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumInletNodes; ++j) {
9128 678 : AirflowNetworkZnRpt(i).InletMass +=
9129 678 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).InletNode(j)).MassFlowRate * ReportingConstant;
9130 : }
9131 1017 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumExhaustNodes; ++j) {
9132 678 : AirflowNetworkZnRpt(i).OutletMass +=
9133 678 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).ExhaustNode(j)).MassFlowRate * ReportingConstant;
9134 : }
9135 678 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumReturnNodes; ++j) {
9136 339 : AirflowNetworkZnRpt(i).OutletMass +=
9137 339 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).ReturnNode(j)).MassFlowRate * ReportingConstant;
9138 : }
9139 : }
9140 1041 : AirflowNetworkZnRpt(i).ExfilMass = AirflowNetworkZnRpt(i).InfilMass + AirflowNetworkZnRpt(i).VentilMass + AirflowNetworkZnRpt(i).MixMass +
9141 1041 : AirflowNetworkZnRpt(i).InletMass - AirflowNetworkZnRpt(i).OutletMass;
9142 1041 : AirflowNetworkZnRpt(i).ExfilSensiLoss = AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * (thisZoneHB.MAT - Tamb) * CpAir;
9143 2082 : AirflowNetworkZnRpt(i).ExfilLatentLoss =
9144 1041 : AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * (thisZoneHB.airHumRat - m_state.dataEnvrn->OutHumRat) * H2OHtOfVap;
9145 1041 : AirflowNetworkZnRpt(i).ExfilTotalLoss = AirflowNetworkZnRpt(i).ExfilSensiLoss + AirflowNetworkZnRpt(i).ExfilLatentLoss;
9146 :
9147 1041 : m_state.dataHeatBal->ZoneTotalExfiltrationHeatLoss += AirflowNetworkZnRpt(i).ExfilTotalLoss * ReportingConstant;
9148 : } // ... end of zone loads report variable update loop.
9149 :
9150 : // Rewrite AirflowNetwork airflow rate
9151 683 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9152 339 : if (DisSysNumOfCVFs == 0) continue;
9153 339 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9154 339 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9155 : }
9156 339 : onceSurfFlag = false;
9157 :
9158 6780 : for (i = 1; i <= NumOfLinksMultiZone; ++i) {
9159 6441 : if (onceSurfFlag(i)) continue;
9160 6441 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9161 6441 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkLinkageData(i).NodeHeights[0]);
9162 6441 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, Tamb, m_state.dataEnvrn->OutHumRat);
9163 10146 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
9164 3705 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
9165 3705 : linkReport(i).VolFLOW = linkReport1(i).FLOW / AirDensity;
9166 3705 : linkReport(i).VolFLOW2 = linkReport1(i).FLOW2 / AirDensity;
9167 : } else {
9168 2736 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity;
9169 2736 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity;
9170 : }
9171 6441 : onceSurfFlag(i) = true;
9172 : }
9173 : }
9174 :
9175 339 : if (AirflowNetworkNumOfLinks > NumOfLinksMultiZone) {
9176 6780 : for (i = NumOfLinksMultiZone + 1; i <= AirflowNetworkNumOfLinks; ++i) {
9177 6441 : if (onceSurfFlag(i)) continue;
9178 6441 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9179 6441 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9180 6441 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9181 : AirDensity =
9182 6441 : PsyRhoAirFnPbTdbW(m_state,
9183 6441 : (AirflowNetworkNodeSimu(n).PZ + AirflowNetworkNodeSimu(M).PZ) / 2.0 + m_state.dataEnvrn->OutBaroPress,
9184 6441 : (AirflowNetworkNodeSimu(n).TZ + AirflowNetworkNodeSimu(M).TZ) / 2.0,
9185 6441 : (AirflowNetworkNodeSimu(n).WZ + AirflowNetworkNodeSimu(M).WZ) / 2.0);
9186 10146 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
9187 3705 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
9188 3705 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity * (1.0 - LoopOnOffFanRunTimeFraction(AirLoopNum));
9189 3705 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity * (1.0 - LoopOnOffFanRunTimeFraction(AirLoopNum));
9190 3705 : onceSurfFlag(i) = true;
9191 : } else {
9192 2736 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity;
9193 2736 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity;
9194 : }
9195 : }
9196 : }
9197 : }
9198 : }
9199 : }
9200 :
9201 16856 : void Solver::update(ObjexxFCL::Optional_bool_const FirstHVACIteration) // True when solution technique on first iteration
9202 : {
9203 :
9204 : // SUBROUTINE INFORMATION:
9205 : // AUTHOR Lixing Gu
9206 : // DATE WRITTEN 12/10/05
9207 : // MODIFIED na
9208 : // RE-ENGINEERED na
9209 :
9210 : // PURPOSE OF THIS SUBROUTINE:
9211 : // This subroutine update variables used in the AirflowNetwork model.
9212 :
9213 : // Using/Aliasing
9214 16856 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
9215 : using HVAC::VerySmallMassFlow;
9216 :
9217 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9218 : int n;
9219 : int M;
9220 : int ZN1;
9221 : int ZN2;
9222 : int Node1;
9223 : int Node2;
9224 : Real64 CpAir;
9225 : Real64 Qsen;
9226 : Real64 Qlat;
9227 : Real64 AirDensity;
9228 : Real64 Tamb;
9229 : Real64 PartLoadRatio;
9230 : Real64 OnOffRatio;
9231 : Real64 NodeMass;
9232 : Real64 AFNMass;
9233 :
9234 16856 : auto &Zone(m_state.dataHeatBal->Zone);
9235 16856 : auto &Node(m_state.dataLoopNodes->Node);
9236 :
9237 67427 : for (auto &e : exchangeData) {
9238 50571 : e.SumMCp = 0.0;
9239 50571 : e.SumMCpT = 0.0;
9240 50571 : e.SumMVCp = 0.0;
9241 50571 : e.SumMVCpT = 0.0;
9242 50571 : e.SumMHr = 0.0;
9243 50571 : e.SumMHrW = 0.0;
9244 50571 : e.SumMMCp = 0.0;
9245 50571 : e.SumMMCpT = 0.0;
9246 50571 : e.SumMMHr = 0.0;
9247 50571 : e.SumMMHrW = 0.0;
9248 : }
9249 16856 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9250 0 : for (auto &e : exchangeData) {
9251 0 : e.SumMHrCO = 0.0;
9252 0 : e.SumMMHrCO = 0.0;
9253 : }
9254 : }
9255 16856 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9256 0 : for (auto &e : exchangeData) {
9257 0 : e.SumMHrGC = 0.0;
9258 0 : e.SumMMHrGC = 0.0;
9259 : }
9260 : }
9261 :
9262 : // Calculate sensible and latent loads in each zone from multizone airflows
9263 16856 : if (multizone_always_simulated ||
9264 0 : (simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation && AirflowNetworkFanActivated)) {
9265 337108 : for (int i = 1; i <= NumOfLinksMultiZone; ++i) { // Multizone airflow energy
9266 320252 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9267 320252 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9268 320252 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
9269 320252 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
9270 320252 : if (ZN1 > 0 && ZN2 == 0) {
9271 : // Find a linkage from outdoors to this zone
9272 286523 : Tamb = Zone(ZN1).OutDryBulbTemp;
9273 286523 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9274 573025 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9275 286502 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9276 269656 : exchangeData(ZN1).SumMCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9277 269656 : exchangeData(ZN1).SumMCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * Tamb;
9278 : } else {
9279 16867 : exchangeData(ZN1).SumMVCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9280 16867 : exchangeData(ZN1).SumMVCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * Tamb;
9281 : }
9282 286523 : exchangeData(ZN1).SumMHr += AirflowNetworkLinkSimu(i).FLOW2;
9283 286523 : exchangeData(ZN1).SumMHrW += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataEnvrn->OutHumRat;
9284 286523 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9285 0 : exchangeData(ZN1).SumMHrCO += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataContaminantBalance->OutdoorCO2;
9286 : }
9287 286523 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9288 0 : exchangeData(ZN1).SumMHrGC += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataContaminantBalance->OutdoorGC;
9289 : }
9290 : }
9291 320252 : if (ZN1 == 0 && ZN2 > 0) {
9292 : // Find a linkage from outdoors to this zone
9293 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
9294 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9295 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9296 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9297 0 : exchangeData(ZN2).SumMCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9298 0 : exchangeData(ZN2).SumMCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * Tamb;
9299 : } else {
9300 0 : exchangeData(ZN2).SumMVCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9301 0 : exchangeData(ZN2).SumMVCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * Tamb;
9302 : }
9303 0 : exchangeData(ZN2).SumMHr += AirflowNetworkLinkSimu(i).FLOW;
9304 0 : exchangeData(ZN2).SumMHrW += AirflowNetworkLinkSimu(i).FLOW * m_state.dataEnvrn->OutHumRat;
9305 0 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9306 0 : exchangeData(ZN2).SumMHrCO += AirflowNetworkLinkSimu(i).FLOW * m_state.dataContaminantBalance->OutdoorCO2;
9307 : }
9308 0 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9309 0 : exchangeData(ZN2).SumMHrGC += AirflowNetworkLinkSimu(i).FLOW * m_state.dataContaminantBalance->OutdoorGC;
9310 : }
9311 : }
9312 320252 : if (ZN1 > 0 && ZN2 > 0) {
9313 : // Find a linkage from outdoors to this zone
9314 33729 : CpAir = PsyCpAirFnW(ANZW(ZN1));
9315 33729 : exchangeData(ZN2).SumMMCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9316 33729 : exchangeData(ZN2).SumMMCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * ANZT(ZN1);
9317 33729 : exchangeData(ZN2).SumMMHr += AirflowNetworkLinkSimu(i).FLOW;
9318 33729 : exchangeData(ZN2).SumMMHrW += AirflowNetworkLinkSimu(i).FLOW * ANZW(ZN1);
9319 33729 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9320 0 : exchangeData(ZN2).SumMMHrCO += AirflowNetworkLinkSimu(i).FLOW * ANCO(ZN1);
9321 : }
9322 33729 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9323 0 : exchangeData(ZN2).SumMMHrGC += AirflowNetworkLinkSimu(i).FLOW * ANGC(ZN1);
9324 : }
9325 33729 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9326 33729 : exchangeData(ZN1).SumMMCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9327 33729 : exchangeData(ZN1).SumMMCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * ANZT(ZN2);
9328 33729 : exchangeData(ZN1).SumMMHr += AirflowNetworkLinkSimu(i).FLOW2;
9329 33729 : exchangeData(ZN1).SumMMHrW += AirflowNetworkLinkSimu(i).FLOW2 * ANZW(ZN2);
9330 33729 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9331 0 : exchangeData(ZN1).SumMMHrCO += AirflowNetworkLinkSimu(i).FLOW2 * ANCO(ZN2);
9332 : }
9333 33729 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9334 0 : exchangeData(ZN1).SumMMHrGC += AirflowNetworkLinkSimu(i).FLOW2 * ANGC(ZN2);
9335 : }
9336 : }
9337 : }
9338 : }
9339 : // End of update of multizone airflow calculations
9340 :
9341 : // Initialize these values
9342 67427 : for (auto &e : exchangeData) {
9343 50571 : e.LeakSen = 0.0;
9344 50571 : e.CondSen = 0.0;
9345 50571 : e.LeakLat = 0.0;
9346 50571 : e.DiffLat = 0.0;
9347 50571 : e.MultiZoneSen = 0.0;
9348 50571 : e.MultiZoneLat = 0.0;
9349 50571 : e.RadGain = 0.0;
9350 : }
9351 :
9352 : // Rewrite AirflowNetwork airflow rate
9353 337108 : for (int i = 1; i <= NumOfLinksMultiZone; ++i) {
9354 320252 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkLinkageData(i).NodeHeights[0]);
9355 320252 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, Tamb, m_state.dataEnvrn->OutHumRat);
9356 320252 : AirflowNetworkLinkSimu(i).VolFLOW = AirflowNetworkLinkSimu(i).FLOW / AirDensity;
9357 320252 : AirflowNetworkLinkSimu(i).VolFLOW2 = AirflowNetworkLinkSimu(i).FLOW2 / AirDensity;
9358 : }
9359 :
9360 657440 : for (std::size_t i = 0; i < linkReport.size(); ++i) {
9361 640584 : auto &r = linkReport[i];
9362 640584 : auto const &s = AirflowNetworkLinkSimu[i];
9363 640584 : r.FLOW = s.FLOW;
9364 640584 : r.FLOW2 = s.FLOW2;
9365 640584 : r.VolFLOW = s.VolFLOW;
9366 640584 : r.VolFLOW2 = s.VolFLOW2;
9367 : }
9368 :
9369 : // Save zone loads from multizone calculation for later summation
9370 16856 : bool OnOffFanFlag = false;
9371 16859 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
9372 16857 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
9373 16854 : OnOffFanFlag = true;
9374 16854 : break;
9375 : }
9376 : }
9377 16856 : if (present(FirstHVACIteration)) {
9378 16853 : if (FirstHVACIteration && OnOffFanFlag) {
9379 2820 : multiExchangeData = exchangeData;
9380 11280 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
9381 8460 : nodeReport(i).PZ = AirflowNetworkNodeSimu(i).PZ;
9382 8460 : nodeReport(i).PZOFF = AirflowNetworkNodeSimu(i).PZ;
9383 8460 : nodeReport(i).PZON = 0.0;
9384 : }
9385 56400 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
9386 53580 : linkReport1(i).FLOW = AirflowNetworkLinkSimu(i).FLOW;
9387 53580 : linkReport1(i).FLOW2 = AirflowNetworkLinkSimu(i).FLOW2;
9388 53580 : linkReport1(i).VolFLOW = AirflowNetworkLinkSimu(i).VolFLOW;
9389 53580 : linkReport1(i).VolFLOW2 = AirflowNetworkLinkSimu(i).VolFLOW2;
9390 53580 : linkReport1(i).FLOWOFF = AirflowNetworkLinkSimu(i).FLOW;
9391 53580 : linkReport1(i).FLOW2OFF = AirflowNetworkLinkSimu(i).FLOW2;
9392 53580 : linkReport1(i).VolFLOWOFF = AirflowNetworkLinkSimu(i).VolFLOW;
9393 53580 : linkReport1(i).VolFLOW2OFF = AirflowNetworkLinkSimu(i).VolFLOW2;
9394 53580 : linkReport1(i).DP = AirflowNetworkLinkSimu(i).DP;
9395 53580 : linkReport1(i).DPOFF = AirflowNetworkLinkSimu(i).DP;
9396 53580 : linkReport1(i).DPON = 0.0;
9397 : }
9398 : }
9399 : }
9400 :
9401 16856 : if (!AirflowNetworkFanActivated && distribution_simulated) {
9402 87080 : for (int i = NumOfNodesMultiZone + NumOfNodesIntraZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
9403 81279 : AirflowNetworkNodeSimu(i).PZ = 0.0;
9404 : }
9405 116107 : for (int i = AirflowNetworkNumOfSurfaces + 1; i <= AirflowNetworkNumOfLinks; ++i) {
9406 110306 : AirflowNetworkLinkSimu(i).DP = 0.0;
9407 110306 : linkReport(i).FLOW = 0.0;
9408 110306 : linkReport(i).FLOW2 = 0.0;
9409 110306 : linkReport(i).VolFLOW = 0.0;
9410 110306 : linkReport(i).VolFLOW2 = 0.0;
9411 : }
9412 : }
9413 :
9414 16856 : if (!(AirflowNetworkFanActivated && distribution_simulated)) return;
9415 :
9416 11054 : if (distribution_simulated) {
9417 221080 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
9418 210026 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9419 210026 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9420 210026 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
9421 210026 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
9422 : // Find a linkage from a zone to outdoors
9423 210026 : if (ZN1 > 0 && ZN2 == 0) {
9424 187918 : Tamb = Zone(ZN1).OutDryBulbTemp;
9425 187918 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9426 187918 : exchangeData(ZN1).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - ANZT(ZN1));
9427 187918 : exchangeData(ZN1).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - ANZW(ZN1));
9428 : }
9429 210026 : if (ZN1 == 0 && ZN2 > 0) {
9430 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
9431 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9432 0 : exchangeData(ZN2).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - ANZT(ZN2));
9433 0 : exchangeData(ZN2).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - ANZW(ZN2));
9434 : }
9435 :
9436 210026 : if (ZN1 > 0 && ZN2 > 0) {
9437 22108 : if (AirflowNetworkLinkSimu(i).FLOW > 0) { // Flow from ZN1 to ZN2
9438 11502 : CpAir = PsyCpAirFnW(ANZW(ZN1));
9439 11502 : exchangeData(ZN2).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW * CpAir * (ANZT(ZN1) - ANZT(ZN2));
9440 11502 : exchangeData(ZN2).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW * (ANZW(ZN1) - ANZW(ZN2));
9441 11502 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9442 11502 : exchangeData(ZN1).MultiZoneSen += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * (ANZT(ZN2) - ANZT(ZN1));
9443 11502 : exchangeData(ZN1).MultiZoneLat += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * (ANZW(ZN2) - ANZW(ZN1));
9444 : } else {
9445 10606 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9446 10606 : exchangeData(ZN1).MultiZoneSen += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * (ANZT(ZN2) - ANZT(ZN1));
9447 10606 : exchangeData(ZN1).MultiZoneLat += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * (ANZW(ZN2) - ANZW(ZN1));
9448 : }
9449 : }
9450 : }
9451 : }
9452 :
9453 : int AirLoopNum;
9454 : int FanNum;
9455 11054 : Real64 MaxPartLoadRatio = 0.0;
9456 11054 : Real64 OnOffFanRunTimeFraction = 0.0;
9457 11054 : MaxOnOffFanRunTimeFraction = 0.0;
9458 22108 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9459 11054 : MaxPartLoadRatio = max(MaxPartLoadRatio, m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio);
9460 11054 : MaxOnOffFanRunTimeFraction = max(MaxOnOffFanRunTimeFraction, LoopOnOffFanRunTimeFraction(AirLoopNum));
9461 : }
9462 22108 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9463 11054 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9464 11054 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9465 : }
9466 11054 : PartLoadRatio = 1.0;
9467 11054 : LoopPartLoadRatio(AirLoopNum) = 1.0;
9468 11054 : OnOffFanRunTimeFraction = 1.0;
9469 11054 : LoopOnOffFanRunTimeFraction(AirLoopNum) = 1.0;
9470 : // Calculate the part load ratio, can't be greater than 1 for a simple ONOFF fan
9471 11054 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff &&
9472 22108 : Node(DisSysCompCVFData(FanNum).InletNode).MassFlowRate > VerySmallMassFlow &&
9473 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling) {
9474 : // Hard code here
9475 11054 : PartLoadRatio = m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
9476 11054 : LoopPartLoadRatio(AirLoopNum) = m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
9477 11054 : OnOffFanRunTimeFraction = max(m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF,
9478 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopOnOffFanRTF,
9479 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF);
9480 11054 : LoopOnOffFanRunTimeFraction(AirLoopNum) = max(m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF,
9481 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopOnOffFanRTF,
9482 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF);
9483 : }
9484 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0;
9485 :
9486 11054 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopPartLoadRatio(AirLoopNum) < 1.0) {
9487 197340 : for (std::size_t i = 0; i < linkReport.size(); ++i) {
9488 192280 : auto &r(linkReport[i]);
9489 192280 : auto const &s(AirflowNetworkLinkSimu[i]);
9490 192280 : auto const &t(AirflowNetworkLinkageData[i]);
9491 192280 : if (t.AirLoopNum == AirLoopNum) {
9492 96140 : r.FLOW = s.FLOW * LoopPartLoadRatio(AirLoopNum);
9493 96140 : r.FLOW2 = s.FLOW2 * LoopPartLoadRatio(AirLoopNum);
9494 96140 : r.VolFLOW = s.VolFLOW * LoopPartLoadRatio(AirLoopNum);
9495 96140 : r.VolFLOW2 = s.VolFLOW2 * LoopPartLoadRatio(AirLoopNum);
9496 : }
9497 192280 : if (t.AirLoopNum == 0) {
9498 96140 : r.FLOW = s.FLOW * MaxPartLoadRatio;
9499 96140 : r.FLOW2 = s.FLOW2 * MaxPartLoadRatio;
9500 96140 : r.VolFLOW = s.VolFLOW * MaxPartLoadRatio;
9501 96140 : r.VolFLOW2 = s.VolFLOW2 * MaxPartLoadRatio;
9502 : }
9503 : }
9504 : }
9505 : }
9506 :
9507 : // One time warning
9508 11054 : if (UpdateAirflowNetworkMyOneTimeFlag) {
9509 22108 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9510 11054 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9511 11054 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9512 : }
9513 22108 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff &&
9514 11054 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Continuous) {
9515 0 : OnOffRatio = std::abs((m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate -
9516 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate) /
9517 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate);
9518 0 : if (OnOffRatio > 0.1) {
9519 0 : ShowWarningError(m_state,
9520 : "The absolute percent difference of supply air mass flow rate between HVAC operation and No HVAC operation "
9521 : "is above 10% with fan operation mode = ContFanCycCoil.");
9522 0 : ShowContinueError(m_state,
9523 : "The added zone loads using the AirflowNetwork model may not be accurate because the zone loads are "
9524 : "calculated based on the mass flow rate during HVAC operation.");
9525 0 : ShowContinueError(
9526 : m_state,
9527 0 : format("The mass flow rate during HVAC operation = {:.2R} The mass flow rate during no HVAC operation = {:.2R}",
9528 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate,
9529 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate));
9530 0 : UpdateAirflowNetworkMyOneTimeFlag = false;
9531 : }
9532 : }
9533 : }
9534 : }
9535 :
9536 : // Check mass flow differences in the zone inlet zones and splitter nodes between node and AFN links
9537 11054 : if (UpdateAirflowNetworkMyOneTimeFlag1) {
9538 1 : if ((!VAVSystem) && m_state.dataGlobal->DisplayExtraWarnings) {
9539 0 : bool WriteFlag = false;
9540 0 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9541 0 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9542 0 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9543 0 : if (AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::SPI ||
9544 0 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::SPO ||
9545 0 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::ZIN) {
9546 : int Node3;
9547 0 : if (AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::SPI) {
9548 0 : Node3 = Node1;
9549 : } else {
9550 0 : Node3 = Node2;
9551 : }
9552 0 : if (AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::ZIN) {
9553 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::Invalid) continue;
9554 : }
9555 0 : NodeMass = Node(AirflowNetworkNodeData(Node3).EPlusNodeNum).MassFlowRate;
9556 0 : AFNMass = AirflowNetworkLinkSimu(i).FLOW;
9557 0 : if (NodeMass > 0.0 && AFNMass > NodeMass + 0.01) {
9558 0 : ShowWarningError(m_state,
9559 0 : "The mass flow rate difference is found between System Node = '" +
9560 0 : m_state.dataLoopNodes->NodeID(AirflowNetworkNodeData(Node3).EPlusNodeNum) + "' and AFN Link = '" +
9561 0 : AirflowNetworkLinkageData(i).Name + "'.");
9562 0 : ShowContinueError(m_state,
9563 0 : format("The system node max mass flow rate = {:.3R} kg/s. The AFN node mass flow rate = {:.3R} kg.s.",
9564 : NodeMass,
9565 : AFNMass));
9566 0 : WriteFlag = true;
9567 : }
9568 : }
9569 : }
9570 0 : UpdateAirflowNetworkMyOneTimeFlag1 = false;
9571 0 : if (WriteFlag) {
9572 0 : ShowWarningError(m_state,
9573 : "Please adjust the rate of Maximum Air Flow Rate field in the terminal objects or duct pressure resistance.");
9574 : }
9575 : } else {
9576 1 : UpdateAirflowNetworkMyOneTimeFlag1 = false;
9577 : }
9578 : }
9579 :
9580 : // Assign airflows to EPLus nodes
9581 431106 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9582 718510 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC ||
9583 298458 : AirflowNetworkLinkageData(i).VAVTermDamper) {
9584 : // Exclude envelope leakage Crack element
9585 121594 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9586 121594 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9587 :
9588 121594 : int j = AirflowNetworkNodeData(Node1).EPlusNodeNum;
9589 121594 : if (j > 0 && AirflowNetworkNodeData(Node1).EPlusZoneNum == 0) {
9590 66324 : Node(j).MassFlowRate = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node1).AirLoopNum);
9591 66324 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Node(j).MassFlowRate = 0.0;
9592 132648 : if (!(AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::DIN ||
9593 66324 : AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::DOU)) {
9594 66324 : Node(j).MassFlowRateMaxAvail = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node1).AirLoopNum);
9595 66324 : Node(j).MassFlowRateMax = AirflowNetworkLinkSimu(i).FLOW;
9596 : }
9597 : }
9598 :
9599 121594 : j = AirflowNetworkNodeData(Node2).EPlusNodeNum;
9600 121594 : if (j > 0) {
9601 77378 : Node(j).MassFlowRate = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node2).AirLoopNum);
9602 77378 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Node(j).MassFlowRate = 0.0;
9603 154756 : if (!(AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::DIN ||
9604 77378 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::DOU)) {
9605 77378 : Node(j).MassFlowRateMaxAvail = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node2).AirLoopNum);
9606 77378 : Node(j).MassFlowRateMax = AirflowNetworkLinkSimu(i).FLOW;
9607 : }
9608 : }
9609 : }
9610 : }
9611 :
9612 : // Assign AirflowNetwork nodal values to Node array
9613 386890 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
9614 375836 : int j = AirflowNetworkNodeData(i).EPlusNodeNum;
9615 375836 : if (j > 0) {
9616 121594 : Node(j).Enthalpy = PsyHFnTdbW(AirflowNetworkNodeSimu(i).TZ, AirflowNetworkNodeSimu(i).WZ);
9617 121594 : Node(j).Temp = AirflowNetworkNodeSimu(i).TZ;
9618 121594 : Node(j).HumRat = AirflowNetworkNodeSimu(i).WZ;
9619 121594 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9620 0 : Node(j).CO2 = AirflowNetworkNodeSimu(i).CO2Z;
9621 : }
9622 121594 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9623 0 : Node(j).GenContam = AirflowNetworkNodeSimu(i).GCZ;
9624 : }
9625 : }
9626 : }
9627 :
9628 : // Calculate sensible loads from forced air flow
9629 431106 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9630 420052 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9631 420052 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9632 420052 : CpAir = PsyCpAirFnW((AirflowNetworkNodeSimu(Node1).WZ + AirflowNetworkNodeSimu(Node2).WZ) / 2.0);
9633 : // Calculate sensible loads from duct conduction losses and loads from duct radiation
9634 497430 : if (AirflowNetworkLinkageData(i).ZoneNum > 0 &&
9635 77378 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC) {
9636 77378 : Qsen = AirflowNetworkLinkSimu(i).FLOW * CpAir * (AirflowNetworkNodeSimu(Node2).TZ - AirflowNetworkNodeSimu(Node1).TZ);
9637 77378 : if (AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum != 0) {
9638 0 : auto const &DuctRadObj(AirflowNetworkLinkageViewFactorData(AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum));
9639 0 : Qsen -= DuctRadObj.QRad;
9640 0 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).RadGain -= DuctRadObj.QRad;
9641 : }
9642 : // When the Airloop is shut off, no duct sensible losses
9643 77378 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qsen = 0.0;
9644 77378 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).CondSen -= Qsen;
9645 : }
9646 : // Calculate sensible leakage losses
9647 840104 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::PLR ||
9648 420052 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::ELR) {
9649 : // Calculate supply leak sensible losses
9650 55270 : if ((AirflowNetworkNodeData(Node2).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node1).EPlusNodeNum == 0) &&
9651 11054 : (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
9652 11054 : ZN2 = AirflowNetworkNodeData(Node2).EPlusZoneNum;
9653 11054 : Qsen = AirflowNetworkLinkSimu(i).FLOW * CpAir * (AirflowNetworkNodeSimu(Node1).TZ - AirflowNetworkNodeSimu(Node2).TZ);
9654 11054 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qsen = 0.0;
9655 11054 : exchangeData(ZN2).LeakSen += Qsen;
9656 : }
9657 66324 : if ((AirflowNetworkNodeData(Node1).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node2).EPlusNodeNum == 0) &&
9658 22108 : (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
9659 0 : ZN1 = AirflowNetworkNodeData(Node1).EPlusZoneNum;
9660 0 : Qsen = AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (AirflowNetworkNodeSimu(Node2).TZ - AirflowNetworkNodeSimu(Node1).TZ);
9661 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qsen = 0.0;
9662 0 : exchangeData(ZN1).LeakSen += Qsen;
9663 : }
9664 : }
9665 : }
9666 :
9667 : // Calculate latent loads from forced air flow
9668 431106 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9669 420052 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9670 420052 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9671 : // Calculate latent loads from duct conduction losses
9672 497430 : if (AirflowNetworkLinkageData(i).ZoneNum > 0 &&
9673 77378 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC) {
9674 77378 : Qlat = AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node2).WZ - AirflowNetworkNodeSimu(Node1).WZ);
9675 77378 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qlat = 0.0;
9676 77378 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).DiffLat -= Qlat;
9677 : }
9678 : // Calculate latent leakage losses
9679 840104 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::PLR ||
9680 420052 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::ELR) {
9681 : // Calculate supply leak latent losses
9682 55270 : if ((AirflowNetworkNodeData(Node2).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node1).EPlusNodeNum == 0) &&
9683 11054 : (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
9684 11054 : ZN2 = AirflowNetworkNodeData(Node2).EPlusZoneNum;
9685 11054 : Qlat = AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).WZ - AirflowNetworkNodeSimu(Node2).WZ);
9686 11054 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qlat = 0.0;
9687 11054 : exchangeData(ZN2).LeakLat += Qlat;
9688 11054 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9689 0 : exchangeData(ZN2).TotalCO2 +=
9690 0 : AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).CO2Z - AirflowNetworkNodeSimu(Node2).CO2Z);
9691 : }
9692 11054 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9693 0 : exchangeData(ZN2).TotalGC +=
9694 0 : AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).GCZ - AirflowNetworkNodeSimu(Node2).GCZ);
9695 : }
9696 : }
9697 66324 : if ((AirflowNetworkNodeData(Node1).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node2).EPlusNodeNum == 0) &&
9698 22108 : (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
9699 0 : ZN1 = AirflowNetworkNodeData(Node1).EPlusZoneNum;
9700 0 : Qlat = AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).WZ - AirflowNetworkNodeSimu(Node1).WZ);
9701 0 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qlat = 0.0;
9702 0 : exchangeData(ZN1).LeakLat += Qlat;
9703 0 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9704 0 : exchangeData(ZN1).TotalCO2 +=
9705 0 : AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).CO2Z - AirflowNetworkNodeSimu(Node1).CO2Z);
9706 : }
9707 0 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9708 0 : exchangeData(ZN1).TotalGC +=
9709 0 : AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).GCZ - AirflowNetworkNodeSimu(Node1).GCZ);
9710 : }
9711 : }
9712 : }
9713 : }
9714 :
9715 : // Sum all the loads
9716 44216 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9717 33162 : exchangeData(i).TotalSen = exchangeData(i).LeakSen + exchangeData(i).CondSen + exchangeData(i).RadGain;
9718 33162 : exchangeData(i).TotalLat = exchangeData(i).LeakLat + exchangeData(i).DiffLat;
9719 : }
9720 :
9721 : // Simple ONOFF fan
9722 22108 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9723 11054 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9724 11054 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9725 : }
9726 11054 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && OnOffFanRunTimeFraction < 1.0) {
9727 20244 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9728 15183 : exchangeData(i).MultiZoneSen *= OnOffFanRunTimeFraction;
9729 15183 : exchangeData(i).MultiZoneLat *= OnOffFanRunTimeFraction;
9730 15183 : exchangeData(i).LeakSen *= OnOffFanRunTimeFraction;
9731 15183 : exchangeData(i).LeakLat *= OnOffFanRunTimeFraction;
9732 15183 : exchangeData(i).CondSen *= OnOffFanRunTimeFraction;
9733 15183 : exchangeData(i).DiffLat *= OnOffFanRunTimeFraction;
9734 15183 : exchangeData(i).RadGain *= OnOffFanRunTimeFraction;
9735 15183 : exchangeData(i).TotalSen *= OnOffFanRunTimeFraction;
9736 15183 : exchangeData(i).TotalLat *= OnOffFanRunTimeFraction;
9737 15183 : exchangeData(i).SumMCp *= OnOffFanRunTimeFraction;
9738 15183 : exchangeData(i).SumMCpT *= OnOffFanRunTimeFraction;
9739 15183 : exchangeData(i).SumMVCp *= OnOffFanRunTimeFraction;
9740 15183 : exchangeData(i).SumMVCpT *= OnOffFanRunTimeFraction;
9741 15183 : exchangeData(i).SumMHr *= OnOffFanRunTimeFraction;
9742 15183 : exchangeData(i).SumMHrW *= OnOffFanRunTimeFraction;
9743 15183 : exchangeData(i).SumMMCp *= OnOffFanRunTimeFraction;
9744 15183 : exchangeData(i).SumMMCpT *= OnOffFanRunTimeFraction;
9745 15183 : exchangeData(i).SumMMHr *= OnOffFanRunTimeFraction;
9746 15183 : exchangeData(i).SumMMHrW *= OnOffFanRunTimeFraction;
9747 15183 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9748 0 : exchangeData(i).SumMHrCO *= OnOffFanRunTimeFraction;
9749 0 : exchangeData(i).SumMMHrCO *= OnOffFanRunTimeFraction;
9750 : }
9751 15183 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9752 0 : exchangeData(i).SumMHrGC *= OnOffFanRunTimeFraction;
9753 0 : exchangeData(i).SumMMHrGC *= OnOffFanRunTimeFraction;
9754 : }
9755 : }
9756 5061 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling) {
9757 20244 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9758 15183 : exchangeData(i).SumMCp += multiExchangeData(i).SumMCp * (1.0 - OnOffFanRunTimeFraction);
9759 15183 : exchangeData(i).SumMCpT += multiExchangeData(i).SumMCpT * (1.0 - OnOffFanRunTimeFraction);
9760 15183 : exchangeData(i).SumMVCp += multiExchangeData(i).SumMVCp * (1.0 - OnOffFanRunTimeFraction);
9761 15183 : exchangeData(i).SumMVCpT += multiExchangeData(i).SumMVCpT * (1.0 - OnOffFanRunTimeFraction);
9762 15183 : exchangeData(i).SumMHr += multiExchangeData(i).SumMHr * (1.0 - OnOffFanRunTimeFraction);
9763 15183 : exchangeData(i).SumMHrW += multiExchangeData(i).SumMHrW * (1.0 - OnOffFanRunTimeFraction);
9764 15183 : exchangeData(i).SumMMCp += multiExchangeData(i).SumMMCp * (1.0 - OnOffFanRunTimeFraction);
9765 15183 : exchangeData(i).SumMMCpT += multiExchangeData(i).SumMMCpT * (1.0 - OnOffFanRunTimeFraction);
9766 15183 : exchangeData(i).SumMMHr += multiExchangeData(i).SumMMHr * (1.0 - OnOffFanRunTimeFraction);
9767 15183 : exchangeData(i).SumMMHrW += multiExchangeData(i).SumMMHrW * (1.0 - OnOffFanRunTimeFraction);
9768 15183 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9769 0 : exchangeData(i).SumMHrCO += multiExchangeData(i).SumMHrCO * (1.0 - OnOffFanRunTimeFraction);
9770 0 : exchangeData(i).SumMMHrCO += multiExchangeData(i).SumMMHrCO * (1.0 - OnOffFanRunTimeFraction);
9771 : }
9772 15183 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9773 0 : exchangeData(i).SumMHrGC += multiExchangeData(i).SumMHrGC * (1.0 - OnOffFanRunTimeFraction);
9774 0 : exchangeData(i).SumMMHrGC += multiExchangeData(i).SumMMHrGC * (1.0 - OnOffFanRunTimeFraction);
9775 : }
9776 : }
9777 : }
9778 : }
9779 :
9780 11054 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff) {
9781 44216 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
9782 33162 : if (AirflowNetworkNodeData(i).AirLoopNum == AirLoopNum) {
9783 22108 : nodeReport(i).PZ = AirflowNetworkNodeSimu(i).PZ * LoopPartLoadRatio(AirLoopNum) +
9784 22108 : nodeReport(i).PZOFF * (1.0 - LoopPartLoadRatio(AirLoopNum));
9785 22108 : nodeReport(i).PZON = AirflowNetworkNodeSimu(i).PZ;
9786 : }
9787 : }
9788 221080 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
9789 210026 : PartLoadRatio = MaxPartLoadRatio;
9790 840104 : for (int j = 1; j <= AirflowNetworkNumOfZones; ++j) {
9791 630078 : if (MultizoneZoneData(j).ZoneNum == MultizoneSurfaceData(i).ZonePtr) {
9792 0 : if (AirflowNetworkNodeData(j).AirLoopNum == AirLoopNum) {
9793 0 : PartLoadRatio = LoopPartLoadRatio(AirLoopNum);
9794 0 : break;
9795 : }
9796 : }
9797 : }
9798 210026 : linkReport1(i).FLOW = AirflowNetworkLinkSimu(i).FLOW * PartLoadRatio + linkReport1(i).FLOWOFF * (1.0 - PartLoadRatio);
9799 210026 : linkReport1(i).FLOW2 = AirflowNetworkLinkSimu(i).FLOW2 * PartLoadRatio + linkReport1(i).FLOW2OFF * (1.0 - PartLoadRatio);
9800 210026 : linkReport1(i).VolFLOW = AirflowNetworkLinkSimu(i).VolFLOW * PartLoadRatio + linkReport1(i).VolFLOWOFF * (1.0 - PartLoadRatio);
9801 210026 : linkReport1(i).VolFLOW2 = AirflowNetworkLinkSimu(i).VolFLOW2 * PartLoadRatio + linkReport1(i).VolFLOW2OFF * (1.0 - PartLoadRatio);
9802 210026 : linkReport1(i).DP = AirflowNetworkLinkSimu(i).DP * PartLoadRatio + linkReport1(i).DPOFF * (1.0 - PartLoadRatio);
9803 210026 : linkReport1(i).DPON = AirflowNetworkLinkSimu(i).DP;
9804 : }
9805 : }
9806 : }
9807 :
9808 : // Save values
9809 386890 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
9810 375836 : AirflowNetworkNodeSimu(i).TZlast = AirflowNetworkNodeSimu(i).TZ;
9811 375836 : AirflowNetworkNodeSimu(i).WZlast = AirflowNetworkNodeSimu(i).WZ;
9812 375836 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9813 0 : AirflowNetworkNodeSimu(i).CO2Zlast = AirflowNetworkNodeSimu(i).CO2Z;
9814 : }
9815 375836 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9816 0 : AirflowNetworkNodeSimu(i).GCZlast = AirflowNetworkNodeSimu(i).GCZ;
9817 : }
9818 : }
9819 : }
9820 :
9821 14 : void Solver::venting_control(int const i, // AirflowNetwork surface number
9822 : Real64 &OpenFactor // Window or door opening factor (used to calculate airflow)
9823 : )
9824 : {
9825 : // SUBROUTINE INFORMATION:
9826 : // AUTHOR Fred Winkelmann
9827 : // DATE WRITTEN April 2003
9828 : // MODIFIED Feb 2004, FCW: allow venting control of interior window/door
9829 : // MODIFIED Nov. 2005, LG: to fit the requirement for AirflowNetwork Model
9830 : // RE-ENGINEERED
9831 :
9832 : // PURPOSE OF THIS SUBROUTINE:
9833 : // Determines the venting opening factor for an exterior or interior window or door
9834 : // as determined by the venting control method.
9835 :
9836 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9837 : Real64 VentTemp; // Venting temperature (C)
9838 : Real64 ZoneAirEnthalpy; // Enthalpy of zone air (J/kg)
9839 : Real64 OpenFactorMult; // Window/door opening modulation multiplier on venting open factor
9840 : Real64 DelTemp; // Inside-outside air temperature difference (K)
9841 : Real64 DelEnthal; // Inside-outside air enthalpy difference (J/kg)
9842 : int IZ; // AirflowNetwork zone number
9843 : int ZoneNum; // EnergyPlus zone number
9844 : int SurfNum; // Heat transfer surface number
9845 : Real64 LimValVentOpenFacMult; // Limiting value of venting opening factor multiplier
9846 : Real64 LowerValInOutTempDiff; // Lower value of inside/outside temperature difference for opening factor modulation
9847 : Real64 UpperValInOutTempDiff; // Upper value of inside/outside temperature difference for opening factor modulation
9848 : Real64 LowerValInOutEnthalDiff; // Lower value of inside/outside enthalpy difference for opening factor modulation
9849 : Real64 UpperValInOutEnthalDiff; // Upper value of inside/outside enthalpy difference for opening factor modulation
9850 : bool VentingAllowed; // True if venting schedule allows venting
9851 : int VentCtrlNum; // Venting control strategy 1: Temperature control; 2: Enthalpy control
9852 : Real64 VentingSchVal; // Current time step value of venting schedule
9853 : Real64 Tamb; // Outdoor dry bulb temperature at surface centroid height
9854 : int PeopleInd;
9855 :
9856 14 : if (MultizoneSurfaceData(i).EMSOpenFactorActuated) { // EMS sets value to use
9857 0 : OpenFactor = MultizoneSurfaceData(i).EMSOpenFactor;
9858 0 : SurfNum = MultizoneSurfaceData(i).SurfNum;
9859 0 : if (MultizoneSurfaceData(i).Factor > 0.0) {
9860 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactor / MultizoneSurfaceData(i).Factor;
9861 : } else {
9862 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactor;
9863 : }
9864 0 : return;
9865 : }
9866 :
9867 14 : SurfNum = MultizoneSurfaceData(i).SurfNum;
9868 :
9869 14 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
9870 :
9871 : // Get venting temperature and venting strategy for exterior window or door
9872 : // and determine whether venting is allowed
9873 :
9874 14 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 1.0;
9875 14 : VentingAllowed = true;
9876 14 : IZ = MultizoneSurfaceData(i).NodeNums[0];
9877 : // Revise for RoomAirflowNetwork model
9878 14 : if (MultizoneSurfaceData(i).RAFNflag) IZ = MultizoneSurfaceData(i).ZonePtr;
9879 14 : ZoneNum = MultizoneZoneData(IZ).ZoneNum;
9880 :
9881 : // Note in the following that individual venting control for a window/door takes
9882 : // precedence over zone-level control
9883 14 : if (MultizoneSurfaceData(i).IndVentControl) {
9884 0 : VentTemp = MultizoneSurfaceData(i).ventTempControlSched ? MultizoneSurfaceData(i).ventTempControlSched->getCurrentVal() : 0.0;
9885 0 : VentCtrlNum = MultizoneSurfaceData(i).VentSurfCtrNum;
9886 0 : if (MultizoneSurfaceData(i).ventAvailSched != nullptr) {
9887 0 : VentingSchVal = MultizoneSurfaceData(i).ventAvailSched->getCurrentVal();
9888 0 : if (VentingSchVal <= 0.0) {
9889 0 : VentingAllowed = false;
9890 0 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 0.0;
9891 : }
9892 : }
9893 : } else {
9894 : // Zone level only by Gu on Nov. 8, 2005
9895 14 : VentTemp = MultizoneZoneData(IZ).ventTempControlSched ? MultizoneZoneData(IZ).ventTempControlSched->getCurrentVal() : 0.0;
9896 14 : VentCtrlNum = MultizoneZoneData(IZ).VentCtrNum;
9897 14 : if (MultizoneZoneData(IZ).ventAvailSched != nullptr) {
9898 12 : VentingSchVal = MultizoneZoneData(IZ).ventAvailSched->getCurrentVal();
9899 12 : if (VentingSchVal <= 0.0) {
9900 0 : VentingAllowed = false;
9901 0 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 0.0;
9902 : }
9903 : }
9904 : }
9905 :
9906 14 : m_state.dataSurface->SurfWinInsideTempForVentingRep(SurfNum) = VentTemp;
9907 14 : OpenFactor = 0.0;
9908 :
9909 : // Venting based on inside-outside air temperature difference
9910 :
9911 14 : if ((VentCtrlNum == VentControlType::Temp || VentCtrlNum == VentControlType::AdjTemp) && VentingAllowed) {
9912 12 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(SurfNum);
9913 : // Check whether this surface is an interior wall or not. If Yes, use adjacent zone conditions
9914 12 : if (VentCtrlNum == VentControlType::AdjTemp && MultizoneSurfaceData(i).IndVentControl) {
9915 0 : Tamb = ANZT(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum);
9916 : }
9917 12 : if (ANZT(ZoneNum) > Tamb && ANZT(ZoneNum) > VentTemp) {
9918 6 : OpenFactor = MultizoneSurfaceData(i).Factor;
9919 6 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
9920 : // Modulation of OpenFactor
9921 6 : if (MultizoneSurfaceData(i).IndVentControl) {
9922 0 : LimValVentOpenFacMult = MultizoneSurfaceData(i).ModulateFactor;
9923 0 : LowerValInOutTempDiff = MultizoneSurfaceData(i).LowValueTemp;
9924 0 : UpperValInOutTempDiff = MultizoneSurfaceData(i).UpValueTemp;
9925 : } else {
9926 6 : LimValVentOpenFacMult = MultizoneZoneData(IZ).OpenFactor;
9927 6 : LowerValInOutTempDiff = MultizoneZoneData(IZ).LowValueTemp;
9928 6 : UpperValInOutTempDiff = MultizoneZoneData(IZ).UpValueTemp;
9929 : }
9930 6 : if (LimValVentOpenFacMult != 1.0) {
9931 4 : DelTemp = ANZT(ZoneNum) - Tamb;
9932 4 : if (DelTemp <= LowerValInOutTempDiff) {
9933 0 : OpenFactorMult = 1.0;
9934 4 : } else if (DelTemp >= UpperValInOutTempDiff) {
9935 4 : OpenFactorMult = LimValVentOpenFacMult;
9936 : } else {
9937 0 : OpenFactorMult =
9938 : LimValVentOpenFacMult +
9939 0 : ((UpperValInOutTempDiff - DelTemp) / (UpperValInOutTempDiff - LowerValInOutTempDiff)) * (1 - LimValVentOpenFacMult);
9940 : }
9941 4 : OpenFactor *= OpenFactorMult;
9942 4 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactorMult;
9943 : }
9944 : } else {
9945 6 : OpenFactor = 0.0;
9946 6 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
9947 : }
9948 : }
9949 :
9950 : // Venting based on inside-outside air enthalpy difference
9951 :
9952 14 : if ((VentCtrlNum == VentControlType::Enth || VentCtrlNum == VentControlType::AdjEnth) && VentingAllowed) {
9953 0 : ZoneAirEnthalpy = PsyHFnTdbW(ANZT(ZoneNum), ANZW(ZoneNum));
9954 : // Check whether this surface is an interior wall or not. If Yes, use adjacent zone conditions
9955 0 : if (VentCtrlNum == VentControlType::AdjEnth && MultizoneSurfaceData(i).IndVentControl) {
9956 0 : m_state.dataEnvrn->OutEnthalpy = PsyHFnTdbW(ANZT(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum),
9957 0 : ANZW(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum));
9958 : }
9959 0 : if (ZoneAirEnthalpy > m_state.dataEnvrn->OutEnthalpy && ANZT(ZoneNum) > VentTemp) {
9960 0 : OpenFactor = MultizoneSurfaceData(i).Factor;
9961 : // Modulation of OpenFactor
9962 0 : if (MultizoneSurfaceData(i).IndVentControl) {
9963 0 : LimValVentOpenFacMult = MultizoneSurfaceData(i).ModulateFactor;
9964 0 : LowerValInOutEnthalDiff = MultizoneSurfaceData(i).LowValueEnth;
9965 0 : UpperValInOutEnthalDiff = MultizoneSurfaceData(i).UpValueEnth;
9966 : } else {
9967 0 : LimValVentOpenFacMult = MultizoneZoneData(IZ).OpenFactor;
9968 0 : LowerValInOutEnthalDiff = MultizoneZoneData(IZ).LowValueEnth;
9969 0 : UpperValInOutEnthalDiff = MultizoneZoneData(IZ).UpValueEnth;
9970 : }
9971 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
9972 :
9973 0 : if (LimValVentOpenFacMult != 1.0) {
9974 0 : DelEnthal = ZoneAirEnthalpy - m_state.dataEnvrn->OutEnthalpy;
9975 0 : if (DelEnthal <= LowerValInOutEnthalDiff) {
9976 0 : OpenFactorMult = 1.0;
9977 0 : } else if (DelEnthal >= UpperValInOutEnthalDiff) {
9978 0 : OpenFactorMult = LimValVentOpenFacMult;
9979 : } else {
9980 0 : OpenFactorMult =
9981 0 : LimValVentOpenFacMult + ((UpperValInOutEnthalDiff - DelEnthal) / (UpperValInOutEnthalDiff - LowerValInOutEnthalDiff)) *
9982 0 : (1 - LimValVentOpenFacMult);
9983 : }
9984 0 : OpenFactor *= OpenFactorMult;
9985 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactorMult;
9986 : }
9987 : } else {
9988 0 : OpenFactor = 0.0;
9989 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
9990 : }
9991 : }
9992 :
9993 : // Constant venting (opening factor as specified in IDF) - C-PH - added by Philip Haves 3/8/01
9994 : // subject to venting availability
9995 :
9996 14 : if (VentCtrlNum == VentControlType::Const && VentingAllowed) { // Constant
9997 2 : OpenFactor = MultizoneSurfaceData(i).Factor;
9998 2 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
9999 : }
10000 :
10001 14 : if (VentCtrlNum == VentControlType::ASH55) {
10002 0 : if (VentingAllowed && (!m_state.dataGlobal->BeginEnvrnFlag) && (!m_state.dataGlobal->WarmupFlag)) {
10003 0 : PeopleInd = MultizoneZoneData(IZ).ASH55PeopleInd;
10004 0 : if (PeopleInd > 0 && m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortAdaptiveASH5590 != -1) {
10005 0 : if (m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortOpTemp >
10006 0 : m_state.dataThermalComforts->ThermalComfortData(PeopleInd).TComfASH55) {
10007 0 : OpenFactor = MultizoneSurfaceData(i).Factor;
10008 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10009 : } else {
10010 0 : OpenFactor = 0.0;
10011 : }
10012 : } else {
10013 0 : OpenFactor = 0.0;
10014 : }
10015 : } else {
10016 0 : OpenFactor = 0.0;
10017 : }
10018 : }
10019 :
10020 14 : if (VentCtrlNum == VentControlType::CEN15251) {
10021 0 : if (VentingAllowed && (!m_state.dataGlobal->BeginEnvrnFlag) && (!m_state.dataGlobal->WarmupFlag)) {
10022 0 : PeopleInd = MultizoneZoneData(IZ).CEN15251PeopleInd;
10023 0 : if (PeopleInd > 0 && m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortAdaptiveCEN15251CatI != -1) {
10024 0 : if (m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortOpTemp >
10025 0 : m_state.dataThermalComforts->ThermalComfortData(PeopleInd).TComfCEN15251) {
10026 0 : OpenFactor = MultizoneSurfaceData(i).Factor;
10027 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10028 : } else {
10029 0 : OpenFactor = 0.0;
10030 : }
10031 : } else {
10032 0 : OpenFactor = 0.0;
10033 : }
10034 : } else {
10035 0 : OpenFactor = 0.0;
10036 : }
10037 : }
10038 :
10039 : // No venting, i.e, window/door always closed - added YJH 8 Aug 02
10040 :
10041 14 : if (VentCtrlNum == VentControlType::NoVent) { // Novent
10042 0 : OpenFactor = 0.0;
10043 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10044 : }
10045 : }
10046 :
10047 17 : void Solver::validate_distribution()
10048 : {
10049 :
10050 : // SUBROUTINE INFORMATION:
10051 : // AUTHOR Lixing Gu
10052 : // DATE WRITTEN Oct. 2005
10053 : // MODIFIED L. Gu, Jan. 2009: allow a desuperheater coil and three heat exchangers
10054 : // RE-ENGINEERED na
10055 :
10056 : // PURPOSE OF THIS SUBROUTINE:
10057 : // This subroutine validates the inputs of distribution system, since node data from a primary airloop
10058 : // are not available in the first call during reading input data of airflownetwork objects.
10059 : // Note: this routine shouldn't be called more than once
10060 :
10061 : // Using/Aliasing
10062 : using BranchNodeConnections::GetNodeConnectionType;
10063 : using MixedAir::GetNumOAMixers;
10064 : using MixedAir::GetOAMixerInletNodeNumber;
10065 : using MixedAir::GetOAMixerReliefNodeNumber;
10066 : using SingleDuct::GetHVACSingleDuctSysIndex;
10067 : using namespace DataLoopNode;
10068 17 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
10069 : using DXCoils::SetDXCoilAirLoopNumber;
10070 : using HeatingCoils::SetHeatingCoilAirLoopNumber;
10071 : using HVACStandAloneERV::GetStandAloneERVNodeNumber;
10072 : using HVACVariableRefrigerantFlow::getVRFTUNodeNumber;
10073 : using SplitterComponent::GetSplitterNodeNumbers;
10074 : using SplitterComponent::GetSplitterOutletNumber;
10075 : using UnitarySystems::getUnitarySystemNodeNumber;
10076 : using WaterThermalTanks::GetHeatPumpWaterHeaterNodeNumber;
10077 : using WindowAC::getWindowACNodeNumber;
10078 : using ZoneDehumidifier::GetZoneDehumidifierNodeNumber;
10079 :
10080 : // SUBROUTINE PARAMETER DEFINITIONS:
10081 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::validate_distribution: "); // include trailing blank space
10082 :
10083 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10084 : int n;
10085 : bool LocalError;
10086 17 : Array1D_bool NodeFound;
10087 :
10088 17 : bool ErrorsFound(false);
10089 17 : bool IsNotOK(false);
10090 17 : bool errFlag(false);
10091 17 : EPVector<DataLoopNode::ConnectionType> NodeConnectionType; // Specifies the type of node connection
10092 17 : std::string CurrentModuleObject;
10093 :
10094 17 : bool hpwhFound(false); // Flag for HPWH identification
10095 17 : bool standaloneERVFound(false); // Flag for Standalone ERV (ZoneHVAC:EnergyRecoveryVentilator) identification
10096 17 : bool packagedUnitaryFound(false); // Flag for packaged unitary systems (ZoneHVAC:PackagedTerminalAirConditioner,
10097 : // ZoneHVAC:PackagedTerminalHeatPump, ZoneHVAC:WaterToAirHeatPump) identification
10098 17 : bool vrfTUFound(false);
10099 17 : bool windowACFound(false); // Flag for Window AC (ZoneHVAC:WindowAirConditioner) identification
10100 :
10101 : // Validate supply and return connections
10102 17 : NodeFound.dimension(m_state.dataLoopNodes->NumOfNodes, false);
10103 : // Validate inlet and outlet nodes for zone exhaust fans
10104 18 : for (int i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
10105 1 : NodeFound(MultizoneCompExhaustFanData(i).InletNode) = true;
10106 1 : NodeFound(MultizoneCompExhaustFanData(i).OutletNode) = true;
10107 : }
10108 : // Validate EPlus Node names and types
10109 31 : for (int i = 1; i <= DisSysNumOfNodes; ++i) {
10110 14 : if (Util::SameString(DisSysNodeData(i).EPlusName, "") || Util::SameString(DisSysNodeData(i).EPlusName, "Other")) continue;
10111 10 : LocalError = false;
10112 94 : for (int j = 1; j <= m_state.dataLoopNodes->NumOfNodes; ++j) { // NodeID
10113 94 : if (DisSysNodeData(i).EPlusName == m_state.dataLoopNodes->NodeID(j)) {
10114 10 : DisSysNodeData(i).AirLoopNum = get_airloop_number(j);
10115 10 : if (DisSysNodeData(i).AirLoopNum == 0) {
10116 0 : ShowSevereError(m_state,
10117 0 : format(RoutineName) + "The Node or Component Name defined in " + DisSysNodeData(i).Name +
10118 : " is not found in the AirLoopHVAC.");
10119 0 : ShowContinueError(m_state,
10120 0 : "The entered name is " + DisSysNodeData(i).EPlusName + " in an AirflowNetwork:Distribution:Node object.");
10121 0 : ErrorsFound = true;
10122 : }
10123 10 : DisSysNodeData(i).EPlusNodeNum = j;
10124 10 : AirflowNetworkNodeData(NumOfNodesMultiZone + i).EPlusNodeNum = j;
10125 10 : AirflowNetworkNodeData(NumOfNodesMultiZone + i).AirLoopNum = DisSysNodeData(i).AirLoopNum;
10126 10 : NodeFound(j) = true;
10127 10 : LocalError = true;
10128 10 : break;
10129 : }
10130 : }
10131 : // Check outdoor air node
10132 20 : if (Util::SameString(DisSysNodeData(i).EPlusType, "OutdoorAir:NodeList") ||
10133 20 : Util::SameString(DisSysNodeData(i).EPlusType, "OutdoorAir:Node")) {
10134 0 : if (!LocalError) {
10135 0 : ShowSevereError(m_state,
10136 0 : format(RoutineName) + "The Node or Component Name defined in " + DisSysNodeData(i).Name +
10137 0 : " is not found in the " + DisSysNodeData(i).EPlusType);
10138 0 : ShowContinueError(m_state,
10139 0 : "The entered name is " + DisSysNodeData(i).EPlusName + " in an AirflowNetwork:Distribution:Node object.");
10140 0 : ErrorsFound = true;
10141 : }
10142 : }
10143 10 : if (DisSysNodeData(i).EPlusNodeNum == 0) {
10144 0 : ShowSevereError(m_state,
10145 0 : format(RoutineName) +
10146 0 : "Primary Air Loop Node is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " + DisSysNodeData(i).Name);
10147 0 : ErrorsFound = true;
10148 : }
10149 : }
10150 :
10151 : // Determine node numbers for zone inlets and outlets
10152 32 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
10153 15 : if (!m_state.dataZoneEquip->ZoneEquipConfig(i).IsControlled) continue;
10154 15 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumInletNodes; ++j) {
10155 60 : for (int k = 1; k <= AirflowNetworkNumOfNodes; ++k) {
10156 59 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).InletNode(j) == AirflowNetworkNodeData(k).EPlusNodeNum) {
10157 1 : AirflowNetworkNodeData(k).EPlusTypeNum = iEPlusNodeType::ZIN;
10158 1 : break;
10159 : }
10160 : }
10161 : }
10162 14 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumReturnNodes; ++j) {
10163 26 : for (int k = 1; k <= AirflowNetworkNumOfNodes; ++k) {
10164 26 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).ReturnNode(j) == AirflowNetworkNodeData(k).EPlusNodeNum) {
10165 1 : AirflowNetworkNodeData(k).EPlusTypeNum = iEPlusNodeType::ZOU;
10166 1 : break;
10167 : }
10168 : }
10169 : }
10170 : }
10171 :
10172 : // Eliminate node not related to AirLoopHVAC
10173 88 : for (int k = 1; k <= m_state.dataBranchNodeConnections->NumOfNodeConnections; ++k) {
10174 71 : if (NodeFound(m_state.dataBranchNodeConnections->NodeConnections(k).NodeNumber)) continue;
10175 41 : if (m_state.dataBranchNodeConnections->NodeConnections(k).FluidStream == NodeInputManager::CompFluidStream::Secondary) {
10176 0 : NodeFound(m_state.dataBranchNodeConnections->NodeConnections(k).NodeNumber) = true;
10177 : }
10178 : }
10179 :
10180 : // Eliminate nodes with fluidtype = water
10181 82 : for (int k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
10182 65 : if (NodeFound(k)) continue;
10183 53 : if (m_state.dataLoopNodes->Node(k).FluidType == DataLoopNode::NodeFluidType::Water) {
10184 0 : NodeFound(k) = true;
10185 : }
10186 : }
10187 :
10188 : // Eliminate local external air node for network
10189 82 : for (int k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
10190 65 : if (NodeFound(k)) continue;
10191 53 : if (m_state.dataLoopNodes->Node(k).IsLocalNode) NodeFound(k) = true;
10192 : }
10193 :
10194 : // Ensure all the nodes used in Eplus are a subset of AirflowNetwork Nodes
10195 82 : for (int i = 1; i <= m_state.dataLoopNodes->NumOfNodes; ++i) {
10196 65 : if (NodeFound(i)) continue;
10197 : // Skip the inlet and outlet nodes of zone dehumidifiers
10198 53 : if (GetZoneDehumidifierNodeNumber(m_state, i)) NodeFound(i) = true;
10199 :
10200 53 : if (simulation_control.allow_unsupported_zone_equipment) {
10201 : // Skip HPWH nodes that don't have to be included in the AFN
10202 42 : if (GetHeatPumpWaterHeaterNodeNumber(m_state, i)) {
10203 2 : NodeFound(i) = true;
10204 2 : hpwhFound = true;
10205 : }
10206 :
10207 : // Skip Standalone ERV nodes that don't have to be included in the AFN
10208 42 : if (GetStandAloneERVNodeNumber(m_state, i)) {
10209 4 : NodeFound(i) = true;
10210 4 : standaloneERVFound = true;
10211 : }
10212 :
10213 : // Skip zonal unitary system based nodes that don't have to be included in the AFN
10214 42 : if (getUnitarySystemNodeNumber(m_state, i)) {
10215 8 : NodeFound(i) = true;
10216 8 : packagedUnitaryFound = true;
10217 : }
10218 :
10219 : // Skip zonal vrf terminal nodes that don't have to be included in the AFN
10220 42 : if (getVRFTUNodeNumber(m_state, i)) {
10221 10 : NodeFound(i) = true;
10222 10 : vrfTUFound = true;
10223 : }
10224 :
10225 : // Skip Window AC with no OA
10226 42 : if (getWindowACNodeNumber(m_state, i)) {
10227 2 : NodeFound(i) = true;
10228 2 : windowACFound = true;
10229 : }
10230 : }
10231 :
10232 97 : for (int zoneNum = 1; zoneNum <= m_state.dataGlobal->NumOfZones; ++zoneNum) {
10233 57 : if (!m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).IsControlled) continue;
10234 53 : if (m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneNode == i) {
10235 13 : if (zoneNum > AirflowNetworkNumOfNodes) {
10236 2 : ShowSevereError(m_state,
10237 2 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10238 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10239 2 : ShowContinueError(
10240 2 : m_state, "This Node is the zone air node for Zone '" + m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneName + "'.");
10241 1 : ErrorsFound = true;
10242 : } else {
10243 12 : NodeFound(i) = true;
10244 26 : for (int iZone = 1; iZone <= AirflowNetworkNumOfZones; iZone++) {
10245 14 : if (MultizoneZoneData(iZone).ZoneNum == zoneNum) {
10246 12 : AirflowNetworkNodeData(iZone).EPlusNodeNum = i;
10247 : }
10248 : }
10249 : }
10250 13 : break;
10251 : }
10252 : }
10253 :
10254 : // skip nodes that are not part of an airflow network
10255 :
10256 : // DX COIL CONDENSER NODE TEST:
10257 : // Outside air nodes are used for DX coil condenser inlet nodes, these are specified in an outside air node or
10258 : // OutdoorAir:NodeList object (and classified with NodeConnectionType as OutsideAir). In addition,
10259 : // this same node is specified in a Coil:DX:CoolingBypassFactorEmpirical object (and classified with
10260 : // NodeConnectionType as OutsideAirReference). In the NodeConnectionType structure, both of these nodes have a
10261 : // unique index but have the same node number. The Outside Air Node will usually be listed first. Search for all
10262 : // indexes with the same node number and check if it is classified as NodeConnectionType = OutsideAirReference.
10263 : // Mark this node as found since it is not used in an airflownetwork simulation.
10264 : // Example (using AirflowNetwork_MultiZone_SmallOffice.idf with a single OA Mixer):
10265 : // (the example shown below is identical to AirflowNetwork_SimpleHouse.idf with no OA Mixer except
10266 : // that the NodeConnections indexes are (7) and (31), respectively and the NodeNumber = 6)
10267 : // The GetNodeConnectionType CALL below returns DataLoopNode::NodeConnectionType::OutsideAir = 7 and
10268 : // DataLoopNode::NodeConnectionType::OutsideAirReference = 14.
10269 : // NodeConnections info from OUTSIDE AIR NODE object read:
10270 : // NodeConnections(9)NodeNumber = 10
10271 : // NodeConnections(9)NodeName = ACDXCOIL 1 CONDENSER NODE
10272 : // NodeConnections(9)ObjectType = OUTSIDE AIR NODE
10273 : // NodeConnections(9)ObjectName = OUTSIDE AIR NODE
10274 : // NodeConnections(9)ConnectionType = OutsideAir
10275 : // NodeConnections info from Coil:DX:CoolingBypassFactorEmpirical object read:
10276 : // NodeConnections(64)NodeNumber = 10
10277 : // NodeConnections(64)NodeName = ACDXCOIL 1 CONDENSER NODE
10278 : // NodeConnections(64)ObjectType = COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
10279 : // NodeConnections(64)ObjectName = ACDXCOIL 1
10280 : // NodeConnections(64)ConnectionType = OutsideAirReference
10281 :
10282 53 : errFlag = false;
10283 53 : GetNodeConnectionType(m_state, i, NodeConnectionType, errFlag); // Gets all connection types for a given node number
10284 53 : if (errFlag) {
10285 42 : ShowContinueError(m_state, "...occurs in Airflow Network simulation.");
10286 : } else {
10287 : // skip nodes for air cooled condensers
10288 80 : for (int j = 1; j <= isize(NodeConnectionType); ++j) {
10289 41 : if (NodeConnectionType(j) == DataLoopNode::ConnectionType::OutsideAirReference) {
10290 0 : NodeFound(i) = true;
10291 : }
10292 : }
10293 : }
10294 :
10295 53 : if (!NodeFound(i)) {
10296 : // Check if this node is the OA relief node. For the time being, OA relief node is not used
10297 13 : if (GetNumOAMixers(m_state) > 1) {
10298 : // ShowSevereError(m_state, format(RoutineName) + "Only one OutdoorAir:Mixer is allowed in the
10299 : // AirflowNetwork model." ); ErrorsFound = true;
10300 : int OAFanNum;
10301 : int OARelNum;
10302 : int OAMixerNum;
10303 :
10304 0 : for (OAFanNum = 1; OAFanNum <= NumOfOAFans; ++OAFanNum) {
10305 0 : DisSysCompOutdoorAirData(OAFanNum).InletNode =
10306 0 : GetOAMixerInletNodeNumber(m_state, DisSysCompOutdoorAirData(OAFanNum).OAMixerNum);
10307 : // NodeFound( DisSysCompOutdoorAirData( OAFanNum ).InletNode
10308 : // ) = true;
10309 : }
10310 0 : for (OARelNum = 1; OARelNum <= NumOfReliefFans; ++OARelNum) {
10311 0 : DisSysCompReliefAirData(OARelNum).OutletNode =
10312 0 : GetOAMixerInletNodeNumber(m_state, DisSysCompReliefAirData(OARelNum).OAMixerNum);
10313 : // NodeFound( DisSysCompOutdoorAirData( OAFanNum ).InletNode
10314 : // ) = true;
10315 : }
10316 : // Check NodeFound status
10317 0 : for (OAMixerNum = 1; OAMixerNum <= GetNumOAMixers(m_state); ++OAMixerNum) {
10318 0 : if (i == GetOAMixerReliefNodeNumber(m_state, OAMixerNum)) {
10319 0 : NodeFound(i) = true;
10320 0 : break;
10321 0 : } else if (i == GetOAMixerInletNodeNumber(m_state, OAMixerNum)) {
10322 0 : NodeFound(i) = true;
10323 0 : break;
10324 : } else {
10325 0 : if (OAMixerNum == GetNumOAMixers(m_state)) {
10326 0 : ShowSevereError(m_state,
10327 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10328 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10329 0 : ErrorsFound = true;
10330 : }
10331 : }
10332 : }
10333 13 : } else if (GetNumOAMixers(m_state) == 0) {
10334 26 : ShowSevereError(m_state,
10335 26 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10336 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10337 13 : ErrorsFound = true;
10338 : } else {
10339 : // TODO: I fail to see how you could enter this block given than NumOAMixers (returned by GetNumOAMixers())
10340 : // is initialized to zero, and we check above if '> 0' or '== 0'
10341 0 : if (NumOfOAFans == 1 && DisSysCompOutdoorAirData(1).InletNode == 0) {
10342 0 : DisSysCompOutdoorAirData(1).InletNode = GetOAMixerInletNodeNumber(m_state, 1);
10343 : }
10344 0 : if (NumOfReliefFans == 1 && DisSysCompReliefAirData(1).OutletNode == 0) {
10345 0 : DisSysCompReliefAirData(1).OutletNode = GetOAMixerInletNodeNumber(m_state, 1);
10346 : }
10347 0 : if (i == GetOAMixerReliefNodeNumber(m_state, 1)) {
10348 0 : NodeFound(i) = true;
10349 0 : } else if (i == GetOAMixerInletNodeNumber(m_state, 1)) {
10350 0 : NodeFound(i) = true;
10351 : } else {
10352 0 : ShowSevereError(m_state,
10353 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10354 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10355 0 : ErrorsFound = true;
10356 : }
10357 : }
10358 : }
10359 : }
10360 17 : if (hpwhFound) {
10361 2 : ShowWarningError(m_state,
10362 2 : format(RoutineName) + "Heat pump water heater is simulated along with an AirflowNetwork but is not included in "
10363 : "the AirflowNetwork.");
10364 : }
10365 17 : if (standaloneERVFound) {
10366 2 : ShowWarningError(m_state,
10367 2 : format(RoutineName) + "A ZoneHVAC:EnergyRecoveryVentilator is simulated along with an AirflowNetwork but is not "
10368 : "included in the AirflowNetwork.");
10369 : }
10370 17 : if (packagedUnitaryFound) {
10371 2 : ShowWarningError(m_state,
10372 2 : format(RoutineName) + "A ZoneHVAC:PackagedTerminalAirConditioner, ZoneHVAC:PackagedTerminalHeatPump, or "
10373 : "ZoneHVAC:WaterToAirHeatPump is simulated along with an AirflowNetwork but is not "
10374 : "included in the AirflowNetwork.");
10375 : }
10376 17 : if (vrfTUFound) {
10377 2 : ShowWarningError(m_state,
10378 2 : format(RoutineName) +
10379 : "A ZoneHVAC:TerminalUnit:VariableRefrigerantFlow is simulated along with an AirflowNetwork but is not "
10380 : "included in the AirflowNetwork.");
10381 : }
10382 17 : if (windowACFound) {
10383 2 : ShowWarningError(m_state,
10384 2 : format(RoutineName) + "A ZoneHVAC:WindowAirConditioner is simulated along with an AirflowNetwork but is not "
10385 : "included in the AirflowNetwork.");
10386 : }
10387 17 : NodeFound.deallocate();
10388 :
10389 : // Assign AirLoop Number to every node and linkage
10390 : // Zone first
10391 31 : for (int i = 1; i <= AirflowNetworkNumOfZones; i++) {
10392 34 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; j++) {
10393 20 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) continue;
10394 14 : if ((MultizoneZoneData(i).ZoneNum == j) && (m_state.dataZoneEquip->ZoneEquipConfig(j).NumInletNodes > 0)) {
10395 : // No multiple Airloop
10396 1 : AirflowNetworkNodeData(i).AirLoopNum = m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(1);
10397 : }
10398 : }
10399 : }
10400 : // Air Distribution system
10401 36 : for (int i = AirflowNetworkNumOfSurfaces + 1; i <= AirflowNetworkNumOfLinks; ++i) {
10402 19 : int j = AirflowNetworkLinkageData(i).NodeNums[0];
10403 19 : int k = AirflowNetworkLinkageData(i).NodeNums[1];
10404 19 : if (AirflowNetworkNodeData(j).AirLoopNum == 0 && AirflowNetworkNodeData(k).AirLoopNum == 0) {
10405 : // Error messaage
10406 0 : ShowSevereError(m_state,
10407 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(i).Name +
10408 : " is not valid for AirLoopNum assignment");
10409 0 : ShowContinueError(m_state,
10410 0 : "AirLoopNum is not found in both nodes for the linkage: " + AirflowNetworkLinkageData(i).NodeNames[0] + " and " +
10411 0 : AirflowNetworkLinkageData(i).NodeNames[1]);
10412 0 : ShowContinueError(m_state,
10413 : "Please ensure one of two AIRFLOWNETWORK:DISTRIBUTION:NODEs in the first AIRFLOWNETWORK:DISTRIBUTION:LINKAGE "
10414 : "object should be defined as EnergyPlus NodeID.");
10415 0 : ErrorsFound = true;
10416 : }
10417 19 : if (AirflowNetworkNodeData(j).AirLoopNum > 0 && AirflowNetworkNodeData(k).AirLoopNum == 0) {
10418 6 : AirflowNetworkNodeData(k).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10419 : }
10420 19 : if (AirflowNetworkNodeData(j).AirLoopNum == 0 && AirflowNetworkNodeData(k).AirLoopNum > 0) {
10421 0 : AirflowNetworkNodeData(j).AirLoopNum = AirflowNetworkNodeData(k).AirLoopNum;
10422 : }
10423 19 : if (AirflowNetworkNodeData(j).AirLoopNum == AirflowNetworkNodeData(k).AirLoopNum) {
10424 19 : AirflowNetworkLinkageData(i).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10425 : }
10426 19 : if (AirflowNetworkNodeData(j).AirLoopNum != AirflowNetworkNodeData(k).AirLoopNum && AirflowNetworkNodeData(j).AirLoopNum > 0 &&
10427 0 : AirflowNetworkNodeData(k).AirLoopNum > 0) {
10428 0 : AirflowNetworkLinkageData(i).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10429 0 : ShowSevereError(m_state,
10430 0 : "The AirLoopNum defined in both AIRFLOWNETWORK:DISTRIBUTION:NODE objects in " + AirflowNetworkLinkageData(i).Name +
10431 : " are not the same. Please make sure both nodes should be listed in the same AirLoop as a valid linkage.");
10432 0 : ShowContinueError(m_state,
10433 0 : "AirLoop defined in " + AirflowNetworkNodeData(j).Name + " is " +
10434 0 : m_state.dataAirSystemsData->PrimaryAirSystems(AirflowNetworkNodeData(j).AirLoopNum).Name +
10435 0 : ", and AirLoop defined in " + AirflowNetworkNodeData(k).Name + " is " +
10436 0 : m_state.dataAirSystemsData->PrimaryAirSystems(AirflowNetworkNodeData(k).AirLoopNum).Name);
10437 0 : ErrorsFound = true;
10438 : }
10439 : // Set AirLoopNum to fans and coils
10440 19 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::FAN) {
10441 1 : n = m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).FanIndex;
10442 1 : m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).AirLoopNum =
10443 1 : AirflowNetworkLinkageData(i).AirLoopNum;
10444 1 : if (m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).FanModelFlag) {
10445 0 : m_state.dataFans
10446 0 : ->fans(m_state.afn->DisSysCompCVFData(m_state.afn->AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum)
10447 : .FanIndex)
10448 0 : ->airLoopNum = AirflowNetworkLinkageData(i).AirLoopNum;
10449 0 : m_state.dataFans
10450 0 : ->fans(m_state.afn->DisSysCompCVFData(m_state.afn->AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum)
10451 : .FanIndex)
10452 0 : ->isAFNFan = true;
10453 : } else {
10454 1 : m_state.dataFans->fans(n)->airLoopNum = AirflowNetworkLinkageData(i).AirLoopNum;
10455 1 : m_state.dataFans->fans(n)->isAFNFan = true;
10456 : }
10457 : }
10458 19 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::COI) {
10459 3 : m_state.afn->DisSysCompCoilData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).AirLoopNum =
10460 3 : AirflowNetworkLinkageData(i).AirLoopNum;
10461 : }
10462 : }
10463 :
10464 : // Validate coil name and type
10465 17 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Coil";
10466 17 : MultiSpeedHPIndicator = 0;
10467 28 : for (int i = 1; i <= DisSysNumOfCoils; ++i) {
10468 : {
10469 11 : auto const SELECT_CASE_var(Util::makeUPPER(DisSysCompCoilData(i).EPlusType));
10470 :
10471 11 : if (SELECT_CASE_var == "COIL:COOLING:DX") {
10472 0 : ValidateComponent(m_state, "Coil:Cooling:DX", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10473 0 : if (IsNotOK) {
10474 0 : ErrorsFound = true;
10475 : } else {
10476 : // Replace the convenience function with in-place code
10477 0 : std::string mycoil = DisSysCompCoilData(i).name;
10478 0 : auto it = std::find_if(m_state.dataCoilCoolingDX->coilCoolingDXs.begin(),
10479 0 : m_state.dataCoilCoolingDX->coilCoolingDXs.end(),
10480 0 : [&mycoil](const CoilCoolingDX &coil) { return coil.name == mycoil; });
10481 0 : if (it != m_state.dataCoilCoolingDX->coilCoolingDXs.end()) {
10482 : // Set the airloop number on the CoilCoolingDX object, which is used to collect the runtime fraction
10483 0 : it->airLoopNum = DisSysCompCoilData(i).AirLoopNum;
10484 : } else {
10485 0 : ShowSevereError(m_state, "SetDXCoilAirLoopNumber: Could not find Coil \"Name=\"" + DisSysCompCoilData(i).name + "\"");
10486 : }
10487 0 : }
10488 11 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:SINGLESPEED") {
10489 2 : ValidateComponent(
10490 3 : m_state, "Coil:Cooling:DX:SingleSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10491 1 : if (IsNotOK) {
10492 0 : ErrorsFound = true;
10493 : } else {
10494 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10495 : }
10496 :
10497 10 : } else if (SELECT_CASE_var == "COIL:HEATING:DX:SINGLESPEED") {
10498 2 : ValidateComponent(
10499 3 : m_state, "Coil:Heating:DX:SingleSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10500 1 : if (IsNotOK) {
10501 0 : ErrorsFound = true;
10502 : } else {
10503 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10504 : }
10505 :
10506 9 : } else if (SELECT_CASE_var == "COIL:HEATING:FUEL") {
10507 0 : ValidateComponent(m_state, "Coil:Heating:Fuel", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10508 0 : if (IsNotOK) {
10509 0 : ErrorsFound = true;
10510 : } else {
10511 0 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10512 : }
10513 :
10514 9 : } else if (SELECT_CASE_var == "COIL:HEATING:ELECTRIC") {
10515 2 : ValidateComponent(
10516 3 : m_state, "Coil:Heating:Electric", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10517 1 : if (IsNotOK) {
10518 0 : ErrorsFound = true;
10519 : } else {
10520 1 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10521 : }
10522 :
10523 8 : } else if (SELECT_CASE_var == "COIL:COOLING:WATER") {
10524 0 : ValidateComponent(m_state, "Coil:Cooling:Water", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10525 0 : if (IsNotOK) {
10526 0 : ErrorsFound = true;
10527 : }
10528 :
10529 8 : } else if (SELECT_CASE_var == "COIL:HEATING:WATER") {
10530 0 : ValidateComponent(m_state, "Coil:Heating:Water", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10531 0 : if (IsNotOK) {
10532 0 : ErrorsFound = true;
10533 : }
10534 :
10535 8 : } else if (SELECT_CASE_var == "COIL:COOLING:WATER:DETAILEDGEOMETRY") {
10536 0 : ValidateComponent(m_state,
10537 : "Coil:Cooling:Water:DetailedGeometry",
10538 0 : DisSysCompCoilData(i).name,
10539 : IsNotOK,
10540 0 : format(RoutineName) + CurrentModuleObject);
10541 0 : if (IsNotOK) {
10542 0 : ErrorsFound = true;
10543 : }
10544 :
10545 8 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:TWOSTAGEWITHHUMIDITYCONTROLMODE") {
10546 0 : ValidateComponent(m_state,
10547 : "Coil:Cooling:DX:TwoStageWithHumidityControlMode",
10548 0 : DisSysCompCoilData(i).name,
10549 : IsNotOK,
10550 0 : format(RoutineName) + CurrentModuleObject);
10551 0 : if (IsNotOK) {
10552 0 : ErrorsFound = true;
10553 : } else {
10554 0 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10555 : }
10556 :
10557 8 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:MULTISPEED") {
10558 0 : ValidateComponent(
10559 0 : m_state, "Coil:Cooling:DX:MultiSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10560 0 : ++MultiSpeedHPIndicator;
10561 0 : if (IsNotOK) {
10562 0 : ErrorsFound = true;
10563 : } else {
10564 0 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10565 : }
10566 :
10567 8 : } else if (SELECT_CASE_var == "COIL:HEATING:DX:MULTISPEED") {
10568 0 : ValidateComponent(
10569 0 : m_state, "Coil:Heating:DX:MultiSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10570 0 : ++MultiSpeedHPIndicator;
10571 0 : if (IsNotOK) {
10572 0 : ErrorsFound = true;
10573 : } else {
10574 0 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10575 : }
10576 :
10577 8 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:VARIABLESPEED") {
10578 2 : ValidateComponent(
10579 3 : m_state, "Coil:Cooling:DX:VariableSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10580 1 : ++MultiSpeedHPIndicator;
10581 1 : if (IsNotOK) {
10582 0 : ErrorsFound = true;
10583 : } else {
10584 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10585 : }
10586 :
10587 7 : } else if (SELECT_CASE_var == "COIL:HEATING:DX:VARIABLESPEED") {
10588 2 : ValidateComponent(
10589 3 : m_state, "Coil:Heating:DX:VariableSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10590 1 : ++MultiSpeedHPIndicator;
10591 1 : if (IsNotOK) {
10592 0 : ErrorsFound = true;
10593 : } else {
10594 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10595 : }
10596 6 : } else if (SELECT_CASE_var == "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") {
10597 2 : ValidateComponent(m_state,
10598 : "Coil:Cooling:WaterToAirHeatPump:EquationFit",
10599 1 : DisSysCompCoilData(i).name,
10600 : IsNotOK,
10601 2 : format(RoutineName) + CurrentModuleObject);
10602 1 : if (IsNotOK) {
10603 0 : ErrorsFound = true;
10604 : }
10605 :
10606 5 : } else if (SELECT_CASE_var == "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT") {
10607 2 : ValidateComponent(m_state,
10608 : "Coil:Heating:WaterToAirHeatPump:EquationFit",
10609 1 : DisSysCompCoilData(i).name,
10610 : IsNotOK,
10611 2 : format(RoutineName) + CurrentModuleObject);
10612 1 : if (IsNotOK) {
10613 0 : ErrorsFound = true;
10614 : }
10615 4 : } else if (SELECT_CASE_var == "COIL:COOLING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT") {
10616 2 : ValidateComponent(m_state,
10617 : "Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit",
10618 1 : DisSysCompCoilData(i).name,
10619 : IsNotOK,
10620 2 : format(RoutineName) + CurrentModuleObject);
10621 1 : if (IsNotOK) {
10622 0 : ErrorsFound = true;
10623 : }
10624 :
10625 3 : } else if (SELECT_CASE_var == "COIL:HEATING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT") {
10626 2 : ValidateComponent(m_state,
10627 : "Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit",
10628 1 : DisSysCompCoilData(i).name,
10629 : IsNotOK,
10630 2 : format(RoutineName) + CurrentModuleObject);
10631 1 : if (IsNotOK) {
10632 0 : ErrorsFound = true;
10633 : }
10634 :
10635 2 : } else if (SELECT_CASE_var == "COIL:HEATING:DESUPERHEATER") {
10636 0 : ValidateComponent(
10637 0 : m_state, "Coil:Heating:Desuperheater", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10638 0 : if (IsNotOK) {
10639 0 : ErrorsFound = true;
10640 : }
10641 :
10642 2 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:TWOSPEED") {
10643 0 : ValidateComponent(
10644 0 : m_state, "Coil:Cooling:DX:TwoSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10645 0 : if (IsNotOK) {
10646 0 : ErrorsFound = true;
10647 : } else {
10648 0 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10649 : }
10650 2 : } else if (SELECT_CASE_var == "COIL:HEATING:ELECTRIC:MULTISTAGE") {
10651 2 : ValidateComponent(
10652 3 : m_state, "Coil:Heating:Electric:MultiStage", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10653 1 : if (IsNotOK) {
10654 0 : ErrorsFound = true;
10655 : } else {
10656 1 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10657 : }
10658 1 : } else if (SELECT_CASE_var == "COIL:HEATING:GAS:MULTISTAGE") {
10659 2 : ValidateComponent(
10660 3 : m_state, "Coil:Heating:Gas:MultiStage", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10661 1 : if (IsNotOK) {
10662 0 : ErrorsFound = true;
10663 : } else {
10664 1 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10665 : }
10666 : } else {
10667 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " Invalid coil type = " + DisSysCompCoilData(i).name);
10668 0 : ErrorsFound = true;
10669 : }
10670 11 : }
10671 : }
10672 :
10673 : // Validate terminal unit name and type
10674 17 : for (int i = 1; i <= DisSysNumOfTermUnits; ++i) {
10675 0 : if (Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:ConstantVolume:Reheat") ||
10676 0 : Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
10677 0 : LocalError = false;
10678 0 : if (Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:ConstantVolume:Reheat"))
10679 0 : GetHVACSingleDuctSysIndex(
10680 0 : m_state, DisSysCompTermUnitData(i).name, n, LocalError, "AirflowNetwork:Distribution:Component:TerminalUnit");
10681 0 : if (Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat"))
10682 0 : GetHVACSingleDuctSysIndex(m_state,
10683 0 : DisSysCompTermUnitData(i).name,
10684 : n,
10685 : LocalError,
10686 : "AirflowNetwork:Distribution:Component:TerminalUnit",
10687 0 : DisSysCompTermUnitData(i).DamperInletNode,
10688 0 : DisSysCompTermUnitData(i).DamperOutletNode);
10689 0 : if (LocalError) ErrorsFound = true;
10690 0 : if (VAVSystem) {
10691 0 : for (int j = 1; j <= DisSysNumOfCVFs; j++) {
10692 0 : if (DisSysCompCVFData(j).fanType == HVAC::FanType::VAV) {
10693 0 : if (DisSysCompCVFData(j).AirLoopNum == DisSysCompTermUnitData(i).AirLoopNum &&
10694 0 : !Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
10695 0 : ShowSevereError(m_state,
10696 0 : format(RoutineName) + CurrentModuleObject +
10697 0 : " Invalid terminal type for a VAV system = " + DisSysCompTermUnitData(i).name);
10698 0 : ShowContinueError(m_state, "The input type = " + DisSysCompTermUnitData(i).EPlusType);
10699 0 : ShowContinueError(m_state, "A VAV system requires all terminal units with type = AirTerminal:SingleDuct:VAV:Reheat");
10700 0 : ErrorsFound = true;
10701 : }
10702 : }
10703 : }
10704 : }
10705 : } else {
10706 0 : ShowSevereError(m_state,
10707 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT TERMINAL UNIT: Invalid Terminal unit type = " +
10708 0 : DisSysCompTermUnitData(i).name);
10709 0 : ErrorsFound = true;
10710 : }
10711 : }
10712 :
10713 : // Validate heat exchanger name and type
10714 17 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:HeatExchanger";
10715 17 : for (int i = 1; i <= DisSysNumOfHXs; ++i) {
10716 : {
10717 0 : auto const SELECT_CASE_var(Util::makeUPPER(DisSysCompHXData(i).EPlusType));
10718 :
10719 0 : if (SELECT_CASE_var == "HEATEXCHANGER:AIRTOAIR:FLATPLATE") {
10720 0 : ValidateComponent(
10721 0 : m_state, "HeatExchanger:AirToAir:FlatPlate", DisSysCompHXData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10722 0 : if (IsNotOK) {
10723 0 : ErrorsFound = true;
10724 : }
10725 :
10726 0 : } else if (SELECT_CASE_var == "HEATEXCHANGER:AIRTOAIR:SENSIBLEANDLATENT") {
10727 0 : ValidateComponent(m_state,
10728 : "HeatExchanger:AirToAir:SensibleAndLatent",
10729 0 : DisSysCompHXData(i).name,
10730 : IsNotOK,
10731 0 : format(RoutineName) + CurrentModuleObject);
10732 0 : if (IsNotOK) {
10733 0 : ErrorsFound = true;
10734 : }
10735 :
10736 0 : } else if (SELECT_CASE_var == "HEATEXCHANGER:DESICCANT:BALANCEDFLOW") {
10737 0 : ValidateComponent(m_state,
10738 : "HeatExchanger:Desiccant:BalancedFlow",
10739 0 : DisSysCompHXData(i).name,
10740 : IsNotOK,
10741 0 : format(RoutineName) + CurrentModuleObject);
10742 0 : if (IsNotOK) {
10743 0 : ErrorsFound = true;
10744 : }
10745 :
10746 : } else {
10747 0 : ShowSevereError(m_state,
10748 0 : format(RoutineName) + CurrentModuleObject + " Invalid heat exchanger type = " + DisSysCompHXData(i).EPlusType);
10749 0 : ErrorsFound = true;
10750 : }
10751 0 : }
10752 : }
10753 :
10754 : // Assign supply and return connection
10755 18 : for (int j = 1; j <= NumPrimaryAirSys; ++j) {
10756 1 : int S1 = 0;
10757 1 : int S2 = 0;
10758 1 : int R1 = 0;
10759 1 : int R2 = 0;
10760 35 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
10761 34 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).AirLoopSupplyNodeNum(1)) S1 = i;
10762 34 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).ZoneEquipSupplyNodeNum(1)) S2 = i;
10763 34 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).ZoneEquipReturnNodeNum(1)) R1 = i;
10764 34 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).AirLoopReturnNodeNum(1)) R2 = i;
10765 : }
10766 39 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
10767 38 : if (AirflowNetworkLinkageData(i).NodeNums[0] == R1 && AirflowNetworkLinkageData(i).NodeNums[1] == R2) {
10768 1 : AirflowNetworkLinkageData(i).ConnectionFlag = iEPlusComponentType::RCN;
10769 : }
10770 38 : if (AirflowNetworkLinkageData(i).NodeNums[0] == S1 && AirflowNetworkLinkageData(i).NodeNums[1] == S2) {
10771 1 : AirflowNetworkLinkageData(i).ConnectionFlag = iEPlusComponentType::SCN;
10772 : }
10773 : }
10774 : }
10775 :
10776 : // Assign fan inlet and outlet node, and coil outlet
10777 55 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
10778 38 : int j = AirflowNetworkLinkageData(i).CompNum;
10779 38 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::CVF) {
10780 1 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::Invalid)
10781 1 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum = iEPlusNodeType::FIN;
10782 1 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::FOU;
10783 : }
10784 38 : if (AirflowNetworkCompData(j).EPlusTypeNum == iEPlusComponentType::COI) {
10785 3 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::COU;
10786 : }
10787 38 : if (AirflowNetworkCompData(j).EPlusTypeNum == iEPlusComponentType::HEX) {
10788 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::HXO;
10789 : }
10790 38 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::TMU) {
10791 0 : if (DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperInletNode > 0) {
10792 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum ==
10793 0 : DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperInletNode &&
10794 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum ==
10795 0 : DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperOutletNode) {
10796 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum = iEPlusNodeType::DIN;
10797 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::DOU;
10798 0 : AirflowNetworkLinkageData(i).VAVTermDamper = true;
10799 : }
10800 : }
10801 : }
10802 : }
10803 :
10804 : // Validate the position of constant pressure drop component
10805 17 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ConstantPressureDrop";
10806 55 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
10807 38 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::CPD) {
10808 0 : for (int j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
10809 0 : if (AirflowNetworkLinkageData(i).NodeNums[0] == AirflowNetworkLinkageData(j).NodeNums[1]) {
10810 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(j).CompNum).CompTypeNum != iComponentTypeNum::DWC) {
10811 0 : ShowSevereError(m_state,
10812 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName +
10813 : ')');
10814 0 : ShowContinueError(m_state, "must connect a duct component upstream and not " + AirflowNetworkLinkageData(j).Name);
10815 0 : ErrorsFound = true;
10816 : }
10817 : }
10818 : }
10819 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::SPL) {
10820 0 : ShowSevereError(m_state,
10821 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10822 0 : ShowContinueError(m_state,
10823 0 : "does not allow a AirLoopHVAC:ZoneSplitter node = " +
10824 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10825 0 : ErrorsFound = true;
10826 : }
10827 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum == iEPlusNodeType::SPL) {
10828 0 : ShowSevereError(m_state,
10829 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10830 0 : ShowContinueError(m_state,
10831 0 : "does not allow a AirLoopHVAC:ZoneSplitter node = " +
10832 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10833 0 : ErrorsFound = true;
10834 : }
10835 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::MIX) {
10836 0 : ShowSevereError(m_state,
10837 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10838 0 : ShowContinueError(m_state,
10839 0 : "does not allow a AirLoopHVAC:ZoneMixer node = " +
10840 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10841 0 : ErrorsFound = true;
10842 : }
10843 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum == iEPlusNodeType::MIX) {
10844 0 : ShowSevereError(m_state,
10845 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10846 0 : ShowContinueError(m_state,
10847 0 : "does not allow a AirLoopHVAC:ZoneMixer node = " +
10848 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10849 0 : ErrorsFound = true;
10850 : }
10851 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
10852 0 : ShowSevereError(m_state,
10853 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10854 0 : ShowContinueError(m_state,
10855 0 : "does not allow to connect an EnergyPlus node = " +
10856 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10857 0 : ErrorsFound = true;
10858 : }
10859 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
10860 0 : ShowSevereError(m_state,
10861 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10862 0 : ShowContinueError(m_state,
10863 0 : "does not allow to connect an EnergyPlus node = " +
10864 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10865 0 : ErrorsFound = true;
10866 : }
10867 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) {
10868 0 : ShowSevereError(m_state,
10869 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10870 0 : ShowContinueError(m_state,
10871 0 : "does not allow to connect an EnergyPlus zone = " +
10872 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10873 0 : ErrorsFound = true;
10874 : }
10875 0 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) {
10876 0 : ShowSevereError(m_state,
10877 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10878 0 : ShowContinueError(m_state,
10879 0 : "does not allow to connect an EnergyPlus zone = " +
10880 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10881 0 : ErrorsFound = true;
10882 : }
10883 : }
10884 : }
10885 :
10886 42 : for (int i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
10887 25 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::SPL) {
10888 1 : LocalError = false;
10889 1 : int j = GetSplitterOutletNumber(m_state, "", 1, LocalError);
10890 1 : SplitterNodeNumbers.allocate(j + 2);
10891 1 : SplitterNodeNumbers = GetSplitterNodeNumbers(m_state, "", 1, LocalError);
10892 1 : if (LocalError) ErrorsFound = true;
10893 : }
10894 : }
10895 :
10896 : // Assigning inlet and outlet nodes for a splitter
10897 62 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
10898 45 : if (AirflowNetworkNodeData(i).EPlusNodeNum == SplitterNodeNumbers(1)) {
10899 1 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::Invalid) AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPI;
10900 : }
10901 79 : for (int j = 1; j <= SplitterNodeNumbers(2); ++j) {
10902 34 : if (AirflowNetworkNodeData(i).EPlusNodeNum == SplitterNodeNumbers(j + 2)) {
10903 1 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::Invalid)
10904 1 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPO;
10905 : }
10906 : }
10907 : }
10908 :
10909 : // Add additional output variables
10910 17 : if (DisSysNumOfCVFs > 1) {
10911 0 : bool OnOffFanFlag = false;
10912 0 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
10913 0 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff && !DisSysCompCVFData(i).FanModelFlag) {
10914 0 : OnOffFanFlag = true;
10915 0 : break;
10916 : }
10917 0 : if (DisSysCompCVFData(i).FanModelFlag && DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
10918 0 : int fanIndex = Fans::GetFanIndex(m_state, DisSysCompCVFData(i).name);
10919 0 : if (m_state.dataFans->fans(fanIndex)->airPathFlag) {
10920 0 : DisSysCompCVFData(i).fanType = HVAC::FanType::Constant;
10921 : } else {
10922 0 : OnOffFanFlag = true;
10923 0 : break;
10924 : }
10925 : }
10926 : }
10927 0 : if (OnOffFanFlag) {
10928 0 : for (int j = 1; j <= AirflowNetworkNumOfZones; ++j) {
10929 0 : if (!m_state.dataZoneEquip->ZoneEquipConfig(AirflowNetworkNodeData(j).EPlusZoneNum).IsControlled) continue;
10930 0 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
10931 0 : if (DisSysCompCVFData(i).AirLoopNum == AirflowNetworkNodeData(j).AirLoopNum &&
10932 0 : DisSysCompCVFData(i).fanType != HVAC::FanType::OnOff) {
10933 0 : SetupOutputVariable(m_state,
10934 : "AFN Node Total Pressure",
10935 : Constant::Units::Pa,
10936 0 : AirflowNetworkNodeSimu(j).PZ,
10937 : OutputProcessor::TimeStepType::System,
10938 : OutputProcessor::StoreType::Average,
10939 0 : AirflowNetworkNodeData(j).Name);
10940 : }
10941 : }
10942 : }
10943 0 : for (int i = 1; i <= NumOfLinksMultiZone; ++i) {
10944 0 : if (!m_state.dataZoneEquip->ZoneEquipConfig(AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum)
10945 0 : .IsControlled)
10946 0 : continue;
10947 0 : for (int j = 1; j <= DisSysNumOfCVFs; j++) {
10948 0 : if (DisSysCompCVFData(j).AirLoopNum == AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).AirLoopNum &&
10949 0 : DisSysCompCVFData(j).fanType != HVAC::FanType::OnOff) {
10950 0 : SetupOutputVariable(m_state,
10951 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
10952 : Constant::Units::kg_s,
10953 0 : linkReport(i).FLOW,
10954 : OutputProcessor::TimeStepType::System,
10955 : OutputProcessor::StoreType::Average,
10956 0 : AirflowNetworkLinkageData(i).Name);
10957 0 : SetupOutputVariable(m_state,
10958 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
10959 : Constant::Units::kg_s,
10960 0 : linkReport(i).FLOW2,
10961 : OutputProcessor::TimeStepType::System,
10962 : OutputProcessor::StoreType::Average,
10963 0 : AirflowNetworkLinkageData(i).Name);
10964 0 : SetupOutputVariable(m_state,
10965 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
10966 : Constant::Units::m3_s,
10967 0 : linkReport(i).VolFLOW,
10968 : OutputProcessor::TimeStepType::System,
10969 : OutputProcessor::StoreType::Average,
10970 0 : AirflowNetworkLinkageData(i).Name);
10971 0 : SetupOutputVariable(m_state,
10972 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
10973 : Constant::Units::m3_s,
10974 0 : linkReport(i).VolFLOW2,
10975 : OutputProcessor::TimeStepType::System,
10976 : OutputProcessor::StoreType::Average,
10977 0 : AirflowNetworkLinkageData(i).Name);
10978 0 : SetupOutputVariable(m_state,
10979 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
10980 : Constant::Units::Pa,
10981 0 : AirflowNetworkLinkSimu(i).DP,
10982 : OutputProcessor::TimeStepType::System,
10983 : OutputProcessor::StoreType::Average,
10984 0 : AirflowNetworkLinkageData(i).Name);
10985 : }
10986 : }
10987 : }
10988 : }
10989 : }
10990 17 : bool FanModelConstFlag = false;
10991 18 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
10992 1 : if (DisSysCompCVFData(i).FanModelFlag) {
10993 0 : int fanIndex = Fans::GetFanIndex(m_state, DisSysCompCVFData(i).name); // What is this accomplishing here?
10994 0 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff && m_state.dataFans->fans(fanIndex)->airPathFlag) {
10995 0 : DisSysCompCVFData(i).fanType = HVAC::FanType::Constant;
10996 0 : supplyFanType = HVAC::FanType::Constant;
10997 0 : FanModelConstFlag = true;
10998 0 : break;
10999 : }
11000 : }
11001 : }
11002 17 : if (FanModelConstFlag) {
11003 0 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
11004 0 : if (supplyFanType == HVAC::FanType::Constant) {
11005 0 : SetupOutputVariable(m_state,
11006 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
11007 : Constant::Units::kg_s,
11008 0 : linkReport(i).FLOW,
11009 : OutputProcessor::TimeStepType::System,
11010 : OutputProcessor::StoreType::Average,
11011 0 : AirflowNetworkLinkageData(i).Name);
11012 0 : SetupOutputVariable(m_state,
11013 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
11014 : Constant::Units::kg_s,
11015 0 : linkReport(i).FLOW2,
11016 : OutputProcessor::TimeStepType::System,
11017 : OutputProcessor::StoreType::Average,
11018 0 : AirflowNetworkLinkageData(i).Name);
11019 0 : SetupOutputVariable(m_state,
11020 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
11021 : Constant::Units::m3_s,
11022 0 : linkReport(i).VolFLOW,
11023 : OutputProcessor::TimeStepType::System,
11024 : OutputProcessor::StoreType::Average,
11025 0 : AirflowNetworkLinkageData(i).Name);
11026 0 : SetupOutputVariable(m_state,
11027 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
11028 : Constant::Units::m3_s,
11029 0 : linkReport(i).VolFLOW2,
11030 : OutputProcessor::TimeStepType::System,
11031 : OutputProcessor::StoreType::Average,
11032 0 : AirflowNetworkLinkageData(i).Name);
11033 0 : SetupOutputVariable(m_state,
11034 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
11035 : Constant::Units::Pa,
11036 0 : AirflowNetworkLinkSimu(i).DP,
11037 : OutputProcessor::TimeStepType::System,
11038 : OutputProcessor::StoreType::Average,
11039 0 : AirflowNetworkLinkageData(i).Name);
11040 : }
11041 : }
11042 : }
11043 :
11044 : // Add AirLoopNum to pressure control object
11045 17 : for (int i = 1; i <= NumOfPressureControllers; ++i) {
11046 0 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11047 0 : if (PressureControllerData(i).ZoneNum == j) {
11048 0 : for (int k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumInletNodes; ++k) {
11049 0 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(k) > 0) {
11050 0 : PressureControllerData(i).AirLoopNum = m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(k);
11051 0 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlRelief) {
11052 0 : PressureControllerData(i).OANodeNum =
11053 0 : m_state.dataAirSystemsData->PrimaryAirSystems(PressureControllerData(i).AirLoopNum).OAMixOAInNodeNum;
11054 0 : for (n = 1; n <= NumOfReliefFans; ++n) {
11055 0 : if (DisSysCompReliefAirData(n).OutletNode == PressureControllerData(i).OANodeNum) {
11056 0 : DisSysCompReliefAirData(n).PressCtrlNum = i;
11057 : }
11058 : }
11059 : }
11060 0 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlExhaust) {
11061 0 : PressureControllerData(i).OANodeNum =
11062 0 : m_state.dataZoneEquip->ZoneEquipConfig(PressureControllerData(i).ZoneNum).ExhaustNode(1);
11063 0 : for (n = 1; n <= AirflowNetworkNumOfExhFan; ++n) {
11064 0 : if (MultizoneCompExhaustFanData(n).EPlusZoneNum == PressureControllerData(i).ZoneNum) {
11065 0 : MultizoneCompExhaustFanData(n).PressCtrlNum = i;
11066 : }
11067 : }
11068 : }
11069 : }
11070 : }
11071 : }
11072 : }
11073 : }
11074 :
11075 : // Check number of fans specified in an AirLoop #6748
11076 : int BranchNum;
11077 : int NumOfFans;
11078 17 : std::string FanNames;
11079 33 : for (BranchNum = 1; BranchNum <= m_state.dataAirSystemsData->PrimaryAirSystems(1).NumBranches; ++BranchNum) {
11080 17 : NumOfFans = 0;
11081 17 : FanNames = "";
11082 37 : for (int CompNum = 1; CompNum <= m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).TotalComponents; ++CompNum) {
11083 29 : if (Util::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf, "Fan:ConstantVolume") ||
11084 29 : Util::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf, "Fan:OnOff") ||
11085 29 : Util::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf, "Fan:VariableVolume")) {
11086 14 : NumOfFans++;
11087 14 : if (NumOfFans > 1) {
11088 1 : FanNames += m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).Name;
11089 1 : break;
11090 : } else {
11091 13 : FanNames += m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).Name + ",";
11092 : }
11093 : }
11094 : }
11095 17 : if (NumOfFans > 1) break;
11096 : }
11097 17 : if (NumOfFans > 1) {
11098 2 : ShowSevereError(m_state,
11099 2 : format(RoutineName) + "An AirLoop branch, " + m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Name +
11100 2 : ", has two or more fans: " + FanNames);
11101 2 : ShowContinueError(m_state,
11102 : "The AirflowNetwork model allows a single supply fan in an AirLoop only. Please make changes in the input "
11103 : "file accordingly.");
11104 1 : ErrorsFound = true;
11105 : }
11106 :
11107 17 : if (ErrorsFound) {
11108 12 : ShowFatalError(m_state, format("{}Program terminates for preceding reason(s).", RoutineName));
11109 : }
11110 35 : }
11111 :
11112 1 : void Solver::validate_fan_flowrate()
11113 : {
11114 :
11115 : // Catch a fan flow rate from EPlus input file and add a flag for VAV terminal damper
11116 39 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
11117 38 : switch (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum) {
11118 1 : case iComponentTypeNum::CVF: { // 'CVF'
11119 1 : int typeNum = AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum;
11120 1 : if (DisSysCompCVFData(typeNum).fanType == HVAC::FanType::VAV) {
11121 0 : DisSysCompCVFData(typeNum).MaxAirMassFlowRate =
11122 0 : m_state.dataFans->fans(DisSysCompCVFData(typeNum).FanIndex)->maxAirFlowRate * m_state.dataEnvrn->StdRhoAir;
11123 : }
11124 1 : } break;
11125 0 : case iComponentTypeNum::FAN:
11126 : case iComponentTypeNum::SOP:
11127 : case iComponentTypeNum::TMU:
11128 0 : break;
11129 37 : default:
11130 37 : break;
11131 : }
11132 : }
11133 1 : }
11134 :
11135 16853 : void Solver::validate_exhaust_fan_input()
11136 : {
11137 :
11138 : // SUBROUTINE INFORMATION:
11139 : // AUTHOR Lixing Gu
11140 : // DATE WRITTEN Dec. 2006
11141 : // MODIFIED na
11142 : // RE-ENGINEERED na
11143 :
11144 : // PURPOSE OF THIS SUBROUTINE:
11145 : // This subroutine validate zone exhaust fan and associated surface
11146 :
11147 : // SUBROUTINE PARAMETER DEFINITIONS:
11148 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::validate_exhaust_fan_input: "); // include trailing blank space
11149 :
11150 : // Validate supply and return connections
11151 16853 : if (ValidateExhaustFanInputOneTimeFlag) {
11152 2 : bool ErrorsFound = false;
11153 2 : std::string const CurrentModuleObject = "AirflowNetwork:MultiZone:Component:ZoneExhaustFan";
11154 2 : if (std::any_of(m_state.dataZoneEquip->ZoneEquipConfig.begin(),
11155 2 : m_state.dataZoneEquip->ZoneEquipConfig.end(),
11156 2 : [](DataZoneEquipment::EquipConfiguration const &e) { return e.IsControlled; })) {
11157 2 : AirflowNetworkZoneExhaustFan.dimension(m_state.dataGlobal->NumOfZones, false);
11158 : }
11159 : // Ensure the number of exhaust fan defined in the AirflowNetwork model matches the number of Zone Exhaust Fan objects
11160 2 : if (NumOfExhaustFans != AirflowNetworkNumOfExhFan) {
11161 0 : ShowSevereError(
11162 : m_state,
11163 0 : format("{}The number of {} is not equal to the number of Fan:ZoneExhaust fans defined in ZoneHVAC:EquipmentConnections",
11164 : RoutineName,
11165 : CurrentModuleObject));
11166 0 : ShowContinueError(m_state, format("The number of {} is {}", CurrentModuleObject, AirflowNetworkNumOfExhFan));
11167 0 : ShowContinueError(m_state,
11168 0 : format("The number of Zone exhaust fans defined in ZoneHVAC:EquipmentConnections is {}", NumOfExhaustFans));
11169 0 : ErrorsFound = true;
11170 : }
11171 :
11172 4 : for (int i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
11173 : // Get zone number
11174 8 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11175 6 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) continue;
11176 5 : for (int k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumExhaustNodes; ++k) {
11177 4 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).ExhaustNode(k) == MultizoneCompExhaustFanData(i).InletNode) {
11178 1 : MultizoneCompExhaustFanData(i).EPlusZoneNum = j;
11179 1 : break;
11180 : }
11181 : }
11182 : }
11183 2 : if (MultizoneCompExhaustFanData(i).EPlusZoneNum == 0) {
11184 0 : ShowSevereError(m_state,
11185 0 : format("{}Zone name in {} = {} does not match the zone name in ZoneHVAC:EquipmentConnections",
11186 : RoutineName,
11187 : CurrentModuleObject,
11188 0 : MultizoneCompExhaustFanData(i).name));
11189 0 : ErrorsFound = true;
11190 : }
11191 : // Ensure a surface using zone exhaust fan to expose to the same zone
11192 2 : bool found = false;
11193 : int j;
11194 38 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
11195 38 : if (Util::SameString(MultizoneSurfaceData(j).OpeningName, MultizoneCompExhaustFanData(i).name)) {
11196 2 : found = true;
11197 2 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond != ExternalEnvironment &&
11198 0 : !(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
11199 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
11200 0 : ShowSevereError(m_state,
11201 0 : format("{}The surface using {} is not an exterior surface: {}",
11202 : RoutineName,
11203 : CurrentModuleObject,
11204 0 : MultizoneSurfaceData(j).SurfName));
11205 0 : ErrorsFound = true;
11206 : }
11207 2 : break;
11208 : }
11209 : }
11210 2 : if (!found) {
11211 0 : ShowSevereError(m_state, CurrentModuleObject + " = " + MultizoneCompExhaustFanData(i).name + " is defined and never used.");
11212 0 : ErrorsFound = true;
11213 : } else {
11214 2 : if (MultizoneCompExhaustFanData(i).EPlusZoneNum != m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Zone) {
11215 0 : ShowSevereError(m_state,
11216 0 : format("{}Zone name in {} = {} does not match the zone name",
11217 : RoutineName,
11218 : CurrentModuleObject,
11219 0 : MultizoneCompExhaustFanData(i).name));
11220 0 : ShowContinueError(m_state, "the surface is exposed to " + m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Name);
11221 0 : ErrorsFound = true;
11222 : } else {
11223 2 : AirflowNetworkZoneExhaustFan(MultizoneCompExhaustFanData(i).EPlusZoneNum) = true;
11224 : }
11225 : }
11226 : }
11227 :
11228 : // Ensure all zone exhaust fans are defined
11229 8 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11230 6 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) continue;
11231 8 : for (int EquipTypeNum = 1; EquipTypeNum <= m_state.dataZoneEquip->ZoneEquipList(j).NumOfEquipTypes; ++EquipTypeNum) {
11232 6 : if (m_state.dataZoneEquip->ZoneEquipList(j).EquipType(EquipTypeNum) == DataZoneEquipment::ZoneEquipType::ExhaustFan) {
11233 2 : bool found = false;
11234 6 : for (int k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumExhaustNodes; ++k) {
11235 8 : for (int i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
11236 4 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).ExhaustNode(k) == MultizoneCompExhaustFanData(i).InletNode) {
11237 1 : MultizoneCompExhaustFanData(i).EPlusZoneNum = j;
11238 1 : found = true;
11239 : }
11240 : }
11241 : }
11242 2 : if (!found) {
11243 1 : ShowSevereError(m_state, format("{}Fan:ZoneExhaust is not defined in {}", RoutineName, CurrentModuleObject));
11244 2 : ShowContinueError(
11245 : m_state,
11246 2 : format("The inlet node of the {} Fan:ZoneExhaust is not defined in the {}'s ZoneHVAC:EquipmentConnections",
11247 1 : m_state.dataZoneEquip->ZoneEquipList(j).EquipName,
11248 1 : m_state.dataZoneEquip->ZoneEquipConfig(j).ZoneName));
11249 1 : ErrorsFound = true;
11250 : }
11251 : }
11252 : }
11253 : }
11254 :
11255 2 : ValidateExhaustFanInputOneTimeFlag = false;
11256 2 : if (ErrorsFound) {
11257 2 : ShowFatalError(m_state, format("{}Program terminates for preceding reason(s).", RoutineName));
11258 : }
11259 2 : } // End if OneTimeFlag_FindFirstLastPtr
11260 16852 : }
11261 :
11262 0 : void Solver::hybrid_ventilation_control()
11263 : {
11264 :
11265 : // SUBROUTINE INFORMATION:
11266 : // AUTHOR Lixing Gu
11267 : // DATE WRITTEN Dec. 2006
11268 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone hybrid ventilation managers
11269 :
11270 : // PURPOSE OF THIS SUBROUTINE:
11271 : // This subroutine performs hybrid ventilation control
11272 :
11273 : // SUBROUTINE PARAMETER DEFINITIONS:
11274 0 : int constexpr IndividualCtrlType(0); // Individual window or door control
11275 0 : int constexpr GlobalCtrlType(1); // Global window or door control
11276 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::hybrid_ventilation_control: "); // include trailing blank space
11277 :
11278 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11279 : int SysAvailNum; // Hybrid ventilation control number
11280 : int ControlledZoneNum; // Controlled zone number
11281 : int ANSurfaceNum; // AirflowNetwork Surface Number
11282 : int SurfNum; // Surface number
11283 : int ControlType; // Hybrid ventilation control type: 0 individual; 1 global
11284 :
11285 0 : for (auto &e : MultizoneSurfaceData) {
11286 0 : e.HybridVentClose = false;
11287 0 : e.HybridCtrlGlobal = false;
11288 0 : e.HybridCtrlMaster = false;
11289 0 : e.WindModifier = 1.0;
11290 : }
11291 0 : ControlType = IndividualCtrlType;
11292 :
11293 0 : for (SysAvailNum = 1; SysAvailNum <= m_state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
11294 0 : auto &hybridVentMgr = m_state.dataAvail->HybridVentData(SysAvailNum);
11295 0 : int AirLoopNum = hybridVentMgr.AirLoopNum;
11296 0 : ventCtrlStatus = hybridVentMgr.ctrlStatus;
11297 0 : if (hybridVentMgr.afnControlTypeSched != nullptr) {
11298 0 : ControlType = static_cast<int>(hybridVentMgr.afnControlTypeSched->getCurrentVal());
11299 : }
11300 0 : bool Found = false; // Logical to indicate whether a master surface is found or not
11301 0 : int ActualZoneNum = 0;
11302 0 : for (ControlledZoneNum = 1; ControlledZoneNum <= m_state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
11303 0 : if (!m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).IsControlled) continue;
11304 : // Ensure all the zones served by this AirLoopHVAC to be controlled by the hybrid ventilation
11305 0 : for (int zoneInNode = 1; zoneInNode <= m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
11306 0 : if (AirLoopNum > 0) {
11307 0 : if (AirLoopNum == m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode)) {
11308 0 : ActualZoneNum = ControlledZoneNum;
11309 0 : break;
11310 : }
11311 : } else {
11312 0 : if (hybridVentMgr.ControlledZoneNum == ControlledZoneNum) {
11313 0 : ActualZoneNum = hybridVentMgr.ControlledZoneNum;
11314 : }
11315 : }
11316 : }
11317 0 : if (ActualZoneNum > 0) {
11318 0 : for (ANSurfaceNum = 1; ANSurfaceNum <= AirflowNetworkNumOfSurfaces; ++ANSurfaceNum) {
11319 0 : SurfNum = MultizoneSurfaceData(ANSurfaceNum).SurfNum;
11320 0 : auto const &surf = m_state.dataSurface->Surface(SurfNum);
11321 :
11322 0 : if (surf.Zone == ActualZoneNum) {
11323 0 : if (ventCtrlStatus == Avail::VentCtrlStatus::Close) {
11324 0 : MultizoneSurfaceData(ANSurfaceNum).HybridVentClose = true;
11325 : } else {
11326 0 : if (hybridVentMgr.WindModifier >= 0) {
11327 0 : MultizoneSurfaceData(ANSurfaceNum).WindModifier = hybridVentMgr.WindModifier;
11328 : }
11329 0 : if (ControlType == GlobalCtrlType) {
11330 0 : MultizoneSurfaceData(ANSurfaceNum).HybridCtrlGlobal = true;
11331 0 : if (hybridVentMgr.Master == ActualZoneNum) {
11332 0 : if ((surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
11333 0 : surf.OriginalClass == SurfaceClass::GlassDoor) &&
11334 0 : surf.ExtBoundCond == ExternalEnvironment) {
11335 0 : MultizoneSurfaceData(ANSurfaceNum).HybridCtrlMaster = true;
11336 0 : Found = true;
11337 : }
11338 : }
11339 : }
11340 : }
11341 : }
11342 : }
11343 : }
11344 : }
11345 0 : if (ControlType == GlobalCtrlType && !Found && !m_state.dataGlobal->WarmupFlag && ventCtrlStatus != Avail::VentCtrlStatus::Close) {
11346 0 : ++HybridGlobalErrCount;
11347 0 : if (HybridGlobalErrCount < 2) {
11348 0 : ShowWarningError(m_state,
11349 0 : format("{}The hybrid ventilation control schedule value indicates global control in the controlled zone = {}",
11350 : RoutineName,
11351 0 : m_state.dataHeatBal->Zone(hybridVentMgr.Master).Name));
11352 0 : ShowContinueError(m_state,
11353 : "The exterior surface containing an opening component in the controlled zone is not found. No global control "
11354 : "will not be modeled.");
11355 0 : ShowContinueError(m_state, "The individual control is assumed.");
11356 0 : ShowContinueErrorTimeStamp(m_state, "");
11357 : } else {
11358 0 : ShowRecurringWarningErrorAtEnd(
11359 : m_state,
11360 0 : format("{}The hybrid ventilation control requires a global control. The individual control continues...", RoutineName),
11361 0 : HybridGlobalErrIndex,
11362 0 : double(ControlType),
11363 0 : double(ControlType));
11364 : }
11365 : }
11366 : }
11367 0 : }
11368 :
11369 2 : void Solver::single_sided_Cps(std::vector<std::vector<Real64>> &valsByFacade, int numWindDir)
11370 : {
11371 : // SUBROUTINE INFORMATION:
11372 : // AUTHOR Sam Brunswick
11373 : // DATE WRITTEN September 2013
11374 : // MODIFIED Revised by J. DeGraw, May 2017, to use tables
11375 : // RE-ENGINEERED n/a
11376 :
11377 : // PURPOSE OF THIS SUBROUTINE:
11378 : // Modify the wind pressure coefficients for single sided ventilation.
11379 :
11380 : // Using/Aliasing
11381 : using namespace DataEnvironment;
11382 :
11383 : // Locals
11384 : int windDirNum;
11385 :
11386 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11387 : int AFNZnNum; // counters
11388 : int SrfNum;
11389 : int ExtOpenNum;
11390 : int ZnNum;
11391 : int DetOpenNum; // row index of surface in MultizoneCompDetOpeningData
11392 : int SimOpenNum; // row index of surface in MultizoneCompSimOpeningData
11393 : int MZDZoneNum; // row index of surface zone in MultizoneZoneData
11394 : Real64 X1;
11395 : Real64 Y1;
11396 : Real64 X2;
11397 : Real64 Y2;
11398 : Real64 ZoneAng1;
11399 : Real64 ZoneAng2;
11400 : Real64 ZoneAngDiff;
11401 2 : Array1D<Real64> ZoneAng; // Azimuth angle of the exterior wall of the zone
11402 2 : Array1D<Real64> PiFormula; // Formula for the mean pressure difference
11403 2 : Array1D<Real64> SigmaFormula; // Formula for the fluctuating pressure difference
11404 2 : Array1D<Real64> Sprime; // The dimensionless ratio of the window separation to the building width
11405 2 : Array1D<Real64> CPV1; // Wind pressure coefficient for the first opening in the zone
11406 2 : Array1D<Real64> CPV2; // Wind pressure coefficient for the second opening in the zone
11407 2 : Array1D_int NumofExtSurfInZone; // List of the number of exterior openings in each zone
11408 :
11409 : struct AFNExtSurfacesProp // External opening information
11410 : {
11411 : // Members
11412 : int SurfNum; // row index of the external opening in the Surface array
11413 : std::string SurfName; // Surface name
11414 : int MSDNum; // row index of the external opening in the MultizoneSurfaceData array
11415 : int ZoneNum; // EnergyPlus zone number
11416 : int MZDZoneNum; // row index of the zone in the MultizoneZoneData array
11417 : int ExtNodeNum; // External node number; = row index in MultizoneExternalNodeData array +
11418 : // AirflowNetworkNumOfZones
11419 : std::string ZoneName; // EnergyPlus zone name
11420 : int facadeNum;
11421 : int curve; // wind pressure coefficient curve index
11422 : iComponentTypeNum CompTypeNum; // Opening type (detailed, simple, etc.)
11423 : Real64 NodeHeight; // Elevation of the opening node
11424 : Real64 OpeningArea; // Opening area (=Height*Width)
11425 : Real64 Height; // Opening height = MultizoneSurfaceData()%Height
11426 : Real64 Width; // Opening width = MultizoneSurfaceData()%Width
11427 : Real64 DischCoeff; // Opening discharge coefficient
11428 :
11429 : // Default Constructor
11430 4 : AFNExtSurfacesProp()
11431 12 : : SurfNum(0), MSDNum(0), ZoneNum(0), MZDZoneNum(0), ExtNodeNum(0), facadeNum(0), curve(0), CompTypeNum(iComponentTypeNum::Invalid),
11432 4 : NodeHeight(0.0), OpeningArea(0.0), Height(0.0), Width(0.0), DischCoeff(0.0)
11433 : {
11434 4 : }
11435 : };
11436 :
11437 : // Object Data
11438 2 : Array1D<AFNExtSurfacesProp> AFNExtSurfaces; // Surface numbers of all exterior openings
11439 : // Count the total number of exterior simple and detailed openings and the number in each zone
11440 : // Verify that each zone with "ADVANCED" single sided wind pressure coefficients has exactly two openings.
11441 : // If it doesn't have two openings, change "ADVANCED" to "STANDARD"
11442 2 : NumofExtSurfInZone.dimension(AirflowNetworkNumOfZones, 0);
11443 4 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
11444 2 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
11445 8 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11446 6 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond ==
11447 : ExternalEnvironment) { // check if outdoor boundary condition
11448 6 : MZDZoneNum = Util::FindItemInList(m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName,
11449 6 : MultizoneZoneData,
11450 : &MultizoneZoneProp::ZoneName);
11451 6 : if (MZDZoneNum == AFNZnNum) {
11452 : // This is terrible, should not do it this way
11453 6 : auto afe = elements.find(MultizoneSurfaceData(SrfNum).OpeningName);
11454 6 : if (afe != elements.end()) {
11455 6 : auto type = afe->second->type();
11456 6 : if (type == ComponentType::DOP) {
11457 4 : ++AFNNumOfExtOpenings;
11458 4 : ++NumofExtSurfInZone(AFNZnNum);
11459 2 : } else if (type == ComponentType::SOP) {
11460 0 : ++AFNNumOfExtOpenings;
11461 0 : ++NumofExtSurfInZone(AFNZnNum);
11462 : }
11463 : }
11464 : }
11465 : }
11466 : }
11467 2 : if (NumofExtSurfInZone(AFNZnNum) == 0) {
11468 0 : ShowWarningError(m_state,
11469 0 : "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName +
11470 : " has single side wind pressure coefficient type \"ADVANCED\", but has no exterior "
11471 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or AirflowNetwork:MultiZone:Component:SimpleOpening "
11472 : "objects.");
11473 0 : ShowContinueError(m_state,
11474 : "Zones must have exactly two exterior openings in order for the \"ADVANCED\" single sided wind pressure "
11475 : "coefficient model to be used.");
11476 0 : ShowContinueError(m_state,
11477 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11478 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11479 2 : } else if (NumofExtSurfInZone(AFNZnNum) == 1) {
11480 0 : ShowWarningError(m_state, "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName);
11481 0 : ShowContinueError(m_state,
11482 : "has single side wind pressure coefficient type \"ADVANCED\", but has only one exterior "
11483 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or "
11484 : "AirflowNetwork:MultiZone:Component:SimpleOpening objects.");
11485 0 : ShowContinueError(m_state,
11486 : "Zones must have exactly two openings in order for the \"ADVANCED\" single side wind pressure coefficient "
11487 : "model to be used.");
11488 0 : ShowContinueError(m_state,
11489 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11490 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11491 2 : } else if (NumofExtSurfInZone(AFNZnNum) > 2) {
11492 0 : ShowWarningError(m_state,
11493 0 : format("AirflowNetwork:Multizone:Zone = {} has single side wind pressure coefficient type "
11494 : "\"ADVANCED\", but has {} exterior "
11495 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or "
11496 : "AirflowNetwork:MultiZone:Component:SimpleOpening objects.",
11497 0 : MultizoneZoneData(AFNZnNum).ZoneName,
11498 : NumofExtSurfInZone(AFNZnNum)));
11499 0 : ShowContinueError(m_state,
11500 : "Zones must have exactly two openings in order for the \"ADVANCED\" single side wind pressure coefficient "
11501 : "model to be used.");
11502 0 : ShowContinueError(m_state,
11503 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11504 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11505 : }
11506 : }
11507 : }
11508 2 : if (AFNNumOfExtOpenings == 0) return;
11509 : // Recount the number of single sided zones
11510 2 : AirflowNetworkNumOfSingleSideZones = 0;
11511 4 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
11512 2 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
11513 2 : ++AirflowNetworkNumOfSingleSideZones;
11514 : }
11515 : }
11516 2 : if (AirflowNetworkNumOfSingleSideZones == 0) return; // Bail if no zones call for the advanced single sided model.
11517 : // Recount the number of detailed and simple exterior openings in zones with "ADVANCED" single sided wind pressure coefficients
11518 2 : AFNNumOfExtOpenings = 0;
11519 8 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11520 6 : MZDZoneNum = Util::FindItemInList(
11521 6 : m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11522 6 : if (MultizoneZoneData(MZDZoneNum).SingleSidedCpType == "ADVANCED") {
11523 6 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond ==
11524 : ExternalEnvironment) { // check if outdoor boundary condition
11525 : // This is terrible, should not do it this way
11526 6 : auto afe = elements.find(MultizoneSurfaceData(SrfNum).OpeningName);
11527 6 : if (afe != elements.end()) {
11528 6 : auto type = afe->second->type();
11529 6 : if (type == ComponentType::DOP) {
11530 4 : ++AFNNumOfExtOpenings;
11531 2 : } else if (type == ComponentType::SOP) {
11532 0 : ++AFNNumOfExtOpenings;
11533 : }
11534 : }
11535 : }
11536 : }
11537 : }
11538 2 : AFNExtSurfaces.allocate(AFNNumOfExtOpenings);
11539 : // Create array of properties for all the exterior single sided openings
11540 2 : ExtOpenNum = 1;
11541 8 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11542 6 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond == ExternalEnvironment) {
11543 6 : if (AirflowNetworkNumOfDetOpenings > 0) {
11544 6 : DetOpenNum = Util::FindItemInList(
11545 6 : MultizoneSurfaceData(SrfNum).OpeningName, MultizoneCompDetOpeningData, &AirflowNetwork::DetailedOpening::name);
11546 6 : MZDZoneNum = Util::FindItemInList(
11547 6 : m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11548 6 : if (MultizoneZoneData(MZDZoneNum).SingleSidedCpType == "ADVANCED") {
11549 6 : if (DetOpenNum > 0) {
11550 4 : AFNExtSurfaces(ExtOpenNum).MSDNum = SrfNum;
11551 4 : AFNExtSurfaces(ExtOpenNum).SurfNum = MultizoneSurfaceData(SrfNum).SurfNum;
11552 4 : AFNExtSurfaces(ExtOpenNum).NodeHeight = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.z;
11553 4 : AFNExtSurfaces(ExtOpenNum).SurfName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Name;
11554 4 : AFNExtSurfaces(ExtOpenNum).ZoneNum = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Zone;
11555 4 : AFNExtSurfaces(ExtOpenNum).ZoneName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName;
11556 8 : AFNExtSurfaces(ExtOpenNum).MZDZoneNum =
11557 4 : Util::FindItemInList(AFNExtSurfaces(ExtOpenNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11558 4 : AFNExtSurfaces(ExtOpenNum).CompTypeNum = iComponentTypeNum::DOP;
11559 4 : AFNExtSurfaces(ExtOpenNum).Height = MultizoneSurfaceData(SrfNum).Height;
11560 4 : AFNExtSurfaces(ExtOpenNum).Width = MultizoneSurfaceData(SrfNum).Width;
11561 8 : AFNExtSurfaces(ExtOpenNum).OpeningArea =
11562 4 : MultizoneSurfaceData(SrfNum).Width * MultizoneSurfaceData(SrfNum).Height * MultizoneSurfaceData(SrfNum).OpenFactor;
11563 4 : AFNExtSurfaces(ExtOpenNum).ExtNodeNum = MultizoneSurfaceData(ExtOpenNum).NodeNums[1];
11564 8 : AFNExtSurfaces(ExtOpenNum).facadeNum =
11565 4 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum;
11566 8 : AFNExtSurfaces(ExtOpenNum).curve =
11567 4 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).curve;
11568 4 : AFNExtSurfaces(ExtOpenNum).DischCoeff = MultizoneCompDetOpeningData(DetOpenNum).DischCoeff2;
11569 4 : ++ExtOpenNum;
11570 : }
11571 : }
11572 0 : } else if (AirflowNetworkNumOfSimOpenings > 0) {
11573 0 : SimOpenNum = Util::FindItemInList(
11574 0 : MultizoneSurfaceData(SrfNum).OpeningName, MultizoneCompSimpleOpeningData, &AirflowNetwork::SimpleOpening::name);
11575 0 : if (SimOpenNum > 0) {
11576 0 : AFNExtSurfaces(ExtOpenNum).MSDNum = SrfNum;
11577 0 : AFNExtSurfaces(ExtOpenNum).SurfNum = MultizoneSurfaceData(SrfNum).SurfNum;
11578 0 : AFNExtSurfaces(ExtOpenNum).SurfName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Name;
11579 0 : AFNExtSurfaces(ExtOpenNum).ZoneNum = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Zone;
11580 0 : AFNExtSurfaces(ExtOpenNum).ZoneName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName;
11581 0 : AFNExtSurfaces(ExtOpenNum).MZDZoneNum =
11582 0 : Util::FindItemInList(AFNExtSurfaces(ExtOpenNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11583 0 : AFNExtSurfaces(ExtOpenNum).CompTypeNum = iComponentTypeNum::SOP;
11584 0 : AFNExtSurfaces(ExtOpenNum).Height = MultizoneSurfaceData(SrfNum).Height;
11585 0 : AFNExtSurfaces(ExtOpenNum).Width = MultizoneSurfaceData(SrfNum).Width;
11586 0 : AFNExtSurfaces(ExtOpenNum).OpeningArea =
11587 0 : MultizoneSurfaceData(SrfNum).Width * MultizoneSurfaceData(SrfNum).Height * MultizoneSurfaceData(SrfNum).OpenFactor;
11588 0 : AFNExtSurfaces(ExtOpenNum).ExtNodeNum = MultizoneSurfaceData(ExtOpenNum).NodeNums[1];
11589 0 : AFNExtSurfaces(ExtOpenNum).curve =
11590 0 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).curve;
11591 0 : AFNExtSurfaces(ExtOpenNum).DischCoeff = MultizoneCompSimpleOpeningData(SimOpenNum).DischCoeff;
11592 0 : ++ExtOpenNum;
11593 : }
11594 : }
11595 : }
11596 : }
11597 : // Calculate the azimuth and the coordinates of the centroid of each opening.
11598 : // Calculate Sprime and DeltaCp for each zone.
11599 2 : PiFormula.allocate(numWindDir);
11600 2 : SigmaFormula.allocate(numWindDir);
11601 2 : DeltaCp.allocate(AirflowNetworkNumOfZones);
11602 2 : EPDeltaCP.allocate(AirflowNetworkNumOfZones);
11603 2 : Sprime.allocate(AirflowNetworkNumOfZones);
11604 2 : ZoneAng.allocate(AirflowNetworkNumOfZones);
11605 4 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11606 2 : DeltaCp(ZnNum).WindDir.allocate(numWindDir);
11607 2 : EPDeltaCP(ZnNum).WindDir.allocate(numWindDir);
11608 74 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11609 72 : DeltaCp(ZnNum).WindDir(windDirNum) = 0.0;
11610 72 : EPDeltaCP(ZnNum).WindDir(windDirNum) = 0.0;
11611 : }
11612 : }
11613 2 : Sprime = 0.0;
11614 2 : ZoneAng = 0.0;
11615 4 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11616 2 : if (MultizoneZoneData(ZnNum).SingleSidedCpType == "ADVANCED") {
11617 2 : OpenNuminZone = 1;
11618 6 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11619 4 : if (OpenNuminZone > 2) break; // Tuned
11620 4 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11621 4 : if (OpenNuminZone == 1) {
11622 2 : X1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.x;
11623 2 : Y1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.y;
11624 2 : ZoneAng1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Azimuth;
11625 2 : ++OpenNuminZone;
11626 2 : } else if (OpenNuminZone == 2) {
11627 2 : X2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.x;
11628 2 : Y2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.y;
11629 2 : ZoneAng2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Azimuth;
11630 2 : ++OpenNuminZone;
11631 : }
11632 : }
11633 : }
11634 2 : ZoneAngDiff = ZoneAng1 - ZoneAng2;
11635 2 : if (ZoneAngDiff > 0.01) {
11636 0 : ShowWarningError(m_state,
11637 0 : "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName +
11638 : " has single side wind pressure coefficient type \"ADVANCED\", but has openings which are not coplanar.");
11639 0 : ShowContinueError(m_state, "The openings should be coplanar for the model to be valid. Simulation Continues.");
11640 : }
11641 2 : ZoneAng(ZnNum) = ZoneAng1;
11642 2 : Sprime(ZnNum) = std::sqrt(pow_2(X1 - X2) + pow_2(Y1 - Y2)) / MultizoneZoneData(ZnNum).BuildWidth;
11643 : // Calculate DeltaCp for each wind direction for each zone
11644 74 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11645 72 : m_state.dataEnvrn->WindDir = (windDirNum - 1) * 10.0;
11646 72 : Real64 WindAng = (windDirNum - 1) * 10.0;
11647 72 : IncAng = std::abs(WindAng - ZoneAng(ZnNum));
11648 72 : if (std::abs(IncAng) > 180.0) IncAng -= 360.0;
11649 72 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
11650 72 : if (std::abs(IncAng) <= 67.5) {
11651 26 : PiFormula(windDirNum) = 0.44 * sign(std::sin(2.67 * std::abs(IncAng) * Constant::Pi / 180.0), IncAng);
11652 46 : } else if (std::abs(IncAng) <= 180.0) {
11653 46 : PiFormula(windDirNum) = -0.69 * sign(std::sin((288 - 1.6 * std::abs(IncAng)) * Constant::Pi / 180.0), IncAng);
11654 : }
11655 72 : SigmaFormula(windDirNum) = 0.423 - 0.00163 * std::abs(IncAng);
11656 72 : DeltaCp(ZnNum).WindDir(windDirNum) =
11657 72 : (0.02 + (0.346 * std::abs(PiFormula(windDirNum)) + 0.084 * SigmaFormula(windDirNum)) * Sprime(ZnNum));
11658 : }
11659 : }
11660 : }
11661 : }
11662 :
11663 : // Calculate the single sided Cp arrays from DeltaCp for each single sided opening
11664 2 : CPV1.allocate(numWindDir); // These two arrays should probably be removed
11665 2 : CPV2.allocate(numWindDir);
11666 2 : CPV1 = 0.0;
11667 2 : CPV2 = 0.0;
11668 2 : SrfNum = 6;
11669 4 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11670 2 : if (MultizoneZoneData(ZnNum).SingleSidedCpType == "ADVANCED") {
11671 2 : OpenNuminZone = 1;
11672 6 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11673 4 : if (OpenNuminZone > 2) break; // Tuned
11674 4 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11675 4 : Real64 const VelRatio_2(std::pow(10.0 / AFNExtSurfaces(ExtOpenNum).NodeHeight, 2.0 * m_state.dataEnvrn->SiteWindExp));
11676 4 : Real64 const AFNEExtSurface_fac(0.5 * (1.0 / pow_2(AFNExtSurfaces(ExtOpenNum).DischCoeff)));
11677 4 : if (OpenNuminZone == 1) {
11678 2 : std::vector<Real64> cpvalues(numWindDir);
11679 74 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11680 72 : Real64 unmodifiedValue = valsByFacade[AFNExtSurfaces(ExtOpenNum).facadeNum - 1][windDirNum - 1] +
11681 72 : AFNEExtSurface_fac * DeltaCp(ZnNum).WindDir(windDirNum);
11682 72 : cpvalues[windDirNum - 1] = CPV1(windDirNum) = VelRatio_2 * unmodifiedValue;
11683 : }
11684 2 : valsByFacade.push_back(cpvalues);
11685 2 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum = SrfNum;
11686 2 : ++OpenNuminZone;
11687 2 : ++SrfNum;
11688 4 : } else if (OpenNuminZone == 2) {
11689 2 : std::vector<Real64> cpvalues(numWindDir);
11690 74 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11691 72 : Real64 unmodifiedValue = valsByFacade[AFNExtSurfaces(ExtOpenNum).facadeNum - 1][windDirNum - 1] -
11692 72 : AFNEExtSurface_fac * DeltaCp(ZnNum).WindDir(windDirNum);
11693 72 : cpvalues[windDirNum - 1] = CPV2(windDirNum) = VelRatio_2 * unmodifiedValue;
11694 72 : EPDeltaCP(ZnNum).WindDir(windDirNum) = std::abs(CPV2(windDirNum) - CPV1(windDirNum));
11695 : }
11696 2 : valsByFacade.push_back(cpvalues);
11697 2 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum = SrfNum;
11698 2 : ++OpenNuminZone;
11699 2 : ++SrfNum;
11700 2 : }
11701 : }
11702 : }
11703 : }
11704 : }
11705 : // Rewrite the CPVNum for all nodes that correspond with a simple or detailed opening
11706 : // Does this loop really do anything?
11707 4 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11708 2 : OpenNuminZone = 1;
11709 6 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11710 4 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11711 4 : if (OpenNuminZone == 1) {
11712 2 : ++OpenNuminZone;
11713 2 : } else if (OpenNuminZone == 2) {
11714 2 : ++OpenNuminZone;
11715 : }
11716 : }
11717 : }
11718 : }
11719 2 : }
11720 :
11721 306607 : Real64 Solver::zone_OA_change_rate(int const ZoneNum) // hybrid ventilation system controlled zone number
11722 : {
11723 :
11724 : // SUBROUTINE INFORMATION:
11725 : // AUTHOR Lixing Gu
11726 : // DATE WRITTEN May. 2007
11727 :
11728 : // PURPOSE OF THIS SUBROUTINE:
11729 : // This function outputs air change per hour in a given zone
11730 :
11731 306607 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
11732 306607 : auto &thisZoneHB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
11733 :
11734 306607 : Real64 CpAir = PsyCpAirFnW(thisZoneHB.airHumRat);
11735 306607 : Real64 RhoAir = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.airHumRat);
11736 306607 : Real64 InfilVolume = ((exchangeData(ZoneNum).SumMCp + exchangeData(ZoneNum).SumMVCp) / CpAir / RhoAir) * TimeStepSys * Constant::rSecsInHour;
11737 306607 : Real64 ACH = InfilVolume / (TimeStepSys * m_state.dataHeatBal->Zone(ZoneNum).Volume);
11738 :
11739 306607 : return ACH;
11740 : }
11741 :
11742 10 : int Solver::get_airloop_number(int const NodeNumber) // Get air loop number for each distribution node and linkage
11743 : {
11744 : // SUBROUTINE INFORMATION:
11745 : // AUTHOR Lixing Gu
11746 : // DATE WRITTEN Feb. 2018
11747 :
11748 : // PURPOSE OF THIS SUBROUTINE:
11749 : // This function outputs an AirLoopNum based on node number
11750 :
11751 : // Using/Aliasing
11752 : using BranchNodeConnections::GetChildrenData;
11753 : using BranchNodeConnections::GetNumChildren;
11754 : using BranchNodeConnections::IsParentObject;
11755 10 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
11756 : using SingleDuct::GetHVACSingleDuctSysIndex;
11757 :
11758 : // Return value
11759 10 : int AirLoopNumber = 0;
11760 :
11761 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11762 : int BranchNum;
11763 : int NumOfNodes;
11764 : int NodeNum;
11765 : int OutNum;
11766 : int SupAirPath;
11767 : int SupAirPathOutNodeNum;
11768 : int CtrlZoneNum;
11769 : int ZoneInNum;
11770 : int ZoneOutNum;
11771 : int AirLoopNum;
11772 10 : int TUNum = 0;
11773 10 : int TermNum = 0;
11774 : bool LocalError;
11775 : int NumOfComp;
11776 : int NumOfSubComp;
11777 : bool ErrorsFound;
11778 : int NumOfSubSubComp;
11779 :
11780 12 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
11781 : // Check OAMixer OA inlet node
11782 10 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).OAMixOAInNodeNum) {
11783 0 : return AirLoopNum;
11784 : }
11785 : // Check branch
11786 15 : for (BranchNum = 1; BranchNum <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
11787 10 : NumOfNodes = m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalNodes;
11788 27 : for (NodeNum = 1; NodeNum <= NumOfNodes; ++NodeNum) {
11789 19 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).NodeNum(NodeNum)) {
11790 2 : return AirLoopNum;
11791 : }
11792 : }
11793 13 : for (NumOfComp = 1; NumOfComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
11794 : ++NumOfComp) {
11795 8 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NodeNumIn) {
11796 0 : return AirLoopNum;
11797 : }
11798 8 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NodeNumOut) {
11799 0 : return AirLoopNum;
11800 : }
11801 8 : if (m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NumSubComps == 0) {
11802 8 : DataLoopNode::ConnectionObjectType TypeOfComp = static_cast<DataLoopNode::ConnectionObjectType>(EnergyPlus::getEnumValue(
11803 : BranchNodeConnections::ConnectionObjectTypeNamesUC,
11804 8 : m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).TypeOf));
11805 : std::string const &NameOfComp =
11806 8 : m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).Name;
11807 8 : if (IsParentObject(m_state, TypeOfComp, NameOfComp)) {
11808 :
11809 8 : int NumChildren = GetNumChildren(m_state, TypeOfComp, NameOfComp);
11810 8 : EPVector<DataLoopNode::ConnectionObjectType> SubCompTypes;
11811 8 : Array1D_string SubCompNames;
11812 8 : Array1D_string InletNodeNames;
11813 8 : Array1D_int InletNodeNumbers;
11814 8 : Array1D_string OutletNodeNames;
11815 8 : Array1D_int OutletNodeNumbers;
11816 :
11817 8 : SubCompTypes.allocate(NumChildren);
11818 8 : SubCompNames.allocate(NumChildren);
11819 8 : InletNodeNames.allocate(NumChildren);
11820 8 : InletNodeNumbers.allocate(NumChildren);
11821 8 : OutletNodeNames.allocate(NumChildren);
11822 8 : OutletNodeNumbers.allocate(NumChildren);
11823 :
11824 8 : GetChildrenData(m_state,
11825 : TypeOfComp,
11826 : NameOfComp,
11827 : NumChildren,
11828 : SubCompTypes,
11829 : SubCompNames,
11830 : InletNodeNames,
11831 : InletNodeNumbers,
11832 : OutletNodeNames,
11833 : OutletNodeNumbers,
11834 : ErrorsFound);
11835 :
11836 31 : for (NumOfSubComp = 1; NumOfSubComp <= NumChildren; ++NumOfSubComp) {
11837 26 : if (NodeNumber == InletNodeNumbers(NumOfSubComp)) {
11838 0 : SubCompTypes.deallocate();
11839 0 : SubCompNames.deallocate();
11840 0 : InletNodeNames.deallocate();
11841 0 : InletNodeNumbers.deallocate();
11842 0 : OutletNodeNames.deallocate();
11843 0 : OutletNodeNumbers.deallocate();
11844 0 : return AirLoopNum;
11845 : }
11846 26 : if (NodeNumber == OutletNodeNumbers(NumOfSubComp)) {
11847 3 : SubCompTypes.deallocate();
11848 3 : SubCompNames.deallocate();
11849 3 : InletNodeNames.deallocate();
11850 3 : InletNodeNumbers.deallocate();
11851 3 : OutletNodeNames.deallocate();
11852 3 : OutletNodeNumbers.deallocate();
11853 3 : return AirLoopNum;
11854 : }
11855 : }
11856 25 : for (NumOfSubComp = 1; NumOfSubComp <= NumChildren; ++NumOfSubComp) {
11857 20 : DataLoopNode::ConnectionObjectType TypeOfSubComp = SubCompTypes(NumOfSubComp);
11858 20 : std::string NameOfSubComp = SubCompNames(NumOfSubComp);
11859 20 : if (IsParentObject(m_state, TypeOfSubComp, NameOfSubComp)) {
11860 :
11861 0 : int NumGrandChildren = GetNumChildren(m_state, TypeOfSubComp, NameOfSubComp);
11862 0 : EPVector<DataLoopNode::ConnectionObjectType> SubSubCompTypes;
11863 0 : Array1D_string SubSubCompNames;
11864 0 : Array1D_string SubSubInletNodeNames;
11865 0 : Array1D_int SubSubInletNodeNumbers;
11866 0 : Array1D_string SubSubOutletNodeNames;
11867 0 : Array1D_int SubSubOutletNodeNumbers;
11868 :
11869 0 : SubSubCompTypes.allocate(NumGrandChildren);
11870 0 : SubSubCompNames.allocate(NumGrandChildren);
11871 0 : SubSubInletNodeNames.allocate(NumGrandChildren);
11872 0 : SubSubInletNodeNumbers.allocate(NumGrandChildren);
11873 0 : SubSubOutletNodeNames.allocate(NumGrandChildren);
11874 0 : SubSubOutletNodeNumbers.allocate(NumGrandChildren);
11875 :
11876 0 : GetChildrenData(m_state,
11877 : TypeOfSubComp,
11878 : NameOfSubComp,
11879 : NumGrandChildren,
11880 : SubSubCompTypes,
11881 : SubSubCompNames,
11882 : SubSubInletNodeNames,
11883 : SubSubInletNodeNumbers,
11884 : SubSubOutletNodeNames,
11885 : SubSubOutletNodeNumbers,
11886 : ErrorsFound);
11887 0 : for (int SubSubCompNum = 1; SubSubCompNum <= NumGrandChildren; ++SubSubCompNum) {
11888 0 : if (NodeNumber == SubSubInletNodeNumbers(SubSubCompNum)) {
11889 0 : SubSubCompTypes.deallocate();
11890 0 : SubSubCompNames.deallocate();
11891 0 : SubSubInletNodeNames.deallocate();
11892 0 : SubSubInletNodeNumbers.deallocate();
11893 0 : SubSubOutletNodeNames.deallocate();
11894 0 : SubSubOutletNodeNumbers.deallocate();
11895 0 : SubCompTypes.deallocate();
11896 0 : SubCompNames.deallocate();
11897 0 : InletNodeNames.deallocate();
11898 0 : InletNodeNumbers.deallocate();
11899 0 : OutletNodeNames.deallocate();
11900 0 : OutletNodeNumbers.deallocate();
11901 0 : return AirLoopNum;
11902 : }
11903 0 : if (NodeNumber == SubSubOutletNodeNumbers(SubSubCompNum)) {
11904 0 : SubSubCompTypes.deallocate();
11905 0 : SubSubCompNames.deallocate();
11906 0 : SubSubInletNodeNames.deallocate();
11907 0 : SubSubInletNodeNumbers.deallocate();
11908 0 : SubSubOutletNodeNames.deallocate();
11909 0 : SubSubOutletNodeNumbers.deallocate();
11910 0 : SubCompTypes.deallocate();
11911 0 : SubCompNames.deallocate();
11912 0 : InletNodeNames.deallocate();
11913 0 : InletNodeNumbers.deallocate();
11914 0 : OutletNodeNames.deallocate();
11915 0 : OutletNodeNumbers.deallocate();
11916 0 : return AirLoopNum;
11917 : }
11918 : }
11919 0 : SubSubCompTypes.deallocate();
11920 0 : SubSubCompNames.deallocate();
11921 0 : SubSubInletNodeNames.deallocate();
11922 0 : SubSubInletNodeNumbers.deallocate();
11923 0 : SubSubOutletNodeNames.deallocate();
11924 0 : SubSubOutletNodeNumbers.deallocate();
11925 0 : }
11926 20 : }
11927 :
11928 5 : SubCompTypes.deallocate();
11929 5 : SubCompNames.deallocate();
11930 5 : InletNodeNames.deallocate();
11931 5 : InletNodeNumbers.deallocate();
11932 5 : OutletNodeNames.deallocate();
11933 5 : OutletNodeNumbers.deallocate();
11934 23 : }
11935 : } else {
11936 0 : for (NumOfSubComp = 1;
11937 0 : NumOfSubComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NumSubComps;
11938 : ++NumOfSubComp) {
11939 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
11940 0 : .Branch(BranchNum)
11941 0 : .Comp(NumOfComp)
11942 0 : .SubComp(NumOfSubComp)
11943 0 : .NodeNumIn) {
11944 0 : return AirLoopNum;
11945 : }
11946 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
11947 0 : .Branch(BranchNum)
11948 0 : .Comp(NumOfComp)
11949 0 : .SubComp(NumOfSubComp)
11950 0 : .NodeNumOut) {
11951 0 : return AirLoopNum;
11952 : }
11953 0 : for (NumOfSubSubComp = 1; NumOfSubSubComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
11954 0 : .Branch(BranchNum)
11955 0 : .Comp(NumOfComp)
11956 0 : .SubComp(NumOfSubComp)
11957 0 : .NumSubSubComps;
11958 : ++NumOfSubSubComp) {
11959 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
11960 0 : .Branch(BranchNum)
11961 0 : .Comp(NumOfComp)
11962 0 : .SubComp(NumOfSubComp)
11963 0 : .SubSubComp(NumOfSubSubComp)
11964 0 : .NodeNumIn) {
11965 0 : return AirLoopNum;
11966 : }
11967 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
11968 0 : .Branch(BranchNum)
11969 0 : .Comp(NumOfComp)
11970 0 : .SubComp(NumOfSubComp)
11971 0 : .SubSubComp(NumOfSubSubComp)
11972 0 : .NodeNumOut) {
11973 0 : return AirLoopNum;
11974 : }
11975 : }
11976 : }
11977 : }
11978 : }
11979 : }
11980 :
11981 : // Check connection between supply and demand
11982 7 : for (OutNum = 1; OutNum <= m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumSupplyNodes; ++OutNum) {
11983 : // AirLoop supply outlet node
11984 5 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopSupplyNodeNum(OutNum) == NodeNumber) {
11985 0 : return AirLoopNum;
11986 : }
11987 5 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(OutNum) == NodeNumber) {
11988 1 : return AirLoopNum;
11989 : }
11990 : // supply path
11991 7 : for (SupAirPath = 1; SupAirPath <= m_state.dataZoneEquip->NumSupplyAirPaths; ++SupAirPath) {
11992 4 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).InletNodeNum ==
11993 4 : m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(OutNum)) {
11994 7 : for (SupAirPathOutNodeNum = 1; SupAirPathOutNodeNum <= m_state.dataZoneEquip->SupplyAirPath(SupAirPath).NumOutletNodes;
11995 : ++SupAirPathOutNodeNum) {
11996 4 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).OutletNode(SupAirPathOutNodeNum) == NodeNumber) {
11997 1 : return AirLoopNum;
11998 : }
11999 3 : for (TUNum = 1; TUNum <= DisSysNumOfTermUnits; ++TUNum) {
12000 0 : if (Util::SameString(DisSysCompTermUnitData(TUNum).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
12001 0 : LocalError = false;
12002 0 : GetHVACSingleDuctSysIndex(m_state,
12003 0 : DisSysCompTermUnitData(TUNum).name,
12004 : TermNum,
12005 : LocalError,
12006 : "AirflowNetwork:Distribution:Component:TerminalUnit",
12007 0 : DisSysCompTermUnitData(TUNum).DamperInletNode,
12008 0 : DisSysCompTermUnitData(TUNum).DamperOutletNode);
12009 0 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).OutletNode(SupAirPathOutNodeNum) ==
12010 0 : DisSysCompTermUnitData(TUNum).DamperInletNode) {
12011 0 : if (DisSysCompTermUnitData(TUNum).DamperOutletNode == NodeNumber) {
12012 0 : DisSysCompTermUnitData(TUNum).AirLoopNum = AirLoopNum;
12013 0 : return AirLoopNum;
12014 : }
12015 : }
12016 0 : if (LocalError) {
12017 : }
12018 : }
12019 : }
12020 : }
12021 : }
12022 : }
12023 : // return path
12024 3 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopReturnNodeNum(OutNum) == NodeNumber) {
12025 0 : return AirLoopNum;
12026 : }
12027 3 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipReturnNodeNum(OutNum) == NodeNumber) {
12028 1 : return AirLoopNum;
12029 : }
12030 4 : for (int retPathNum = 1; retPathNum <= m_state.dataZoneEquip->NumReturnAirPaths; ++retPathNum) {
12031 2 : if (m_state.dataZoneEquip->ReturnAirPath(retPathNum).OutletNodeNum ==
12032 2 : m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipReturnNodeNum(1)) {
12033 2 : if (m_state.dataZoneEquip->ReturnAirPath(retPathNum).OutletNodeNum == NodeNumber) {
12034 0 : return AirLoopNum;
12035 : }
12036 : }
12037 : }
12038 : // Supply inlet node
12039 :
12040 : // Terminal damper node
12041 : }
12042 : }
12043 :
12044 2 : for (CtrlZoneNum = 1; CtrlZoneNum <= m_state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
12045 2 : if (!m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
12046 5 : for (ZoneInNum = 1; ZoneInNum <= m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumInletNodes; ++ZoneInNum) {
12047 4 : if (m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNode(ZoneInNum) == NodeNumber) {
12048 1 : return m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNodeAirLoopNum(ZoneInNum);
12049 : }
12050 : }
12051 1 : for (ZoneOutNum = 1; ZoneOutNum <= m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumReturnNodes; ++ZoneOutNum) {
12052 1 : if (m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ReturnNode(ZoneOutNum) == NodeNumber) {
12053 1 : return m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ReturnNodeAirLoopNum(ZoneOutNum);
12054 : }
12055 : }
12056 : }
12057 :
12058 0 : return AirLoopNumber;
12059 : }
12060 :
12061 3 : void Solver::SizeDucts()
12062 : {
12063 3 : Real64 constexpr EPS(0.001);
12064 3 : int constexpr MaxIte(500);
12065 3 : Real64 constexpr MinVelocity(0.5); // minimum airflow velocity (m/s)
12066 3 : Real64 constexpr MaxVelocity(20.0); // maximum airflow velocity (m/s)
12067 :
12068 3 : int NodeLoopSupply = 0;
12069 3 : int NodeLoopReturn = 0;
12070 3 : int NodeSplitter = 0;
12071 3 : int NodeMixer = 0;
12072 3 : int NodeZoneIntlet = 0;
12073 3 : int NodeZoneReturn = 0;
12074 : int AFNNodeNum;
12075 : int AFNLinkNum;
12076 : int AFNLinkNum1;
12077 3 : Real64 SumLength = 0.0;
12078 3 : Real64 DynamicLoss = 0.0;
12079 3 : Real64 MaxRough = 0.0;
12080 : bool DuctSizingSTFlag;
12081 : bool DuctSizingSBFlag;
12082 : bool DuctSizingRTFlag;
12083 : bool DuctSizingRBFlag;
12084 3 : Real64 hydraulicDiameter = 0.0;
12085 3 : Real64 SupplyTrunkD = 0.0;
12086 3 : Real64 SupplyTrunkArea = 0.0;
12087 3 : Real64 SupplyBranchD = 0.0;
12088 3 : Real64 SupplyBranchArea = 0.0;
12089 3 : Real64 ReturnTrunkD = 0.0;
12090 3 : Real64 ReturnTrunkArea = 0.0;
12091 3 : Real64 ReturnBranchD = 0.0;
12092 3 : Real64 ReturnBranchArea = 0.0;
12093 3 : Real64 MdotBranch = 0.0;
12094 3 : int SolFla = 0;
12095 :
12096 3 : int NumOfCtrlZones = 0;
12097 12 : for (int ZoneNum = 1; ZoneNum <= m_state.dataGlobal->NumOfZones; ++ZoneNum) {
12098 9 : if (!m_state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) continue;
12099 3 : NumOfCtrlZones++;
12100 3 : for (int EquipTypeNum = 1; EquipTypeNum <= m_state.dataZoneEquip->ZoneEquipList(ZoneNum).NumOfEquipTypes; ++EquipTypeNum) {
12101 3 : if (m_state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipType(EquipTypeNum) == DataZoneEquipment::ZoneEquipType::AirDistributionUnit) {
12102 3 : int AirDistUnitNum = m_state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipIndex(EquipTypeNum);
12103 3 : MdotBranch = m_state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).MassFlowRateTU;
12104 3 : break;
12105 : }
12106 : }
12107 : }
12108 3 : if (NumOfCtrlZones != 1) {
12109 0 : ShowWarningError(m_state, "AirflowNetwork Duct Sizing: The current restriction is limited to a single controlled zone only");
12110 0 : ShowContinueError(m_state, format("The number of controlled zone is {}", NumOfCtrlZones));
12111 0 : ShowContinueError(m_state, "..Duct sizing is not performed");
12112 0 : simulation_control.autosize_ducts = false;
12113 0 : simulation_control.iWPCCnt = iWPCCntr::Input;
12114 0 : simulation_control.allow_unsupported_zone_equipment = false;
12115 : }
12116 3 : Real64 factor = simulation_control.ductSizing.factor;
12117 :
12118 3 : NodeLoopSupply = m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipSupplyNodeNum(1);
12119 3 : NodeLoopReturn = m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipReturnNodeNum(1);
12120 66 : for (AFNNodeNum = 1; AFNNodeNum <= AirflowNetworkNumOfNodes; AFNNodeNum++) {
12121 63 : if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::SPL) {
12122 3 : NodeSplitter = AFNNodeNum;
12123 60 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::MIX) {
12124 3 : NodeMixer = AFNNodeNum;
12125 57 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipSupplyNodeNum(1)) {
12126 3 : NodeLoopSupply = AFNNodeNum;
12127 54 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipReturnNodeNum(1)) {
12128 3 : NodeLoopReturn = AFNNodeNum;
12129 51 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::ZIN) {
12130 3 : NodeZoneIntlet = AFNNodeNum;
12131 48 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::ZOU) {
12132 3 : NodeZoneReturn = AFNNodeNum;
12133 : }
12134 : }
12135 :
12136 : // find trunk ducts
12137 3 : DuctSizingSTFlag = false;
12138 3 : DuctSizingSBFlag = false;
12139 3 : int CompNum = 0;
12140 3 : int TypeNum = 0;
12141 :
12142 72 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12143 69 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12144 69 : iComponentTypeNum CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
12145 69 : SumLength = 0.0;
12146 69 : DynamicLoss = 0.0;
12147 69 : MaxRough = 0.0;
12148 : // supply duct trunk
12149 69 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeLoopSupply) {
12150 3 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeSplitter) {
12151 : // A single trunk duct
12152 3 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12153 3 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12154 3 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12155 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12156 3 : SumLength = disSysCompDuct.L;
12157 3 : MaxRough = disSysCompDuct.roughness;
12158 3 : DynamicLoss = disSysCompDuct.TurDynCoef;
12159 3 : DuctSizingSTFlag = true;
12160 : }
12161 : } else {
12162 0 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1];
12163 : int CompNum1;
12164 : iComponentTypeNum CompTypeNum1;
12165 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12166 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12167 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12168 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12169 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12170 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12171 0 : SumLength += disSysCompDuct.L;
12172 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12173 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12174 : // NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12175 0 : DuctSizingSBFlag = true;
12176 : }
12177 0 : while (NodeNum1 != NodeSplitter) {
12178 0 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12179 0 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) continue;
12180 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12181 0 : continue;
12182 0 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
12183 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12184 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12185 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12186 0 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::SupplyTrunk;
12187 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12188 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12189 0 : SumLength += disSysCompDuct.L;
12190 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12191 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12192 0 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1];
12193 0 : DuctSizingSTFlag = true;
12194 0 : break;
12195 : }
12196 : }
12197 : }
12198 : }
12199 : }
12200 3 : if (DuctSizingSTFlag) {
12201 3 : Real64 Velocity = 0.0;
12202 3 : Real64 flowrate = DisSysCompCVFData(1).FlowRate / m_state.dataEnvrn->StdRhoAir;
12203 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12204 1 : SupplyTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12205 1 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * Constant::Pi;
12206 : } else {
12207 2 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12208 2 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12209 2 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12210 2 : Real64 const deltaP = simulation_control.ductSizing.supply_trunk_pressure_loss;
12211 2 : Real64 const MassFlowRate = DisSysCompCVFData(1).FlowRate;
12212 222 : auto f = [&thisState, deltaP, MassFlowRate, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12213 222 : return DuctDResidual(thisState, D, deltaP, MassFlowRate, SumLength, DynamicLoss, MaxRough);
12214 2 : };
12215 2 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12216 2 : if (SolFla == -1) {
12217 0 : if (!m_state.dataGlobal->WarmupFlag) {
12218 0 : if (ErrCountDuct == 0) {
12219 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12220 0 : ShowWarningError(m_state,
12221 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Supply Duct Trunk size.");
12222 0 : ShowContinueErrorTimeStamp(m_state, format("Supply Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12223 : } else {
12224 0 : ++ErrCountDuct;
12225 0 : ShowRecurringWarningErrorAtEnd(
12226 : m_state,
12227 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Trunk "
12228 : "size. Supply Trunk is calculated using velocity at 5m/s. Simulation continues...",
12229 0 : ErrIndexDuct,
12230 : hydraulicDiameter,
12231 : hydraulicDiameter);
12232 : }
12233 : }
12234 2 : } else if (SolFla == -2) {
12235 0 : ShowFatalError(
12236 : m_state,
12237 : "Duct Autosizing for Supply Trunk calculation failed: iteration limits exceeded. Supply Trunk is calculated "
12238 : "using velocity at 5m/s.");
12239 : }
12240 2 : if (SolFla < 0) {
12241 0 : SupplyTrunkD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12242 : } else {
12243 2 : SupplyTrunkD = hydraulicDiameter * factor;
12244 : }
12245 2 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * Constant::Pi;
12246 2 : Velocity = flowrate / SupplyTrunkArea;
12247 : }
12248 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12249 1 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12250 0 : SupplyTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12251 0 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * Constant::Pi;
12252 0 : ShowWarningError(
12253 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Supply Trunk size");
12254 0 : ShowContinueError(
12255 : m_state,
12256 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12257 0 : simulation_control.ductSizing.max_velocity,
12258 : Velocity));
12259 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Supply Trunk Diameter");
12260 : }
12261 : }
12262 : }
12263 : }
12264 : // supply duct branch
12265 69 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeZoneIntlet) {
12266 3 : SumLength = 0.0;
12267 3 : DynamicLoss = 0.0;
12268 3 : MaxRough = 0.0;
12269 3 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeSplitter) {
12270 : // A single branch duct
12271 0 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12272 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12273 0 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12274 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12275 0 : SumLength = disSysCompDuct.L;
12276 0 : MaxRough = disSysCompDuct.roughness;
12277 0 : DynamicLoss = disSysCompDuct.TurDynCoef;
12278 0 : DuctSizingSTFlag = true;
12279 : }
12280 : } else {
12281 3 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12282 : int CompNum1;
12283 : iComponentTypeNum CompTypeNum1;
12284 3 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12285 3 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12286 3 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12287 3 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyBranch;
12288 3 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12289 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12290 3 : SumLength += disSysCompDuct.L;
12291 3 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12292 3 : DynamicLoss += disSysCompDuct.TurDynCoef;
12293 3 : DuctSizingSBFlag = true;
12294 : }
12295 9 : while (NodeNum1 != NodeSplitter) {
12296 24 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12297 24 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) continue;
12298 3 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12299 0 : continue;
12300 3 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
12301 3 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12302 3 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12303 3 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12304 3 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::SupplyBranch;
12305 3 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12306 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12307 3 : SumLength += disSysCompDuct.L;
12308 3 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12309 3 : DynamicLoss += disSysCompDuct.TurDynCoef;
12310 3 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0];
12311 3 : DuctSizingSBFlag = true;
12312 3 : break;
12313 : }
12314 : }
12315 : }
12316 : }
12317 : }
12318 3 : if (DuctSizingSBFlag) {
12319 3 : SolFla = 0;
12320 : Real64 Velocity;
12321 3 : Real64 flowrate = MdotBranch / m_state.dataEnvrn->StdRhoAir;
12322 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12323 1 : SupplyBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12324 1 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * Constant::Pi;
12325 : } else {
12326 2 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12327 2 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12328 2 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12329 2 : Real64 const deltaP = simulation_control.ductSizing.supply_branch_pressure_loss;
12330 138 : auto f = [&thisState, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12331 138 : return DuctDResidual(thisState, D, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough);
12332 2 : };
12333 2 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12334 2 : if (SolFla == -1) {
12335 0 : if (!m_state.dataGlobal->WarmupFlag) {
12336 0 : if (ErrCountDuct == 0) {
12337 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12338 0 : ShowWarningError(m_state,
12339 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Supply Duct Branch size.");
12340 0 : ShowContinueErrorTimeStamp(m_state, format("Supply Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12341 : } else {
12342 0 : ++ErrCountDuct;
12343 0 : ShowRecurringWarningErrorAtEnd(
12344 : m_state,
12345 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Branch "
12346 : "size. Supply Branch is calculated using velocity at 5m/s. Simulation continues...",
12347 0 : ErrIndexDuct,
12348 : hydraulicDiameter,
12349 : hydraulicDiameter);
12350 : }
12351 : }
12352 2 : } else if (SolFla == -2) {
12353 0 : ShowFatalError(
12354 : m_state,
12355 : "Duct Autosizing for Supply Branch calculation failed: iteration limits exceeded. Supply Branch is calculated "
12356 : "using velocity at 5m/s.");
12357 : }
12358 2 : if (SolFla < 0) {
12359 0 : SupplyBranchD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12360 : } else {
12361 2 : SupplyBranchD = hydraulicDiameter * factor;
12362 : }
12363 2 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * Constant::Pi;
12364 2 : Velocity = flowrate / SupplyBranchArea;
12365 : }
12366 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12367 1 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12368 1 : SupplyBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12369 1 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * Constant::Pi;
12370 2 : ShowWarningError(
12371 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Supply Branch size");
12372 2 : ShowContinueError(
12373 : m_state,
12374 2 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12375 1 : simulation_control.ductSizing.max_velocity,
12376 : Velocity));
12377 3 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Supply Branch Diameter");
12378 : }
12379 : }
12380 : }
12381 : }
12382 :
12383 69 : DuctSizingRTFlag = false;
12384 69 : DuctSizingRBFlag = false;
12385 :
12386 : // return duct trunk
12387 69 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeLoopReturn) {
12388 3 : SumLength = 0.0;
12389 3 : DynamicLoss = 0.0;
12390 3 : MaxRough = 0.0;
12391 3 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeMixer) {
12392 : // A single branch duct
12393 3 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12394 3 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnTrunk;
12395 3 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12396 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12397 3 : SumLength = disSysCompDuct.L;
12398 3 : MaxRough = disSysCompDuct.roughness;
12399 3 : DynamicLoss = disSysCompDuct.TurDynCoef;
12400 3 : DuctSizingRTFlag = true;
12401 : }
12402 : } else {
12403 0 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12404 : int CompNum1;
12405 : iComponentTypeNum CompTypeNum1;
12406 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12407 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12408 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12409 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnTrunk;
12410 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12411 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12412 0 : SumLength += disSysCompDuct.L;
12413 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12414 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12415 0 : DuctSizingRTFlag = true;
12416 : }
12417 0 : while (NodeNum1 != NodeMixer) {
12418 0 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12419 0 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) continue;
12420 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12421 0 : continue;
12422 0 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
12423 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12424 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12425 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12426 0 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::ReturnTrunk;
12427 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12428 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12429 0 : SumLength += disSysCompDuct.L;
12430 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12431 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12432 0 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0];
12433 0 : DuctSizingRTFlag = true;
12434 0 : break;
12435 : }
12436 : }
12437 : }
12438 : }
12439 : }
12440 3 : if (DuctSizingRTFlag) {
12441 3 : SolFla = 0;
12442 : Real64 Velocity;
12443 3 : Real64 flowrate = DisSysCompCVFData(1).FlowRate / m_state.dataEnvrn->StdRhoAir;
12444 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12445 1 : ReturnTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12446 1 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * Constant::Pi;
12447 : } else {
12448 2 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12449 2 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12450 2 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12451 2 : Real64 const deltaP = simulation_control.ductSizing.return_trunk_pressure_loss;
12452 2 : Real64 const massFlowRate = DisSysCompCVFData(1).FlowRate;
12453 378 : auto f = [&thisState, deltaP, massFlowRate, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12454 378 : return DuctDResidual(thisState, D, deltaP, massFlowRate, SumLength, DynamicLoss, MaxRough);
12455 2 : };
12456 2 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12457 2 : if (SolFla == -1) {
12458 0 : if (!m_state.dataGlobal->WarmupFlag) {
12459 0 : if (ErrCountDuct == 0) {
12460 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12461 0 : ShowWarningError(m_state,
12462 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Return Duct Trunk size.");
12463 0 : ShowContinueErrorTimeStamp(m_state, format("Return Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12464 : } else {
12465 0 : ++ErrCountDuct;
12466 0 : ShowRecurringWarningErrorAtEnd(
12467 : m_state,
12468 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Return Duct Trunk "
12469 : "size. Supply Branch is calculated using velocity at 5m/s. Simulation continues...",
12470 0 : ErrIndexDuct,
12471 : hydraulicDiameter,
12472 : hydraulicDiameter);
12473 : }
12474 : }
12475 2 : } else if (SolFla == -2) {
12476 0 : ShowFatalError(
12477 : m_state,
12478 : "Duct Autosizing for Return Trunk calculation failed: iteration limits exceeded. Return Trunk is calculated "
12479 : "using velocity at 5m/s.");
12480 : }
12481 2 : if (SolFla < 0) {
12482 0 : ReturnTrunkD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12483 : } else {
12484 2 : ReturnTrunkD = hydraulicDiameter * factor;
12485 : }
12486 2 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * Constant::Pi;
12487 2 : Velocity = flowrate / SupplyBranchArea;
12488 : }
12489 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12490 1 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12491 0 : ReturnTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12492 0 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * Constant::Pi;
12493 0 : ShowWarningError(
12494 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Return Trunk size");
12495 0 : ShowContinueError(
12496 : m_state,
12497 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12498 0 : simulation_control.ductSizing.max_velocity,
12499 : Velocity));
12500 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Return Trunk Diameter");
12501 : }
12502 : }
12503 : }
12504 : }
12505 :
12506 : // return duct branch
12507 69 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeZoneReturn) {
12508 3 : SumLength = 0.0;
12509 3 : DynamicLoss = 0.0;
12510 3 : MaxRough = 0.0;
12511 3 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeMixer) {
12512 : // A single trunk duct
12513 0 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12514 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnBranch;
12515 0 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12516 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12517 0 : SumLength = disSysCompDuct.L;
12518 0 : MaxRough = disSysCompDuct.roughness;
12519 0 : DynamicLoss = disSysCompDuct.TurDynCoef;
12520 0 : DuctSizingRBFlag = true;
12521 : }
12522 : } else {
12523 3 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1];
12524 : int CompNum1;
12525 : iComponentTypeNum CompTypeNum1;
12526 3 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12527 3 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12528 3 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12529 3 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnBranch;
12530 3 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12531 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12532 3 : SumLength += disSysCompDuct.L;
12533 3 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12534 3 : DynamicLoss += disSysCompDuct.TurDynCoef;
12535 3 : DuctSizingRBFlag = true;
12536 : }
12537 9 : while (NodeNum1 != NodeMixer) {
12538 39 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12539 39 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) continue;
12540 3 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12541 0 : continue;
12542 3 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
12543 3 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12544 3 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12545 3 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12546 3 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::ReturnBranch;
12547 3 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12548 3 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12549 3 : SumLength += disSysCompDuct.L;
12550 3 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12551 3 : DynamicLoss += disSysCompDuct.TurDynCoef;
12552 3 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1];
12553 3 : DuctSizingRBFlag = true;
12554 3 : break;
12555 : }
12556 : }
12557 : }
12558 : }
12559 : }
12560 3 : if (DuctSizingRBFlag) {
12561 3 : SolFla = 0;
12562 : Real64 Velocity;
12563 3 : Real64 flowrate = MdotBranch / m_state.dataEnvrn->StdRhoAir;
12564 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12565 1 : ReturnBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12566 1 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * Constant::Pi;
12567 : } else {
12568 2 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12569 2 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12570 2 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12571 2 : Real64 const deltaP = simulation_control.ductSizing.return_branch_pressure_loss;
12572 346 : auto f = [&thisState, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12573 346 : return DuctDResidual(thisState, D, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough);
12574 2 : };
12575 2 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12576 2 : if (SolFla == -1) {
12577 0 : if (!m_state.dataGlobal->WarmupFlag) {
12578 0 : if (ErrCountDuct == 0) {
12579 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12580 0 : ShowWarningError(m_state,
12581 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Return Duct Branch size.");
12582 0 : ShowContinueErrorTimeStamp(m_state, format("Return Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12583 : } else {
12584 0 : ++ErrCountDuct;
12585 0 : ShowRecurringWarningErrorAtEnd(
12586 : m_state,
12587 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Branch "
12588 : "size. Return Branch is calculated using velocity at 5m/s. Simulation continues...",
12589 0 : ErrIndexDuct,
12590 : hydraulicDiameter,
12591 : hydraulicDiameter);
12592 : }
12593 : }
12594 2 : } else if (SolFla == -2) {
12595 0 : ShowFatalError(
12596 : m_state,
12597 : "Duct Autosizing for Return Branch calculation failed: iteration limits exceeded. Return Branch is calculated "
12598 : "using velocity at 5m/s.");
12599 : }
12600 2 : if (SolFla < 0) {
12601 0 : ReturnBranchD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12602 : } else {
12603 2 : ReturnBranchD = hydraulicDiameter * factor;
12604 : }
12605 2 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * Constant::Pi;
12606 2 : Velocity = flowrate / ReturnBranchArea;
12607 : }
12608 3 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12609 1 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12610 0 : ReturnBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12611 0 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * Constant::Pi;
12612 0 : ShowWarningError(
12613 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Return Branch size");
12614 0 : ShowContinueError(
12615 : m_state,
12616 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12617 0 : simulation_control.ductSizing.max_velocity,
12618 : Velocity));
12619 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Return Branch Diameter");
12620 : }
12621 : }
12622 : }
12623 : }
12624 : }
12625 : // Assign autosize values in Duct element
12626 72 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12627 69 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12628 69 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12629 69 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12630 69 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyTrunk) {
12631 3 : disSysCompDuct.hydraulicDiameter = SupplyTrunkD;
12632 3 : disSysCompDuct.A = SupplyTrunkArea;
12633 3 : disSysCompDuct.RelRough = disSysCompDuct.roughness / SupplyTrunkD; // e/D: relative roughness
12634 3 : disSysCompDuct.RelL = disSysCompDuct.L / SupplyTrunkD; // L/D: relative length
12635 3 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12636 3 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12637 66 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyBranch) {
12638 6 : disSysCompDuct.hydraulicDiameter = SupplyBranchD;
12639 6 : disSysCompDuct.A = SupplyBranchArea;
12640 6 : disSysCompDuct.RelRough = disSysCompDuct.roughness / SupplyBranchD; // e/D: relative roughness
12641 6 : disSysCompDuct.RelL = disSysCompDuct.L / SupplyBranchD; // L/D: relative length
12642 6 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12643 6 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12644 60 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnTrunk) {
12645 3 : disSysCompDuct.hydraulicDiameter = ReturnTrunkD;
12646 3 : disSysCompDuct.A = ReturnTrunkArea;
12647 3 : disSysCompDuct.RelRough = disSysCompDuct.roughness / ReturnTrunkD; // e/D: relative roughness
12648 3 : disSysCompDuct.RelL = disSysCompDuct.L / ReturnTrunkD; // L/D: relative length
12649 3 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12650 3 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12651 57 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnBranch) {
12652 6 : disSysCompDuct.hydraulicDiameter = ReturnBranchD;
12653 6 : disSysCompDuct.A = ReturnBranchArea;
12654 6 : disSysCompDuct.RelRough = disSysCompDuct.roughness / ReturnBranchD; // e/D: relative roughness
12655 6 : disSysCompDuct.RelL = disSysCompDuct.L / ReturnBranchD; // L/D: relative length
12656 6 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12657 6 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12658 : }
12659 : }
12660 :
12661 : // Print data in eio
12662 3 : print(m_state.files.eio,
12663 : "! <AirflowNetwork Model:Duct Autosizing>, Linkage Name, Duct Type, Duct Name, Duct Hydraunic Diameter, Duct Cross Section Area\n");
12664 :
12665 : // Assign autosize values in Duct element
12666 72 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12667 69 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12668 69 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12669 69 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12670 69 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyTrunk) {
12671 3 : print(m_state.files.eio,
12672 : "AirflowNetwork Model:Duct Autosizing, {}, Supply Trunk, {}, ",
12673 3 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12674 3 : disSysCompDuct.name);
12675 3 : print(m_state.files.eio, "{:.4R},{:.4R}\n", SupplyTrunkD, SupplyTrunkArea);
12676 : }
12677 69 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyBranch) {
12678 6 : print(m_state.files.eio,
12679 : "AirflowNetwork Model:Duct Autosizing, {}, Supply Branch, {}, ",
12680 6 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12681 6 : disSysCompDuct.name);
12682 6 : print(m_state.files.eio, "{:.4R},{:.4R}\n", SupplyBranchD, SupplyBranchArea);
12683 : }
12684 69 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnTrunk) {
12685 3 : print(m_state.files.eio,
12686 : "AirflowNetwork Model:Duct Autosizing, {}, Return Trunk, {}, ",
12687 3 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12688 3 : disSysCompDuct.name);
12689 3 : print(m_state.files.eio, "{:.4R},{:.4R}\n", ReturnTrunkD, ReturnTrunkArea);
12690 : }
12691 69 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnBranch) {
12692 6 : print(m_state.files.eio,
12693 : "AirflowNetwork Model:Duct Autosizing, {}, Return Branch, {}, ",
12694 6 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12695 6 : disSysCompDuct.name);
12696 6 : print(m_state.files.eio, "{:.4R},{:.4R}\n", ReturnBranchD, ReturnBranchArea);
12697 : }
12698 : }
12699 3 : }
12700 :
12701 1084 : Real64 Solver::CalcDuctDiameter(Real64 hydraulicDiameter, Real64 DeltaP, Real64 MassFlowrate, Real64 TotalL, Real64 TotalLossCoe, Real64 MaxRough)
12702 : {
12703 1084 : Real64 CalcDeltaP = 0.0;
12704 :
12705 : Real64 A;
12706 : Real64 A0;
12707 : Real64 A1;
12708 : Real64 A2;
12709 : Real64 B;
12710 : Real64 D;
12711 : Real64 S2;
12712 : Real64 CDM;
12713 : Real64 FL; // friction factor for laminar flow.
12714 : Real64 FT; // friction factor for turbulent flow.
12715 : Real64 FTT;
12716 : Real64 RE; // Reynolds number.
12717 : Real64 ed;
12718 : Real64 ld;
12719 : Real64 g;
12720 : Real64 AA1;
12721 : Real64 velocity;
12722 1084 : Real64 constexpr LamDynCoef(64.0);
12723 1084 : Real64 constexpr LamFriCoef(0.001);
12724 1084 : Real64 constexpr EPS(0.001);
12725 1084 : Real64 constexpr C(0.868589);
12726 :
12727 : //// Initial guess with 5 m/s
12728 1084 : Real64 flowrate = MassFlowrate / m_state.dataEnvrn->StdRhoAir;
12729 :
12730 1084 : ed = MaxRough / hydraulicDiameter;
12731 1084 : ld = TotalL / hydraulicDiameter;
12732 1084 : g = 1.14 - 0.868589 * std::log(ed);
12733 1084 : AA1 = g;
12734 1084 : A = hydraulicDiameter * hydraulicDiameter / 4.0 * Constant::Pi;
12735 1084 : Real64 viscosity{AirflowNetwork::AIRDYNAMICVISCOSITY_CONSTEXPR(20)};
12736 1084 : velocity = flowrate / A;
12737 :
12738 : if (LamFriCoef >= 0.001) {
12739 1084 : A2 = LamFriCoef / (2.0 * m_state.dataEnvrn->StdRhoAir * A * A);
12740 1084 : A1 = (viscosity * LamDynCoef * ld) / (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter);
12741 1084 : A0 = -DeltaP;
12742 1084 : CDM = std::sqrt(A1 * A1 - 4.0 * A2 * A0);
12743 1084 : FL = (CDM - A1) / (2.0 * A2);
12744 1084 : CDM = 1.0 / CDM;
12745 : } else {
12746 : CDM = (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter) / (viscosity * LamDynCoef * ld);
12747 : FL = CDM * DeltaP;
12748 : }
12749 :
12750 : // CDM = (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter) / (viscosity * LamDynCoef * ld);
12751 : // FL = CDM * DeltaP;
12752 :
12753 1084 : RE = FL * hydraulicDiameter / (viscosity * A);
12754 1084 : S2 = std::sqrt(2.0 * m_state.dataEnvrn->StdRhoAir * DeltaP) * A;
12755 1084 : FTT = S2 / std::sqrt(ld / pow_2(g) + TotalLossCoe);
12756 : while (true) {
12757 2144 : FT = FTT;
12758 2144 : B = (9.3 * viscosity * A) / (FT * MaxRough);
12759 2144 : D = 1.0 + g * B;
12760 2144 : g -= (g - AA1 + C * std::log(D)) / (1.0 + C * B / D);
12761 2144 : FTT = S2 / std::sqrt(ld / pow_2(g) + TotalLossCoe);
12762 2144 : if (std::abs(FTT - FT) / FTT < EPS) break;
12763 : }
12764 1084 : FT = FTT;
12765 :
12766 1084 : Real64 f = 1.0 / (g * g);
12767 :
12768 : // CalcDeltaP = ((FT * TotalL) / hydraulicDiameter + TotalLossCoe) * (m_state.dataEnvrn->StdRhoAir * velocity * velocity / 2.0);
12769 1084 : CalcDeltaP = ((f * TotalL) / hydraulicDiameter + TotalLossCoe) * (m_state.dataEnvrn->StdRhoAir * velocity * velocity / 2.0);
12770 :
12771 1084 : return CalcDeltaP;
12772 : }
12773 :
12774 1084 : Real64 DuctDResidual(EnergyPlusData &state,
12775 : Real64 D, // duct diameter
12776 : Real64 DeltaP,
12777 : Real64 MassFlowrate,
12778 : Real64 TotalL,
12779 : Real64 TotalLossCoe,
12780 : Real64 MaxRough)
12781 : {
12782 1084 : Real64 CalcDeltaP = state.afn->CalcDuctDiameter(D, DeltaP, MassFlowrate, TotalL, TotalLossCoe, MaxRough);
12783 1084 : return (CalcDeltaP - DeltaP) / DeltaP;
12784 : }
12785 :
12786 8 : void OccupantVentilationControlProp::calc(EnergyPlusData &state,
12787 : int const ZoneNum,
12788 : Real64 const TimeOpenDuration,
12789 : Real64 const TimeCloseDuration,
12790 : int &OpeningStatus,
12791 : int &OpeningProbStatus,
12792 : int &ClosingProbStatus)
12793 : {
12794 :
12795 : Real64 Tcomfort; // Thermal comfort temperature
12796 : Real64 ComfortBand; // Thermal comfort band
12797 : Real64 Toperative; // Operative temperature
12798 : Real64 OutDryBulb; // Outdoor dry-bulb temperature
12799 :
12800 8 : auto &Zone(state.dataHeatBal->Zone);
12801 :
12802 8 : if (TimeOpenDuration > 0) {
12803 4 : if (TimeOpenDuration >= MinOpeningTime) {
12804 3 : OpeningStatus = OpenStatus::FreeOperation; // free operation
12805 : } else {
12806 1 : OpeningStatus = OpenStatus::MinCheckForceOpen; // forced to open
12807 : }
12808 : }
12809 8 : if (TimeCloseDuration > 0) {
12810 4 : if (TimeCloseDuration >= MinClosingTime) {
12811 3 : OpeningStatus = OpenStatus::FreeOperation; // free operation
12812 : } else {
12813 1 : OpeningStatus = OpenStatus::MinCheckForceClose; // forced to close
12814 : }
12815 : }
12816 :
12817 8 : if (MinTimeControlOnly) return;
12818 :
12819 4 : if (Zone(ZoneNum).LinkedOutAirNode > 0) {
12820 0 : OutDryBulb = Zone(ZoneNum).OutDryBulbTemp;
12821 : } else {
12822 4 : OutDryBulb = OutDryBulbTempAt(state, Zone(ZoneNum).Centroid.z);
12823 : }
12824 :
12825 4 : if (OutDryBulb < ComfortBouPoint) {
12826 0 : Tcomfort = CurveValue(state, ComfortLowTempCurveNum, OutDryBulb);
12827 : } else {
12828 4 : Tcomfort = CurveValue(state, ComfortHighTempCurveNum, OutDryBulb);
12829 : }
12830 4 : ComfortBand = -0.0028 * (100 - MaxPPD) * (100 - MaxPPD) + 0.3419 * (100 - MaxPPD) - 6.6275;
12831 4 : Toperative = 0.5 * (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT +
12832 4 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MRT);
12833 :
12834 4 : if (Toperative > (Tcomfort + ComfortBand)) {
12835 3 : if (opening_probability(state, ZoneNum, TimeCloseDuration)) {
12836 2 : OpeningProbStatus = ProbabilityCheck::ForceChange;
12837 : ; // forced to open
12838 : } else {
12839 1 : OpeningProbStatus = ProbabilityCheck::KeepStatus; // Keep previous status
12840 : }
12841 : } else {
12842 1 : OpeningProbStatus = ProbabilityCheck::NoAction; // free operation
12843 : }
12844 :
12845 4 : if (Toperative < (Tcomfort - ComfortBand)) {
12846 1 : if (closing_probability(state, TimeOpenDuration)) {
12847 1 : ClosingProbStatus = ProbabilityCheck::ForceChange; // forced to close
12848 : } else {
12849 0 : ClosingProbStatus = ProbabilityCheck::KeepStatus; // Keep previous status
12850 : }
12851 : } else {
12852 3 : ClosingProbStatus = ProbabilityCheck::NoAction; // free operation
12853 : }
12854 : }
12855 :
12856 : bool
12857 3 : OccupantVentilationControlProp::opening_probability(EnergyPlusData &state,
12858 : int const ZoneNum,
12859 : Real64 const TimeCloseDuration) // function to perform calculations of opening probability
12860 : {
12861 : Real64 SchValue;
12862 : Real64 RandomValue;
12863 3 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
12864 3 : auto &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
12865 :
12866 3 : if (TimeCloseDuration < MinClosingTime) {
12867 1 : return false;
12868 : }
12869 2 : if (OccupancyCheck) {
12870 0 : if (state.dataHeatBal->ZoneIntGain(ZoneNum).NOFOCC <= 0.0) {
12871 0 : return false;
12872 : }
12873 : }
12874 :
12875 2 : switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
12876 0 : case HVAC::SetptType::SingleHeat: {
12877 0 : if (thisZoneHB.MAT <= zoneTstatSetpt.setptLo) {
12878 0 : return false;
12879 : }
12880 0 : } break;
12881 :
12882 0 : case HVAC::SetptType::SingleCool: {
12883 0 : if (thisZoneHB.MAT >= zoneTstatSetpt.setptHi) {
12884 0 : return false;
12885 : }
12886 0 : } break;
12887 0 : case HVAC::SetptType::SingleHeatCool: {
12888 0 : return false;
12889 : } break;
12890 :
12891 1 : case HVAC::SetptType::DualHeatCool: {
12892 1 : if (thisZoneHB.MAT < zoneTstatSetpt.setptLo || thisZoneHB.MAT > zoneTstatSetpt.setptHi) {
12893 0 : return false;
12894 : }
12895 1 : } break;
12896 :
12897 1 : default: {
12898 1 : } break;
12899 : } // switch
12900 :
12901 2 : if (openingProbSched == nullptr) {
12902 2 : return true;
12903 : } else {
12904 0 : SchValue = openingProbSched->getCurrentVal();
12905 0 : RandomValue = Real64(rand()) / RAND_MAX;
12906 0 : if (SchValue > RandomValue) {
12907 0 : return true;
12908 : } else {
12909 0 : return false;
12910 : }
12911 : }
12912 : }
12913 :
12914 1 : bool OccupantVentilationControlProp::closing_probability(EnergyPlusData &state,
12915 : Real64 const TimeOpenDuration) // function to perform calculations of closing probability
12916 : {
12917 : Real64 SchValue;
12918 : Real64 RandomValue;
12919 :
12920 1 : if (TimeOpenDuration < MinOpeningTime) {
12921 0 : return false;
12922 : }
12923 1 : if (closingProbSched == nullptr) {
12924 1 : return true;
12925 : } else {
12926 0 : SchValue = closingProbSched->getCurrentVal();
12927 0 : RandomValue = Real64(rand()) / RAND_MAX;
12928 0 : if (SchValue > RandomValue) {
12929 0 : return true;
12930 : } else {
12931 0 : return false;
12932 : }
12933 : }
12934 : }
12935 :
12936 24 : void Solver::allocate()
12937 : {
12938 :
12939 : // SUBROUTINE INFORMATION:
12940 : // AUTHOR Lixing Gu
12941 : // DATE WRITTEN Aug. 2003
12942 : // MODIFIED na
12943 : // RE-ENGINEERED na
12944 :
12945 : // PURPOSE OF THIS SUBROUTINE:
12946 : // This subroutine allocates dynamic arrays for AirflowNetworkSolver.
12947 :
12948 : // METHODOLOGY EMPLOYED:
12949 : // na
12950 :
12951 : // REFERENCES:
12952 : // na
12953 :
12954 : // USE STATEMENTS:
12955 : // na
12956 :
12957 : // Locals
12958 : // SUBROUTINE ARGUMENT DEFINITIONS:
12959 : // na
12960 :
12961 : // SUBROUTINE PARAMETER DEFINITIONS:
12962 : // na
12963 :
12964 : // INTERFACE BLOCK SPECIFICATIONS
12965 : // na
12966 :
12967 : // DERIVED TYPE DEFINITIONS
12968 : // na
12969 :
12970 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12971 : int i;
12972 : iComponentTypeNum j;
12973 : int n;
12974 :
12975 : // Formats
12976 :
12977 : // Assume a network to simulate multizone airflow is a subset of the network to simulate air distribution system.
12978 : // Network array size is allocated based on the network of air distribution system.
12979 : // If multizone airflow is simulated only, the array size is allocated based on the multizone network.
12980 :
12981 24 : auto &NetworkNumOfLinks = ActualNumOfLinks;
12982 24 : auto &NetworkNumOfNodes = ActualNumOfNodes;
12983 :
12984 24 : NetworkNumOfLinks = AirflowNetworkNumOfLinks;
12985 24 : NetworkNumOfNodes = AirflowNetworkNumOfNodes;
12986 :
12987 24 : AFECTL.allocate(NetworkNumOfLinks);
12988 24 : AFLOW2.allocate(NetworkNumOfLinks);
12989 24 : AFLOW.allocate(NetworkNumOfLinks);
12990 24 : PW.allocate(NetworkNumOfLinks);
12991 24 : PS.allocate(NetworkNumOfLinks);
12992 :
12993 : // TZ.allocate(NetworkNumOfNodes);
12994 : // WZ.allocate(NetworkNumOfNodes);
12995 24 : PZ.allocate(NetworkNumOfNodes);
12996 : // RHOZ.allocate(NetworkNumOfNodes);
12997 : // SQRTDZ.allocate(NetworkNumOfNodes);
12998 : // VISCZ.allocate(NetworkNumOfNodes);
12999 24 : SUMAF.allocate(NetworkNumOfNodes);
13000 :
13001 335 : for (int it = 0; it <= NetworkNumOfNodes + 1; ++it)
13002 311 : node_states.emplace_back(properties.density(101325.0, 20.0, 0.0));
13003 :
13004 24 : ID.allocate(NetworkNumOfNodes);
13005 24 : IK.allocate(NetworkNumOfNodes + 1);
13006 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13007 24 : newIK.allocate(NetworkNumOfNodes + 1);
13008 : #endif
13009 24 : AD.allocate(NetworkNumOfNodes);
13010 24 : SUMF.allocate(NetworkNumOfNodes);
13011 :
13012 24 : n = 0;
13013 328 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
13014 304 : j = AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum;
13015 304 : if (j == iComponentTypeNum::DOP) {
13016 6 : ++n;
13017 : }
13018 : }
13019 :
13020 24 : dos.allocate(AirflowNetworkNumOfLinks, n);
13021 :
13022 24 : PB = 101325.0;
13023 : // LIST = 5
13024 : // LIST = 0;
13025 :
13026 287 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13027 263 : ID(n) = n;
13028 : }
13029 328 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13030 304 : AFECTL(i) = 1.0;
13031 304 : AFLOW(i) = 0.0;
13032 304 : AFLOW2(i) = 0.0;
13033 : }
13034 :
13035 287 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13036 : // TZ(i) = AirflowNetworkNodeSimu(i).TZ;
13037 : // WZ(i) = AirflowNetworkNodeSimu(i).WZ;
13038 263 : PZ(i) = AirflowNetworkNodeSimu(i).PZ;
13039 263 : node_states[i].temperature = AirflowNetworkNodeSimu(i).TZ;
13040 263 : node_states[i].humidity_ratio = AirflowNetworkNodeSimu(i).WZ;
13041 : // properties[i].pressure = AirflowNetworkNodeSimu(i).PZ;
13042 : }
13043 :
13044 : // Assign linkage values
13045 328 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13046 304 : PW(i) = 0.0;
13047 : }
13048 : // Write an ouput file used for AIRNET input
13049 : /*
13050 : if (LIST >= 5) {
13051 : Unit11 = GetNewUnitNumber();
13052 : ObjexxFCL::gio::open(Unit11, DataStringGlobals::eplusADSFileName);
13053 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13054 : ObjexxFCL::gio::write(Unit11, Format_901) << i << state.afn->AirflowNetworkNodeData(i).NodeTypeNum <<
13055 : state.afn->AirflowNetworkNodeData(i).NodeHeight << TZ(i)
13056 : << PZ(i);
13057 : }
13058 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13059 : for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
13060 : j = state.afn->AirflowNetworkCompData(i).TypeNum;
13061 : {
13062 : auto const SELECT_CASE_var(state.afn->AirflowNetworkCompData(i).CompTypeNum);
13063 : if (SELECT_CASE_var == CompTypeNum_PLR) { //'PLR' Power law component
13064 : // WRITE(Unit11,902)
13065 : state.afn->AirflowNetworkCompData(i)%CompNum,1,DisSysCompLeakData(j)%FlowCoef, &
13066 : // DisSysCompLeakData(j)%FlowCoef,DisSysCompLeakData(j)%FlowCoef,DisSysCompLeakData(j)%FlowExpo
13067 : } else if (SELECT_CASE_var == CompTypeNum_SCR) { //'SCR' Surface crack component
13068 : ObjexxFCL::gio::write(Unit11, Format_902) << state.afn->AirflowNetworkCompData(i).CompNum << 1 <<
13069 : MultizoneSurfaceCrackData(j).FlowCoef
13070 : << MultizoneSurfaceCrackData(j).FlowCoef << MultizoneSurfaceCrackData(j).FlowCoef
13071 : << MultizoneSurfaceCrackData(j).FlowExpo;
13072 : } else if (SELECT_CASE_var == CompTypeNum_DWC) { //'DWC' Duct component
13073 : // WRITE(Unit11,902)
13074 : state.afn->AirflowNetworkCompData(i)%CompNum,2,DisSysCompDuctData(j)%L,DisSysCompDuctData(j)%D, &
13075 : // DisSysCompDuctData(j)%A,DisSysCompDuctData(j)%Rough
13076 : // WRITE(Unit11,903) DisSysCompDuctData(i)%TurDynCoef,DisSysCompDuctData(j)%LamFriCoef, &
13077 : // DisSysCompDuctData(j)%LamFriCoef,DisSysCompDuctData(j)%InitLamCoef
13078 : // CASE (CompTypeNum_CVF) ! 'CVF' Constant volume fan component
13079 : // WRITE(Unit11,904) state.afn->AirflowNetworkCompData(i)%CompNum,4,DisSysCompCVFData(j)%FlowRate
13080 : } else if (SELECT_CASE_var == CompTypeNum_EXF) { // 'EXF' Zone exhaust fan
13081 : ObjexxFCL::gio::write(Unit11, Format_904) << state.afn->AirflowNetworkCompData(i).CompNum << 4 <<
13082 : MultizoneCompExhaustFanData(j).FlowRate; } else {
13083 : }
13084 : }
13085 : }
13086 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13087 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13088 : gio::write(Unit11, Format_910) << i << state.afn->AirflowNetworkLinkageData(i).NodeNums[0] <<
13089 : state.afn->AirflowNetworkLinkageData(i).NodeHeights[0]
13090 : << state.afn->AirflowNetworkLinkageData(i).NodeNums[1] <<
13091 : state.afn->AirflowNetworkLinkageData(i).NodeHeights[1]
13092 : << state.afn->AirflowNetworkLinkageData(i).CompNum << 0 << 0;
13093 : }
13094 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13095 : }
13096 : */
13097 24 : setsky();
13098 :
13099 : // SETSKY figures out the IK stuff -- which is why E+ doesn't allocate AU until here
13100 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13101 : // ! only printing to screen, can be commented
13102 : // print*, "SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS is defined"
13103 : // write(*,'(2(a,i8))') "AllocateAirflowNetworkData: after SETSKY, allocating AU. NetworkNumOfNodes=", &
13104 : // NetworkNumOfNodes, " IK(NetworkNumOfNodes+1)= NNZE=", IK(NetworkNumOfNodes+1)
13105 : // print*, " NetworkNumOfLinks=", NetworkNumOfLinks
13106 : // allocate same size as others -- this will be maximum !noel
13107 24 : newAU.allocate(IK(NetworkNumOfNodes + 1));
13108 : #endif
13109 :
13110 : // noel, GNU says the AU is indexed above its upper bound
13111 : // ALLOCATE(AU(IK(NetworkNumOfNodes+1)-1))
13112 24 : AU.allocate(IK(NetworkNumOfNodes + 1));
13113 24 : }
13114 :
13115 16874 : void Solver::initialize_calculation()
13116 : {
13117 :
13118 : // SUBROUTINE INFORMATION:
13119 : // AUTHOR Lixing Gu
13120 : // DATE WRITTEN Aug. 2003
13121 : // MODIFIED na
13122 : // RE-ENGINEERED na
13123 :
13124 : // PURPOSE OF THIS SUBROUTINE:
13125 : // This subroutine initializes variables for AirflowNetworkSolver.
13126 :
13127 : // METHODOLOGY EMPLOYED:
13128 : // na
13129 :
13130 : // REFERENCES:
13131 : // na
13132 :
13133 : // USE STATEMENTS:
13134 : // na
13135 :
13136 : // Locals
13137 : // SUBROUTINE ARGUMENT DEFINITIONS:
13138 : // na
13139 :
13140 : // SUBROUTINE PARAMETER DEFINITIONS:
13141 : // na
13142 :
13143 : // INTERFACE BLOCK SPECIFICATIONS
13144 : // na
13145 :
13146 : // DERIVED TYPE DEFINITIONS
13147 : // na
13148 :
13149 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13150 :
13151 509242 : for (int i = 1; i <= ActualNumOfNodes; ++i) {
13152 492368 : ID(i) = i;
13153 : }
13154 547956 : for (int i = 1; i <= ActualNumOfLinks; ++i) {
13155 531082 : AFECTL(i) = 1.0;
13156 531082 : AFLOW(i) = 0.0;
13157 531082 : AFLOW2(i) = 0.0;
13158 : }
13159 :
13160 509242 : for (int i = 1; i <= ActualNumOfNodes; ++i) {
13161 : // TZ(i) = AirflowNetworkNodeSimu(i).TZ;
13162 : // WZ(i) = AirflowNetworkNodeSimu(i).WZ;
13163 492368 : PZ(i) = AirflowNetworkNodeSimu(i).PZ;
13164 492368 : node_states[i].temperature = AirflowNetworkNodeSimu(i).TZ;
13165 492368 : node_states[i].humidity_ratio = AirflowNetworkNodeSimu(i).WZ;
13166 : // properties[i].pressure = AirflowNetworkNodeSimu(i).PZ;
13167 : }
13168 16874 : }
13169 :
13170 24 : void Solver::setsky()
13171 : {
13172 : // SUBROUTINE INFORMATION:
13173 : // AUTHOR George Walton
13174 : // DATE WRITTEN 1998
13175 : // MODIFIED Feb. 2006 (L. Gu) to meet requirements of AirflowNetwork
13176 : // RE-ENGINEERED na
13177 :
13178 : // PURPOSE OF THIS SUBROUTINE:
13179 : // This subroutine sets up the "IK" array describing the sparse matrix [A] in skyline
13180 : // form by using the location matrix.
13181 :
13182 : // METHODOLOGY EMPLOYED:
13183 : // na
13184 :
13185 : // REFERENCES:
13186 : // AIRNET
13187 :
13188 : // USE STATEMENTS:
13189 : // na
13190 :
13191 : // Locals
13192 : // SUBROUTINE ARGUMENT DEFINITIONS:
13193 : // na
13194 :
13195 : // SUBROUTINE PARAMETER DEFINITIONS:
13196 : // na
13197 :
13198 : // INTERFACE BLOCK SPECIFICATIONS
13199 : // na
13200 :
13201 : // DERIVED TYPE DEFINITIONS
13202 : // na
13203 :
13204 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13205 : // IK(K) - pointer to the top of column/row "K".
13206 : int i;
13207 : int j;
13208 : int k;
13209 : int L;
13210 : int M;
13211 : int N1;
13212 : int N2;
13213 :
13214 : // Initialize "IK".
13215 311 : for (i = 1; i <= ActualNumOfNodes + 1; ++i) {
13216 287 : IK(i) = 0;
13217 : }
13218 : // Determine column heights.
13219 328 : for (M = 1; M <= ActualNumOfLinks; ++M) {
13220 304 : j = AirflowNetworkLinkageData(M).NodeNums[1];
13221 304 : if (j == 0) continue;
13222 304 : L = ID(j);
13223 304 : i = AirflowNetworkLinkageData(M).NodeNums[0];
13224 304 : k = ID(i);
13225 304 : N1 = std::abs(L - k);
13226 304 : N2 = max(k, L);
13227 304 : IK(N2) = max(IK(N2), N1);
13228 : }
13229 : // Convert heights to column addresses.
13230 24 : j = IK(1);
13231 24 : IK(1) = 1;
13232 287 : for (k = 1; k <= ActualNumOfNodes; ++k) {
13233 263 : i = IK(k + 1);
13234 263 : IK(k + 1) = IK(k) + j;
13235 263 : j = i;
13236 : }
13237 24 : }
13238 :
13239 16873 : void Solver::airmov()
13240 : {
13241 : // SUBROUTINE INFORMATION:
13242 : // AUTHOR George Walton
13243 : // DATE WRITTEN Extracted from AIRNETf
13244 : // MODIFIED Lixing Gu, 2/1/04
13245 : // Revised the subroutine to meet E+ needs
13246 : // MODIFIED Lixing Gu, 6/8/05
13247 : // RE-ENGINEERED na
13248 :
13249 : // PURPOSE OF THIS SUBROUTINE:
13250 : // This subroutine is a driver for AIRNET to calculate nodal pressures and linkage airflows
13251 :
13252 : // METHODOLOGY EMPLOYED:
13253 : // na
13254 :
13255 : // REFERENCES:
13256 : // na
13257 :
13258 : // USE STATEMENTS:
13259 :
13260 : // Locals
13261 : // SUBROUTINE ARGUMENT DEFINITIONS:
13262 : // na
13263 :
13264 : // SUBROUTINE PARAMETER DEFINITIONS:
13265 : // na
13266 :
13267 : // INTERFACE BLOCK SPECIFICATIONS
13268 : // na
13269 :
13270 : // DERIVED TYPE DEFINITIONS
13271 : // na
13272 :
13273 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13274 : int i;
13275 : int m;
13276 : int n;
13277 : int ITER;
13278 :
13279 : // Formats
13280 :
13281 : // static ObjexxFCL::gio::Fmt Format_900("(,/,11X,'i n m DP',12x,'F1',12X,'F2')");
13282 : // static ObjexxFCL::gio::Fmt Format_901("(1X,A6,3I5,3F14.6)");
13283 : // static ObjexxFCL::gio::Fmt Format_902("(,/,11X,'n P',12x,'sumF')");
13284 : // static ObjexxFCL::gio::Fmt Format_903("(1X,A6,I5,3F14.6)");
13285 : // static ObjexxFCL::gio::Fmt Format_907("(,/,' CPU seconds for ',A,F12.3)");
13286 :
13287 16873 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13288 16873 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13289 :
13290 : // Initialize pressure for pressure control and for Initialization Type = LinearInitializationMethod
13291 16873 : if ((simulation_control.InitFlag == 0) || (PressureSetFlag > 0 && AirflowNetworkFanActivated)) {
13292 333 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13293 324 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) PZ(n) = 0.0;
13294 : }
13295 : }
13296 : // Compute zone air properties.
13297 509205 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13298 984664 : node_states[n].density =
13299 492332 : properties.density(m_state.dataEnvrn->StdBaroPress + PZ(n), node_states[n].temperature, node_states[n].humidity_ratio);
13300 : // RHOZ(n) = PsyRhoAirFnPbTdbW(StdBaroPress + PZ(n), TZ(n), WZ(n));
13301 492332 : if (AirflowNetworkNodeData(n).ExtNodeNum > 0) {
13302 573162 : node_states[n].density =
13303 286581 : properties.density(m_state.dataEnvrn->StdBaroPress + PZ(n), m_state.dataEnvrn->OutDryBulbTemp, m_state.dataEnvrn->OutHumRat);
13304 286581 : node_states[n].temperature = m_state.dataEnvrn->OutDryBulbTemp;
13305 286581 : node_states[n].humidity_ratio = m_state.dataEnvrn->OutHumRat;
13306 : }
13307 492332 : node_states[n].sqrt_density = std::sqrt(node_states[n].density);
13308 492332 : node_states[n].viscosity = 1.71432e-5 + 4.828e-8 * node_states[n].temperature;
13309 : // if (LIST >= 2) ObjexxFCL::gio::write(outputFile, Format_903) << "D,V:" << n << properties[n].density << properties[n].viscosity;
13310 : }
13311 : // Compute stack pressures.
13312 547896 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13313 531023 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13314 531023 : m = AirflowNetworkLinkageData(i).NodeNums[1];
13315 531023 : if (AFLOW(i) > 0.0) {
13316 0 : PS(i) = 9.80 * (node_states[n].density * (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13317 0 : m_state.afn->AirflowNetworkLinkageData(i).NodeHeights[1] * (node_states[m].density - node_states[n].density));
13318 531023 : } else if (AFLOW(i) < 0.0) {
13319 0 : PS(i) = 9.80 * (node_states[m].density * (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13320 0 : AirflowNetworkLinkageData(i).NodeHeights[0] * (node_states[m].density - node_states[n].density));
13321 : } else {
13322 1062046 : PS(i) = 4.90 * ((node_states[n].density + node_states[m].density) *
13323 531023 : (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13324 531023 : (AirflowNetworkLinkageData(i).NodeHeights[0] + AirflowNetworkLinkageData(i).NodeHeights[1]) *
13325 531023 : (node_states[m].density - node_states[n].density));
13326 : }
13327 : }
13328 :
13329 : // Calculate pressure field in a large opening
13330 16873 : dos.pstack(m_state, node_states, PZ);
13331 16873 : solvzp(ITER);
13332 :
13333 : // Report element flows and zone pressures.
13334 509205 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13335 492332 : SUMAF(n) = 0.0;
13336 : }
13337 : // if (LIST >= 1) ObjexxFCL::gio::write(outputFile, Format_900);
13338 547896 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13339 531023 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13340 531023 : m = AirflowNetworkLinkageData(i).NodeNums[1];
13341 : // if (LIST >= 1) {
13342 : // gio::write(outputFile, Format_901) << "Flow: " << i << n << m << AirflowNetworkLinkSimu(i).DP << AFLOW(i) << AFLOW2(i);
13343 : //}
13344 531023 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
13345 0 : SUMAF(n) = SUMAF(n) - AFLOW(i);
13346 0 : SUMAF(m) += AFLOW(i);
13347 : } else {
13348 531023 : SUMAF(n) = SUMAF(n) - AFLOW(i) - AFLOW2(i);
13349 531023 : SUMAF(m) += AFLOW(i) + AFLOW2(i);
13350 : }
13351 : }
13352 : // for (n = 1; n <= NetworkNumOfNodes; ++n) {
13353 : // if (LIST >= 1) gio::write(outputFile, Format_903) << "Room: " << n << PZ(n) << SUMAF(n) << properties[n].temperature;
13354 : //}
13355 :
13356 547896 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13357 531023 : if (AFLOW2(i) != 0.0) {
13358 : }
13359 531023 : if (AFLOW(i) > 0.0) {
13360 366378 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i);
13361 366378 : AirflowNetworkLinkSimu(i).FLOW2 = 0.0;
13362 : } else {
13363 164645 : AirflowNetworkLinkSimu(i).FLOW = 0.0;
13364 164645 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i);
13365 : }
13366 531023 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
13367 0 : if (AFLOW(i) > 0.0) {
13368 0 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i) + AFLOW2(i);
13369 0 : AirflowNetworkLinkSimu(i).FLOW2 = AFLOW2(i);
13370 : } else {
13371 0 : AirflowNetworkLinkSimu(i).FLOW = AFLOW2(i);
13372 0 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i) + AFLOW2(i);
13373 : }
13374 : }
13375 531023 : if (AirflowNetworkLinkageData(i).DetOpenNum > 0) {
13376 2 : if (AFLOW2(i) != 0.0) {
13377 2 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i) + AFLOW2(i);
13378 2 : AirflowNetworkLinkSimu(i).FLOW2 = AFLOW2(i);
13379 : }
13380 : }
13381 531023 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SOP && AFLOW2(i) != 0.0) {
13382 0 : if (AFLOW(i) >= 0.0) {
13383 0 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i);
13384 0 : AirflowNetworkLinkSimu(i).FLOW2 = std::abs(AFLOW2(i));
13385 : } else {
13386 0 : AirflowNetworkLinkSimu(i).FLOW = std::abs(AFLOW2(i));
13387 0 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i);
13388 : }
13389 : }
13390 : }
13391 :
13392 509205 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13393 492332 : AirflowNetworkNodeSimu(i).PZ = PZ(i);
13394 : }
13395 16873 : }
13396 :
13397 16873 : void Solver::solvzp(int &ITER) // number of iterations
13398 : {
13399 :
13400 : // SUBROUTINE INFORMATION:
13401 : // AUTHOR George Walton
13402 : // DATE WRITTEN Extracted from AIRNET
13403 : // MODIFIED Lixing Gu, 2/1/04
13404 : // Revised the subroutine to meet E+ needs
13405 : // MODIFIED Lixing Gu, 6/8/05
13406 : // RE-ENGINEERED na
13407 :
13408 : // PURPOSE OF THIS SUBROUTINE:
13409 : // This subroutine solves zone pressures by modified Newton-Raphson iteration
13410 :
13411 : // METHODOLOGY EMPLOYED:
13412 : // na
13413 :
13414 : // REFERENCES:
13415 : // na
13416 :
13417 16873 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13418 : // auto &NetworkNumOfLinks = ActualNumOfLinks;
13419 :
13420 : // Argument array dimensioning (these used to be arguments, need to also test newAU and newIK)
13421 16873 : EP_SIZE_CHECK(IK, NetworkNumOfNodes + 1);
13422 16873 : EP_SIZE_CHECK(AD, NetworkNumOfNodes);
13423 16873 : EP_SIZE_CHECK(AU, IK(NetworkNumOfNodes + 1));
13424 :
13425 : // Locals
13426 : // SUBROUTINE ARGUMENT DEFINITIONS:
13427 : // noel GNU says AU is being indexed beyound bounds
13428 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
13429 :
13430 : // SUBROUTINE PARAMETER DEFINITIONS:
13431 :
13432 : // INTERFACE BLOCK SPECIFICATIONS
13433 : // na
13434 :
13435 : // DERIVED TYPE DEFINITIONS
13436 : // na
13437 :
13438 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13439 :
13440 : // NNZE - number of nonzero entries in the "AU" array.
13441 : // LFLAG - if = 1, use laminar relationship (initialization).
13442 : // I - element number.
13443 : // N - number of node/zone 1.
13444 : // M - number of node/zone 2.
13445 : // F - flows through the element (kg/s).
13446 : // DF - partial derivatives: DF/DP.
13447 : // NF - number of flows, 1 or 2.
13448 : // SUMF - sum of flows into node/zone.
13449 : // CCF - current pressure correction (Pa).
13450 : // PCF - previous pressure correction (Pa).
13451 : // CEF - convergence enhancement factor.
13452 : int n;
13453 : int NNZE;
13454 : int NSYM;
13455 : bool LFLAG;
13456 : int CONVG;
13457 : int ACCEL;
13458 16873 : Array1D<Real64> PCF(NetworkNumOfNodes);
13459 16873 : Array1D<Real64> CEF(NetworkNumOfNodes);
13460 : Real64 C;
13461 : Real64 SSUMF;
13462 : Real64 SSUMAF;
13463 : Real64 ACC0;
13464 : Real64 ACC1;
13465 16873 : Array1D<Real64> CCF(NetworkNumOfNodes);
13466 :
13467 : // auto &outputFile = std::cout;
13468 :
13469 16873 : ACC1 = 0.0;
13470 16873 : ACCEL = 0;
13471 16873 : NSYM = 0;
13472 16873 : NNZE = IK(NetworkNumOfNodes + 1) - 1;
13473 : // if (LIST >= 2) print(outputFile, "Initialization{:16}{:16}{:16}\n", NetworkNumOfNodes, NetworkNumOfLinks, NNZE);
13474 16873 : ITER = 0;
13475 :
13476 509205 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13477 492332 : PCF(n) = 0.0;
13478 492332 : CEF(n) = 0.0;
13479 : }
13480 :
13481 16873 : if (simulation_control.InitFlag != 1) {
13482 : // Initialize node/zone pressure values by assuming only linear relationship between
13483 : // airflows and pressure drops.
13484 0 : LFLAG = true;
13485 0 : filjac(NNZE, LFLAG);
13486 0 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13487 0 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) PZ(n) = SUMF(n);
13488 : }
13489 : // Data dump.
13490 : // if (LIST >= 3) {
13491 : // DUMPVD("AD:", AD, NetworkNumOfNodes, outputFile);
13492 : // DUMPVD("AU:", AU, NNZE, outputFile);
13493 : // DUMPVR("AF:", SUMF, NetworkNumOfNodes, outputFile);
13494 : // }
13495 : // Solve linear system for approximate PZ.
13496 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13497 0 : facsky(newAU, AD, newAU, newIK, NetworkNumOfNodes, NSYM); // noel
13498 0 : slvsky(newAU, AD, newAU, PZ, newIK, NetworkNumOfNodes, NSYM); // noel
13499 : #else
13500 : facsky(AU, AD, AU, IK, NetworkNumOfNodes, NSYM);
13501 : slvsky(AU, AD, AU, PZ, IK, NetworkNumOfNodes, NSYM);
13502 : #endif
13503 : // if (LIST >= 2) DUMPVD("PZ:", PZ, NetworkNumOfNodes, outputFile);
13504 : }
13505 : // Solve nonlinear airflow network equations by modified Newton's method.
13506 196676 : while (ITER < simulation_control.maximum_iterations) {
13507 196676 : LFLAG = false;
13508 196676 : ++ITER;
13509 : // if (LIST >= 2) {
13510 : // print(outputFile, "Begin iteration {}\n", ITER);
13511 : // }
13512 : // Set up the Jacobian matrix.
13513 196676 : filjac(NNZE, LFLAG);
13514 : // Data dump.
13515 : // if (LIST >= 3) {
13516 : // DUMPVR("SUMF:", SUMF, NetworkNumOfNodes, outputFile);
13517 : // DUMPVR("SUMAF:", SUMAF, NetworkNumOfNodes, outputFile);
13518 : // }
13519 : // Check convergence.
13520 196676 : CONVG = 1;
13521 196676 : SSUMF = 0.0;
13522 196676 : SSUMAF = 0.0;
13523 6417520 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13524 6220844 : SSUMF += std::abs(SUMF(n));
13525 6220844 : SSUMAF += SUMAF(n);
13526 6220844 : if (CONVG == 1) {
13527 2795876 : if (std::abs(SUMF(n)) <= simulation_control.absolute_convergence_tolerance) continue;
13528 262023 : if (std::abs(SUMF(n) / SUMAF(n)) > simulation_control.relative_convergence_tolerance) CONVG = 0;
13529 : }
13530 : }
13531 196676 : ACC0 = ACC1;
13532 196676 : if (SSUMAF > 0.0) ACC1 = SSUMF / SSUMAF;
13533 196676 : if (CONVG == 1 && ITER > 1) return;
13534 179803 : if (ITER >= simulation_control.maximum_iterations) break;
13535 : // Data dump.
13536 : // if (LIST >= 3) {
13537 : // DUMPVD("AD:", AD, NetworkNumOfNodes, outputFile);
13538 : // DUMPVD("AU:", AU, NNZE, outputFile);
13539 : // }
13540 : // Solve AA * CCF = SUMF.
13541 5908315 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13542 5728512 : CCF(n) = SUMF(n);
13543 : }
13544 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13545 179803 : facsky(newAU, AD, newAU, newIK, NetworkNumOfNodes, NSYM); // noel
13546 179803 : slvsky(newAU, AD, newAU, CCF, newIK, NetworkNumOfNodes, NSYM); // noel
13547 : #else
13548 : facsky(AU, AD, AU, IK, NetworkNumOfNodes, NSYM);
13549 : slvsky(AU, AD, AU, CCF, IK, NetworkNumOfNodes, NSYM);
13550 : #endif
13551 : // Revise PZ (Steffensen iteration on the N-R correction factors to handle oscillating corrections).
13552 179803 : if (ACCEL == 1) {
13553 61529 : ACCEL = 0;
13554 : } else {
13555 118274 : if (ITER > 2 && ACC1 > 0.5 * ACC0) ACCEL = 1;
13556 : }
13557 5908315 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13558 5728512 : if (AirflowNetworkNodeData(n).NodeTypeNum == 1) continue;
13559 2673889 : CEF(n) = 1.0;
13560 2673889 : if (ACCEL == 1) {
13561 985263 : C = CCF(n) / PCF(n);
13562 985263 : if (C < simulation_control.convergence_acceleration_limit) CEF(n) = 1.0 / (1.0 - C);
13563 985263 : C = CCF(n) * CEF(n);
13564 : } else {
13565 : // IF (CCF(N) .EQ. 0.0d0) CCF(N)=TINY(CCF(N)) ! 1.0E-40
13566 1688626 : if (CCF(n) == 0.0) CCF(n) = Constant::rTinyValue; // 1.0E-40 (Epsilon)
13567 1688626 : PCF(n) = CCF(n);
13568 1688626 : C = CCF(n);
13569 : }
13570 2673889 : if (std::abs(C) > simulation_control.MaxPressure) {
13571 0 : CEF(n) *= simulation_control.MaxPressure / std::abs(C);
13572 0 : PZ(n) -= CCF(n) * CEF(n);
13573 : } else {
13574 2673889 : PZ(n) -= C;
13575 : }
13576 : }
13577 : // Data revision dump.
13578 : // if (LIST >= 2) {
13579 : // for (n = 1; n <= NetworkNumOfNodes; ++n) {
13580 : // if (state.afn->AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13581 : // print(outputFile, "Rev: {:5}{:3}{:14.6E} {:8.4F}{:24.14F}", n, SUMF(n), CCF(n), CEF(n), PZ(n));
13582 : // }
13583 : // }
13584 : // }
13585 : }
13586 :
13587 : // Error termination.
13588 0 : ShowSevereError(m_state, "Too many iterations (SOLVZP) in Airflow Network simulation");
13589 0 : ++ExtLargeOpeningErrCount;
13590 0 : if (ExtLargeOpeningErrCount < 2) {
13591 0 : ShowWarningError(m_state,
13592 : "AirflowNetwork: SOLVER, Changing values for initialization flag, Relative airflow convergence, Absolute airflow "
13593 : "convergence, Convergence acceleration limit or Maximum Iteration Number may solve the problem.");
13594 0 : ShowContinueErrorTimeStamp(m_state, "");
13595 0 : ShowContinueError(m_state,
13596 0 : "..Iterations=" + std::to_string(ITER) + ", Max allowed=" + std::to_string(simulation_control.maximum_iterations));
13597 0 : ShowFatalError(m_state, "AirflowNetwork: SOLVER, The previous error causes termination.");
13598 : } else {
13599 0 : ShowRecurringWarningErrorAtEnd(
13600 0 : m_state, "AirFlowNetwork: Too many iterations (SOLVZP) in AirflowNetwork simulation continues.", ExtLargeOpeningErrIndex);
13601 : }
13602 50619 : }
13603 :
13604 196676 : void Solver::filjac(int const NNZE, // number of nonzero entries in the "AU" array.
13605 : bool const LFLAG // if = 1, use laminar relationship (initialization).
13606 : )
13607 : {
13608 :
13609 : // SUBROUTINE INFORMATION:
13610 : // AUTHOR George Walton
13611 : // DATE WRITTEN Extracted from AIRNET
13612 : // MODIFIED Lixing Gu, 2/1/04
13613 : // Revised the subroutine to meet E+ needs
13614 : // MODIFIED Lixing Gu, 6/8/05
13615 : // RE-ENGINEERED na
13616 :
13617 : // PURPOSE OF THIS SUBROUTINE:
13618 : // This subroutine creates matrices for solution of flows
13619 :
13620 : // METHODOLOGY EMPLOYED:
13621 : // na
13622 :
13623 : // REFERENCES:
13624 : // na
13625 :
13626 : // USE STATEMENTS:
13627 : // na
13628 :
13629 : // Locals
13630 : // SUBROUTINE ARGUMENT DEFINITIONS:
13631 :
13632 : // SUBROUTINE PARAMETER DEFINITIONS:
13633 : // na
13634 :
13635 : // INTERFACE BLOCK SPECIFICATIONS
13636 : // na
13637 :
13638 : // DERIVED TYPE DEFINITIONS
13639 : // na
13640 :
13641 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13642 :
13643 : // I - component number.
13644 : // N - number of node/zone 1.
13645 : // M - number of node/zone 2.
13646 : // F - flows through the element (kg/s).
13647 : // DF - partial derivatives: DF/DP.
13648 : // NF - number of flows, 1 or 2.
13649 : int i;
13650 : int j;
13651 : int n;
13652 : int FLAG;
13653 : int NF;
13654 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13655 : int LHK; // noel
13656 : int JHK;
13657 : int JHK1;
13658 : int newsum;
13659 : int newh;
13660 : int ispan;
13661 : int thisIK;
13662 : bool allZero; // noel
13663 : #endif
13664 196676 : Array1D<Real64> X(4);
13665 : Real64 DP;
13666 196676 : std::array<Real64, 2> F{{0.0, 0.0}};
13667 196676 : std::array<Real64, 2> DF{{0.0, 0.0}};
13668 :
13669 196676 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13670 196676 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13671 :
13672 6417520 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13673 6220844 : SUMF(n) = 0.0;
13674 6220844 : SUMAF(n) = 0.0;
13675 6220844 : if (AirflowNetworkNodeData(n).NodeTypeNum == 1) {
13676 3341204 : AD(n) = 1.0;
13677 : } else {
13678 2879640 : AD(n) = 0.0;
13679 : }
13680 : }
13681 56392737 : for (n = 1; n <= NNZE; ++n) {
13682 56196061 : AU(n) = 0.0;
13683 : }
13684 : // Loop(s) to calculate control, etc.
13685 : // Set up the Jacobian matrix.
13686 7040245 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13687 6843569 : if (AirflowNetworkLinkageData(i).element == nullptr) {
13688 0 : continue;
13689 : }
13690 6843569 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13691 6843569 : int m = AirflowNetworkLinkageData(i).NodeNums[1];
13692 : //!!! Check array of DP. DpL is used for multizone air flow calculation only
13693 : //!!! and is not for forced air calculation
13694 6843569 : if (i > NumOfLinksMultiZone) {
13695 3107535 : DP = PZ(n) - PZ(m) + PS(i) + PW(i);
13696 : } else {
13697 3736034 : DP = PZ(n) - PZ(m) + dos.DpL(i, 1) + PW(i);
13698 : }
13699 6843569 : Real64 multiplier = 1.0;
13700 6843569 : Real64 control = AirflowNetworkLinkageData(i).control;
13701 : // if (LIST >= 4) ObjexxFCL::gio::write(outputFile, Format_901) << "PS:" << i << n << M << PS(i) << PW(i) << AirflowNetworkLinkSimu(i).DP;
13702 6843569 : j = AirflowNetworkLinkageData(i).CompNum;
13703 :
13704 6843569 : NF = AirflowNetworkLinkageData(i).element->calculate(m_state, LFLAG, DP, i, multiplier, control, node_states[n], node_states[m], F, DF);
13705 6843569 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::CPD && DP != 0.0) {
13706 120 : DP = DisSysCompCPDData(AirflowNetworkCompData(j).TypeNum).DP;
13707 : }
13708 :
13709 6843569 : AirflowNetworkLinkSimu(i).DP = DP;
13710 6843569 : AFLOW(i) = F[0];
13711 6843569 : AFLOW2(i) = 0.0;
13712 6843569 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DOP) {
13713 14 : AFLOW2(i) = F[1];
13714 : }
13715 : // if (LIST >= 3) ObjexxFCL::gio::write(outputFile, Format_901) << " NRi:" << i << n << M << AirflowNetworkLinkSimu(i).DP << F[0] <<
13716 : // DF[0];
13717 6843569 : FLAG = 1;
13718 6843569 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13719 6843397 : ++FLAG;
13720 6843397 : X(1) = DF[0];
13721 6843397 : X(2) = -DF[0];
13722 6843397 : SUMF(n) += F[0];
13723 6843397 : SUMAF(n) += std::abs(F[0]);
13724 : }
13725 6843569 : if (AirflowNetworkNodeData(m).NodeTypeNum == 0) {
13726 3501101 : FLAG += 2;
13727 3501101 : X(4) = DF[0];
13728 3501101 : X(3) = -DF[0];
13729 3501101 : SUMF(m) -= F[0];
13730 3501101 : SUMAF(m) += std::abs(F[0]);
13731 : }
13732 6843569 : if (FLAG != 1) filsky(X, AirflowNetworkLinkageData(i).NodeNums, IK, AU, AD, FLAG);
13733 6843569 : if (NF == 1) continue;
13734 0 : AFLOW2(i) = F[1];
13735 : // if (LIST >= 3) ObjexxFCL::gio::write(outputFile, Format_901) << " NRj:" << i << n << m << AirflowNetworkLinkSimu(i).DP << F[1] <<
13736 : // DF[1];
13737 0 : FLAG = 1;
13738 0 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13739 0 : ++FLAG;
13740 0 : X(1) = DF[1];
13741 0 : X(2) = -DF[1];
13742 0 : SUMF(n) += F[1];
13743 0 : SUMAF(n) += std::abs(F[1]);
13744 : }
13745 0 : if (AirflowNetworkNodeData(m).NodeTypeNum == 0) {
13746 0 : FLAG += 2;
13747 0 : X(4) = DF[1];
13748 0 : X(3) = -DF[1];
13749 0 : SUMF(m) -= F[1];
13750 0 : SUMAF(m) += std::abs(F[1]);
13751 : }
13752 0 : if (FLAG != 1) filsky(X, AirflowNetworkLinkageData(i).NodeNums, IK, AU, AD, FLAG);
13753 : }
13754 :
13755 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13756 :
13757 : // After the matrix values have been set, we can look at them and see if any columns are filled with zeros.
13758 : // If they are, let's remove them from the matrix -- but only for the purposes of doing the solve.
13759 : // They way I do this is building a separate IK array (newIK) that simply changes the column heights.
13760 : // So the affected SOLVEs would use this newIK and nothing else changes.
13761 6614196 : for (n = 1; n <= NetworkNumOfNodes + 1; ++n) {
13762 6417520 : newIK(n) = IK(n);
13763 : // print*, " NetworkNumOfNodes n=", n, " IK(n)=", IK(n)
13764 : }
13765 :
13766 196676 : newsum = IK(2) - IK(1); // always 0?
13767 :
13768 196676 : JHK = 1;
13769 6220844 : for (n = 2; n <= NetworkNumOfNodes; ++n) {
13770 6024168 : JHK1 = IK(n + 1); // starts at IK(3)-IK(2)
13771 6024168 : LHK = JHK1 - JHK;
13772 6024168 : if (LHK <= 0) {
13773 163441 : newIK(n + 1) = newIK(n);
13774 163441 : continue;
13775 : }
13776 : // write(*,'(4(a,i8))') "n=", n, " ik=", ik(n), " JHK=", JHK, " LHK=", LHK
13777 :
13778 : // is the entire column zero? noel
13779 5860727 : allZero = true;
13780 39431122 : for (i = 0; i <= LHK - 1; ++i) {
13781 35926509 : if (AU(JHK + i) != 0.0) {
13782 2356114 : allZero = false;
13783 2356114 : break;
13784 : }
13785 : }
13786 :
13787 5860727 : newh = LHK;
13788 5860727 : if (allZero) {
13789 : // print*, "allzero n=", n
13790 3504613 : newh = 0;
13791 : } else {
13792 : // DO i=0,LHK-1
13793 : // write(*, '(2(a,i8),a, f15.3)') " n=", n, " i=", i, " AU(JHK+i)=", AU(JHK+i)
13794 : // enddo
13795 : }
13796 5860727 : newIK(n + 1) = newIK(n) + newh;
13797 5860727 : newsum += newh;
13798 :
13799 : // do i = LHK-1,0, -1
13800 : // write(*, '(2(a,i8),a, f15.3)') " n=", n, " i=", i, " AU(JHK+i)=", AU(JHK+i)
13801 : // enddo
13802 5860727 : JHK = JHK1;
13803 : }
13804 :
13805 : // this is just a print to screen, is not necessary
13806 : // if (firstTime) then
13807 : // write(*, '(2(a,i8))') " After SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS: newsum=", newsum, " oldsum=", IK(NetworkNumOfNodes+1)
13808 : // firstTime=.FALSE.
13809 : // endif
13810 :
13811 : // Now fill newAU from AU, using newIK
13812 6220844 : for (n = 2; n <= NetworkNumOfNodes; ++n) {
13813 6024168 : thisIK = newIK(n);
13814 6024168 : ispan = newIK(n + 1) - thisIK;
13815 :
13816 6024168 : if (ispan <= 0) continue;
13817 24981780 : for (i = 0; i <= ispan - 1; ++i) {
13818 22625666 : newAU(thisIK + i) = AU(IK(n) + i);
13819 : }
13820 : }
13821 : #endif
13822 196676 : }
13823 :
13824 179803 : void Solver::facsky(Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
13825 : Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
13826 : Array1D<Real64> &AL, // the lower triangle of [A] before and after factoring
13827 : const Array1D_int &IK, // pointer to the top of column/row "K"
13828 : int const NEQ, // number of equations
13829 : int const NSYM // symmetry: 0 = symmetric matrix, 1 = non-symmetric
13830 : )
13831 : {
13832 :
13833 : // SUBROUTINE INFORMATION:
13834 : // AUTHOR George Walton
13835 : // DATE WRITTEN Extracted from AIRNET
13836 : // MODIFIED Lixing Gu, 2/1/04
13837 : // Revised the subroutine to meet E+ needs
13838 : // MODIFIED Lixing Gu, 6/8/05
13839 : // RE-ENGINEERED This subroutine is revised from FACSKY developed by George Walton, NIST
13840 :
13841 : // PURPOSE OF THIS SUBROUTINE:
13842 : // This subroutine performs L-U factorization of a skyline ordered matrix, [A]
13843 : // The algorithm has been restructured for clarity.
13844 : // Note dependence on compiler for optimizing the inner do loops.
13845 :
13846 : // METHODOLOGY EMPLOYED:
13847 : // L-U factorization of a skyline ordered matrix, [A], used for
13848 : // solution of simultaneous linear algebraic equations [A] * X = B.
13849 : // No pivoting! No scaling! No warnings!!!
13850 : // Related routines: SLVSKY, SETSKY, FILSKY.
13851 :
13852 : // REFERENCES:
13853 : // Algorithm is described in "The Finite Element Method Displayed",
13854 : // by G. Dhatt and G. Touzot, John Wiley & Sons, New York, 1984.
13855 :
13856 : // USE STATEMENTS:
13857 : // na
13858 :
13859 : // Argument array dimensioning
13860 179803 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
13861 179803 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
13862 179803 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
13863 179803 : EP_SIZE_CHECK(AL, IK(ActualNumOfNodes + 1) - 1);
13864 :
13865 : // Locals
13866 : // SUBROUTINE ARGUMENT DEFINITIONS:
13867 : // noel, GNU says the AU is indexed above its upper bound
13868 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
13869 :
13870 : // SUBROUTINE PARAMETER DEFINITIONS:
13871 : // na
13872 :
13873 : // INTERFACE BLOCK SPECIFICATIONS
13874 : // na
13875 :
13876 : // DERIVED TYPE DEFINITIONS
13877 : // na
13878 :
13879 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13880 : int JHK;
13881 : int LHK1;
13882 : int IMIN;
13883 : int IMIN1;
13884 : int JHJ;
13885 : int JHJ1;
13886 : int IC;
13887 : int i;
13888 : int j;
13889 : int k;
13890 : Real64 T1;
13891 : Real64 T2;
13892 : Real64 SDOT;
13893 : Real64 SUMD;
13894 :
13895 179803 : AD(1) = 1.0 / AD(1);
13896 179803 : JHK = 1;
13897 5728512 : for (k = 2; k <= NEQ; ++k) {
13898 5548709 : SUMD = 0.0;
13899 5548709 : int JHK1 = IK(k + 1);
13900 5548709 : int LHK = JHK1 - JHK;
13901 5548709 : if (LHK > 0) {
13902 2189376 : LHK1 = LHK - 1;
13903 2189376 : IMIN = k - LHK1;
13904 2189376 : IMIN1 = IMIN - 1;
13905 2189376 : if (NSYM == 1) AL(JHK) *= AD(IMIN1);
13906 2189376 : if (LHK1 != 0) {
13907 1067601 : JHJ = IK(IMIN);
13908 1067601 : if (NSYM == 0) {
13909 19963949 : for (j = 1; j <= LHK1; ++j) {
13910 18896348 : JHJ1 = IK(IMIN + j);
13911 18896348 : IC = min(j, JHJ1 - JHJ);
13912 18896348 : if (IC > 0) {
13913 5039385 : SDOT = 0.0;
13914 44555044 : for (i = 0; i <= IC - 1; ++i) {
13915 39515659 : SDOT += AU(JHJ1 - IC + i) * AU(JHK + j - IC + i);
13916 : }
13917 5039385 : AU(JHK + j) -= SDOT;
13918 : }
13919 18896348 : JHJ = JHJ1;
13920 : }
13921 : } else {
13922 0 : for (j = 1; j <= LHK1; ++j) {
13923 0 : JHJ1 = IK(IMIN + j);
13924 0 : IC = min(j, JHJ1 - JHJ);
13925 0 : SDOT = 0.0;
13926 0 : if (IC > 0) {
13927 0 : for (i = 0; i <= IC - 1; ++i) {
13928 0 : SDOT += AL(JHJ1 - IC + i) * AU(JHK + j - IC + i);
13929 : }
13930 0 : AU(JHK + j) -= SDOT;
13931 0 : SDOT = 0.0;
13932 0 : for (i = 0; i <= IC - 1; ++i) {
13933 0 : SDOT += AU(JHJ1 - IC + i) * AL(JHK + j - IC + i);
13934 : }
13935 : }
13936 0 : AL(JHK + j) = (AL(JHK + j) - SDOT) * AD(IMIN1 + j);
13937 0 : JHJ = JHJ1;
13938 : }
13939 : }
13940 : }
13941 2189376 : if (NSYM == 0) {
13942 23275100 : for (i = 0; i <= LHK1; ++i) {
13943 21085724 : T1 = AU(JHK + i);
13944 21085724 : T2 = T1 * AD(IMIN1 + i);
13945 21085724 : AU(JHK + i) = T2;
13946 21085724 : SUMD += T1 * T2;
13947 : }
13948 : } else {
13949 0 : for (i = 0; i <= LHK1; ++i) {
13950 0 : SUMD += AU(JHK + i) * AL(JHK + i);
13951 : }
13952 : }
13953 : }
13954 5548709 : if (AD(k) - SUMD == 0.0) {
13955 0 : ShowSevereError(m_state, "AirflowNetworkSolver: L-U factorization in Subroutine FACSKY.");
13956 0 : ShowContinueError(
13957 : m_state,
13958 0 : "The denominator used in L-U factorizationis equal to 0.0 at node = " + m_state.afn->AirflowNetworkNodeData(k).Name + '.');
13959 0 : ShowContinueError(
13960 : m_state, "One possible cause is that this node may not be connected directly, or indirectly via airflow network connections ");
13961 0 : ShowContinueError(
13962 : m_state, "(e.g., AirflowNetwork:Multizone:SurfaceCrack, AirflowNetwork:Multizone:Component:SimpleOpening, etc.), to an external");
13963 0 : ShowContinueError(m_state, "node (AirflowNetwork:MultiZone:Surface).");
13964 0 : ShowContinueError(m_state,
13965 : "Please send your input file and weather file to EnergyPlus support/development team for further investigation.");
13966 0 : ShowFatalError(m_state, "Preceding condition causes termination.");
13967 : }
13968 5548709 : AD(k) = 1.0 / (AD(k) - SUMD);
13969 5548709 : JHK = JHK1;
13970 : }
13971 179803 : }
13972 :
13973 179803 : void Solver::slvsky(const Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
13974 : const Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
13975 : const Array1D<Real64> &AL, // the lower triangle of [A] before and after factoring
13976 : Array1D<Real64> &B, // "B" vector (input); "X" vector (output).
13977 : const Array1D_int &IK, // pointer to the top of column/row "K"
13978 : int const NEQ, // number of equations
13979 : int const NSYM // symmetry: 0 = symmetric matrix, 1 = non-symmetric
13980 : )
13981 : {
13982 :
13983 : // SUBROUTINE INFORMATION:
13984 : // AUTHOR George Walton
13985 : // DATE WRITTEN Extracted from AIRNET
13986 : // MODIFIED Lixing Gu, 2/1/04
13987 : // Revised the subroutine to meet E+ needs
13988 : // MODIFIED Lixing Gu, 6/8/05
13989 : // RE-ENGINEERED This subroutine is revised from CLVSKY developed by George Walton, NIST
13990 :
13991 : // PURPOSE OF THIS SUBROUTINE:
13992 : // This subroutine solves simultaneous linear algebraic equations [A] * X = B
13993 : // using L-U factored skyline form of [A] from "FACSKY"
13994 :
13995 : // METHODOLOGY EMPLOYED:
13996 : // na
13997 :
13998 : // REFERENCES:
13999 : // na
14000 :
14001 : // USE STATEMENTS:
14002 : // na
14003 :
14004 : // Argument array dimensioning
14005 179803 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
14006 179803 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
14007 179803 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
14008 179803 : EP_SIZE_CHECK(AL, IK(ActualNumOfNodes + 1) - 1);
14009 179803 : EP_SIZE_CHECK(B, ActualNumOfNodes);
14010 :
14011 : // Locals
14012 : // SUBROUTINE ARGUMENT DEFINITIONS:
14013 : // noel, GNU says the AU is indexed above its upper bound
14014 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
14015 :
14016 : // SUBROUTINE PARAMETER DEFINITIONS:
14017 : // na
14018 :
14019 : // INTERFACE BLOCK SPECIFICATIONS
14020 : // na
14021 :
14022 : // DERIVED TYPE DEFINITIONS
14023 : // na
14024 :
14025 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14026 :
14027 : int i;
14028 : int JHK;
14029 : int JHK1;
14030 : int k;
14031 : Real64 SDOT;
14032 : Real64 T1;
14033 :
14034 179803 : JHK = 1;
14035 5728512 : for (k = 2; k <= NEQ; ++k) {
14036 5548709 : JHK1 = IK(k + 1);
14037 5548709 : int LHK = JHK1 - JHK;
14038 5548709 : if (LHK <= 0) continue;
14039 2189376 : SDOT = 0.0;
14040 2189376 : if (NSYM == 0) {
14041 23275100 : for (i = 0; i <= LHK - 1; ++i) {
14042 21085724 : SDOT += AU(JHK + i) * B(k - LHK + i);
14043 : }
14044 : } else {
14045 0 : for (i = 0; i <= LHK - 1; ++i) {
14046 0 : SDOT += AL(JHK + i) * B(k - LHK + i);
14047 : }
14048 : }
14049 2189376 : B(k) -= SDOT;
14050 2189376 : JHK = JHK1;
14051 : }
14052 179803 : if (NSYM == 0) {
14053 5908315 : for (k = 1; k <= NEQ; ++k) {
14054 5728512 : B(k) *= AD(k);
14055 : }
14056 : }
14057 179803 : k = NEQ + 1;
14058 179803 : JHK1 = IK(k);
14059 5728512 : while (k != 1) {
14060 5728512 : --k;
14061 5728512 : if (NSYM == 1) B(k) *= AD(k);
14062 5728512 : if (k == 1) break;
14063 : // IF(K.EQ.1) RETURN
14064 5548709 : JHK = IK(k);
14065 5548709 : T1 = B(k);
14066 26634433 : for (i = 0; i <= JHK1 - JHK - 1; ++i) {
14067 21085724 : B(k - JHK1 + JHK + i) -= AU(JHK + i) * T1;
14068 : }
14069 5548709 : JHK1 = JHK;
14070 : }
14071 179803 : }
14072 :
14073 6843569 : void Solver::filsky(const Array1D<Real64> &X, // element array (row-wise sequence)
14074 : std::array<int, 2> const LM, // location matrix
14075 : const Array1D_int &IK, // pointer to the top of column/row "K"
14076 : Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
14077 : Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
14078 : int const FLAG // mode of operation
14079 : )
14080 : {
14081 :
14082 : // SUBROUTINE INFORMATION:
14083 : // AUTHOR George Walton
14084 : // DATE WRITTEN Extracted from AIRNET
14085 : // MODIFIED Lixing Gu, 2/1/04
14086 : // Revised the subroutine to meet E+ needs
14087 : // MODIFIED Lixing Gu, 6/8/05
14088 : // RE-ENGINEERED This subroutine is revised from FILSKY developed by George Walton, NIST
14089 :
14090 : // PURPOSE OF THIS SUBROUTINE:
14091 : // This subroutine adds element array "X" to the sparse skyline matrix [A]
14092 :
14093 : // Argument array dimensioning
14094 6843569 : EP_SIZE_CHECK(X, 4);
14095 6843569 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
14096 6843569 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
14097 6843569 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
14098 :
14099 : // SUBROUTINE ARGUMENT DEFINITIONS:
14100 : // noel, GNU says the AU is indexed above its upper bound
14101 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
14102 :
14103 : // K = row number, L = column number.
14104 6843569 : if (FLAG > 1) {
14105 6843569 : int k = LM[0];
14106 6843569 : int L = LM[1];
14107 6843569 : if (FLAG == 4) {
14108 3500929 : AD(k) += X(1);
14109 3500929 : if (k < L) {
14110 2487037 : int j = IK(L + 1) - L + k;
14111 2487037 : AU(j) += X(2);
14112 : } else {
14113 1013892 : int j = IK(k + 1) - k + L;
14114 1013892 : AU(j) += X(3);
14115 : }
14116 3500929 : AD(L) += X(4);
14117 3342640 : } else if (FLAG == 3) {
14118 172 : AD(L) += X(4);
14119 3342468 : } else if (FLAG == 2) {
14120 3342468 : AD(k) += X(1);
14121 : }
14122 : }
14123 6843569 : }
14124 :
14125 : } // namespace AirflowNetwork
14126 :
14127 : } // namespace EnergyPlus
|