Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #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 : using ScheduleManager::GetCurrentScheduleValue;
148 : using ScheduleManager::GetScheduleIndex;
149 :
150 796 : Solver::Solver(EnergyPlusData &state) : m_state(state), properties(state)
151 : {
152 796 : }
153 :
154 : int constexpr NumOfVentCtrTypes(6); // Number of zone level venting control types
155 :
156 541910 : void Solver::manage_balance(ObjexxFCL::Optional_bool_const FirstHVACIteration, // True when solution technique on first iteration
157 : ObjexxFCL::Optional_int_const Iter, // Iteration number
158 : ObjexxFCL::Optional_bool ResimulateAirZone // True when solution technique on third iteration
159 : )
160 : {
161 :
162 : // SUBROUTINE INFORMATION:
163 : // AUTHOR Lixing Gu
164 : // DATE WRITTEN July 28, 2005
165 :
166 : // PURPOSE OF THIS SUBROUTINE:
167 : // This subroutine performs simulation of air distribution system.
168 :
169 : // Locals
170 : int i;
171 541910 : HVAC::FanType AFNSupplyFanType = HVAC::FanType::Invalid;
172 :
173 541910 : if (AirflowNetworkGetInputFlag) {
174 796 : get_input();
175 796 : AirflowNetworkGetInputFlag = false;
176 796 : return;
177 : }
178 :
179 541114 : if (present(ResimulateAirZone)) {
180 255589 : ResimulateAirZone = false;
181 : }
182 :
183 541114 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) return;
184 :
185 541114 : if (m_state.dataGlobal->BeginEnvrnFlag) {
186 2342 : m_state.dataHVACGlobal->TurnFansOn = false; // The FAN should be off when BeginEnvrnFlag = .True.
187 : }
188 :
189 541114 : initialize();
190 :
191 541114 : auto &NetworkNumOfNodes = ActualNumOfNodes;
192 541114 : auto &NetworkNumOfLinks = ActualNumOfLinks;
193 :
194 541114 : NetworkNumOfNodes = NumOfNodesMultiZone;
195 541114 : NetworkNumOfLinks = NumOfLinksMultiZone;
196 :
197 541114 : AirflowNetworkFanActivated = false;
198 :
199 541114 : if (present(FirstHVACIteration) && distribution_simulated) {
200 429676 : if (FirstHVACIteration) {
201 96091 : if (allocated(m_state.dataAirLoop->AirLoopAFNInfo)) {
202 195697 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
203 99625 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopHeatingCoilMaxRTF = 0.0;
204 99625 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopOnOffFanRTF = 0.0;
205 99625 : m_state.dataAirLoop->AirLoopAFNInfo(i).AFNLoopDXCoilRTF = 0.0;
206 99625 : m_state.dataAirLoop->AirLoopAFNInfo(i).LoopOnOffFanPartLoadRatio = 0.0;
207 : }
208 : }
209 : }
210 429676 : Real64 FanMassFlowRate = 0.0;
211 429676 : HVAC::FanOp FanOperModeCyc = HVAC::FanOp::Invalid;
212 429676 : AFNSupplyFanType = HVAC::FanType::Invalid;
213 :
214 655935 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
215 446071 : AFNSupplyFanType = DisSysCompCVFData(i).fanType;
216 446071 : FanMassFlowRate = max(FanMassFlowRate, m_state.dataLoopNodes->Node(DisSysCompCVFData(i).OutletNode).MassFlowRate);
217 : // VAV take high priority
218 446071 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::VAV) {
219 20243 : AFNSupplyFanType = DisSysCompCVFData(i).fanType;
220 20243 : break;
221 : }
222 781124 : if (FanMassFlowRate > HVAC::VerySmallMassFlow &&
223 626217 : m_state.dataAirLoop->AirLoopAFNInfo(i).LoopFanOperationMode == HVAC::FanOp::Cycling &&
224 200389 : m_state.dataAirLoop->AirLoopAFNInfo(i).LoopSystemOnMassFlowrate > 0.0) {
225 199569 : FanOperModeCyc = HVAC::FanOp::Cycling;
226 199569 : AFNSupplyFanType = DisSysCompCVFData(i).fanType;
227 199569 : if (AFNSupplyFanType == HVAC::FanType::OnOff) {
228 199569 : break;
229 : }
230 : }
231 : }
232 : // Revised to meet heat exchanger requirement
233 429676 : if ((FanMassFlowRate > HVAC::VerySmallMassFlow) && (!FirstHVACIteration)) {
234 275203 : if (AFNSupplyFanType == HVAC::FanType::OnOff && FanOperModeCyc == HVAC::FanOp::Cycling) {
235 170864 : AirflowNetworkFanActivated = true;
236 104339 : } else if (AFNSupplyFanType == HVAC::FanType::VAV) {
237 6797 : if (present(Iter) && Iter > 1) AirflowNetworkFanActivated = true;
238 97542 : } else if (AirflowNetworkUnitarySystem) {
239 0 : if (present(Iter) && Iter > 1) AirflowNetworkFanActivated = true;
240 : } else {
241 97542 : AirflowNetworkFanActivated = true;
242 : }
243 : }
244 : }
245 630018 : if (allocated(m_state.dataZoneEquip->ZoneEquipConfig) && m_state.dataAvail->NumHybridVentSysAvailMgrs > 0 &&
246 88904 : allocated(m_state.dataAirSystemsData->PrimaryAirSystems)) {
247 82088 : hybrid_ventilation_control();
248 : }
249 541114 : if (ventCtrlStatus == Avail::VentCtrlStatus::Open && m_state.dataAvail->NumHybridVentSysAvailMgrs > 0) {
250 11775 : AirflowNetworkFanActivated = false;
251 : }
252 :
253 541114 : if (present(Iter) && present(ResimulateAirZone) && distribution_simulated) {
254 223000 : if (AirflowNetworkFanActivated && Iter < 3 && AFNSupplyFanType == HVAC::FanType::OnOff) {
255 98584 : ResimulateAirZone = true;
256 : }
257 223000 : if (AFNSupplyFanType == HVAC::FanType::VAV) {
258 9200 : if (!AirflowNetworkFanActivated && Iter < 3) ResimulateAirZone = true;
259 : }
260 223000 : if (AirflowNetworkUnitarySystem) {
261 0 : if (!AirflowNetworkFanActivated && Iter < 3) ResimulateAirZone = true;
262 : }
263 : }
264 541114 : if (AirflowNetworkFanActivated && distribution_simulated) {
265 270514 : NetworkNumOfNodes = AirflowNetworkNumOfNodes;
266 270514 : NetworkNumOfLinks = AirflowNetworkNumOfLinks;
267 : }
268 :
269 541114 : if (allocated(m_state.dataZoneEquip->ZoneEquipConfig)) validate_exhaust_fan_input();
270 :
271 : // VAV terminal set only
272 541114 : if (present(FirstHVACIteration) && FirstHVACIteration) VAVTerminalRatio = 0.0;
273 :
274 541114 : if (AirflowNetworkFanActivated && distribution_simulated) {
275 270514 : if (ValidateDistributionSystemFlag) {
276 23 : validate_distribution();
277 23 : validate_fan_flowrate();
278 23 : ValidateDistributionSystemFlag = false;
279 23 : if (simulation_control.autosize_ducts) {
280 1 : SizeDucts();
281 : }
282 : }
283 : }
284 541114 : calculate_balance();
285 :
286 541114 : if (AirflowNetworkFanActivated && distribution_simulated) {
287 :
288 270514 : LoopOnOffFlag = false;
289 551546 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
290 281032 : if (DisSysCompCVFData(i).AirLoopNum > 0) {
291 281032 : if (m_state.dataLoopNodes->Node(DisSysCompCVFData(i).InletNode).MassFlowRate > 0.0) {
292 280376 : LoopOnOffFlag(DisSysCompCVFData(i).AirLoopNum) = true;
293 : }
294 : }
295 : }
296 :
297 270514 : calculate_heat_balance();
298 270514 : calculate_moisture_balance();
299 270514 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) calculate_CO2_balance();
300 270514 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) calculate_GC_balance();
301 : }
302 :
303 541114 : update(FirstHVACIteration);
304 : }
305 :
306 35 : bool Solver::get_element_input()
307 : {
308 : // SUBROUTINE INFORMATION:
309 : // AUTHOR Jason DeGraw
310 : // DATE WRITTEN Oct. 2018
311 : // MODIFIED na
312 : // RE-ENGINEERED na
313 :
314 : // PURPOSE OF THIS SUBROUTINE:
315 : // This subroutine reads airflow element inputs (eventually)
316 :
317 : static constexpr std::string_view RoutineName{"get_element_input"};
318 35 : std::string CurrentModuleObject;
319 35 : bool success{true};
320 :
321 : // *** Read AirflowNetwork simulation reference crack conditions
322 35 : std::unordered_map<std::string, ReferenceConditions> referenceConditions; // Map for lookups
323 70 : ReferenceConditions defaultReferenceConditions("Default"); // Defaulted conditions
324 35 : bool conditionsAreDefaulted(true); // Conditions are defaulted?
325 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:ReferenceCrackConditions";
326 35 : auto instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
327 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
328 : // globalSolverObject.referenceConditions.clear();
329 32 : auto &instancesValue = instances.value();
330 64 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
331 32 : auto const &fields = instance.value();
332 32 : auto const &thisObjectName = Util::makeUPPER(instance.key());
333 32 : Real64 temperature(20.0);
334 32 : if (fields.find("reference_temperature") != fields.end()) { // required field, has default value
335 32 : temperature = fields.at("reference_temperature").get<Real64>();
336 : }
337 32 : Real64 pressure(101325.0);
338 32 : if (fields.find("reference_barometric_pressure") != fields.end()) { // not required field, has default value
339 32 : pressure = fields.at("reference_barometric_pressure").get<Real64>();
340 32 : if (std::abs((pressure - m_state.dataEnvrn->StdBaroPress) / m_state.dataEnvrn->StdBaroPress) > 0.1) { // 10% off
341 2 : ShowWarningError(m_state,
342 2 : format("{}: {}: Pressure = {:.0R} differs by more than 10% from Standard Barometric Pressure = {:.0R}.",
343 : RoutineName,
344 : CurrentModuleObject,
345 : pressure,
346 1 : m_state.dataEnvrn->StdBaroPress));
347 1 : ShowContinueError(m_state, "...occurs in " + CurrentModuleObject + " = " + thisObjectName);
348 : }
349 32 : if (pressure <= 31000.0) {
350 0 : ShowSevereError(m_state,
351 0 : format("{}: {}: {}. Reference Barometric Pressure must be greater than 31000 Pa.",
352 : RoutineName,
353 : CurrentModuleObject,
354 : thisObjectName));
355 0 : success = false;
356 : }
357 : }
358 32 : Real64 humidity(0.0);
359 32 : if (fields.find("reference_humidity_ratio") != fields.end()) { // not required field, has default value
360 32 : humidity = fields.at("reference_humidity_ratio").get<Real64>();
361 : }
362 : // globalSolverObject.referenceConditions.emplace_back(thisObjectName, temperature, pressure, humidity);
363 32 : referenceConditions.emplace(std::piecewise_construct,
364 32 : std::forward_as_tuple(thisObjectName),
365 32 : std::forward_as_tuple(instance.key(), temperature, pressure, humidity));
366 64 : }
367 : // Check that there is more than one
368 32 : if (referenceConditions.size() == 1) {
369 64 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
370 64 : referenceConditions.begin()->second.name);
371 32 : defaultReferenceConditions = referenceConditions.begin()->second;
372 :
373 : } else {
374 0 : conditionsAreDefaulted = false;
375 : }
376 : }
377 35 : if (!success) {
378 0 : return false;
379 : }
380 :
381 : // *** Read AirflowNetwork simulation surface crack component
382 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface:Crack";
383 35 : AirflowNetworkNumOfSurCracks =
384 35 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
385 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
386 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
387 32 : int i = 1; // Temporary workaround
388 32 : MultizoneSurfaceCrackData.allocate(AirflowNetworkNumOfSurCracks); // Temporary workaround
389 32 : auto &instancesValue = instances.value();
390 115 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
391 83 : auto const &fields = instance.value();
392 83 : auto const &thisObjectName = Util::makeUPPER(instance.key());
393 83 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
394 :
395 83 : Real64 coeff{fields.at("air_mass_flow_coefficient_at_reference_conditions")}; // Required field
396 83 : Real64 expnt{0.65};
397 83 : if (fields.find("air_mass_flow_exponent") != fields.end()) { // not required field, has default value
398 83 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
399 : }
400 83 : Real64 refT = defaultReferenceConditions.temperature;
401 83 : Real64 refP = defaultReferenceConditions.pressure;
402 83 : Real64 refW = defaultReferenceConditions.humidity_ratio;
403 83 : if (!conditionsAreDefaulted) {
404 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
405 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
406 0 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
407 :
408 0 : if (result == referenceConditions.end()) {
409 0 : ShowSevereError(m_state,
410 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
411 : RoutineName,
412 : CurrentModuleObject,
413 : thisObjectName,
414 : refCrackCondName));
415 0 : success = false;
416 : } else {
417 0 : refT = result->second.temperature;
418 0 : refP = result->second.pressure;
419 0 : refW = result->second.humidity_ratio;
420 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
421 0 : result->second.name);
422 : }
423 0 : }
424 : }
425 : // globalSolverObject.cracks[thisObjectName] = SurfaceCrack(coeff, expnt, refT, refP, refW);
426 83 : MultizoneSurfaceCrackData(i).name = thisObjectName; // Name of surface crack component
427 83 : MultizoneSurfaceCrackData(i).coefficient = coeff; // Air Mass Flow Coefficient
428 83 : MultizoneSurfaceCrackData(i).exponent = expnt; // Air Mass Flow exponent
429 83 : MultizoneSurfaceCrackData(i).reference_density = properties.density(refP, refT, refW);
430 83 : MultizoneSurfaceCrackData(i).reference_viscosity = properties.dynamic_viscosity(refT);
431 :
432 : // This is the first element that is being added to the lookup table, so no check of naming overlaps
433 83 : elements[thisObjectName] = &MultizoneSurfaceCrackData(i); // Yet another workaround
434 :
435 83 : ++i;
436 115 : }
437 : }
438 :
439 : // *** Read AirflowNetwork simulation zone exhaust fan component
440 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:ZoneExhaustFan";
441 35 : AirflowNetworkNumOfExhFan =
442 35 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
443 35 : NumOfExhaustFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "Fan:ZoneExhaust"); // Temporary workaround
444 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
445 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
446 14 : int i = 1; // Temporary workaround
447 14 : MultizoneCompExhaustFanData.allocate(AirflowNetworkNumOfExhFan); // Temporary workaround
448 14 : auto &instancesValue = instances.value();
449 28 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
450 14 : auto const &fields = instance.value();
451 14 : auto const &thisObjectName = Util::makeUPPER(instance.key());
452 :
453 14 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
454 :
455 14 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_the_zone_exhaust_fan_is_off_at_reference_conditions")}; // Required field
456 14 : Real64 expnt{0.65};
457 14 : if (fields.find("air_mass_flow_exponent_when_the_zone_exhaust_fan_is_off") != fields.end()) { // not required field, has default value
458 14 : expnt = fields.at("air_mass_flow_exponent_when_the_zone_exhaust_fan_is_off").get<Real64>();
459 : }
460 :
461 : // This breaks the component model, need to fix
462 14 : int fanIndex = GetFanIndex(m_state, thisObjectName);
463 14 : if (fanIndex == 0) {
464 0 : ShowSevereError(m_state,
465 0 : format("{}: {} = {} is not found in Fan:ZoneExhaust objects.", RoutineName, CurrentModuleObject, thisObjectName));
466 0 : success = false;
467 : }
468 :
469 14 : auto *fan = m_state.dataFans->fans(fanIndex);
470 :
471 14 : Real64 flowRate = fan->maxAirFlowRate;
472 14 : flowRate *= m_state.dataEnvrn->StdRhoAir;
473 14 : bool nodeErrorsFound{false};
474 14 : int inletNode = fan->inletNodeNum;
475 14 : int outletNode = fan->outletNodeNum;
476 14 : if (nodeErrorsFound) {
477 0 : success = false;
478 : }
479 14 : HVAC::FanType fanType = fan->type;
480 14 : if (fanType != HVAC::FanType::Exhaust) {
481 0 : ShowSevereError(m_state,
482 0 : format("{}: {} = {}. The specified Name is not found as a valid Fan:ZoneExhaust object.",
483 : RoutineName,
484 : CurrentModuleObject,
485 : thisObjectName));
486 0 : success = false;
487 : }
488 :
489 14 : Real64 refT = defaultReferenceConditions.temperature;
490 14 : Real64 refP = defaultReferenceConditions.pressure;
491 14 : Real64 refW = defaultReferenceConditions.humidity_ratio;
492 14 : if (!conditionsAreDefaulted) {
493 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
494 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
495 0 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
496 0 : if (result == referenceConditions.end()) {
497 0 : ShowSevereError(m_state,
498 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
499 : RoutineName,
500 : CurrentModuleObject,
501 : thisObjectName,
502 0 : fields.at("reference_crack_conditions").get<std::string>()));
503 0 : success = false;
504 : } else {
505 0 : refT = result->second.temperature;
506 0 : refP = result->second.pressure;
507 0 : refW = result->second.humidity_ratio;
508 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
509 0 : result->second.name);
510 : }
511 0 : }
512 : }
513 :
514 14 : MultizoneCompExhaustFanData(i).name = thisObjectName; // Name of zone exhaust fan component
515 14 : MultizoneCompExhaustFanData(i).FlowCoef = coeff; // flow coefficient
516 14 : MultizoneCompExhaustFanData(i).FlowExpo = expnt; // Flow exponent
517 :
518 14 : MultizoneCompExhaustFanData(i).FlowRate = flowRate;
519 14 : MultizoneCompExhaustFanData(i).InletNode = inletNode;
520 14 : MultizoneCompExhaustFanData(i).OutletNode = outletNode;
521 :
522 14 : MultizoneCompExhaustFanData(i).StandardT = refT;
523 14 : MultizoneCompExhaustFanData(i).StandardP = refP;
524 14 : MultizoneCompExhaustFanData(i).StandardW = refW;
525 :
526 : // Add the element to the lookup table, check for name overlaps
527 14 : if (elements.find(thisObjectName) == elements.end()) {
528 14 : elements[thisObjectName] = &MultizoneCompExhaustFanData(i); // Yet another workaround
529 : } else {
530 0 : ShowSevereError(
531 : m_state,
532 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
533 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
534 0 : success = false;
535 : }
536 :
537 14 : ++i;
538 28 : }
539 : }
540 :
541 : // Read Outdoor Airflow object
542 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:OutdoorAirFlow";
543 35 : NumOfOAFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
544 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
545 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
546 2 : int i = 1; // Temporary workaround
547 2 : DisSysCompOutdoorAirData.allocate(NumOfOAFans); // Temporary workaround
548 2 : auto &instancesValue = instances.value();
549 4 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
550 2 : auto const &fields = instance.value();
551 2 : auto const &thisObjectName = Util::makeUPPER(instance.key());
552 2 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
553 :
554 4 : std::string mixer_name = Util::makeUPPER(fields.at("outdoor_air_mixer_name").get<std::string>());
555 2 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_no_outdoor_air_flow_at_reference_conditions")};
556 2 : Real64 expnt{0.65};
557 2 : if (fields.find("air_mass_flow_exponent_when_no_outdoor_air_flow") != fields.end()) {
558 2 : expnt = fields.at("air_mass_flow_exponent_when_no_outdoor_air_flow").get<Real64>();
559 : }
560 :
561 2 : int OAMixerNum = MixedAir::GetOAMixerNumber(m_state, mixer_name);
562 2 : if (OAMixerNum == 0) {
563 0 : ShowSevereError(m_state,
564 0 : format("{}: {}: {}. Invalid Outdoor Air Mixer Name \"{}\" given.",
565 : RoutineName,
566 : CurrentModuleObject,
567 : thisObjectName,
568 : mixer_name));
569 0 : success = false;
570 : }
571 :
572 2 : Real64 refT = defaultReferenceConditions.temperature;
573 2 : Real64 refP = defaultReferenceConditions.pressure;
574 2 : Real64 refW = defaultReferenceConditions.humidity_ratio;
575 2 : if (!conditionsAreDefaulted) {
576 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
577 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
578 0 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
579 0 : if (result == referenceConditions.end()) {
580 0 : ShowSevereError(m_state,
581 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
582 : RoutineName,
583 : CurrentModuleObject,
584 : thisObjectName,
585 : refCrackCondName));
586 0 : success = false;
587 : } else {
588 0 : refT = result->second.temperature;
589 0 : refP = result->second.pressure;
590 0 : refW = result->second.humidity_ratio;
591 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
592 0 : result->second.name);
593 : }
594 0 : }
595 : }
596 :
597 2 : DisSysCompOutdoorAirData(i).name = thisObjectName; // Name of zone exhaust fan component
598 2 : DisSysCompOutdoorAirData(i).FlowCoef = coeff; // flow coefficient
599 2 : DisSysCompOutdoorAirData(i).FlowExpo = expnt; // Flow exponent
600 :
601 2 : DisSysCompOutdoorAirData(i).OAMixerNum = OAMixerNum;
602 :
603 2 : DisSysCompOutdoorAirData(i).StandardT = refT;
604 2 : DisSysCompOutdoorAirData(i).StandardP = refP;
605 2 : DisSysCompOutdoorAirData(i).StandardW = refW;
606 :
607 : // Add the element to the lookup table, check for name overlaps
608 2 : if (elements.find(thisObjectName) == elements.end()) {
609 2 : elements[thisObjectName] = &DisSysCompOutdoorAirData(i); // Yet another workaround
610 : } else {
611 0 : ShowSevereError(
612 : m_state,
613 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
614 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
615 0 : success = false;
616 : }
617 :
618 2 : ++i;
619 4 : }
620 : }
621 :
622 : // Read Relief Airflow object
623 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ReliefAirFlow";
624 35 : NumOfReliefFans = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
625 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
626 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
627 2 : int i = 1; // Temporary workaround
628 2 : DisSysCompReliefAirData.allocate(m_state.afn->NumOfReliefFans); // Temporary workaround
629 2 : auto &instancesValue = instances.value();
630 4 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
631 2 : auto const &fields = instance.value();
632 2 : auto const &thisObjectName = Util::makeUPPER(instance.key());
633 2 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
634 :
635 4 : std::string mixer_name = Util::makeUPPER(fields.at("outdoor_air_mixer_name").get<std::string>());
636 2 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_no_outdoor_air_flow_at_reference_conditions")};
637 2 : Real64 expnt{0.65};
638 2 : if (fields.find("air_mass_flow_exponent_when_no_outdoor_air_flow") != fields.end()) {
639 2 : expnt = fields.at("air_mass_flow_exponent_when_no_outdoor_air_flow").get<Real64>();
640 : }
641 :
642 2 : int OAMixerNum{MixedAir::GetOAMixerNumber(m_state, mixer_name)};
643 2 : if (OAMixerNum == 0) {
644 0 : ShowSevereError(m_state,
645 0 : format(RoutineName) + ": " + CurrentModuleObject + " object " + thisObjectName + ". Invalid " +
646 0 : "Outdoor Air Mixer Name" + " \"" + mixer_name + "\" given.");
647 0 : success = false;
648 : }
649 :
650 2 : Real64 refT = defaultReferenceConditions.temperature;
651 2 : Real64 refP = defaultReferenceConditions.pressure;
652 2 : Real64 refW = defaultReferenceConditions.humidity_ratio;
653 2 : if (!conditionsAreDefaulted) {
654 0 : if (fields.find("reference_crack_conditions") != fields.end()) { // not required field, *should* have default value
655 0 : auto refCrackCondName = fields.at("reference_crack_conditions").get<std::string>();
656 0 : auto result = referenceConditions.find(Util::makeUPPER(refCrackCondName));
657 0 : if (result == referenceConditions.end()) {
658 0 : ShowSevereError(m_state,
659 0 : format("{}: {}: {}. Cannot find reference crack conditions object \"{}\".",
660 : RoutineName,
661 : CurrentModuleObject,
662 : thisObjectName,
663 : refCrackCondName));
664 0 : success = false;
665 : } else {
666 0 : refT = result->second.temperature;
667 0 : refP = result->second.pressure;
668 0 : refW = result->second.humidity_ratio;
669 0 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed("AirflowNetwork:MultiZone:ReferenceCrackConditions",
670 0 : result->second.name);
671 : }
672 0 : }
673 : }
674 :
675 2 : DisSysCompReliefAirData(i).name = thisObjectName; // Name of zone exhaust fan component
676 2 : DisSysCompReliefAirData(i).FlowCoef = coeff; // flow coefficient
677 2 : DisSysCompReliefAirData(i).FlowExpo = expnt; // Flow exponent
678 2 : DisSysCompReliefAirData(i).OAMixerNum = OAMixerNum;
679 2 : DisSysCompReliefAirData(i).StandardT = refT;
680 2 : DisSysCompReliefAirData(i).StandardP = refP;
681 2 : DisSysCompReliefAirData(i).StandardW = refW;
682 :
683 : // Add the element to the lookup table, check for name overlaps
684 2 : if (elements.find(thisObjectName) == elements.end()) {
685 2 : elements[thisObjectName] = &DisSysCompReliefAirData(i); // Yet another workaround
686 : } else {
687 0 : ShowSevereError(
688 : m_state,
689 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
690 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
691 0 : success = false;
692 : }
693 :
694 2 : ++i;
695 4 : }
696 : }
697 :
698 : // Read AirflowNetwork simulation detailed openings
699 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:DetailedOpening";
700 35 : AirflowNetworkNumOfDetOpenings =
701 35 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
702 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
703 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
704 35 : int i = 1; // Temporary workaround
705 35 : MultizoneCompDetOpeningData.allocate(AirflowNetworkNumOfDetOpenings); // Temporary workaround
706 35 : auto &instancesValue = instances.value();
707 66 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
708 31 : auto const &fields = instance.value();
709 31 : auto const &thisObjectName = Util::makeUPPER(instance.key());
710 31 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
711 :
712 31 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
713 31 : Real64 expnt{0.65};
714 31 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
715 31 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
716 : }
717 :
718 31 : int LVOtype{1};
719 31 : std::string LVOstring;
720 31 : if (fields.find("type_of_rectangular_large_vertical_opening_lvo_") != fields.end()) {
721 31 : LVOstring = fields.at("type_of_rectangular_large_vertical_opening_lvo_").get<std::string>();
722 31 : if (Util::SameString(LVOstring, "NonPivoted") || Util::SameString(LVOstring, "1")) {
723 31 : LVOtype = 1; // Large vertical opening type number
724 0 : } else if (Util::SameString(LVOstring, "HorizontallyPivoted") || Util::SameString(LVOstring, "2")) {
725 0 : LVOtype = 2; // Large vertical opening type number
726 : } else {
727 : // Code will never be executed, validation will catch invalid input
728 0 : ShowSevereError(m_state,
729 0 : format(RoutineName) + "Invalid Type of Rectangular Large Vertical Opening (LVO) = " + LVOstring + "in " +
730 0 : CurrentModuleObject + " = " + thisObjectName);
731 0 : ShowContinueError(m_state, "Valid choices are NonPivoted and HorizontallyPivoted.");
732 0 : success = false;
733 : }
734 : }
735 :
736 31 : Real64 extra{0.0};
737 31 : if (fields.find("extra_crack_length_or_height_of_pivoting_axis") != fields.end()) {
738 31 : extra = fields.at("extra_crack_length_or_height_of_pivoting_axis").get<Real64>();
739 : }
740 :
741 31 : int N{fields.at("number_of_sets_of_opening_factor_data")};
742 :
743 31 : std::vector<Real64> factors(N);
744 31 : std::vector<Real64> cds(N);
745 31 : std::vector<Real64> width_factors(N);
746 31 : std::vector<Real64> height_factors(N);
747 31 : std::vector<Real64> start_height_factors(N);
748 :
749 : // Real64 factor{0.0};
750 : // if (fields.find("opening_factor_1") != fields.end()) {
751 : // factor = fields.at("opening_factor_1");
752 : //}
753 31 : Real64 cd{0.001};
754 31 : if (fields.find("discharge_coefficient_for_opening_factor_1") != fields.end()) {
755 31 : cd = fields.at("discharge_coefficient_for_opening_factor_1").get<Real64>();
756 : }
757 31 : Real64 width_factor{0.0};
758 31 : if (fields.find("width_factor_for_opening_factor_1") != fields.end()) {
759 31 : width_factor = fields.at("width_factor_for_opening_factor_1").get<Real64>();
760 : }
761 31 : Real64 height_factor{0.0};
762 31 : if (fields.find("height_factor_for_opening_factor_1") != fields.end()) {
763 31 : height_factor = fields.at("height_factor_for_opening_factor_1").get<Real64>();
764 : }
765 31 : Real64 start_height_factor{0.0};
766 31 : if (fields.find("start_height_factor_for_opening_factor_1") != fields.end()) {
767 31 : start_height_factor = fields.at("start_height_factor_for_opening_factor_1").get<Real64>();
768 : }
769 :
770 31 : factors[0] = 0.0; // factor; // This factor must be zero
771 31 : cds[0] = cd;
772 31 : width_factors[0] = width_factor;
773 31 : height_factors[0] = height_factor;
774 31 : start_height_factors[0] = start_height_factor;
775 :
776 31 : Real64 factor{fields.at("opening_factor_2")};
777 31 : cd = 1.0;
778 31 : if (fields.find("discharge_coefficient_for_opening_factor_2") != fields.end()) {
779 31 : cd = fields.at("discharge_coefficient_for_opening_factor_2").get<Real64>();
780 : }
781 31 : width_factor = 1.0;
782 31 : if (fields.find("width_factor_for_opening_factor_2") != fields.end()) {
783 31 : width_factor = fields.at("width_factor_for_opening_factor_2").get<Real64>();
784 : }
785 31 : height_factor = 1.0;
786 31 : if (fields.find("height_factor_for_opening_factor_2") != fields.end()) {
787 31 : height_factor = fields.at("height_factor_for_opening_factor_2").get<Real64>();
788 : }
789 31 : start_height_factor = 0.0;
790 31 : if (fields.find("start_height_factor_for_opening_factor_2") != fields.end()) {
791 31 : start_height_factor = fields.at("start_height_factor_for_opening_factor_2").get<Real64>();
792 : }
793 :
794 31 : factors[1] = factor;
795 31 : cds[1] = cd;
796 31 : width_factors[1] = width_factor;
797 31 : height_factors[1] = height_factor;
798 31 : start_height_factors[1] = start_height_factor;
799 :
800 31 : if (N >= 3) {
801 0 : factor = fields.at("opening_factor_3").get<Real64>();
802 0 : cd = 0.0;
803 0 : if (fields.find("discharge_coefficient_for_opening_factor_3") != fields.end()) {
804 0 : cd = fields.at("discharge_coefficient_for_opening_factor_3").get<Real64>();
805 : }
806 0 : width_factor = 0.0;
807 0 : if (fields.find("width_factor_for_opening_factor_3") != fields.end()) {
808 0 : width_factor = fields.at("width_factor_for_opening_factor_3").get<Real64>();
809 : }
810 0 : height_factor = 0.0;
811 0 : if (fields.find("height_factor_for_opening_factor_3") != fields.end()) {
812 0 : height_factor = fields.at("height_factor_for_opening_factor_3").get<Real64>();
813 : }
814 0 : start_height_factor = 0.0;
815 0 : if (fields.find("start_height_factor_for_opening_factor_3") != fields.end()) {
816 0 : start_height_factor = fields.at("start_height_factor_for_opening_factor_3").get<Real64>();
817 : }
818 :
819 0 : factors[2] = factor;
820 0 : cds[2] = cd;
821 0 : width_factors[2] = width_factor;
822 0 : height_factors[2] = height_factor;
823 0 : start_height_factors[2] = start_height_factor;
824 :
825 0 : if (N >= 4) {
826 0 : factor = fields.at("opening_factor_4").get<Real64>();
827 0 : cd = 0.0;
828 0 : if (fields.find("discharge_coefficient_for_opening_factor_4") != fields.end()) {
829 0 : cd = fields.at("discharge_coefficient_for_opening_factor_4").get<Real64>();
830 : }
831 0 : width_factor = 0.0;
832 0 : if (fields.find("width_factor_for_opening_factor_4") != fields.end()) {
833 0 : width_factor = fields.at("width_factor_for_opening_factor_4").get<Real64>();
834 : }
835 0 : height_factor = 0.0;
836 0 : if (fields.find("height_factor_for_opening_factor_4") != fields.end()) {
837 0 : height_factor = fields.at("height_factor_for_opening_factor_4").get<Real64>();
838 : }
839 0 : start_height_factor = 0.0;
840 0 : if (fields.find("start_height_factor_for_opening_factor_4") != fields.end()) {
841 0 : start_height_factor = fields.at("start_height_factor_for_opening_factor_4").get<Real64>();
842 : }
843 :
844 0 : factors[3] = factor;
845 0 : cds[3] = cd;
846 0 : width_factors[3] = width_factor;
847 0 : height_factors[3] = height_factor;
848 0 : start_height_factors[3] = start_height_factor;
849 : }
850 : }
851 :
852 31 : MultizoneCompDetOpeningData(i).name = thisObjectName; // Name of large detailed opening component
853 31 : MultizoneCompDetOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
854 31 : MultizoneCompDetOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
855 31 : MultizoneCompDetOpeningData(i).TypeName = LVOstring; // Large vertical opening type
856 31 : MultizoneCompDetOpeningData(i).LVOType = LVOtype; // Large vertical opening type number
857 31 : MultizoneCompDetOpeningData(i).LVOValue = extra; // Extra crack length for LVO type 1 with multiple openable
858 : // parts, or Height of pivoting axis for LVO type 2
859 :
860 31 : MultizoneCompDetOpeningData(i).NumFac = N; // Number of Opening Factor Values
861 :
862 31 : MultizoneCompDetOpeningData(i).OpenFac1 = factors[0]; // Opening factor #1
863 31 : MultizoneCompDetOpeningData(i).DischCoeff1 = cds[0]; // Discharge coefficient for opening factor #1
864 31 : MultizoneCompDetOpeningData(i).WidthFac1 = width_factors[0]; // Width factor for for Opening factor #1
865 31 : MultizoneCompDetOpeningData(i).HeightFac1 = height_factors[0]; // Height factor for opening factor #1
866 31 : MultizoneCompDetOpeningData(i).StartHFac1 = start_height_factors[0]; // Start height factor for opening factor #1
867 31 : MultizoneCompDetOpeningData(i).OpenFac2 = factors[1]; // Opening factor #2
868 31 : MultizoneCompDetOpeningData(i).DischCoeff2 = cds[1]; // Discharge coefficient for opening factor #2
869 31 : MultizoneCompDetOpeningData(i).WidthFac2 = width_factors[1]; // Width factor for for Opening factor #2
870 31 : MultizoneCompDetOpeningData(i).HeightFac2 = height_factors[1]; // Height factor for opening factor #2
871 31 : MultizoneCompDetOpeningData(i).StartHFac2 = start_height_factors[1]; // Start height factor for opening factor #2
872 :
873 31 : MultizoneCompDetOpeningData(i).OpenFac3 = 0.0; // Opening factor #3
874 31 : MultizoneCompDetOpeningData(i).DischCoeff3 = 0.0; // Discharge coefficient for opening factor #3
875 31 : MultizoneCompDetOpeningData(i).WidthFac3 = 0.0; // Width factor for for Opening factor #3
876 31 : MultizoneCompDetOpeningData(i).HeightFac3 = 0.0; // Height factor for opening factor #3
877 31 : MultizoneCompDetOpeningData(i).StartHFac3 = 0.0; // Start height factor for opening factor #3
878 31 : MultizoneCompDetOpeningData(i).OpenFac4 = 0.0; // Opening factor #4
879 31 : MultizoneCompDetOpeningData(i).DischCoeff4 = 0.0; // Discharge coefficient for opening factor #4
880 31 : MultizoneCompDetOpeningData(i).WidthFac4 = 0.0; // Width factor for for Opening factor #4
881 31 : MultizoneCompDetOpeningData(i).HeightFac4 = 0.0; // Height factor for opening factor #4
882 31 : MultizoneCompDetOpeningData(i).StartHFac4 = 0.0; // Start height factor for opening factor #4
883 31 : if (N == 2) {
884 31 : if (factors[1] != 1.0) {
885 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
886 0 : ShowContinueError(
887 : m_state,
888 : "..This object specifies that only 3 opening factors will be used. So, the value of Opening Factor #2 is set to 1.0.");
889 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac2));
890 0 : MultizoneCompDetOpeningData(i).OpenFac2 = 1.0;
891 : }
892 0 : } else if (N >= 3) {
893 0 : MultizoneCompDetOpeningData(i).OpenFac3 = factors[2]; // Opening factor #3
894 0 : MultizoneCompDetOpeningData(i).DischCoeff3 = cds[2]; // Discharge coefficient for opening factor #3
895 0 : MultizoneCompDetOpeningData(i).WidthFac3 = width_factors[2]; // Width factor for for Opening factor #3
896 0 : MultizoneCompDetOpeningData(i).HeightFac3 = height_factors[2]; // Height factor for opening factor #3
897 0 : MultizoneCompDetOpeningData(i).StartHFac3 = start_height_factors[2]; // Start height factor for opening factor #3
898 0 : if (N >= 4) {
899 0 : MultizoneCompDetOpeningData(i).OpenFac4 = factors[3]; // Opening factor #4
900 0 : if (factors[3] != 1.0) {
901 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
902 0 : ShowContinueError(m_state,
903 : "..This object specifies that 4 opening factors will be used. So, the value of Opening Factor #4 "
904 : "is set to 1.0.");
905 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac4));
906 0 : MultizoneCompDetOpeningData(i).OpenFac4 = 1.0;
907 : }
908 0 : MultizoneCompDetOpeningData(i).DischCoeff4 = cds[3]; // Discharge coefficient for opening factor #4
909 0 : MultizoneCompDetOpeningData(i).WidthFac4 = width_factors[3]; // Width factor for for Opening factor #4
910 0 : MultizoneCompDetOpeningData(i).HeightFac4 = height_factors[3]; // Height factor for opening factor #4
911 0 : MultizoneCompDetOpeningData(i).StartHFac4 = start_height_factors[3]; // Start height factor for opening factor #4
912 : } else {
913 0 : if (factors[2] != 1.0) {
914 0 : ShowWarningError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
915 0 : ShowContinueError(m_state,
916 : "..This object specifies that only 3 opening factors will be used. So, the value of Opening Factor #3 "
917 : "is set to 1.0.");
918 0 : ShowContinueError(m_state, format("..Input value was {:.2R}", MultizoneCompDetOpeningData(i).OpenFac3));
919 0 : MultizoneCompDetOpeningData(i).OpenFac3 = 1.0;
920 : }
921 : }
922 : }
923 :
924 : // Sanity checks, check sum of Height Factor and the Start Height Factor
925 31 : if (MultizoneCompDetOpeningData(i).HeightFac1 + MultizoneCompDetOpeningData(i).StartHFac1 > 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 1 and Start Height Factor for Opening Factor 1 is greater than 1.0");
929 0 : success = false;
930 : }
931 31 : if (MultizoneCompDetOpeningData(i).HeightFac2 + MultizoneCompDetOpeningData(i).StartHFac2 > 1.0) {
932 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
933 0 : ShowContinueError(
934 : m_state, "..The sum of Height Factor for Opening Factor 2 and Start Height Factor for Opening Factor 2 is greater than 1.0");
935 0 : success = false;
936 : }
937 31 : if (MultizoneCompDetOpeningData(i).NumFac > 2) {
938 0 : if (MultizoneCompDetOpeningData(i).OpenFac2 >= MultizoneCompDetOpeningData(i).OpenFac3) {
939 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
940 0 : ShowContinueError(m_state, "..The value of Opening Factor #2 >= the value of Opening Factor #3");
941 0 : success = false;
942 : }
943 0 : if (MultizoneCompDetOpeningData(i).HeightFac3 + MultizoneCompDetOpeningData(i).StartHFac3 > 1.0) {
944 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
945 0 : ShowContinueError(
946 : m_state,
947 : "..The sum of Height Factor for Opening Factor 3 and Start Height Factor for Opening Factor 3 is greater than 1.0");
948 0 : success = false;
949 : }
950 0 : if (MultizoneCompDetOpeningData(i).NumFac == 4) {
951 0 : if (MultizoneCompDetOpeningData(i).OpenFac3 >= MultizoneCompDetOpeningData(i).OpenFac4) {
952 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
953 0 : ShowContinueError(m_state, "..The value of Opening Factor #3 >= the value of Opening Factor #4");
954 0 : success = false;
955 : }
956 0 : if (MultizoneCompDetOpeningData(i).HeightFac4 + MultizoneCompDetOpeningData(i).StartHFac4 > 1.0) {
957 0 : ShowSevereError(m_state, format("{}: {} = {}", RoutineName, CurrentModuleObject, thisObjectName));
958 0 : ShowContinueError(
959 : m_state,
960 : "..The sum of Height Factor for Opening Factor 4 and Start Height Factor for Opening Factor 4 is greater than 1.0");
961 0 : success = false;
962 : }
963 : }
964 : }
965 :
966 : // Add the element to the lookup table, check for name overlaps
967 31 : if (elements.find(thisObjectName) == elements.end()) {
968 31 : elements[thisObjectName] = &MultizoneCompDetOpeningData(i); // Yet another workaround
969 : } else {
970 0 : ShowSevereError(
971 : m_state,
972 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
973 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
974 0 : success = false;
975 : }
976 :
977 31 : ++i;
978 66 : }
979 : }
980 :
981 : // Read AirflowNetwork simulation simple openings
982 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:SimpleOpening";
983 35 : AirflowNetworkNumOfSimOpenings =
984 35 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
985 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
986 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
987 12 : int i = 1; // Temporary workaround
988 12 : MultizoneCompSimpleOpeningData.allocate(AirflowNetworkNumOfSimOpenings); // Temporary workaround
989 12 : auto &instancesValue = instances.value();
990 24 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
991 12 : auto const &fields = instance.value();
992 12 : auto const &thisObjectName = Util::makeUPPER(instance.key());
993 12 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
994 :
995 12 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
996 12 : Real64 expnt{0.65};
997 12 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
998 12 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
999 : }
1000 12 : Real64 diff{fields.at("minimum_density_difference_for_two_way_flow")};
1001 12 : Real64 dischargeCoeff{fields.at("discharge_coefficient")};
1002 :
1003 12 : MultizoneCompSimpleOpeningData(i).name = thisObjectName; // Name of large simple opening component
1004 12 : MultizoneCompSimpleOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
1005 12 : MultizoneCompSimpleOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
1006 12 : MultizoneCompSimpleOpeningData(i).MinRhoDiff = diff; // Minimum density difference for two-way flow
1007 12 : MultizoneCompSimpleOpeningData(i).DischCoeff = dischargeCoeff; // Discharge coefficient at full opening
1008 :
1009 : // Add the element to the lookup table, check for name overlaps
1010 12 : if (elements.find(thisObjectName) == elements.end()) {
1011 12 : elements[thisObjectName] = &MultizoneCompSimpleOpeningData(i); // Yet another workaround
1012 : } else {
1013 0 : ShowSevereError(
1014 : m_state,
1015 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1016 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1017 0 : success = false;
1018 : }
1019 :
1020 12 : ++i;
1021 24 : }
1022 : }
1023 :
1024 : // Read AirflowNetwork simulation horizontal openings
1025 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:Component:HorizontalOpening";
1026 35 : AirflowNetworkNumOfHorOpenings =
1027 35 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1028 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1029 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1030 2 : int i = 1; // Temporary workaround
1031 2 : MultizoneCompHorOpeningData.allocate(AirflowNetworkNumOfHorOpenings); // Temporary workaround
1032 2 : auto &instancesValue = instances.value();
1033 4 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1034 2 : auto const &fields = instance.value();
1035 2 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1036 2 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1037 :
1038 2 : Real64 coeff{fields.at("air_mass_flow_coefficient_when_opening_is_closed")};
1039 2 : Real64 expnt{0.65};
1040 2 : if (fields.find("air_mass_flow_exponent_when_opening_is_closed") != fields.end()) {
1041 2 : expnt = fields.at("air_mass_flow_exponent_when_opening_is_closed").get<Real64>();
1042 : }
1043 2 : Real64 angle{90.0};
1044 2 : if (fields.find("sloping_plane_angle") != fields.end()) {
1045 2 : angle = fields.at("sloping_plane_angle").get<Real64>();
1046 : }
1047 2 : Real64 dischargeCoeff{fields.at("discharge_coefficient")};
1048 :
1049 2 : MultizoneCompHorOpeningData(i).name = thisObjectName; // Name of large simple opening component
1050 2 : MultizoneCompHorOpeningData(i).FlowCoef = coeff; // Air Mass Flow Coefficient When Window or Door Is Closed
1051 2 : MultizoneCompHorOpeningData(i).FlowExpo = expnt; // Air Mass Flow exponent When Window or Door Is Closed
1052 2 : MultizoneCompHorOpeningData(i).Slope = angle; // Sloping plane angle
1053 2 : MultizoneCompHorOpeningData(i).DischCoeff = dischargeCoeff; // Discharge coefficient at full opening
1054 :
1055 : // Add the element to the lookup table, check for name overlaps
1056 2 : if (elements.find(thisObjectName) == elements.end()) {
1057 2 : elements[thisObjectName] = &MultizoneCompHorOpeningData(i); // Yet another workaround
1058 : } else {
1059 0 : ShowSevereError(
1060 : m_state,
1061 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1062 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1063 0 : success = false;
1064 : }
1065 :
1066 2 : ++i;
1067 4 : }
1068 : }
1069 :
1070 : // *** Read AirflowNetwork simulation surface effective leakage area component
1071 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea";
1072 35 : AirflowNetworkNumOfSurELA =
1073 35 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1074 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1075 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1076 16 : int i = 1; // Temporary workaround
1077 16 : MultizoneSurfaceELAData.allocate(AirflowNetworkNumOfSurELA); // Temporary workaround
1078 16 : auto &instancesValue = instances.value();
1079 47 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1080 31 : auto const &fields = instance.value();
1081 31 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1082 :
1083 31 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1084 :
1085 31 : Real64 ela{fields.at("effective_leakage_area")};
1086 31 : Real64 cd{1.0};
1087 31 : if (fields.find("discharge_coefficient") != fields.end()) {
1088 31 : cd = fields.at("discharge_coefficient").get<Real64>();
1089 : }
1090 31 : Real64 dp{4.0};
1091 31 : if (fields.find("reference_pressure_difference") != fields.end()) {
1092 31 : dp = fields.at("reference_pressure_difference").get<Real64>();
1093 : }
1094 31 : Real64 expnt{0.65};
1095 31 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1096 31 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1097 : }
1098 :
1099 31 : MultizoneSurfaceELAData(i).name = thisObjectName; // Name of surface effective leakage area component
1100 31 : MultizoneSurfaceELAData(i).ELA = ela; // Effective leakage area
1101 31 : MultizoneSurfaceELAData(i).DischCoeff = cd; // Discharge coefficient
1102 31 : MultizoneSurfaceELAData(i).RefDeltaP = dp; // Reference pressure difference
1103 31 : MultizoneSurfaceELAData(i).FlowExpo = expnt; // Air Mass Flow exponent
1104 31 : MultizoneSurfaceELAData(i).TestDeltaP = 0.0; // Testing pressure difference
1105 31 : MultizoneSurfaceELAData(i).TestDisCoef = 0.0; // Testing Discharge coefficient
1106 :
1107 : // Add the element to the lookup table, check for name overlaps
1108 31 : if (elements.find(thisObjectName) == elements.end()) {
1109 31 : elements[thisObjectName] = &MultizoneSurfaceELAData(i); // Yet another workaround
1110 : } else {
1111 0 : ShowSevereError(
1112 : m_state,
1113 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1114 0 : success = false;
1115 : }
1116 :
1117 31 : ++i;
1118 47 : }
1119 : }
1120 :
1121 : // *** Read AirflowNetwork simulation specified flow components
1122 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:SpecifiedFlowRate";
1123 35 : AirflowNetworkNumOfSFR =
1124 35 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1125 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1126 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1127 1 : int i_mass = 0; // Temporary workaround that increasingly looks like the long term solution
1128 1 : int i_vol = 0;
1129 1 : auto &instancesValue = instances.value();
1130 :
1131 1 : instancesValue = instances.value();
1132 2 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1133 1 : auto const &fields = instance.value();
1134 1 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1135 :
1136 1 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1137 :
1138 1 : Real64 flow_rate{fields.at("air_flow_value")};
1139 1 : bool is_mass_flow = true;
1140 1 : if (fields.find("air_flow_units") != fields.end()) {
1141 1 : if (fields.at("air_flow_units") != "MassFlow") {
1142 0 : is_mass_flow = false;
1143 : }
1144 : }
1145 :
1146 : // Check for name overlaps
1147 1 : if (elements.find(thisObjectName) != elements.end()) {
1148 0 : ShowSevereError(
1149 : m_state,
1150 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1151 0 : success = false;
1152 : }
1153 :
1154 1 : if (is_mass_flow) {
1155 1 : SpecifiedMassFlowData.emplace_back();
1156 1 : SpecifiedMassFlowData[i_mass].name = thisObjectName;
1157 1 : SpecifiedMassFlowData[i_mass].mass_flow = flow_rate;
1158 1 : ++i_mass;
1159 : } else {
1160 0 : SpecifiedVolumeFlowData.emplace_back();
1161 0 : SpecifiedVolumeFlowData[i_vol].name = thisObjectName;
1162 0 : SpecifiedVolumeFlowData[i_vol].volume_flow = flow_rate;
1163 0 : ++i_vol;
1164 : }
1165 2 : }
1166 2 : for (auto &afe : SpecifiedMassFlowData) {
1167 1 : elements[afe.name] = &afe; // Yet another workaround
1168 : }
1169 1 : for (auto &afe : SpecifiedVolumeFlowData) {
1170 0 : elements[afe.name] = &afe; // Yet another workaround
1171 : }
1172 : }
1173 :
1174 : // Read AirflowNetwork Distribution system component: duct leakage
1175 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Leak";
1176 35 : DisSysNumOfLeaks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1177 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1178 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1179 11 : int i = 1; // Temporary workaround
1180 11 : DisSysCompLeakData.allocate(DisSysNumOfLeaks); // Temporary workaround
1181 11 : auto &instancesValue = instances.value();
1182 25 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1183 14 : auto const &fields = instance.value();
1184 14 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1185 14 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1186 :
1187 14 : Real64 coeff{fields.at("air_mass_flow_coefficient")};
1188 14 : Real64 expnt{0.65};
1189 14 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1190 14 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1191 : }
1192 :
1193 14 : DisSysCompLeakData(i).name = thisObjectName; // Name of duct leak component
1194 14 : DisSysCompLeakData(i).FlowCoef = coeff; // Air Mass Flow Coefficient
1195 14 : DisSysCompLeakData(i).FlowExpo = expnt; // Air Mass Flow exponent
1196 :
1197 : // Add the element to the lookup table, check for name overlaps
1198 14 : if (elements.find(thisObjectName) == elements.end()) {
1199 14 : elements[thisObjectName] = &DisSysCompLeakData(i); // Yet another workaround
1200 : } else {
1201 0 : ShowSevereError(
1202 : m_state,
1203 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1204 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1205 0 : success = false;
1206 : }
1207 :
1208 14 : ++i;
1209 25 : }
1210 : }
1211 :
1212 : // Read AirflowNetwork Distribution system component: duct effective leakage ratio
1213 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:LeakageRatio";
1214 35 : DisSysNumOfELRs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1215 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1216 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1217 23 : int i = 1; // Temporary workaround
1218 23 : DisSysCompELRData.allocate(DisSysNumOfELRs); // Temporary workaround
1219 23 : auto &instancesValue = instances.value();
1220 123 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1221 100 : auto const &fields = instance.value();
1222 100 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1223 100 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1224 :
1225 100 : Real64 elr{fields.at("effective_leakage_ratio")};
1226 100 : Real64 maxflow{fields.at("maximum_flow_rate")};
1227 100 : Real64 dp{fields.at("reference_pressure_difference")};
1228 100 : Real64 expnt{0.65};
1229 100 : if (fields.find("air_mass_flow_exponent") != fields.end()) {
1230 100 : expnt = fields.at("air_mass_flow_exponent").get<Real64>();
1231 : }
1232 :
1233 100 : DisSysCompELRData(i).name = thisObjectName; // Name of duct effective leakage ratio component
1234 100 : DisSysCompELRData(i).ELR = elr; // Value of effective leakage ratio
1235 100 : DisSysCompELRData(i).FlowRate = maxflow * m_state.dataEnvrn->StdRhoAir; // Maximum airflow rate
1236 100 : DisSysCompELRData(i).RefPres = dp; // Reference pressure difference
1237 100 : DisSysCompELRData(i).FlowExpo = expnt; // Air Mass Flow exponent
1238 :
1239 : // Add the element to the lookup table, check for name overlaps
1240 100 : if (elements.find(thisObjectName) == elements.end()) {
1241 100 : elements[thisObjectName] = &DisSysCompELRData(i); // Yet another workaround
1242 : } else {
1243 0 : ShowSevereError(
1244 : m_state,
1245 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1246 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1247 0 : success = false;
1248 : }
1249 :
1250 100 : ++i;
1251 123 : }
1252 : }
1253 :
1254 : // Read AirflowNetwork Distribution system component: duct
1255 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Duct";
1256 35 : DisSysNumOfDucts = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1257 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1258 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1259 23 : int i = 1; // Temporary workaround
1260 23 : DisSysCompDuctData.allocate(DisSysNumOfDucts); // Temporary workaround
1261 23 : auto &instancesValue = instances.value();
1262 278 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1263 255 : auto const &fields = instance.value();
1264 255 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1265 255 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1266 :
1267 255 : Real64 L{fields.at("duct_length")};
1268 255 : Real64 D{fields.at("hydraulic_diameter")};
1269 255 : Real64 A{fields.at("cross_section_area")};
1270 255 : Real64 e{0.0009};
1271 255 : if (fields.find("surface_roughness") != fields.end()) {
1272 255 : e = fields.at("surface_roughness").get<Real64>();
1273 : }
1274 255 : Real64 dlc{0.0};
1275 255 : if (fields.find("coefficient_for_local_dynamic_loss_due_to_fitting") != fields.end()) {
1276 255 : dlc = fields.at("coefficient_for_local_dynamic_loss_due_to_fitting").get<Real64>();
1277 : }
1278 255 : Real64 U{0.943};
1279 255 : if (fields.find("heat_transmittance_coefficient_u_factor_for_duct_wall_construction") != fields.end()) {
1280 255 : U = fields.at("heat_transmittance_coefficient_u_factor_for_duct_wall_construction").get<Real64>();
1281 : }
1282 255 : Real64 Um{0.001};
1283 255 : if (fields.find("overall_moisture_transmittance_coefficient_from_air_to_air") != fields.end()) {
1284 255 : Um = fields.at("overall_moisture_transmittance_coefficient_from_air_to_air").get<Real64>();
1285 : }
1286 255 : Real64 hout{0.0};
1287 255 : if (fields.find("outside_convection_coefficient") != fields.end()) {
1288 218 : hout = fields.at("outside_convection_coefficient").get<Real64>();
1289 : }
1290 255 : Real64 hin{0.0};
1291 255 : if (fields.find("inside_convection_coefficient") != fields.end()) {
1292 218 : hin = fields.at("inside_convection_coefficient").get<Real64>();
1293 : }
1294 :
1295 255 : DisSysCompDuctData(i).name = thisObjectName; // Name of duct effective leakage ratio component
1296 255 : DisSysCompDuctData(i).L = L; // Duct length [m]
1297 255 : DisSysCompDuctData(i).hydraulicDiameter = D; // Hydraulic diameter [m]
1298 255 : DisSysCompDuctData(i).A = A; // Cross section area [m2]
1299 255 : DisSysCompDuctData(i).roughness = e; // Surface roughness [m]
1300 255 : DisSysCompDuctData(i).TurDynCoef = dlc; // Turbulent dynamic loss coefficient
1301 255 : DisSysCompDuctData(i).UThermConduct = U; // Conduction heat transmittance [W/m2.K]
1302 255 : DisSysCompDuctData(i).UMoisture = Um; // Overall moisture transmittance [kg/m2]
1303 255 : DisSysCompDuctData(i).OutsideConvCoeff = hout; // Outside convection coefficient [W/m2.K]
1304 255 : DisSysCompDuctData(i).InsideConvCoeff = hin; // Inside convection coefficient [W/m2.K]
1305 255 : DisSysCompDuctData(i).MThermal = 0.0; // Thermal capacity [J/K]
1306 255 : DisSysCompDuctData(i).MMoisture = 0.0; // Moisture capacity [kg]
1307 255 : DisSysCompDuctData(i).LamDynCoef = 64.0; // Laminar dynamic loss coefficient
1308 255 : DisSysCompDuctData(i).LamFriCoef = dlc; // Laminar friction loss coefficient
1309 255 : DisSysCompDuctData(i).InitLamCoef = 128.0; // Coefficient of linear initialization
1310 255 : DisSysCompDuctData(i).RelRough = e / D; // e/D: relative roughness
1311 255 : DisSysCompDuctData(i).RelL = L / D; // L/D: relative length
1312 255 : DisSysCompDuctData(i).A1 = 1.14 - 0.868589 * std::log(DisSysCompDuctData(i).RelRough); // 1.14 - 0.868589*ln(e/D)
1313 255 : DisSysCompDuctData(i).g = DisSysCompDuctData(i).A1; // 1/sqrt(Darcy friction factor)
1314 :
1315 : // Add the element to the lookup table, check for name overlaps
1316 255 : if (elements.find(thisObjectName) == elements.end()) {
1317 255 : elements[thisObjectName] = &DisSysCompDuctData(i); // Yet another workaround
1318 : } else {
1319 0 : ShowSevereError(
1320 : m_state,
1321 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1322 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1323 0 : success = false;
1324 : }
1325 :
1326 255 : ++i;
1327 278 : }
1328 : }
1329 :
1330 : // Read AirflowNetwork Distribution system component: constant volume fan
1331 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Fan";
1332 35 : DisSysNumOfCVFs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1333 35 : if (DisSysNumOfCVFs > 0 && DisSysNumOfCVFs != m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC")) {
1334 0 : ShowSevereError(m_state, format("The number of entered AirflowNetwork:Distribution:Component:Fan objects is {}", DisSysNumOfCVFs));
1335 0 : ShowSevereError(m_state,
1336 0 : format("The number of entered AirLoopHVAC objects is {}",
1337 0 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC")));
1338 0 : ShowContinueError(m_state, "Both numbers should be equal. Please check your inputs.");
1339 0 : success = false;
1340 : }
1341 :
1342 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1343 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1344 23 : int i = 1; // Temporary workaround
1345 23 : DisSysCompCVFData.allocate(DisSysNumOfCVFs); // Temporary workaround
1346 23 : auto &instancesValue = instances.value();
1347 47 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1348 24 : auto const &fields = instance.value();
1349 24 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1350 24 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1351 :
1352 48 : std::string fan_name = Util::makeUPPER(fields.at("fan_name").get<std::string>());
1353 :
1354 : int fanIndex;
1355 24 : Real64 flowRate = 0.0;
1356 : int inletNode;
1357 : int outletNode;
1358 :
1359 : HVAC::FanType fanType = static_cast<HVAC::FanType>(
1360 24 : getEnumValue(HVAC::fanTypeNamesUC, Util::makeUPPER(fields.at("supply_fan_object_type").get<std::string>())));
1361 :
1362 24 : HVAC::FanType fanType2 = HVAC::FanType::Invalid;
1363 :
1364 24 : if (fanType == HVAC::FanType::SystemModel) {
1365 1 : fanIndex = Fans::GetFanIndex(m_state, fan_name);
1366 1 : if (fanIndex < 0) {
1367 0 : ShowSevereError(m_state, "...occurs in " + CurrentModuleObject + " = " + DisSysCompCVFData(i).name);
1368 0 : success = false;
1369 : } else {
1370 1 : auto *fanSys = dynamic_cast<Fans::FanSystem *>(m_state.dataFans->fans(fanIndex));
1371 1 : assert(fanSys != nullptr);
1372 1 : flowRate = fanSys->maxAirFlowRate * m_state.dataEnvrn->StdRhoAir;
1373 1 : DisSysCompCVFData(i).FanModelFlag = true;
1374 1 : inletNode = fanSys->inletNodeNum;
1375 1 : outletNode = fanSys->outletNodeNum;
1376 1 : if (fanSys->speedControl == Fans::SpeedControl::Continuous) {
1377 0 : fanType2 = HVAC::FanType::VAV;
1378 0 : VAVSystem = true;
1379 : } else {
1380 1 : fanType2 = HVAC::FanType::OnOff;
1381 : }
1382 1 : supplyFanType = fanType2;
1383 : }
1384 :
1385 : } else {
1386 23 : fanIndex = GetFanIndex(m_state, fan_name);
1387 :
1388 23 : if (fanIndex == 0) {
1389 0 : ErrorObjectHeader eoh{RoutineName, CurrentModuleObject, DisSysCompCVFData(i).name};
1390 0 : ShowSevereItemNotFound(m_state, eoh, "Fan Name", fan_name);
1391 0 : success = false;
1392 : }
1393 :
1394 23 : auto *fan = m_state.dataFans->fans(fanIndex);
1395 23 : flowRate = fan->maxAirFlowRate * m_state.dataEnvrn->StdRhoAir;
1396 :
1397 23 : fanType2 = fan->type;
1398 23 : supplyFanType = fanType2;
1399 : }
1400 :
1401 24 : if (!(fanType2 == HVAC::FanType::Constant || fanType2 == HVAC::FanType::OnOff || fanType2 == HVAC::FanType::VAV)) {
1402 0 : ShowSevereError(
1403 : m_state,
1404 0 : format("{}The Supply Fan Object Type in {} = {} is not a valid fan type.", RoutineName, CurrentModuleObject, thisObjectName));
1405 0 : ShowContinueError(m_state, "Valid fan types are Fan:ConstantVolume, Fan:OnOff, Fan:VariableVolume, or Fan:SystemModel.");
1406 0 : success = false;
1407 : } else {
1408 24 : if (fanType == HVAC::FanType::Constant && fanType2 == HVAC::FanType::OnOff) {
1409 0 : ShowSevereError(m_state, "The Supply Fan Object Type defined in " + CurrentModuleObject + " is Fan:ConstantVolume");
1410 0 : ShowContinueError(m_state, "The Supply Fan Object Type defined in an AirLoopHVAC is Fan:OnOff");
1411 0 : success = false;
1412 24 : } else if (fanType == HVAC::FanType::OnOff && fanType2 == HVAC::FanType::Constant) {
1413 0 : ShowSevereError(m_state, "The Supply Fan Object Type defined in " + CurrentModuleObject + " is Fan:SimpleOnOff");
1414 0 : ShowContinueError(m_state, "The Supply Fan Object Type defined in an AirLoopHVAC is Fan:ConstantVolume");
1415 0 : success = false;
1416 : }
1417 : }
1418 24 : bool ErrorsFound{false};
1419 24 : auto *fan = m_state.dataFans->fans(fanIndex);
1420 24 : if (fanType2 == HVAC::FanType::Constant) {
1421 14 : inletNode = fan->inletNodeNum;
1422 14 : outletNode = fan->outletNodeNum;
1423 : }
1424 24 : if (fanType2 == HVAC::FanType::OnOff && !DisSysCompCVFData(i).FanModelFlag) {
1425 8 : inletNode = fan->inletNodeNum;
1426 8 : outletNode = fan->outletNodeNum;
1427 : }
1428 24 : if (fanType2 == HVAC::FanType::VAV && !DisSysCompCVFData(i).FanModelFlag) {
1429 1 : inletNode = fan->inletNodeNum;
1430 1 : outletNode = fan->outletNodeNum;
1431 1 : VAVSystem = true;
1432 : }
1433 :
1434 24 : if (ErrorsFound) {
1435 0 : success = false;
1436 : }
1437 :
1438 24 : DisSysCompCVFData(i).name = fan_name; // Name of duct effective leakage ratio component
1439 24 : DisSysCompCVFData(i).Ctrl = 1.0; // Control ratio
1440 24 : DisSysCompCVFData(i).FanIndex = fanIndex;
1441 24 : DisSysCompCVFData(i).FlowRate = flowRate;
1442 24 : DisSysCompCVFData(i).fanType = fanType2;
1443 24 : DisSysCompCVFData(i).InletNode = inletNode;
1444 24 : DisSysCompCVFData(i).OutletNode = outletNode;
1445 :
1446 : // Add the element to the lookup table, check for name overlaps
1447 24 : if (elements.find(fan_name) == elements.end()) {
1448 24 : elements[fan_name] = &DisSysCompCVFData(i); // Yet another workaround
1449 : } else {
1450 0 : ShowSevereError(
1451 0 : m_state, format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, fan_name));
1452 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1453 0 : success = false;
1454 : }
1455 :
1456 24 : ++i;
1457 47 : }
1458 : }
1459 :
1460 : // Read AirflowNetwork Distribution system component: coil
1461 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Coil";
1462 35 : DisSysNumOfCoils = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1463 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1464 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1465 23 : int i = 1; // Temporary workaround
1466 23 : DisSysCompCoilData.allocate(DisSysNumOfCoils); // Temporary workaround
1467 23 : auto &instancesValue = instances.value();
1468 80 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1469 57 : auto const &fields = instance.value();
1470 : // auto const &thisObjectName = Util::makeUPPER(instance.key());
1471 57 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1472 :
1473 114 : std::string coil_name = fields.at("coil_name").get<std::string>();
1474 114 : std::string coil_type = fields.at("coil_object_type").get<std::string>();
1475 57 : Real64 L{fields.at("air_path_length")};
1476 57 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1477 :
1478 57 : DisSysCompCoilData(i).name = Util::makeUPPER(coil_name); // Name of associated EPlus coil component
1479 57 : DisSysCompCoilData(i).EPlusType = coil_type; // coil type
1480 57 : DisSysCompCoilData(i).L = L; // Air path length
1481 57 : DisSysCompCoilData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1482 :
1483 : // Add the element to the lookup table, check for name overlaps
1484 57 : if (elements.find(DisSysCompCoilData(i).name) == elements.end()) {
1485 57 : elements[DisSysCompCoilData(i).name] = &DisSysCompCoilData(i); // Yet another workaround
1486 : } else {
1487 0 : ShowSevereError(m_state,
1488 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1489 : RoutineName,
1490 : CurrentModuleObject,
1491 0 : DisSysCompCoilData(i).name));
1492 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1493 0 : success = false;
1494 : }
1495 :
1496 57 : ++i;
1497 80 : }
1498 : }
1499 :
1500 : // Read AirflowNetwork Distribution system component: heat exchanger
1501 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:HeatExchanger";
1502 35 : DisSysNumOfHXs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1503 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1504 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1505 1 : int i = 1; // Temporary workaround
1506 1 : DisSysCompHXData.allocate(DisSysNumOfHXs); // Temporary workaround
1507 1 : auto &instancesValue = instances.value();
1508 2 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1509 1 : auto const &fields = instance.value();
1510 : // auto const &thisObjectName = Util::makeUPPER(instance.key());
1511 1 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1512 :
1513 2 : std::string hx_name = fields.at("heatexchanger_name").get<std::string>();
1514 2 : std::string hx_type = fields.at("heatexchanger_object_type").get<std::string>();
1515 1 : Real64 L{fields.at("air_path_length")};
1516 1 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1517 :
1518 1 : DisSysCompHXData(i).name = Util::makeUPPER(hx_name); // Name of associated EPlus heat exchange component
1519 1 : DisSysCompHXData(i).EPlusType = hx_type; // coil type
1520 1 : DisSysCompHXData(i).L = L; // Air path length
1521 1 : DisSysCompHXData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1522 1 : DisSysCompHXData(i).CoilParentExists = HVACHXAssistedCoolingCoil::VerifyHeatExchangerParent(m_state, hx_type, hx_name);
1523 :
1524 : // Add the element to the lookup table, check for name overlaps
1525 1 : if (elements.find(DisSysCompHXData(i).name) == elements.end()) {
1526 1 : elements[DisSysCompHXData(i).name] = &DisSysCompHXData(i); // Yet another workaround
1527 : } else {
1528 0 : ShowSevereError(m_state,
1529 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1530 : RoutineName,
1531 : CurrentModuleObject,
1532 0 : DisSysCompHXData(i).name));
1533 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1534 0 : success = false;
1535 : }
1536 1 : ++i;
1537 2 : }
1538 : }
1539 :
1540 : // Read AirflowNetwork Distribution system component: terminal unit
1541 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:TerminalUnit";
1542 35 : DisSysNumOfTermUnits = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1543 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1544 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1545 12 : int i = 1; // Temporary workaround
1546 12 : DisSysCompTermUnitData.allocate(DisSysNumOfTermUnits); // Temporary workaround
1547 12 : auto &instancesValue = instances.value();
1548 36 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1549 24 : auto const &fields = instance.value();
1550 : // auto const &thisObjectName = Util::makeUPPER(instance.key());
1551 24 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1552 :
1553 48 : std::string tu_name = fields.at("terminal_unit_name").get<std::string>();
1554 48 : std::string tu_type = fields.at("terminal_unit_object_type").get<std::string>();
1555 24 : Real64 L{fields.at("air_path_length")};
1556 24 : Real64 D{fields.at("air_path_hydraulic_diameter")};
1557 :
1558 24 : DisSysCompTermUnitData(i).name = Util::makeUPPER(tu_name); // Name of associated EPlus coil component
1559 24 : DisSysCompTermUnitData(i).EPlusType = tu_type; // Terminal unit type
1560 24 : DisSysCompTermUnitData(i).L = L; // Air path length
1561 24 : DisSysCompTermUnitData(i).hydraulicDiameter = D; // Air path hydraulic diameter
1562 :
1563 : // Add the element to the lookup table, check for name overlaps
1564 24 : if (elements.find(DisSysCompTermUnitData(i).name) == elements.end()) {
1565 24 : elements[DisSysCompTermUnitData(i).name] = &DisSysCompTermUnitData(i); // Yet another workaround
1566 : } else {
1567 0 : ShowSevereError(m_state,
1568 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".",
1569 : RoutineName,
1570 : CurrentModuleObject,
1571 0 : DisSysCompTermUnitData(i).name));
1572 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1573 0 : success = false;
1574 : }
1575 :
1576 24 : ++i;
1577 36 : }
1578 : }
1579 :
1580 : // Get input data of constant pressure drop component
1581 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ConstantPressureDrop";
1582 35 : DisSysNumOfCPDs = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject); // Temporary workaround
1583 35 : instances = m_state.dataInputProcessing->inputProcessor->epJSON.find(CurrentModuleObject);
1584 35 : if (instances != m_state.dataInputProcessing->inputProcessor->epJSON.end()) {
1585 12 : int i = 1; // Temporary workaround
1586 12 : DisSysCompCPDData.allocate(DisSysNumOfCPDs); // Temporary workaround
1587 12 : auto &instancesValue = instances.value();
1588 24 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1589 12 : auto const &fields = instance.value();
1590 12 : auto const &thisObjectName = Util::makeUPPER(instance.key());
1591 12 : m_state.dataInputProcessing->inputProcessor->markObjectAsUsed(CurrentModuleObject, instance.key()); // Temporary workaround
1592 :
1593 12 : Real64 dp{fields.at("pressure_difference_across_the_component")};
1594 :
1595 12 : DisSysCompCPDData(i).name = thisObjectName; // Name of constant pressure drop component
1596 12 : DisSysCompCPDData(i).A = 1.0; // cross section area
1597 12 : DisSysCompCPDData(i).DP = dp; // Pressure difference across the component
1598 :
1599 : // Add the element to the lookup table, check for name overlaps
1600 12 : if (elements.find(thisObjectName) == elements.end()) {
1601 12 : elements[thisObjectName] = &DisSysCompCPDData(i); // Yet another workaround
1602 : } else {
1603 0 : ShowSevereError(
1604 : m_state,
1605 0 : format("{}: {}: Duplicated airflow element names are found = \"{}\".", RoutineName, CurrentModuleObject, thisObjectName));
1606 : // ShowContinueError(state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
1607 0 : success = false;
1608 : }
1609 :
1610 12 : ++i;
1611 24 : }
1612 : }
1613 :
1614 35 : return success;
1615 35 : }
1616 :
1617 796 : void Solver::get_input()
1618 : {
1619 :
1620 : // SUBROUTINE INFORMATION:
1621 : // AUTHOR Lixing Gu
1622 : // DATE WRITTEN Aug. 2003
1623 : // MODIFIED Aug. 2005
1624 : // RE-ENGINEERED na
1625 :
1626 : // PURPOSE OF THIS SUBROUTINE:
1627 : // This subroutine reads inputs of air distribution system
1628 :
1629 : // Using/Aliasing
1630 : using Curve::GetCurveIndex;
1631 : using DataLoopNode::ObjectIsParent;
1632 : using HVACHXAssistedCoolingCoil::VerifyHeatExchangerParent;
1633 : using MixedAir::GetOAMixerNumber;
1634 : using NodeInputManager::GetOnlySingleNode;
1635 : using OutAirNodeManager::SetOutAirNodes;
1636 : using RoomAir::GetRAFNNodeNum;
1637 :
1638 : // SUBROUTINE PARAMETER DEFINITIONS:
1639 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::get_input: "); // include trailing blank space
1640 :
1641 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1642 : int n;
1643 : int k;
1644 : int count;
1645 : bool NodeFound;
1646 : bool found;
1647 : int NumAPL;
1648 796 : Array1D_string CompName(2);
1649 796 : std::string SimAirNetworkKey;
1650 :
1651 : // Declare variables used in this subroutine for debug purpose
1652 796 : Array1D_int ZoneCheck;
1653 796 : Array1D_int ZoneBCCheck;
1654 :
1655 : int NumAlphas; // Number of Alphas for each GetObjectItem call
1656 : int NumNumbers; // Number of Numbers for each GetObjectItem call
1657 : int IOStatus; // Used in GetObjectItem
1658 796 : std::string CurrentModuleObject;
1659 796 : Array1D_string Alphas; // Alpha input items for object
1660 796 : Array1D_string cAlphaFields; // Alpha field names
1661 796 : Array1D_string cNumericFields; // Numeric field names
1662 796 : Array1D<Real64> Numbers; // Numeric input items for object
1663 796 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
1664 796 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
1665 796 : int MaxNums(0); // Maximum number of numeric input fields
1666 796 : int MaxAlphas(0); // Maximum number of alpha input fields
1667 796 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
1668 : Real64 minHeight;
1669 : Real64 maxHeight;
1670 : Real64 baseratio;
1671 :
1672 796 : auto &Node(m_state.dataLoopNodes->Node);
1673 :
1674 : // Formats
1675 : static constexpr std::string_view Format_110(
1676 : "! <AirflowNetwork Model:Control>, No Multizone or Distribution/Multizone with Distribution/Multizone "
1677 : "without Distribution/Multizone with Distribution only during Fan Operation\n");
1678 : static constexpr std::string_view Format_120("AirflowNetwork Model:Control,{}\n");
1679 :
1680 : // Set the maximum numbers of input fields
1681 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1682 : m_state, "AirflowNetwork:SimulationControl", TotalArgs, NumAlphas, NumNumbers);
1683 796 : MaxNums = max(MaxNums, NumNumbers);
1684 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1685 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(m_state, "AirflowNetwork:MultiZone:Zone", TotalArgs, NumAlphas, NumNumbers);
1686 796 : MaxNums = max(MaxNums, NumNumbers);
1687 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1688 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1689 : m_state, "AirflowNetwork:MultiZone:Surface", TotalArgs, NumAlphas, NumNumbers);
1690 796 : MaxNums = max(MaxNums, NumNumbers);
1691 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1692 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1693 : m_state, "AirflowNetwork:MultiZone:Component:DetailedOpening", TotalArgs, NumAlphas, NumNumbers);
1694 796 : MaxNums = max(MaxNums, NumNumbers);
1695 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1696 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1697 : m_state, "AirflowNetwork:MultiZone:ExternalNode", TotalArgs, NumAlphas, NumNumbers);
1698 796 : MaxNums = max(MaxNums, NumNumbers);
1699 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1700 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1701 : m_state, "AirflowNetwork:MultiZone:WindPressureCoefficientArray", TotalArgs, NumAlphas, NumNumbers);
1702 796 : MaxNums = max(MaxNums, NumNumbers);
1703 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1704 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1705 : m_state, "AirflowNetwork:MultiZone:WindPressureCoefficientValues", TotalArgs, NumAlphas, NumNumbers);
1706 796 : MaxNums = max(MaxNums, NumNumbers);
1707 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1708 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1709 : m_state, "AirflowNetwork:Distribution:Node", TotalArgs, NumAlphas, NumNumbers);
1710 796 : MaxNums = max(MaxNums, NumNumbers);
1711 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1712 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1713 : m_state, "AirflowNetwork:Distribution:DuctViewFactors", TotalArgs, NumAlphas, NumNumbers);
1714 796 : MaxNums = max(MaxNums, NumNumbers);
1715 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1716 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1717 : m_state, "AirflowNetwork:Distribution:Linkage", TotalArgs, NumAlphas, NumNumbers);
1718 796 : MaxNums = max(MaxNums, NumNumbers);
1719 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1720 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1721 : m_state, "AirflowNetwork:OccupantVentilationControl", TotalArgs, NumAlphas, NumNumbers);
1722 796 : MaxNums = max(MaxNums, NumNumbers);
1723 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1724 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(m_state, "AirflowNetwork:IntraZone:Node", TotalArgs, NumAlphas, NumNumbers);
1725 796 : MaxNums = max(MaxNums, NumNumbers);
1726 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1727 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1728 : m_state, "AirflowNetwork:IntraZone:Linkage", TotalArgs, NumAlphas, NumNumbers);
1729 796 : MaxNums = max(MaxNums, NumNumbers);
1730 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1731 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1732 : m_state, "AirflowNetwork:ZoneControl:PressureController", TotalArgs, NumAlphas, NumNumbers);
1733 796 : MaxNums = max(MaxNums, NumNumbers);
1734 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1735 796 : m_state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
1736 : m_state, "AirflowNetwork:Distribution:DuctSizing", TotalArgs, NumAlphas, NumNumbers);
1737 796 : MaxNums = max(MaxNums, NumNumbers);
1738 796 : MaxAlphas = max(MaxAlphas, NumAlphas);
1739 :
1740 796 : Alphas.allocate(MaxAlphas);
1741 796 : cAlphaFields.allocate(MaxAlphas);
1742 796 : cNumericFields.allocate(MaxNums);
1743 796 : Numbers.dimension(MaxNums, 0.0);
1744 796 : lAlphaBlanks.dimension(MaxAlphas, true);
1745 796 : lNumericBlanks.dimension(MaxNums, true);
1746 :
1747 796 : bool ErrorsFound = false;
1748 :
1749 796 : auto &Zone(m_state.dataHeatBal->Zone);
1750 :
1751 : // Read AirflowNetwork OccupantVentilationControl before reading other AirflowNetwork objects, so that this object can be called by other
1752 : // simple ventilation objects
1753 796 : CurrentModuleObject = "AirflowNetwork:OccupantVentilationControl";
1754 796 : AirflowNetworkNumOfOccuVentCtrls = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1755 796 : if (AirflowNetworkNumOfOccuVentCtrls > 0) {
1756 1 : OccupantVentilationControl.allocate(AirflowNetworkNumOfOccuVentCtrls);
1757 2 : for (int i = 1; i <= AirflowNetworkNumOfOccuVentCtrls; ++i) {
1758 1 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
1759 : CurrentModuleObject,
1760 : i,
1761 : Alphas,
1762 : NumAlphas,
1763 : Numbers,
1764 : NumNumbers,
1765 : IOStatus,
1766 : lNumericBlanks,
1767 : lAlphaBlanks,
1768 : cAlphaFields,
1769 : cNumericFields);
1770 1 : OccupantVentilationControl(i).Name = Alphas(1); // Name of object
1771 1 : OccupantVentilationControl(i).MinOpeningTime = Numbers(1);
1772 1 : if (OccupantVentilationControl(i).MinOpeningTime < 0.0) {
1773 : // Code will never be executed, validation will catch invalid input
1774 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(1) + " < 0.0");
1775 0 : ShowContinueError(m_state,
1776 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", OccupantVentilationControl(i).MinOpeningTime));
1777 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1778 0 : OccupantVentilationControl(i).MinOpeningTime = 0.0;
1779 : }
1780 1 : OccupantVentilationControl(i).MinClosingTime = Numbers(2);
1781 1 : if (OccupantVentilationControl(i).MinClosingTime < 0.0) {
1782 : // Code will never be executed, validation will catch invalid input
1783 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " < 0.0");
1784 0 : ShowContinueError(m_state,
1785 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", OccupantVentilationControl(i).MinClosingTime));
1786 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1787 0 : OccupantVentilationControl(i).MinClosingTime = 0.0;
1788 : }
1789 1 : if (NumAlphas == 1 && NumNumbers == 2) {
1790 0 : OccupantVentilationControl(i).MinTimeControlOnly = true;
1791 : }
1792 1 : if (!lAlphaBlanks(2)) {
1793 1 : OccupantVentilationControl(i).ComfortLowTempCurveName = Alphas(2);
1794 1 : OccupantVentilationControl(i).ComfortLowTempCurveNum = GetCurveIndex(m_state, Alphas(2)); // convert curve name to number
1795 1 : if (OccupantVentilationControl(i).ComfortLowTempCurveNum == 0) {
1796 0 : OccupantVentilationControl(i).MinTimeControlOnly = true;
1797 0 : ShowWarningError(m_state,
1798 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(2) +
1799 0 : " not found = " + OccupantVentilationControl(i).ComfortLowTempCurveName);
1800 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1801 0 : ShowContinueError(
1802 : m_state,
1803 : "Thermal comfort will not be performed and minimum opening and closing times are checked only. Simulation continues.");
1804 : } else {
1805 2 : ErrorsFound |= Curve::CheckCurveDims(m_state,
1806 1 : OccupantVentilationControl(i).ComfortLowTempCurveNum, // Curve index
1807 : {1}, // Valid dimensions
1808 : RoutineName, // Routine name
1809 : CurrentModuleObject, // Object Type
1810 1 : OccupantVentilationControl(i).Name, // Object Name
1811 1 : cAlphaFields(2)); // Field Name
1812 : }
1813 : }
1814 1 : if (!lAlphaBlanks(3)) {
1815 1 : OccupantVentilationControl(i).ComfortHighTempCurveName = Alphas(3);
1816 1 : OccupantVentilationControl(i).ComfortHighTempCurveNum = GetCurveIndex(m_state, Alphas(3)); // convert curve name to number
1817 1 : if (OccupantVentilationControl(i).ComfortHighTempCurveNum > 0) {
1818 2 : ErrorsFound |= Curve::CheckCurveDims(m_state,
1819 1 : OccupantVentilationControl(i).ComfortHighTempCurveNum, // Curve index
1820 : {1}, // Valid dimensions
1821 : RoutineName, // Routine name
1822 : CurrentModuleObject, // Object Type
1823 1 : OccupantVentilationControl(i).Name, // Object Name
1824 1 : cAlphaFields(3)); // Field Name
1825 : } else {
1826 0 : ShowWarningError(m_state,
1827 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) +
1828 0 : " not found = " + OccupantVentilationControl(i).ComfortHighTempCurveName);
1829 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1830 0 : ShowContinueError(m_state, "A single curve of thermal comfort low temperature is used only. Simulation continues.");
1831 : }
1832 : }
1833 1 : if (OccupantVentilationControl(i).ComfortHighTempCurveNum > 0) {
1834 1 : OccupantVentilationControl(i).ComfortBouPoint = Numbers(3);
1835 1 : if (OccupantVentilationControl(i).ComfortBouPoint < 0.0) {
1836 : // Code will never be executed, validation will catch invalid input
1837 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(3) + " < 0.0");
1838 0 : ShowContinueError(
1839 : m_state,
1840 0 : format("..Input value = {:.1R}, Value will be reset to 10.0 as default", OccupantVentilationControl(i).ComfortBouPoint));
1841 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1842 0 : OccupantVentilationControl(i).ComfortBouPoint = 10.0;
1843 : }
1844 : }
1845 : // Check continuity of both curves at boundary point
1846 1 : if (OccupantVentilationControl(i).ComfortLowTempCurveNum > 0 && OccupantVentilationControl(i).ComfortHighTempCurveNum) {
1847 1 : if (std::abs(CurveValue(m_state, OccupantVentilationControl(i).ComfortLowTempCurveNum, Numbers(3)) -
1848 1 : CurveValue(m_state, OccupantVentilationControl(i).ComfortHighTempCurveNum, Numbers(3))) > 0.1) {
1849 0 : ShowSevereError(m_state,
1850 0 : format(RoutineName) + CurrentModuleObject +
1851 : " object: The difference of both curve values at boundary point > 0.1");
1852 0 : ShowContinueError(m_state, "Both curve names are = " + cAlphaFields(2) + " and " + cAlphaFields(3));
1853 0 : ShowContinueError(m_state,
1854 0 : format("The input value of {} = {:.1R}", cNumericFields(3), OccupantVentilationControl(i).ComfortBouPoint));
1855 0 : ErrorsFound = true;
1856 : }
1857 : }
1858 1 : if (!lNumericBlanks(4)) {
1859 1 : OccupantVentilationControl(i).MaxPPD = Numbers(4);
1860 1 : if (OccupantVentilationControl(i).MaxPPD < 0.0 || OccupantVentilationControl(i).MaxPPD > 100.0) {
1861 : // Code will never be executed, validation will catch invalid input
1862 0 : ShowWarningError(m_state,
1863 0 : format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " beyond 0.0 and 100.0");
1864 0 : ShowContinueError(
1865 0 : m_state, format("..Input value = {:.1R}, Value will be reset to 10.0 as default", OccupantVentilationControl(i).MaxPPD));
1866 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + OccupantVentilationControl(i).Name);
1867 0 : OccupantVentilationControl(i).MaxPPD = 10.0;
1868 : }
1869 : }
1870 1 : if (!lAlphaBlanks(4)) {
1871 1 : if (Util::SameString(Alphas(4), "Yes")) {
1872 1 : OccupantVentilationControl(i).OccupancyCheck = true;
1873 0 : } else if (Util::SameString(Alphas(4), "No")) {
1874 0 : OccupantVentilationControl(i).OccupancyCheck = false;
1875 : } else {
1876 : // Code will never be executed, validation will catch invalid input
1877 0 : ShowSevereError(m_state,
1878 0 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" invalid " + cAlphaFields(2) + "=\"" +
1879 0 : Alphas(2) + "\" illegal key.");
1880 0 : ShowContinueError(m_state, "Valid keys are: Yes or No");
1881 0 : ErrorsFound = true;
1882 : }
1883 : }
1884 1 : if (!lAlphaBlanks(5)) {
1885 0 : OccupantVentilationControl(i).OpeningProbSchName = Alphas(5); // a schedule name for opening probability
1886 0 : OccupantVentilationControl(i).OpeningProbSchNum = GetScheduleIndex(m_state, OccupantVentilationControl(i).OpeningProbSchName);
1887 0 : if (OccupantVentilationControl(i).OpeningProbSchNum == 0) {
1888 0 : ShowSevereError(m_state,
1889 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(5) +
1890 0 : " not found = " + OccupantVentilationControl(i).OpeningProbSchName);
1891 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1892 0 : ErrorsFound = true;
1893 : }
1894 : }
1895 1 : if (!lAlphaBlanks(6)) {
1896 0 : OccupantVentilationControl(i).ClosingProbSchName = Alphas(6); // a schedule name for closing probability
1897 0 : OccupantVentilationControl(i).ClosingProbSchNum = GetScheduleIndex(m_state, OccupantVentilationControl(i).ClosingProbSchName);
1898 0 : if (OccupantVentilationControl(i).OpeningProbSchNum == 0) {
1899 0 : ShowSevereError(m_state,
1900 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) +
1901 0 : " not found = " + OccupantVentilationControl(i).ClosingProbSchName);
1902 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
1903 0 : ErrorsFound = true;
1904 : }
1905 : }
1906 : }
1907 : }
1908 :
1909 796 : if (ErrorsFound) {
1910 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
1911 : }
1912 :
1913 : // *** Read AirflowNetwork simulation parameters
1914 796 : CurrentModuleObject = "AirflowNetwork:SimulationControl";
1915 796 : NumAirflowNetwork = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
1916 796 : if (NumAirflowNetwork == 0) {
1917 761 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:Zone") >= 1 &&
1918 761 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:Surface") >= 2) {
1919 0 : control_defaulted = true;
1920 0 : simulation_control.name = "AFNDefaultControl";
1921 0 : simulation_control.type = ControlType::MultizoneWithoutDistribution;
1922 0 : simulation_control.WPCCntr = "SURFACEAVERAGECALCULATION";
1923 0 : simulation_control.HeightOption = "OPENINGHEIGHT";
1924 0 : simulation_control.BldgType = "LOWRISE";
1925 0 : simulation_control.InitType = "ZERONODEPRESSURES";
1926 0 : simulation_control.temperature_height_dependence = false;
1927 0 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
1928 : // Use default values for numerical fields
1929 0 : simulation_control.maximum_iterations = 500;
1930 0 : simulation_control.relative_convergence_tolerance = 1.E-4;
1931 0 : simulation_control.absolute_convergence_tolerance = 1.E-6;
1932 0 : simulation_control.convergence_acceleration_limit = -0.5;
1933 0 : simulation_control.azimuth = 0.0;
1934 0 : simulation_control.aspect_ratio = 1.0;
1935 0 : simulation_control.MaxPressure = 500.0; // Maximum pressure difference by default
1936 0 : SimAirNetworkKey = "MultizoneWithoutDistribution";
1937 0 : simulation_control.InitFlag = 1;
1938 0 : ShowWarningError(m_state, format("{}{} object is not found ", RoutineName, CurrentModuleObject));
1939 0 : ShowContinueError(m_state, "..The default behaviour values are assigned. Please see details in Input Output Reference.");
1940 : } else {
1941 761 : simulation_control.type = ControlType::NoMultizoneOrDistribution;
1942 761 : print(m_state.files.eio, Format_110);
1943 761 : print(m_state.files.eio, Format_120, "NoMultizoneOrDistribution");
1944 761 : return;
1945 : }
1946 : }
1947 35 : if (NumAirflowNetwork > 1) {
1948 0 : ShowFatalError(m_state, format("{}Only one (\"1\") {} object per simulation is allowed.", RoutineName, CurrentModuleObject));
1949 : }
1950 :
1951 35 : if (!control_defaulted) {
1952 35 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
1953 : CurrentModuleObject,
1954 : NumAirflowNetwork,
1955 : Alphas,
1956 : NumAlphas,
1957 : Numbers,
1958 : NumNumbers,
1959 : IOStatus,
1960 : lNumericBlanks,
1961 : lAlphaBlanks,
1962 : cAlphaFields,
1963 : cNumericFields);
1964 :
1965 35 : simulation_control.name = Alphas(1);
1966 35 : simulation_control.WPCCntr = Alphas(3);
1967 35 : simulation_control.HeightOption = Alphas(4);
1968 35 : simulation_control.BldgType = Alphas(5);
1969 :
1970 : // Retrieve flag allowing the support of zone equipment
1971 35 : simulation_control.allow_unsupported_zone_equipment = false;
1972 35 : if (Util::SameString(Alphas(9), "Yes")) {
1973 3 : simulation_control.allow_unsupported_zone_equipment = true;
1974 : }
1975 :
1976 : // Find a flag for possible combination of vent and distribution system
1977 : // This SELECT_CASE_var will go on input refactor, no need to fix
1978 : {
1979 35 : auto const SELECT_CASE_var(Util::makeUPPER(Alphas(2)));
1980 35 : if (SELECT_CASE_var == "NOMULTIZONEORDISTRIBUTION") {
1981 0 : simulation_control.type = ControlType::NoMultizoneOrDistribution;
1982 0 : SimAirNetworkKey = "NoMultizoneOrDistribution";
1983 35 : } else if (SELECT_CASE_var == "MULTIZONEWITHOUTDISTRIBUTION") {
1984 12 : simulation_control.type = ControlType::MultizoneWithoutDistribution;
1985 12 : SimAirNetworkKey = "MultizoneWithoutDistribution";
1986 23 : } else if (SELECT_CASE_var == "MULTIZONEWITHDISTRIBUTIONONLYDURINGFANOPERATION") {
1987 2 : simulation_control.type = ControlType::MultizoneWithDistributionOnlyDuringFanOperation;
1988 2 : SimAirNetworkKey = "MultizoneWithDistributionOnlyDuringFanOperation";
1989 : } else { // if (SELECT_CASE_var == "MULTIZONEWITHDISTRIBUTION") {
1990 21 : simulation_control.type = ControlType::MultizoneWithDistribution;
1991 21 : SimAirNetworkKey = "MultizoneWithDistribution";
1992 : }
1993 35 : }
1994 : }
1995 :
1996 : // Determine a convenience boolean or two to simplify the checking
1997 : // The first one is true if distribution is simulated, replaces some > and >= comparisons
1998 : // SimulateAirflowNetwork > AirflowNetworkControlMultizone -> type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation
1999 : // type == ControlType::MultizoneWithDistribution
2000 : // SimulateAirflowNetwork >= AirflowNetworkControlSimpleADS -> type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation
2001 : // type == ControlType::MultizoneWithDistribution
2002 68 : distribution_simulated = simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation ||
2003 33 : simulation_control.type == ControlType::MultizoneWithDistribution;
2004 : // This one is true if the multizone simulation is ALWAYS done
2005 35 : multizone_always_simulated =
2006 35 : simulation_control.type == ControlType::MultizoneWithDistribution || simulation_control.type == ControlType::MultizoneWithoutDistribution;
2007 :
2008 : // Check the number of primary air loops
2009 35 : if (distribution_simulated) {
2010 23 : NumAPL = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirLoopHVAC");
2011 23 : if (NumAPL > 0) {
2012 23 : LoopPartLoadRatio.allocate(NumAPL);
2013 23 : LoopOnOffFanRunTimeFraction.allocate(NumAPL);
2014 23 : LoopOnOffFlag.allocate(NumAPL);
2015 23 : LoopPartLoadRatio = 0.0;
2016 23 : LoopOnOffFanRunTimeFraction = 0.0;
2017 23 : LoopOnOffFlag = false;
2018 : }
2019 : }
2020 35 : print(m_state.files.eio, Format_110);
2021 35 : print(m_state.files.eio, Format_120, SimAirNetworkKey);
2022 :
2023 35 : if (control_defaulted) {
2024 0 : cAlphaFields(2) = "AirflowNetwork Control";
2025 : }
2026 :
2027 : // Check whether there are any objects from infiltration, ventilation, mixing and cross mixing
2028 35 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution ||
2029 35 : simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation) {
2030 2 : if (m_state.dataHeatBal->TotInfiltration + m_state.dataHeatBal->TotVentilation + m_state.dataHeatBal->TotMixing +
2031 2 : m_state.dataHeatBal->TotCrossMixing + m_state.dataHeatBal->TotZoneAirBalance +
2032 2 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneEarthtube") +
2033 2 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneThermalChimney") +
2034 2 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneCoolTower:Shower") ==
2035 : 0) {
2036 0 : ShowWarningError(m_state, format("{}{} = \"{}\"", RoutineName, cAlphaFields(2), SimAirNetworkKey));
2037 0 : ShowContinueError(
2038 : m_state,
2039 : "..but there are no Infiltration, Ventilation, Mixing, Cross Mixing or ZoneAirBalance objects. The simulation continues...");
2040 : }
2041 : }
2042 :
2043 : // Check whether a user wants to perform SIMPLE calculation only or not
2044 35 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) {
2045 0 : return;
2046 : }
2047 :
2048 35 : if (multizone_always_simulated) {
2049 33 : if (m_state.dataHeatBal->TotInfiltration > 0) {
2050 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2051 0 : ShowContinueError(m_state,
2052 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneInfiltration:* objects are present.");
2053 0 : ShowContinueError(m_state, "..ZoneInfiltration objects will not be simulated.");
2054 : }
2055 33 : if (m_state.dataHeatBal->TotVentilation > 0) {
2056 3 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2057 6 : ShowContinueError(m_state,
2058 6 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneVentilation:* objects are present.");
2059 3 : ShowContinueError(m_state, "..ZoneVentilation objects will not be simulated.");
2060 : }
2061 33 : if (m_state.dataHeatBal->TotMixing > 0) {
2062 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2063 0 : ShowContinueError(m_state, "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneMixing objects are present.");
2064 0 : ShowContinueError(m_state, "..ZoneMixing objects will not be simulated.");
2065 : }
2066 33 : if (m_state.dataHeatBal->TotCrossMixing > 0) {
2067 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2068 0 : ShowContinueError(m_state,
2069 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneCrossMixing objects are present.");
2070 0 : ShowContinueError(m_state, "..ZoneCrossMixing objects will not be simulated.");
2071 : }
2072 33 : if (m_state.dataHeatBal->TotZoneAirBalance > 0) {
2073 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2074 0 : ShowContinueError(
2075 0 : m_state, "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneAirBalance:OutdoorAir objects are present.");
2076 0 : ShowContinueError(m_state, "..ZoneAirBalance:OutdoorAir objects will not be simulated.");
2077 : }
2078 33 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneEarthtube") > 0) {
2079 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2080 0 : ShowContinueError(m_state,
2081 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneEarthtube objects are present.");
2082 0 : ShowContinueError(m_state, "..ZoneEarthtube objects will not be simulated.");
2083 : }
2084 33 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneThermalChimney") > 0) {
2085 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2086 0 : ShowContinueError(m_state,
2087 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneThermalChimney objects are present.");
2088 0 : ShowContinueError(m_state, "..ZoneThermalChimney objects will not be simulated.");
2089 : }
2090 33 : if (m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "ZoneCoolTower:Shower") > 0) {
2091 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2092 0 : ShowContinueError(m_state,
2093 0 : "..Specified " + cAlphaFields(2) + " = \"" + SimAirNetworkKey + "\" and ZoneCoolTower:Shower objects are present.");
2094 0 : ShowContinueError(m_state, "..ZoneCoolTower:Shower objects will not be simulated.");
2095 : }
2096 : }
2097 :
2098 35 : SetOutAirNodes(m_state);
2099 35 : if (!control_defaulted) {
2100 35 : bool SimObjectError = false;
2101 35 : if (Util::SameString(simulation_control.WPCCntr, "Input")) {
2102 27 : simulation_control.iWPCCnt = iWPCCntr::Input;
2103 27 : if (lAlphaBlanks(4)) {
2104 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) + " = INPUT.");
2105 0 : ShowContinueError(m_state, ".." + cAlphaFields(4) + " was not entered.");
2106 0 : ErrorsFound = true;
2107 0 : SimObjectError = true;
2108 : } else {
2109 27 : if (!(Util::SameString(simulation_control.HeightOption, "ExternalNode") ||
2110 27 : Util::SameString(simulation_control.HeightOption, "OpeningHeight"))) {
2111 0 : ShowSevereError(
2112 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(4) + " = " + Alphas(4) + " is invalid.");
2113 0 : ShowContinueError(m_state,
2114 0 : "Valid choices are ExternalNode or OpeningHeight. " + CurrentModuleObject + ": " + cAlphaFields(1) + " = " +
2115 0 : simulation_control.name);
2116 0 : ErrorsFound = true;
2117 0 : SimObjectError = true;
2118 : }
2119 : }
2120 8 : } else if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
2121 8 : simulation_control.iWPCCnt = iWPCCntr::SurfAvg;
2122 8 : if (!(Util::SameString(simulation_control.BldgType, "LowRise") || Util::SameString(simulation_control.BldgType, "HighRise"))) {
2123 0 : ShowSevereError(m_state,
2124 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(5) + " = " + Alphas(5) + " is invalid.");
2125 0 : ShowContinueError(m_state,
2126 0 : "Valid choices are LowRise or HighRise. " + CurrentModuleObject + ": " + cAlphaFields(1) + " = " +
2127 0 : simulation_control.name);
2128 0 : ErrorsFound = true;
2129 0 : SimObjectError = true;
2130 : }
2131 160 : for (k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
2132 152 : if (Node(k).IsLocalNode) {
2133 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(3) + "=" + Alphas(3));
2134 0 : ShowContinueError(m_state,
2135 : "A local air node is defined to INPUT the wind pressure coefficient curve, while Wind Pressure Coefficient "
2136 : "Type is set to SurfaceAverageCalculation.");
2137 0 : ShowContinueError(m_state, "It requires the Wind Pressure Coefficient Type be set to INPUT to use the local air node.");
2138 0 : ErrorsFound = true;
2139 0 : SimObjectError = true;
2140 0 : break;
2141 : }
2142 : }
2143 : } else {
2144 0 : ShowSevereError(m_state,
2145 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) + " = " + simulation_control.WPCCntr +
2146 : " is not valid.");
2147 0 : ShowContinueError(m_state,
2148 0 : "Valid choices are Input or SurfaceAverageCalculation. " + CurrentModuleObject + " = " + simulation_control.name);
2149 0 : ErrorsFound = true;
2150 0 : SimObjectError = true;
2151 : }
2152 :
2153 35 : simulation_control.InitType = Alphas(6);
2154 35 : if (Util::SameString(simulation_control.InitType, "LinearInitializationMethod")) {
2155 0 : simulation_control.InitFlag = 0;
2156 35 : } else if (Util::SameString(simulation_control.InitType, "ZeroNodePressures")) {
2157 35 : simulation_control.InitFlag = 1;
2158 0 : } else if (Util::SameString(simulation_control.InitType, "0")) {
2159 0 : simulation_control.InitFlag = 0;
2160 0 : } else if (Util::SameString(simulation_control.InitType, "1")) {
2161 0 : simulation_control.InitFlag = 1;
2162 : } else {
2163 : // Code will never be executed, validation will catch invalid input
2164 0 : ShowSevereError(m_state,
2165 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) + " = " + Alphas(6) + " is invalid.");
2166 0 : ShowContinueError(m_state,
2167 0 : "Valid choices are LinearInitializationMethod or ZeroNodePressures. " + CurrentModuleObject + " = " +
2168 0 : simulation_control.name);
2169 0 : ErrorsFound = true;
2170 0 : SimObjectError = true;
2171 : }
2172 :
2173 35 : if (!lAlphaBlanks(7) && Util::SameString(Alphas(7), "Yes")) simulation_control.temperature_height_dependence = true;
2174 :
2175 35 : if (lAlphaBlanks(8)) {
2176 34 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2177 1 : } else if (Util::SameString(Alphas(8), "SkylineLU")) {
2178 1 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2179 0 : } else if (Util::SameString(Alphas(8), "ConjugateGradient")) {
2180 0 : simulation_control.solver = SimulationControl::Solver::ConjugateGradient;
2181 : } else {
2182 0 : simulation_control.solver = SimulationControl::Solver::SkylineLU;
2183 0 : ShowWarningError(m_state, format("{}{} object, ", RoutineName, CurrentModuleObject));
2184 0 : ShowContinueError(m_state, "..Specified " + cAlphaFields(8) + " = \"" + Alphas(8) + "\" is unrecognized.");
2185 0 : ShowContinueError(m_state, "..Default value \"SkylineLU\" will be used.");
2186 : }
2187 :
2188 : // Get inputs for duct sizing
2189 35 : simulation_control.autosize_ducts = false;
2190 35 : if (NumAlphas == 10) {
2191 35 : if (Util::SameString(Alphas(10), "YES")) {
2192 1 : simulation_control.autosize_ducts = true;
2193 1 : if (simulation_control.type == ControlType::MultizoneWithDistribution) {
2194 1 : if (NumAPL > 1) {
2195 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2196 0 : ShowContinueError(
2197 : m_state,
2198 0 : format("The number of AirLoopHAVC is greater than 1. The current requirement for Duct Sizing requires a "
2199 : "single AirLoopHVAC."));
2200 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2201 0 : simulation_control.autosize_ducts = false;
2202 : }
2203 : }
2204 : }
2205 : }
2206 :
2207 35 : if (SimObjectError) {
2208 0 : ShowFatalError(
2209 : m_state,
2210 0 : format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
2211 : }
2212 :
2213 35 : simulation_control.maximum_iterations = static_cast<int>(Numbers(1));
2214 35 : simulation_control.relative_convergence_tolerance = Numbers(2);
2215 35 : simulation_control.absolute_convergence_tolerance = Numbers(3);
2216 35 : simulation_control.convergence_acceleration_limit = Numbers(4);
2217 35 : simulation_control.azimuth = Numbers(5);
2218 35 : simulation_control.aspect_ratio = Numbers(6);
2219 35 : simulation_control.MaxPressure = 500.0; // Maximum pressure difference by default
2220 : }
2221 :
2222 35 : CurrentModuleObject = "AirflowNetwork:Distribution:DuctSizing";
2223 35 : int NumDuctSizing = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2224 35 : if (NumDuctSizing > 1) {
2225 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2226 0 : ShowContinueError(
2227 : m_state,
2228 0 : format("The number of AirflowNetwork:Distribution:DuctSizing is greater than 1. The current requirement for Duct Sizing requires a "
2229 : "single object."));
2230 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2231 0 : simulation_control.autosize_ducts = false;
2232 35 : } else if (simulation_control.autosize_ducts && NumDuctSizing == 0) {
2233 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2234 0 : ShowContinueError(
2235 : m_state,
2236 0 : format("The number of AirflowNetwork:Distribution:DuctSizing is not avalable. The current requirement for Duct Sizing requires a "
2237 : "single object."));
2238 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2239 0 : simulation_control.autosize_ducts = false;
2240 : }
2241 35 : if (simulation_control.autosize_ducts && NumDuctSizing == 1) {
2242 1 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2243 : CurrentModuleObject,
2244 : NumDuctSizing,
2245 : Alphas,
2246 : NumAlphas,
2247 : Numbers,
2248 : NumNumbers,
2249 : IOStatus,
2250 : lNumericBlanks,
2251 : lAlphaBlanks,
2252 : cAlphaFields,
2253 : cNumericFields);
2254 :
2255 1 : simulation_control.ductSizing.name = Alphas(1);
2256 1 : if (Util::SameString(Alphas(2), Util::makeUPPER("MaximumVelocity"))) {
2257 0 : simulation_control.ductSizing.method = DuctSizingMethod::MaxVelocity;
2258 1 : } else if (Util::SameString(Alphas(2), Util::makeUPPER("PressureLoss"))) {
2259 1 : simulation_control.ductSizing.method = DuctSizingMethod::PressureLoss;
2260 0 : } else if (Util::SameString(Alphas(2), Util::makeUPPER("PressureLossWithMaximumVelocity"))) {
2261 0 : simulation_control.ductSizing.method = DuctSizingMethod::VelocityAndLoss;
2262 : } else {
2263 0 : ShowSevereError(m_state, format("{} {} object, {} = {} is invalid.", RoutineName, CurrentModuleObject, cAlphaFields(2), Alphas(2)));
2264 0 : ShowContinueError(m_state,
2265 0 : format("Valid choices are MaximumVelocity, PressureLoss, and PressureLossWithMaximumVelocity. {}: {} = {}",
2266 : CurrentModuleObject,
2267 : cAlphaFields(1),
2268 : Alphas(1)));
2269 0 : ErrorsFound = true;
2270 : }
2271 1 : if (simulation_control.type != ControlType::MultizoneWithDistribution) {
2272 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, ");
2273 0 : ShowContinueError(m_state,
2274 0 : format("Although {} = \"{}\" is entered, but {} is not MultizoneWithoutDistribution.",
2275 : cAlphaFields(10),
2276 : Alphas(10),
2277 : cAlphaFields(2)));
2278 0 : ShowContinueError(m_state, format("..Duct sizing is not performed"));
2279 0 : simulation_control.autosize_ducts = false;
2280 : }
2281 1 : simulation_control.ductSizing.factor = Numbers(1);
2282 1 : simulation_control.ductSizing.max_velocity = Numbers(2);
2283 1 : simulation_control.ductSizing.supply_trunk_pressure_loss = Numbers(3);
2284 1 : simulation_control.ductSizing.supply_branch_pressure_loss = Numbers(4);
2285 1 : simulation_control.ductSizing.return_trunk_pressure_loss = Numbers(5);
2286 1 : simulation_control.ductSizing.return_branch_pressure_loss = Numbers(6);
2287 : }
2288 :
2289 : // *** Read AirflowNetwork simulation zone data
2290 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:Zone";
2291 35 : AirflowNetworkNumOfZones = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2292 35 : if (AirflowNetworkNumOfZones > 0) {
2293 35 : MultizoneZoneData.allocate(AirflowNetworkNumOfZones);
2294 35 : AirflowNetworkZoneFlag.dimension(m_state.dataGlobal->NumOfZones, false); // AirflowNetwork zone flag
2295 150 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
2296 115 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2297 : CurrentModuleObject,
2298 : i,
2299 : Alphas,
2300 : NumAlphas,
2301 : Numbers,
2302 : NumNumbers,
2303 : IOStatus,
2304 : lNumericBlanks,
2305 : lAlphaBlanks,
2306 : cAlphaFields,
2307 : cNumericFields);
2308 115 : MultizoneZoneData(i).ZoneName = Alphas(1); // Name of Associated EnergyPlus Thermal Zone
2309 115 : if (!lAlphaBlanks(2)) MultizoneZoneData(i).VentControl = Alphas(2); // Ventilation Control Mode: "Temperature", "Enthalpy",
2310 : // "ASHRAE55ADAPTIVE", "CEN15251AdaptiveComfort,
2311 : // "Constant", or "NoVent"
2312 115 : MultizoneZoneData(i).VentSchName = Alphas(3); // Name of ventilation temperature control schedule
2313 115 : MultizoneZoneData(i).OpenFactor = Numbers(1); // Limit Value on Multiplier for Modulating Venting Open Factor,
2314 : // Not applicable if Vent Control Mode = CONSTANT or NOVENT
2315 115 : MultizoneZoneData(i).LowValueTemp = Numbers(2); // Lower Value on Inside/Outside Temperature Difference
2316 : // for Modulating the Venting Open Factor with temp control
2317 115 : MultizoneZoneData(i).UpValueTemp = Numbers(3); // Upper Value on Inside/Outside Temperature Difference
2318 : // for Modulating the Venting Open Factor with temp control
2319 115 : MultizoneZoneData(i).LowValueEnth = Numbers(4); // Lower Value on Inside/Outside Temperature Difference
2320 : // for Modulating the Venting Open Factor with Enthalpy control
2321 115 : MultizoneZoneData(i).UpValueEnth = Numbers(5); // Upper Value on Inside/Outside Temperature Difference
2322 : // for Modulating the Venting Open Factor with Enthalpy control
2323 115 : MultizoneZoneData(i).VentCtrNum = VentControlType::None;
2324 115 : MultizoneZoneData(i).SingleSidedCpType = Alphas(5);
2325 115 : MultizoneZoneData(i).BuildWidth = Numbers(6);
2326 :
2327 115 : if (!lAlphaBlanks(6)) {
2328 1 : MultizoneZoneData(i).OccupantVentilationControlName = Alphas(6);
2329 2 : MultizoneZoneData(i).OccupantVentilationControlNum =
2330 1 : Util::FindItemInList(MultizoneZoneData(i).OccupantVentilationControlName, OccupantVentilationControl);
2331 1 : if (MultizoneZoneData(i).OccupantVentilationControlNum == 0) {
2332 0 : ShowSevereError(m_state,
2333 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(6) +
2334 0 : " not found = " + MultizoneZoneData(i).OccupantVentilationControlName);
2335 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
2336 0 : ErrorsFound = true;
2337 : }
2338 : }
2339 115 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Temperature")) MultizoneZoneData(i).VentCtrNum = VentControlType::Temp;
2340 115 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Enthalpy")) MultizoneZoneData(i).VentCtrNum = VentControlType::Enth;
2341 115 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Constant")) MultizoneZoneData(i).VentCtrNum = VentControlType::Const;
2342 115 : if (Util::SameString(MultizoneZoneData(i).VentControl, "ASHRAE55Adaptive")) MultizoneZoneData(i).VentCtrNum = VentControlType::ASH55;
2343 115 : if (Util::SameString(MultizoneZoneData(i).VentControl, "CEN15251Adaptive"))
2344 0 : MultizoneZoneData(i).VentCtrNum = VentControlType::CEN15251;
2345 115 : if (Util::SameString(MultizoneZoneData(i).VentControl, "NoVent")) MultizoneZoneData(i).VentCtrNum = VentControlType::NoVent;
2346 :
2347 115 : if (MultizoneZoneData(i).VentCtrNum < NumOfVentCtrTypes) {
2348 67 : if (NumAlphas >= 4 && (!lAlphaBlanks(4))) {
2349 32 : MultizoneZoneData(i).VentingSchName = Alphas(4);
2350 32 : MultizoneZoneData(i).VentingSchNum = GetScheduleIndex(m_state, MultizoneZoneData(i).VentingSchName);
2351 32 : if (MultizoneZoneData(i).VentingSchNum == 0) {
2352 0 : ShowSevereError(m_state,
2353 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(4) +
2354 0 : " not found = " + MultizoneZoneData(i).VentingSchName);
2355 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
2356 0 : ErrorsFound = true;
2357 : }
2358 : }
2359 : } else {
2360 48 : MultizoneZoneData(i).VentingSchName = std::string();
2361 48 : MultizoneZoneData(i).VentingSchNum = 0;
2362 : }
2363 : }
2364 : } else {
2365 0 : ShowSevereError(m_state,
2366 0 : format(RoutineName) + "For an AirflowNetwork Simulation, at least one " + CurrentModuleObject +
2367 : " object is required but none were found.");
2368 0 : ShowFatalError(
2369 0 : m_state, format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
2370 : }
2371 :
2372 : // ==> Zone data validation
2373 150 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
2374 : // Zone name validation
2375 115 : MultizoneZoneData(i).ZoneNum = Util::FindItemInList(MultizoneZoneData(i).ZoneName, Zone);
2376 115 : if (MultizoneZoneData(i).ZoneNum == 0) {
2377 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(1) + " given.");
2378 0 : ShowContinueError(m_state, "..invalid " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\"");
2379 0 : ErrorsFound = true;
2380 : } else {
2381 115 : AirflowNetworkZoneFlag(MultizoneZoneData(i).ZoneNum) = true;
2382 115 : MultizoneZoneData(i).Height = Zone(MultizoneZoneData(i).ZoneNum).Centroid.z; // Nodal height
2383 : }
2384 115 : if (MultizoneZoneData(i).VentCtrNum == VentControlType::None) {
2385 0 : ShowSevereError(m_state,
2386 0 : format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(2) + " = " +
2387 0 : MultizoneZoneData(i).VentControl);
2388 0 : ShowContinueError(m_state, "Valid choices are Temperature, Enthalpy, Constant, or NoVent");
2389 0 : ShowContinueError(m_state, ".. in " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\"");
2390 0 : ErrorsFound = true;
2391 : }
2392 115 : if (Util::SameString(MultizoneZoneData(i).VentControl, "Temperature") || Util::SameString(MultizoneZoneData(i).VentControl, "Enthalpy")) {
2393 : // .or. &
2394 : // Util::SameString(MultizoneZoneData(i)%VentControl,'ASHRAE55Adaptive') .or. &
2395 : // Util::SameString(MultizoneZoneData(i)%VentControl,'CEN15251Adaptive')) then
2396 55 : MultizoneZoneData(i).VentSchNum = GetScheduleIndex(m_state, MultizoneZoneData(i).VentSchName);
2397 55 : if (MultizoneZoneData(i).VentSchName == std::string()) {
2398 0 : ShowSevereError(m_state,
2399 0 : format(RoutineName) + CurrentModuleObject + " object, No " + cAlphaFields(3) +
2400 0 : " was found, but is required when " + cAlphaFields(2) + " is Temperature or Enthalpy.");
2401 0 : ShowContinueError(m_state,
2402 0 : "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\", with " + cAlphaFields(2) + " = \"" +
2403 0 : MultizoneZoneData(i).VentControl + "\"");
2404 0 : ErrorsFound = true;
2405 55 : } else if (MultizoneZoneData(i).VentSchNum == 0) {
2406 0 : ShowSevereError(m_state,
2407 0 : format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(3) + ", required when " +
2408 0 : cAlphaFields(2) + " is Temperature or Enthalpy.");
2409 0 : ShowContinueError(m_state, ".." + cAlphaFields(3) + " in error = " + MultizoneZoneData(i).VentSchName);
2410 0 : ShowContinueError(m_state,
2411 0 : "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\", with " + cAlphaFields(2) + " = \"" +
2412 0 : MultizoneZoneData(i).VentControl + "\"");
2413 0 : ErrorsFound = true;
2414 : }
2415 : } else {
2416 60 : MultizoneZoneData(i).VentSchNum = GetScheduleIndex(m_state, MultizoneZoneData(i).VentSchName);
2417 60 : if (MultizoneZoneData(i).VentSchNum > 0) {
2418 4 : ShowWarningError(m_state,
2419 4 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(3) + " not required, when " +
2420 6 : cAlphaFields(2) + " is neither Temperature nor Enthalpy.");
2421 2 : ShowContinueError(m_state, ".." + cAlphaFields(3) + " specified = " + MultizoneZoneData(i).VentSchName);
2422 4 : ShowContinueError(m_state,
2423 4 : "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName + "\", with " + cAlphaFields(2) + " = \"" +
2424 6 : MultizoneZoneData(i).VentControl + "\"");
2425 2 : MultizoneZoneData(i).VentSchNum = 0;
2426 2 : MultizoneZoneData(i).VentSchName = std::string();
2427 : }
2428 : }
2429 115 : if (MultizoneZoneData(i).OpenFactor > 1.0 || MultizoneZoneData(i).OpenFactor < 0.0) {
2430 : // Code will never be executed, validation will catch invalid input
2431 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(1) + " is out of range [0.0,1.0]");
2432 0 : ShowContinueError(m_state, format("..Input value = {:.2R}, Value will be set to 1.0", MultizoneZoneData(i).OpenFactor));
2433 0 : MultizoneZoneData(i).OpenFactor = 1.0;
2434 : }
2435 :
2436 : {
2437 : // These SELECT_CASE_vars will go on input refactor, no need to fix
2438 115 : auto const SELECT_CASE_var(Util::makeUPPER(MultizoneZoneData(i).VentControl));
2439 115 : if (SELECT_CASE_var == "TEMPERATURE") { // checks on Temperature control
2440 55 : if (MultizoneZoneData(i).LowValueTemp < 0.0) {
2441 : // Code will never be executed, validation will catch invalid input
2442 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " < 0.0");
2443 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be set to 0.0", MultizoneZoneData(i).LowValueTemp));
2444 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2445 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
2446 : }
2447 55 : if (MultizoneZoneData(i).LowValueTemp >= 100.0) {
2448 : // Code will never be executed, validation will catch invalid input
2449 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(2) + " >= 100.0");
2450 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneZoneData(i).LowValueTemp));
2451 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2452 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
2453 : }
2454 55 : if (MultizoneZoneData(i).UpValueTemp <= MultizoneZoneData(i).LowValueTemp) {
2455 0 : ShowWarningError(m_state,
2456 0 : format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(3) + " <= " + cNumericFields(2));
2457 0 : ShowContinueError(m_state,
2458 0 : format("..Input value for {} = {:.1R}, Value will be reset to 100.0",
2459 : cNumericFields(3),
2460 0 : MultizoneZoneData(i).UpValueTemp));
2461 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2462 0 : MultizoneZoneData(i).UpValueTemp = 100.0;
2463 : }
2464 :
2465 60 : } else if (SELECT_CASE_var == "ENTHALPY") { // checks for Enthalpy control
2466 0 : if (MultizoneZoneData(i).LowValueEnth < 0.0) {
2467 : // Code will never be executed, validation will catch invalid input
2468 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " < 0.0");
2469 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneZoneData(i).LowValueEnth));
2470 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2471 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
2472 : }
2473 0 : if (MultizoneZoneData(i).LowValueEnth >= 300000.0) {
2474 : // Code will never be executed, validation will catch invalid input
2475 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, " + cNumericFields(4) + " >= 300000.0");
2476 0 : ShowContinueError(m_state, format("..Input value = {:.1R}, Value will be reset to 0.0.", MultizoneZoneData(i).LowValueEnth));
2477 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2478 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
2479 : }
2480 0 : if (MultizoneZoneData(i).UpValueEnth <= MultizoneZoneData(i).LowValueEnth) {
2481 0 : ShowWarningError(m_state,
2482 0 : format("{}{} object, {} <= {}", RoutineName, CurrentModuleObject, cNumericFields(5), cNumericFields(4)));
2483 0 : ShowContinueError(m_state,
2484 0 : format("..Input value for {}= {:.1R}, Value will be reset to 300000.0",
2485 : cNumericFields(5),
2486 0 : MultizoneZoneData(i).UpValueEnth));
2487 0 : ShowContinueError(m_state, "..for " + cAlphaFields(1) + " = \"" + MultizoneZoneData(i).ZoneName);
2488 0 : MultizoneZoneData(i).UpValueEnth = 300000.0;
2489 : }
2490 60 : } else if (SELECT_CASE_var == "ASHRAE55ADAPTIVE") {
2491 : // Check that for the given zone, there is a people object for which ASHRAE 55 calculations are carried out
2492 1 : int ZoneNum = MultizoneZoneData(i).ZoneNum;
2493 2 : for (int j = 1; j <= m_state.dataHeatBal->TotPeople; ++j) {
2494 1 : if (ZoneNum == m_state.dataHeatBal->People(j).ZonePtr && m_state.dataHeatBal->People(j).AdaptiveASH55) {
2495 1 : MultizoneZoneData(i).ASH55PeopleInd = j;
2496 : }
2497 : }
2498 1 : if (MultizoneZoneData(i).ASH55PeopleInd == 0) {
2499 0 : ShowFatalError(m_state,
2500 0 : "ASHRAE55 ventilation control for zone " + MultizoneZoneData(i).ZoneName +
2501 : " requires a people object with respective model calculations.");
2502 : }
2503 59 : } else if (SELECT_CASE_var == "CEN15251ADAPTIVE") {
2504 : // Check that for the given zone, there is a people object for which CEN-15251 calculations are carried out
2505 0 : int ZoneNum = MultizoneZoneData(i).ZoneNum;
2506 0 : for (int j = 1; j <= m_state.dataHeatBal->TotPeople; ++j) {
2507 0 : if (ZoneNum == m_state.dataHeatBal->People(j).ZonePtr && m_state.dataHeatBal->People(j).AdaptiveCEN15251) {
2508 0 : MultizoneZoneData(i).CEN15251PeopleInd = j;
2509 0 : break;
2510 : }
2511 : }
2512 0 : if (MultizoneZoneData(i).CEN15251PeopleInd == 0) {
2513 0 : ShowFatalError(m_state,
2514 0 : "CEN15251 ventilation control for zone " + MultizoneZoneData(i).ZoneName +
2515 : " requires a people object with respective model calculations.");
2516 : }
2517 : } else {
2518 : }
2519 115 : }
2520 : }
2521 :
2522 : // *** Read AirflowNetwork external node
2523 35 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
2524 : // Wind coefficient == Surface-Average does not need inputs of external nodes
2525 27 : AirflowNetworkNumOfExtNode =
2526 27 : m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "AirflowNetwork:MultiZone:ExternalNode");
2527 27 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel) {
2528 1 : AirflowNetworkNumOfOutAirNode = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, "OutdoorAir:Node");
2529 1 : AirflowNetworkNumOfExtNode += AirflowNetworkNumOfOutAirNode;
2530 : }
2531 :
2532 27 : if (AirflowNetworkNumOfExtNode > 0) {
2533 27 : MultizoneExternalNodeData.allocate(AirflowNetworkNumOfExtNode);
2534 27 : CurrentModuleObject = "AirflowNetwork:MultiZone:ExternalNode";
2535 142 : for (int i = 1; i <= AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode; ++i) {
2536 115 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2537 : CurrentModuleObject,
2538 : i,
2539 : Alphas,
2540 : NumAlphas,
2541 : Numbers,
2542 : NumNumbers,
2543 : IOStatus,
2544 : lNumericBlanks,
2545 : lAlphaBlanks,
2546 : cAlphaFields,
2547 : cNumericFields);
2548 115 : MultizoneExternalNodeData(i).Name = Alphas(1); // Name of external node
2549 115 : MultizoneExternalNodeData(i).height = Numbers(1); // Nodal height
2550 115 : if (Util::SameString(simulation_control.HeightOption, "ExternalNode") && lNumericBlanks(1)) {
2551 0 : ShowWarningError(m_state,
2552 0 : format(RoutineName) + CurrentModuleObject + " object =" + Alphas(1) + ". The input of " + cNumericFields(1) +
2553 : " is required, but a blank is found.");
2554 0 : ShowContinueError(m_state, format("The default value is assigned as {:.1R}", Numbers(1)));
2555 : }
2556 115 : MultizoneExternalNodeData(i).ExtNum = AirflowNetworkNumOfZones + i; // External node number
2557 115 : MultizoneExternalNodeData(i).curve = Curve::GetCurveIndex(m_state, Alphas(2)); // Wind pressure curve
2558 115 : if (MultizoneExternalNodeData(i).curve == 0) {
2559 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(2) + "=" + Alphas(2));
2560 0 : ShowContinueError(m_state, "Entered in " + CurrentModuleObject + '=' + Alphas(1));
2561 0 : ErrorsFound = true;
2562 : }
2563 115 : if (NumAlphas >= 3 && !lAlphaBlanks(3)) { // Symmetric curve
2564 0 : if (Util::SameString(Alphas(3), "Yes")) {
2565 0 : MultizoneExternalNodeData(i).symmetricCurve = true;
2566 0 : } else if (!Util::SameString(Alphas(3), "No")) {
2567 0 : ShowWarningError(
2568 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(3) + " = " + Alphas(3));
2569 0 : ShowContinueError(m_state, "The default value is assigned as No.");
2570 : }
2571 : }
2572 115 : if (NumAlphas == 4 && !lAlphaBlanks(4)) { // Relative or absolute wind angle
2573 0 : if (Util::SameString(Alphas(4), "Relative")) {
2574 0 : MultizoneExternalNodeData(i).useRelativeAngle = true;
2575 0 : } else if (!Util::SameString(Alphas(4), "Absolute")) {
2576 : // Code will never be executed, validation will catch invalid input
2577 0 : ShowWarningError(
2578 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(4) + " = " + Alphas(4));
2579 0 : ShowContinueError(m_state, "The default value is assigned as Absolute.");
2580 : }
2581 : }
2582 : }
2583 27 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel) {
2584 :
2585 1 : CurrentModuleObject = "OutdoorAir:Node";
2586 2 : for (int i = AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode + 1; i <= AirflowNetworkNumOfExtNode; ++i) {
2587 2 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2588 : CurrentModuleObject,
2589 1 : i - (AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode),
2590 : Alphas,
2591 : NumAlphas,
2592 : Numbers,
2593 : NumNumbers,
2594 : IOStatus,
2595 : lNumericBlanks,
2596 : lAlphaBlanks,
2597 : cAlphaFields,
2598 : cNumericFields);
2599 : // HACK: Need to verify name is unique between "OutdoorAir:Node" and "AirflowNetwork:MultiZone:ExternalNode"
2600 :
2601 1 : if (NumAlphas > 5 && !lAlphaBlanks(6)) { // Wind pressure curve
2602 1 : MultizoneExternalNodeData(i).curve = GetCurveIndex(m_state, Alphas(6));
2603 1 : if (MultizoneExternalNodeData(i).curve == 0) {
2604 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(6) + "=" + Alphas(6));
2605 0 : ShowContinueError(m_state, "Entered in " + CurrentModuleObject + '=' + Alphas(1));
2606 0 : ErrorsFound = true;
2607 : }
2608 : }
2609 :
2610 1 : if (NumAlphas > 6 && !lAlphaBlanks(7)) { // Symmetric curve
2611 1 : if (Util::SameString(Alphas(7), "Yes")) {
2612 0 : MultizoneExternalNodeData(i).symmetricCurve = true;
2613 1 : } else if (!Util::SameString(Alphas(7), "No")) {
2614 0 : ShowWarningError(m_state,
2615 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(7) + " = " +
2616 0 : Alphas(7));
2617 0 : ShowContinueError(m_state, "The default value is assigned as No.");
2618 : }
2619 : }
2620 :
2621 1 : if (NumAlphas > 7 && !lAlphaBlanks(8)) { // Relative or absolute wind angle
2622 1 : if (Util::SameString(Alphas(8), "Relative")) {
2623 0 : MultizoneExternalNodeData(i).useRelativeAngle = true;
2624 1 : } else if (!Util::SameString(Alphas(8), "Absolute")) {
2625 0 : ShowWarningError(m_state,
2626 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid input " + cAlphaFields(8) + " = " +
2627 0 : Alphas(8));
2628 0 : ShowContinueError(m_state, "The default value is assigned as Absolute.");
2629 : }
2630 : }
2631 :
2632 1 : MultizoneExternalNodeData(i).Name = Alphas(1); // Name of external node
2633 2 : int NodeNum = GetOnlySingleNode(m_state,
2634 1 : Alphas(1),
2635 : ErrorsFound,
2636 : DataLoopNode::ConnectionObjectType::OutdoorAirNode,
2637 : "AirflowNetwork:Multizone:Surface",
2638 : DataLoopNode::NodeFluidType::Air,
2639 : DataLoopNode::ConnectionType::Inlet,
2640 : NodeInputManager::CompFluidStream::Primary,
2641 : ObjectIsParent);
2642 1 : MultizoneExternalNodeData(i).OutAirNodeNum = NodeNum; // Name of outdoor air node
2643 1 : MultizoneExternalNodeData(i).height = Node(NodeNum).Height; // Nodal height
2644 1 : MultizoneExternalNodeData(i).ExtNum = AirflowNetworkNumOfZones + i; // External node number
2645 : }
2646 : }
2647 : } else {
2648 0 : ShowSevereError(m_state,
2649 0 : format(RoutineName) + "An " + CurrentModuleObject +
2650 : " object is required but not found when Wind Pressure Coefficient Type = Input.");
2651 0 : ErrorsFound = true;
2652 : }
2653 : }
2654 :
2655 : // *** Read AirflowNetwork element data
2656 35 : ErrorsFound = ErrorsFound || !get_element_input();
2657 :
2658 : // *** Read AirflowNetwork simulation surface data
2659 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
2660 35 : AirflowNetworkNumOfSurfaces = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
2661 35 : if (AirflowNetworkNumOfSurfaces > 0) {
2662 35 : MultizoneSurfaceData.allocate(AirflowNetworkNumOfSurfaces);
2663 526 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
2664 491 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
2665 : CurrentModuleObject,
2666 : i,
2667 : Alphas,
2668 : NumAlphas,
2669 : Numbers,
2670 : NumNumbers,
2671 : IOStatus,
2672 : lNumericBlanks,
2673 : lAlphaBlanks,
2674 : cAlphaFields,
2675 : cNumericFields);
2676 491 : MultizoneSurfaceData(i).SurfName = Alphas(1); // Name of Associated EnergyPlus surface
2677 491 : MultizoneSurfaceData(i).OpeningName = Alphas(2); // Name of crack or opening component,
2678 : // either simple or detailed large opening, or crack
2679 491 : MultizoneSurfaceData(i).ExternalNodeName = Alphas(3); // Name of external node, but not used at WPC="INPUT"
2680 738 : if (Util::FindItemInList(Alphas(3), MultizoneExternalNodeData) &&
2681 247 : m_state.afn->MultizoneExternalNodeData(Util::FindItemInList(Alphas(3), MultizoneExternalNodeData)).curve == 0) {
2682 0 : ShowSevereError(m_state, format(RoutineName) + "Invalid " + cAlphaFields(3) + "=" + Alphas(3));
2683 0 : ShowContinueError(m_state,
2684 : "A valid wind pressure coefficient curve name is required but not found when Wind Pressure "
2685 : "Coefficient Type = Input.");
2686 0 : ErrorsFound = true;
2687 : }
2688 491 : MultizoneSurfaceData(i).Factor = Numbers(1); // Crack Actual Value or Window Open Factor for Ventilation
2689 491 : if (MultizoneSurfaceData(i).Factor > 1.0 || MultizoneSurfaceData(i).Factor <= 0.0) {
2690 0 : ShowWarningError(m_state,
2691 0 : format(RoutineName) + CurrentModuleObject + " object=" + MultizoneSurfaceData(i).SurfName + ", " +
2692 0 : cNumericFields(1) + " is out of range (0.0,1.0]");
2693 0 : ShowContinueError(m_state, format("..Input value = {:.2R}, Value will be set to 1.0", MultizoneSurfaceData(i).Factor));
2694 0 : MultizoneSurfaceData(i).Factor = 1.0;
2695 : }
2696 : // Get input of ventilation control and associated data
2697 491 : if (NumAlphas >= 4) {
2698 : // Ventilation Control Mode: "TEMPERATURE", "ENTHALPY",
2699 : // "CONSTANT", "ZONELEVEL", "NOVENT", "ADJACENTTEMPERATURE",
2700 : // or "ADJACENTENTHALPY"
2701 54 : if (!lAlphaBlanks(4)) MultizoneSurfaceData(i).VentControl = Alphas(4);
2702 : // Name of ventilation temperature control schedule
2703 54 : if (!lAlphaBlanks(5)) MultizoneSurfaceData(i).VentSchName = Alphas(5);
2704 : {
2705 : // This SELECT_CASE_var will go on input refactor, no need to fix
2706 54 : auto const SELECT_CASE_var(Util::makeUPPER(MultizoneSurfaceData(i).VentControl));
2707 54 : if (SELECT_CASE_var == "TEMPERATURE") {
2708 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Temp;
2709 0 : MultizoneSurfaceData(i).IndVentControl = true;
2710 54 : } else if (SELECT_CASE_var == "ENTHALPY") {
2711 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Enth;
2712 0 : MultizoneSurfaceData(i).IndVentControl = true;
2713 54 : } else if (SELECT_CASE_var == "CONSTANT") {
2714 19 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Const;
2715 19 : MultizoneSurfaceData(i).IndVentControl = true;
2716 35 : } else if (SELECT_CASE_var == "ASHRAE55ADAPTIVE") {
2717 3 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::ASH55;
2718 3 : MultizoneSurfaceData(i).IndVentControl = true;
2719 32 : } else if (SELECT_CASE_var == "CEN15251ADAPTIVE") {
2720 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::CEN15251;
2721 0 : MultizoneSurfaceData(i).IndVentControl = true;
2722 32 : } else if (SELECT_CASE_var == "NOVENT") {
2723 28 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::NoVent;
2724 28 : MultizoneSurfaceData(i).IndVentControl = true;
2725 4 : } else if (SELECT_CASE_var == "ZONELEVEL") {
2726 4 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::ZoneLevel;
2727 4 : MultizoneSurfaceData(i).IndVentControl = false;
2728 0 : } else if (SELECT_CASE_var == "ADJACENTTEMPERATURE") {
2729 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::AdjTemp;
2730 0 : MultizoneSurfaceData(i).IndVentControl = true;
2731 0 : } else if (SELECT_CASE_var == "ADJACENTENTHALPY") {
2732 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::AdjEnth;
2733 0 : MultizoneSurfaceData(i).IndVentControl = true;
2734 : } else {
2735 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(4));
2736 0 : ShowContinueError(m_state,
2737 0 : ".." + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName + ", Specified " + cAlphaFields(4) +
2738 0 : " = " + Alphas(4));
2739 0 : ShowContinueError(m_state,
2740 : "..The valid choices are \"Temperature\", \"Enthalpy\", \"Constant\", \"NoVent\", \"ZoneLevel\", "
2741 : "\"AdjancentTemperature\" or \"AdjacentEnthalpy\"");
2742 0 : ErrorsFound = true;
2743 : }
2744 54 : }
2745 : }
2746 491 : MultizoneSurfaceData(i).ModulateFactor = Numbers(2); // Limit Value on Multiplier for Modulating Venting Open Factor
2747 491 : MultizoneSurfaceData(i).LowValueTemp = Numbers(3); // Lower temperature value for modulation of temperature control
2748 491 : MultizoneSurfaceData(i).UpValueTemp = Numbers(4); // Upper temperature value for modulation of temperature control
2749 491 : MultizoneSurfaceData(i).LowValueEnth = Numbers(5); // Lower Enthalpy value for modulation of Enthalpy control
2750 491 : MultizoneSurfaceData(i).UpValueEnth = Numbers(6); // Lower Enthalpy value for modulation of Enthalpy control
2751 526 : if (MultizoneSurfaceData(i).VentSurfCtrNum < 4 || MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjTemp ||
2752 35 : MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjEnth) {
2753 456 : if (!lAlphaBlanks(6)) {
2754 16 : MultizoneSurfaceData(i).VentingSchName = Alphas(6); // Name of ventilation availability schedule
2755 : }
2756 : }
2757 491 : if (!lAlphaBlanks(7)) {
2758 0 : MultizoneSurfaceData(i).OccupantVentilationControlName = Alphas(7);
2759 0 : MultizoneSurfaceData(i).OccupantVentilationControlNum =
2760 0 : Util::FindItemInList(MultizoneSurfaceData(i).OccupantVentilationControlName, OccupantVentilationControl);
2761 0 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) {
2762 0 : ShowSevereError(m_state,
2763 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(7) +
2764 0 : " not found = " + MultizoneSurfaceData(i).OccupantVentilationControlName);
2765 0 : ShowContinueError(m_state, "..for specified " + cAlphaFields(1) + " = " + Alphas(1));
2766 0 : ErrorsFound = true;
2767 : }
2768 : }
2769 : // Get data of polygonal surface
2770 491 : if (!lAlphaBlanks(8)) {
2771 0 : if (Alphas(8) == "POLYGONHEIGHT") {
2772 0 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::Height;
2773 0 : } else if (Alphas(8) == "BASESURFACEASPECTRATIO") {
2774 0 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::BaseAspectRatio;
2775 0 : } else if (Alphas(8) == "USERDEFINEDASPECTRATIO") {
2776 0 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::UserAspectRatio;
2777 : } else {
2778 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(8));
2779 0 : ShowContinueError(m_state,
2780 0 : ".." + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName + ", Specified " + cAlphaFields(8) +
2781 0 : " = " + Alphas(8));
2782 0 : ShowContinueError(m_state,
2783 : "..The valid choices are \"PolygonHeight\", \"BaseSurfaceAspectRatio\", or \"UserDefinedAspectRatio\"");
2784 0 : ErrorsFound = true;
2785 : }
2786 : } else {
2787 491 : MultizoneSurfaceData(i).EquivRecMethod = EquivRec::Height;
2788 : }
2789 491 : if (!lNumericBlanks(7)) {
2790 0 : MultizoneSurfaceData(i).EquivRecUserAspectRatio = Numbers(7);
2791 : } else {
2792 491 : MultizoneSurfaceData(i).EquivRecUserAspectRatio = 1.0;
2793 : }
2794 : }
2795 : } else {
2796 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
2797 0 : ErrorsFound = true;
2798 : }
2799 :
2800 : // remove extra OutdoorAir:Node, not assigned to External Node Name
2801 35 : if (m_state.dataGlobal->AnyLocalEnvironmentsInModel && AirflowNetworkNumOfOutAirNode > 0) {
2802 2 : for (int i = AirflowNetworkNumOfExtNode - AirflowNetworkNumOfOutAirNode + 1; i <= AirflowNetworkNumOfExtNode; ++i) {
2803 1 : found = false;
2804 7 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
2805 6 : if (Util::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
2806 1 : found = true;
2807 : }
2808 : }
2809 1 : if (!found) {
2810 0 : if (i < AirflowNetworkNumOfExtNode) {
2811 0 : for (k = i; k <= AirflowNetworkNumOfExtNode - 1; ++k) {
2812 0 : MultizoneExternalNodeData(k).Name = MultizoneExternalNodeData(k + 1).Name;
2813 0 : MultizoneExternalNodeData(k).OutAirNodeNum = MultizoneExternalNodeData(k + 1).OutAirNodeNum;
2814 0 : MultizoneExternalNodeData(k).height = MultizoneExternalNodeData(k + 1).height;
2815 0 : MultizoneExternalNodeData(k).ExtNum = MultizoneExternalNodeData(k + 1).ExtNum - 1;
2816 : }
2817 0 : i -= 1;
2818 : }
2819 0 : AirflowNetworkNumOfOutAirNode -= 1;
2820 0 : AirflowNetworkNumOfExtNode -= 1;
2821 0 : MultizoneExternalNodeData.resize(AirflowNetworkNumOfExtNode);
2822 : }
2823 : }
2824 : }
2825 :
2826 : // ==> Validate AirflowNetwork simulation surface data
2827 35 : NumOfExtNodes = 0;
2828 526 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
2829 : // Check a valid surface defined earlier
2830 491 : MultizoneSurfaceData(i).SurfNum = Util::FindItemInList(MultizoneSurfaceData(i).SurfName, m_state.dataSurface->Surface);
2831 491 : if (MultizoneSurfaceData(i).SurfNum == 0) {
2832 0 : ShowSevereError(m_state,
2833 0 : format(RoutineName) + CurrentModuleObject + " object, Invalid " + cAlphaFields(1) +
2834 0 : " given = " + MultizoneSurfaceData(i).SurfName);
2835 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
2836 : }
2837 491 : if (!m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).HeatTransSurf &&
2838 0 : !m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) {
2839 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2840 0 : ShowContinueError(m_state,
2841 0 : "..The surface specified must be a heat transfer surface. Invalid " + cAlphaFields(1) + " = " +
2842 0 : MultizoneSurfaceData(i).SurfName);
2843 0 : ErrorsFound = true;
2844 0 : continue;
2845 : }
2846 : // Ensure an interior surface does not face itself
2847 491 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1) {
2848 : // Check the surface is a subsurface or not
2849 163 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf == MultizoneSurfaceData(i).SurfNum) {
2850 136 : if (MultizoneSurfaceData(i).SurfNum == m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond) {
2851 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2852 0 : ShowContinueError(m_state,
2853 0 : "..The surface facing itself is not allowed. Invalid " + cAlphaFields(1) + " = " +
2854 0 : MultizoneSurfaceData(i).SurfName);
2855 0 : ErrorsFound = true;
2856 : }
2857 : } else {
2858 27 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf ==
2859 27 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).ExtBoundCond) {
2860 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object");
2861 0 : ShowContinueError(m_state,
2862 0 : "..The base surface facing itself is not allowed. Invalid " + cAlphaFields(1) + " = " +
2863 0 : MultizoneSurfaceData(i).SurfName);
2864 0 : ErrorsFound = true;
2865 : }
2866 : }
2867 : }
2868 : // Ensure zones defined in inside and outside environment are used in the object of AIRFLOWNETWORK:MULTIZONE:ZONE
2869 491 : found = false;
2870 491 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone;
2871 : int j;
2872 1060 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
2873 1060 : if (MultizoneZoneData(j).ZoneNum == n) {
2874 491 : found = true;
2875 491 : break;
2876 : }
2877 : }
2878 : // find a surface geometry
2879 491 : MultizoneSurfaceData(i).Height = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Height;
2880 491 : MultizoneSurfaceData(i).Width = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Width;
2881 491 : MultizoneSurfaceData(i).CHeight = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Centroid.z;
2882 491 : if (found) {
2883 491 : MultizoneSurfaceData(i).NodeNums[0] = j;
2884 : } else {
2885 0 : ShowSevereError(m_state,
2886 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " + MultizoneSurfaceData(i).SurfName);
2887 0 : ShowContinueError(m_state,
2888 0 : "..Zone for inside surface must be defined in a AirflowNetwork:MultiZone:Zone object. Could not find Zone = " +
2889 0 : Zone(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone).Name);
2890 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
2891 : }
2892 :
2893 : // Calculate equivalent width and height
2894 491 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides != 4) {
2895 10 : MultizoneSurfaceData(i).NonRectangular = true;
2896 10 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::Height) {
2897 20 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Tilt < 1.0 ||
2898 10 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Tilt > 179.0) { // horizontal surface
2899 : // check base surface shape
2900 0 : if (m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Sides == 4) {
2901 0 : baseratio = m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Width /
2902 0 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Height;
2903 0 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * baseratio);
2904 0 : MultizoneSurfaceData(i).Height =
2905 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2906 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2907 0 : ShowWarningError(m_state,
2908 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2909 0 : ShowContinueError(m_state,
2910 : "The entered choice of Equivalent Rectangle Method is PolygonHeight. This choice is not valid for "
2911 : "a horizontal surface.");
2912 0 : ShowContinueError(m_state, "The BaseSurfaceAspectRatio choice is used. Simulation continues.");
2913 : }
2914 : } else {
2915 0 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area *
2916 0 : MultizoneSurfaceData(i).EquivRecUserAspectRatio);
2917 0 : MultizoneSurfaceData(i).Height =
2918 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2919 : // add warning
2920 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2921 0 : ShowWarningError(m_state,
2922 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2923 0 : ShowContinueError(m_state,
2924 : "The entered choice of Equivalent Rectangle Method is PolygonHeight. This choice is not valid for "
2925 : "a horizontal surface with a polygonal base surface.");
2926 0 : ShowContinueError(m_state, "The default aspect ratio at 1 is used. Simulation continues.");
2927 : }
2928 : }
2929 : } else {
2930 10 : minHeight = min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2931 10 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2932 10 : maxHeight = max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2933 10 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2934 20 : for (j = 3; j <= m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides; ++j) {
2935 10 : minHeight = min(minHeight,
2936 10 : min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2937 10 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2938 10 : maxHeight = max(maxHeight,
2939 10 : max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2940 10 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2941 : }
2942 10 : if (maxHeight > minHeight) {
2943 10 : MultizoneSurfaceData(i).Height = maxHeight - minHeight;
2944 10 : MultizoneSurfaceData(i).Width =
2945 10 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / (maxHeight - minHeight);
2946 : }
2947 : }
2948 : }
2949 10 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::BaseAspectRatio) {
2950 0 : if (m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Sides == 4) {
2951 0 : baseratio = m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Width /
2952 0 : m_state.dataSurface->Surface(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).BaseSurf).Height;
2953 0 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * baseratio);
2954 0 : MultizoneSurfaceData(i).Height =
2955 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2956 : } else {
2957 0 : minHeight = min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2958 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2959 0 : maxHeight = max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(1).z,
2960 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(2).z);
2961 0 : for (j = 3; j <= m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides; ++j) {
2962 0 : minHeight = min(minHeight,
2963 0 : min(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2964 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2965 0 : maxHeight = max(maxHeight,
2966 0 : max(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j - 1).z,
2967 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Vertex(j).z));
2968 : }
2969 0 : if (maxHeight > minHeight) {
2970 0 : MultizoneSurfaceData(i).Height = maxHeight - minHeight;
2971 0 : MultizoneSurfaceData(i).Width =
2972 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / (maxHeight - minHeight);
2973 : // add warning
2974 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2975 0 : ShowWarningError(m_state,
2976 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2977 0 : ShowContinueError(m_state,
2978 : "The entered choice of Equivalent Rectangle Method is BaseSurfaceAspectRatio. This choice is not "
2979 : "valid for a polygonal base surface.");
2980 0 : ShowContinueError(m_state, "The PolygonHeight choice is used. Simulation continues.");
2981 : }
2982 : } else {
2983 0 : MultizoneSurfaceData(i).Width = sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area *
2984 0 : MultizoneSurfaceData(i).EquivRecUserAspectRatio);
2985 0 : MultizoneSurfaceData(i).Height =
2986 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
2987 : // add warning
2988 0 : if (m_state.dataGlobal->DisplayExtraWarnings) {
2989 0 : ShowWarningError(m_state,
2990 0 : format(RoutineName) + CurrentModuleObject + " object = " + MultizoneSurfaceData(i).SurfName);
2991 0 : ShowContinueError(m_state,
2992 : "The entered choice of Equivalent Rectangle Method is BaseSurfaceAspectRatio. This choice is not "
2993 : "valid for a horizontal surface with a polygonal base surface.");
2994 0 : ShowContinueError(m_state, "The default aspect ratio at 1 is used. Simulation continues.");
2995 : }
2996 : }
2997 : }
2998 : }
2999 10 : if (MultizoneSurfaceData(i).EquivRecMethod == EquivRec::UserAspectRatio) {
3000 0 : MultizoneSurfaceData(i).Width =
3001 0 : sqrt(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area * MultizoneSurfaceData(i).EquivRecUserAspectRatio);
3002 0 : MultizoneSurfaceData(i).Height =
3003 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Area / MultizoneSurfaceData(i).Width;
3004 : }
3005 : }
3006 :
3007 : // Get the number of external surfaces
3008 654 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == ExternalEnvironment ||
3009 163 : (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3010 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3011 328 : ++AirflowNetworkNumOfExtSurfaces;
3012 : }
3013 :
3014 : // Outside face environment
3015 491 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
3016 393 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond;
3017 539 : if (n == ExternalEnvironment ||
3018 146 : (n == OtherSideCoefNoCalcExt && m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3019 247 : ++NumOfExtNodes;
3020 247 : if (AirflowNetworkNumOfExtNode > 0) {
3021 247 : found = false;
3022 720 : for (j = 1; j <= AirflowNetworkNumOfExtNode; ++j) {
3023 720 : if (Util::SameString(MultizoneSurfaceData(i).ExternalNodeName, MultizoneExternalNodeData(j).Name)) {
3024 247 : MultizoneSurfaceData(i).NodeNums[1] = MultizoneExternalNodeData(j).ExtNum;
3025 247 : found = true;
3026 247 : break;
3027 : }
3028 : }
3029 247 : if (!found) {
3030 0 : ShowSevereError(m_state,
3031 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(3) + " = " +
3032 0 : MultizoneSurfaceData(i).ExternalNodeName);
3033 0 : ShowContinueError(m_state, "A valid " + cAlphaFields(3) + " is required when Wind Pressure Coefficient Type = Input");
3034 0 : ErrorsFound = true;
3035 : }
3036 : } else {
3037 : // MultizoneSurfaceData(i)%NodeNums[1] =
3038 : // AirflowNetworkNumOfZones+NumOfExtNodes
3039 : }
3040 247 : continue;
3041 : } else {
3042 146 : if (n < ExternalEnvironment &&
3043 0 : !(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3044 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3045 0 : ShowSevereError(m_state,
3046 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(1) + " = " +
3047 0 : MultizoneSurfaceData(i).SurfName);
3048 0 : ShowContinueError(m_state, "This type of surface (has ground, etc exposure) cannot be used in the AiflowNetwork model.");
3049 0 : ErrorsFound = true;
3050 : }
3051 : }
3052 146 : found = false;
3053 458 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
3054 458 : if (MultizoneZoneData(j).ZoneNum == m_state.dataSurface->Surface(n).Zone) {
3055 146 : found = true;
3056 146 : break;
3057 : }
3058 : }
3059 146 : if (found) {
3060 146 : MultizoneSurfaceData(i).NodeNums[1] = j;
3061 : } else {
3062 0 : ShowSevereError(m_state,
3063 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3064 0 : MultizoneSurfaceData(i).SurfName);
3065 0 : ShowContinueError(
3066 : m_state,
3067 0 : "..Zone for outside surface must be defined in a AirflowNetwork:MultiZone:Zone object. Could not find Zone = " +
3068 0 : Zone(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Zone).Name);
3069 0 : ErrorsFound = true;
3070 0 : continue;
3071 : }
3072 : }
3073 244 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
3074 98 : n = m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond;
3075 98 : if (n >= 1) { // exterior boundary condition is a surface
3076 17 : found = false;
3077 47 : for (j = 1; j <= AirflowNetworkNumOfZones; ++j) {
3078 47 : if (MultizoneZoneData(j).ZoneNum == m_state.dataSurface->Surface(n).Zone) {
3079 17 : found = true;
3080 17 : break;
3081 : }
3082 : }
3083 17 : if (found) {
3084 17 : MultizoneSurfaceData(i).NodeNums[1] = j;
3085 : } else {
3086 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " = " + MultizoneSurfaceData(i).SurfName);
3087 0 : ShowContinueError(m_state,
3088 0 : "An adjacent zone = " + Zone(m_state.dataSurface->Surface(n).Zone).Name +
3089 : " is not described in AIRFLOWNETWORK:MULTIZONE:ZONE");
3090 0 : ErrorsFound = true;
3091 0 : continue;
3092 : }
3093 : }
3094 : }
3095 244 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == -2 &&
3096 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
3097 244 : if (MultizoneSurfaceData(i).NodeNums[1] == 0 && m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond < 0) {
3098 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " = " + MultizoneSurfaceData(i).SurfName);
3099 0 : ShowContinueError(m_state,
3100 0 : "Outside boundary condition and object are " +
3101 0 : cExtBoundCondition(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond) + " and " +
3102 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCondName + ".");
3103 0 : ShowContinueError(m_state, "The outside boundary condition must be exposed to either the outside or an adjacent zone.");
3104 0 : ErrorsFound = true;
3105 0 : continue;
3106 : }
3107 : }
3108 : }
3109 :
3110 : // write outputs in eio file
3111 35 : found = true;
3112 526 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3113 491 : if (MultizoneSurfaceData(i).NonRectangular) {
3114 10 : if (found) {
3115 5 : print(m_state.files.eio,
3116 : "! <AirflowNetwork Model:Equivalent Rectangle Surface>, Name, Equivalent Height {{m}}, Equivalent Width {{m}} "
3117 : "AirflowNetwork "
3118 : "Model:Equivalent Rectangle\n");
3119 5 : found = false;
3120 : }
3121 10 : print(m_state.files.eio,
3122 : "AirflowNetwork Model:Equivalent Rectangle Surface, {}, {:.2R},{:.2R}\n",
3123 10 : MultizoneSurfaceData(i).SurfName,
3124 10 : MultizoneSurfaceData(i).Height,
3125 10 : MultizoneSurfaceData(i).Width);
3126 : }
3127 : }
3128 :
3129 : // Validate adjacent temperature and Enthalpy control for an interior surface only
3130 526 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3131 491 : if (MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjTemp) {
3132 0 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1)) {
3133 0 : ShowSevereError(m_state,
3134 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3135 0 : MultizoneSurfaceData(i).SurfName);
3136 0 : ShowContinueError(m_state, "..AdjacentTemperature venting control must be defined for an interzone surface.");
3137 0 : ErrorsFound = true;
3138 : }
3139 : }
3140 491 : if (MultizoneSurfaceData(i).VentSurfCtrNum == VentControlType::AdjEnth) {
3141 0 : if (!(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond >= 1)) {
3142 0 : ShowSevereError(m_state,
3143 0 : format(RoutineName) + CurrentModuleObject + " object, " + cAlphaFields(1) + " = " +
3144 0 : MultizoneSurfaceData(i).SurfName);
3145 0 : ShowContinueError(m_state, "..AdjacentEnthalpy venting control must be defined for an interzone surface.");
3146 0 : ErrorsFound = true;
3147 : }
3148 : }
3149 : }
3150 :
3151 : // Ensure the number of external node = the number of external surface with HeightOption choice = OpeningHeight
3152 35 : if (Util::SameString(simulation_control.HeightOption, "OpeningHeight") && simulation_control.iWPCCnt == iWPCCntr::Input) {
3153 0 : if (AirflowNetworkNumOfExtSurfaces != AirflowNetworkNumOfExtNode) {
3154 0 : ShowSevereError(m_state,
3155 0 : format(RoutineName) +
3156 : "When the choice of Height Selection for Local Wind Speed Calculation is OpeningHeight, the number of external "
3157 0 : "surfaces defined in " +
3158 0 : CurrentModuleObject + " objects ");
3159 0 : ShowContinueError(m_state, "has to be equal to the number of AirflowNetwork:MultiZone:ExternalNode objects.");
3160 0 : ShowContinueError(m_state,
3161 0 : format("The entered number of external nodes is {}. The entered number of external surfaces is {}.",
3162 0 : AirflowNetworkNumOfExtNode,
3163 0 : AirflowNetworkNumOfExtSurfaces));
3164 0 : ErrorsFound = true;
3165 : }
3166 : }
3167 :
3168 : // Read AirflowNetwork simulation detailed openings
3169 : // Moved into getAirflowElementInput
3170 :
3171 : // Validate opening component and assign opening dimension
3172 35 : if (AirflowNetworkNumOfDetOpenings > 0) {
3173 53 : for (int i = 1; i <= AirflowNetworkNumOfDetOpenings; ++i) {
3174 31 : found = false;
3175 505 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3176 474 : if (MultizoneCompDetOpeningData(i).name == MultizoneSurfaceData(j).OpeningName) {
3177 : // MultizoneCompDetOpeningData(i)%Width =
3178 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Width
3179 : // MultizoneCompDetOpeningData(i)%Height =
3180 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Height
3181 70 : found = true;
3182 : }
3183 : }
3184 : }
3185 : }
3186 :
3187 : // Read AirflowNetwork simulation simple openings
3188 : // Moved into getAirflowElementInput
3189 :
3190 : // Read AirflowNetwork simulation horizontal openings
3191 : // Moved into getAirflowElementInput
3192 :
3193 : // Check status of control level for each surface with an opening
3194 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
3195 526 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3196 491 : if (MultizoneSurfaceData(i).SurfNum == 0) continue;
3197 491 : bool has_Opening{false};
3198 : // This is terrible, should not do it this way
3199 491 : auto afe = elements.find(MultizoneSurfaceData(i).OpeningName);
3200 491 : if (afe != elements.end()) {
3201 491 : auto type = afe->second->type();
3202 491 : has_Opening = (type == ComponentType::DOP) || (type == ComponentType::SOP) || (type == ComponentType::HOP);
3203 : }
3204 : // Obtain schedule number and check surface shape
3205 491 : if (has_Opening) {
3206 88 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).Sides == 3) {
3207 2 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName + "\".");
3208 2 : ShowContinueError(m_state,
3209 : "The opening is a Triangular subsurface. A rectangular subsurface will be used with equivalent "
3210 : "width and height.");
3211 : }
3212 : // Venting controls are not allowed for an air boundary surface
3213 88 : if ((m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) &&
3214 0 : (MultizoneSurfaceData(i).VentSurfCtrNum != VentControlType::Const)) {
3215 0 : ShowWarningError(m_state,
3216 0 : format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName +
3217 : "\" is an air boundary surface.");
3218 0 : ShowContinueError(m_state, "Ventilation Control Mode = " + Alphas(4) + " is not valid. Resetting to Constant.");
3219 0 : MultizoneSurfaceData(i).VentSurfCtrNum = VentControlType::Const;
3220 0 : MultizoneSurfaceData(i).IndVentControl = true;
3221 : }
3222 88 : if (!MultizoneSurfaceData(i).VentingSchName.empty()) {
3223 0 : MultizoneSurfaceData(i).VentingSchNum = GetScheduleIndex(m_state, MultizoneSurfaceData(i).VentingSchName);
3224 0 : if (MultizoneSurfaceData(i).VentingSchNum == 0) {
3225 0 : ShowSevereError(
3226 0 : m_state, format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName + "\", invalid schedule.");
3227 0 : ShowContinueError(m_state, "Venting Schedule not found=\"" + MultizoneSurfaceData(i).VentingSchName + "\".");
3228 0 : ErrorsFound = true;
3229 0 : } else if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).IsAirBoundarySurf) {
3230 0 : ShowWarningError(m_state,
3231 0 : format(RoutineName) + CurrentModuleObject + "=\"" + MultizoneSurfaceData(i).SurfName +
3232 : "\" is an air boundary surface.");
3233 0 : ShowContinueError(m_state, "Venting Availability Schedule will be ignored, venting is always available.");
3234 0 : MultizoneSurfaceData(i).VentingSchName = "";
3235 0 : MultizoneSurfaceData(i).VentingSchNum = 0;
3236 : }
3237 : } else {
3238 88 : MultizoneSurfaceData(i).VentingSchName = "";
3239 88 : MultizoneSurfaceData(i).VentingSchNum = 0;
3240 : }
3241 88 : switch (MultizoneSurfaceData(i).VentSurfCtrNum) {
3242 0 : case VentControlType::Temp:
3243 : case VentControlType::AdjTemp: {
3244 0 : MultizoneSurfaceData(i).VentSchNum = GetScheduleIndex(m_state, MultizoneSurfaceData(i).VentSchName);
3245 0 : if (MultizoneSurfaceData(i).VentSchName == std::string()) {
3246 0 : ShowSevereError(m_state,
3247 0 : format(RoutineName) + CurrentModuleObject +
3248 : " object, No Ventilation Schedule was found, but is required when ventilation control is "
3249 : "Temperature.");
3250 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3251 0 : ErrorsFound = true;
3252 0 : } else if (MultizoneSurfaceData(i).VentSchNum == 0) {
3253 0 : ShowSevereError(m_state,
3254 0 : format(RoutineName) + CurrentModuleObject +
3255 : " object, Invalid Ventilation Schedule, required when ventilation control is Temperature.");
3256 0 : ShowContinueError(m_state, "..Schedule name in error = " + MultizoneSurfaceData(i).VentSchName);
3257 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3258 0 : ErrorsFound = true;
3259 : }
3260 0 : if (MultizoneSurfaceData(i).LowValueTemp < 0.0) {
3261 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Temperature difference value < 0.0d0");
3262 0 : ShowContinueError(m_state, format("..Input value={:.1R}, Value will be reset to 0.0.", MultizoneSurfaceData(i).LowValueTemp));
3263 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3264 0 : MultizoneSurfaceData(i).LowValueTemp = 0.0;
3265 : }
3266 0 : if (MultizoneSurfaceData(i).LowValueTemp >= 100.0) {
3267 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Temperature difference value >= 100.0d0");
3268 0 : ShowContinueError(m_state,
3269 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueTemp));
3270 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3271 0 : MultizoneZoneData(i).LowValueTemp = 0.0;
3272 : }
3273 0 : if (MultizoneSurfaceData(i).UpValueTemp <= MultizoneSurfaceData(i).LowValueTemp) {
3274 0 : ShowWarningError(
3275 0 : m_state, format(RoutineName) + CurrentModuleObject + " object, Upper Temperature <= Lower Temperature difference value.");
3276 0 : ShowContinueError(m_state,
3277 0 : format("..Input value = {:.1R}, Value will be reset to 100.0", MultizoneSurfaceData(i).UpValueTemp));
3278 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3279 0 : MultizoneSurfaceData(i).UpValueTemp = 100.0;
3280 : }
3281 :
3282 0 : } break;
3283 0 : case VentControlType::Enth:
3284 : case VentControlType::AdjEnth: {
3285 0 : MultizoneSurfaceData(i).VentSchNum = GetScheduleIndex(m_state, MultizoneSurfaceData(i).VentSchName);
3286 0 : if (MultizoneSurfaceData(i).VentSchName == std::string()) {
3287 0 : ShowSevereError(m_state,
3288 0 : format(RoutineName) + CurrentModuleObject +
3289 : " object, No Ventilation Schedule was found, but is required when ventilation control is Enthalpy.");
3290 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3291 0 : ErrorsFound = true;
3292 0 : } else if (MultizoneSurfaceData(i).VentSchNum == 0) {
3293 0 : ShowSevereError(m_state,
3294 0 : format(RoutineName) + CurrentModuleObject +
3295 : " object, Invalid Ventilation Schedule, required when ventilation control is Enthalpy.");
3296 0 : ShowContinueError(m_state, "..Schedule name in error = " + MultizoneSurfaceData(i).VentSchName);
3297 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3298 0 : ErrorsFound = true;
3299 : }
3300 0 : if (MultizoneSurfaceData(i).LowValueEnth < 0.0) {
3301 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Enthalpy difference value < 0.0d0");
3302 0 : ShowContinueError(m_state,
3303 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueEnth));
3304 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3305 0 : MultizoneSurfaceData(i).LowValueEnth = 0.0;
3306 : }
3307 0 : if (MultizoneSurfaceData(i).LowValueEnth >= 300000.0) {
3308 0 : ShowWarningError(m_state, format(RoutineName) + CurrentModuleObject + " object, Low Enthalpy difference value >= 300000.0");
3309 0 : ShowContinueError(m_state,
3310 0 : format("..Input value = {:.1R}, Value will be reset to 0.0", MultizoneSurfaceData(i).LowValueEnth));
3311 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3312 0 : MultizoneZoneData(i).LowValueEnth = 0.0;
3313 : }
3314 0 : if (MultizoneSurfaceData(i).UpValueEnth <= MultizoneSurfaceData(i).LowValueEnth) {
3315 0 : ShowWarningError(m_state,
3316 0 : format(RoutineName) + CurrentModuleObject + " object, Upper Enthalpy <= Lower Enthalpy difference value.");
3317 0 : ShowContinueError(m_state,
3318 0 : format("..Input value = {:.1R}, Value will be set to 300000.0", MultizoneSurfaceData(i).UpValueEnth));
3319 0 : ShowContinueError(m_state, "..for Surface = \"" + MultizoneSurfaceData(i).SurfName + "\"");
3320 0 : MultizoneSurfaceData(i).UpValueEnth = 300000.0;
3321 : }
3322 :
3323 0 : } break;
3324 7 : case VentControlType::Const:
3325 : case VentControlType::ASH55:
3326 : case VentControlType::CEN15251:
3327 : case VentControlType::NoVent:
3328 : case VentControlType::ZoneLevel: {
3329 7 : MultizoneSurfaceData(i).VentSchNum = 0;
3330 7 : MultizoneSurfaceData(i).VentSchName = "";
3331 7 : } break;
3332 81 : default:
3333 81 : break;
3334 : }
3335 : }
3336 491 : }
3337 :
3338 : // Validate opening component and assign opening dimension
3339 35 : if (AirflowNetworkNumOfSimOpenings > 0) {
3340 24 : for (int i = 1; i <= AirflowNetworkNumOfSimOpenings; ++i) {
3341 12 : found = false;
3342 254 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3343 242 : if (MultizoneCompSimpleOpeningData(i).name == MultizoneSurfaceData(j).OpeningName) {
3344 : // MultizoneCompSimpleOpeningData(i)%Width =
3345 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Width
3346 : // MultizoneCompSimpleOpeningData(i)%Height =
3347 : // Surface(MultizoneSurfaceData(j)%SurfNum)%Height
3348 17 : found = true;
3349 : }
3350 : }
3351 : }
3352 : }
3353 :
3354 : // Calculate CP values
3355 35 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
3356 8 : calculate_Cps();
3357 : // Ensure automatic generation is OK
3358 8 : n = 0;
3359 48 : for (int j = 1; j <= 5; ++j) {
3360 40 : found = false;
3361 182 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3362 177 : if (MultizoneExternalNodeData(i).facadeNum == j) {
3363 35 : found = true;
3364 35 : break;
3365 : }
3366 : }
3367 40 : if (found) ++n;
3368 40 : if (j == 5 && (!found)) {
3369 3 : found = true;
3370 3 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3371 0 : ShowWarningError(m_state,
3372 0 : format(RoutineName) +
3373 : "SurfaceAverageCalculation is entered for field = Wind Pressure Coefficient Type, but no roof "
3374 : "surface is defined using an AirflowNetwork:MultiZone:Surface object.");
3375 0 : ShowContinueError(m_state, "Reconsider if this is your modeling intent. Simulation continues.");
3376 : }
3377 : }
3378 : }
3379 8 : if (n < 5 && m_state.dataGlobal->DisplayExtraWarnings) {
3380 0 : ShowWarningError(m_state, format(RoutineName) + "SurfaceAverageCalculation is entered for field = Wind Pressure Coefficient Type.");
3381 0 : ShowContinueError(m_state,
3382 : "The AirflowNetwork model provides wind pressure coefficients for 4 vertical exterior orientations and "
3383 : "1 horizontal roof.");
3384 0 : ShowContinueError(m_state,
3385 0 : format(" There are only {} exterior surface orientations defined in this input file using "
3386 : "AirflowNetwork:MultiZone:Surface objects.",
3387 : n));
3388 0 : ShowContinueError(m_state, "Reconsider if this is your modeling intent. Simulation continues.");
3389 : }
3390 : }
3391 :
3392 : // Assign external node height
3393 62 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation") ||
3394 62 : Util::SameString(simulation_control.HeightOption, "OpeningHeight")) {
3395 89 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3396 611 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3397 698 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == ExternalEnvironment ||
3398 87 : (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3399 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtWind)) {
3400 524 : if (Util::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
3401 81 : MultizoneExternalNodeData(i).height = m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Centroid.z;
3402 81 : break;
3403 : }
3404 : }
3405 : }
3406 : }
3407 : }
3408 :
3409 : // Assign external node azimuth, should consider combining this with the above to avoid the repeated search
3410 232 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3411 1405 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3412 1785 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == ExternalEnvironment ||
3413 387 : (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
3414 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtWind)) {
3415 1011 : if (Util::SameString(MultizoneSurfaceData(j).ExternalNodeName, MultizoneExternalNodeData(i).Name)) {
3416 190 : MultizoneExternalNodeData(i).azimuth = m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Azimuth;
3417 190 : break;
3418 : }
3419 : }
3420 : }
3421 : }
3422 :
3423 35 : if (ErrorsFound) {
3424 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3425 : }
3426 :
3427 : // Write wind pressure coefficients in the EIO file
3428 35 : print(m_state.files.eio, "! <AirflowNetwork Model:Wind Direction>, Wind Direction #1 to n (degree)\n");
3429 35 : print(m_state.files.eio, "AirflowNetwork Model:Wind Direction, ");
3430 :
3431 35 : int numWinDirs = 11;
3432 35 : Real64 angleDelta = 30.0;
3433 35 : if (AirflowNetworkNumOfSingleSideZones > 0) {
3434 1 : numWinDirs = 35;
3435 1 : angleDelta = 10.0;
3436 : }
3437 :
3438 444 : for (int i = 0; i < numWinDirs; ++i) {
3439 409 : print(m_state.files.eio, "{:.1R},", i * angleDelta);
3440 : }
3441 35 : print(m_state.files.eio, "{:.1R}\n", numWinDirs * angleDelta);
3442 :
3443 35 : print(m_state.files.eio, "! <AirflowNetwork Model:Wind Pressure Coefficients>, Name, Wind Pressure Coefficients #1 to n (dimensionless)\n");
3444 :
3445 : // The old version used to write info with single-sided natural ventilation specific labeling, this version no longer does that.
3446 70 : std::set<int> curves;
3447 232 : for (int i = 1; i <= AirflowNetworkNumOfExtNode; ++i) {
3448 197 : curves.insert(MultizoneExternalNodeData(i).curve);
3449 : }
3450 189 : for (auto index : curves) {
3451 154 : print(m_state.files.eio, "AirflowNetwork Model:Wind Pressure Coefficients, {}, ", Curve::GetCurveName(m_state, index));
3452 :
3453 2088 : for (int j = 0; j < numWinDirs; ++j) {
3454 1934 : print(m_state.files.eio, "{:.2R},", Curve::CurveValue(m_state, index, j * angleDelta));
3455 : }
3456 154 : print(m_state.files.eio, "{:.2R}\n", Curve::CurveValue(m_state, index, numWinDirs * angleDelta));
3457 35 : }
3458 :
3459 35 : if (AirflowNetworkNumOfSingleSideZones > 0) {
3460 5 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3461 4 : if (MultizoneZoneData(i).SingleSidedCpType == "ADVANCED") {
3462 3 : print(m_state.files.eio,
3463 : "AirflowNetwork: Advanced Single-Sided Model: Difference in Opening Wind Pressure Coefficients (DeltaCP), ");
3464 3 : print(m_state.files.eio, "{}, ", MultizoneZoneData(i).ZoneName);
3465 108 : for (unsigned j = 1; j <= EPDeltaCP(i).WindDir.size() - 1; ++j) {
3466 105 : print(m_state.files.eio, "{:.2R},", EPDeltaCP(i).WindDir(j));
3467 : }
3468 3 : print(m_state.files.eio, "{:.2R}\n", EPDeltaCP(i).WindDir(static_cast<int>(EPDeltaCP(i).WindDir.size())));
3469 : }
3470 : }
3471 : }
3472 :
3473 : // If no zone object, exit
3474 35 : if (AirflowNetworkNumOfZones == 0) {
3475 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3476 : }
3477 : // If zone node number =0, exit.
3478 526 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3479 491 : if (MultizoneSurfaceData(j).NodeNums[0] == 0 && ErrorsFound) {
3480 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3481 : }
3482 491 : if (MultizoneSurfaceData(j).NodeNums[1] == 0 && ErrorsFound) {
3483 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
3484 : }
3485 : }
3486 :
3487 : // Ensure at least two surfaces are exposed to a zone
3488 35 : ZoneCheck.allocate(AirflowNetworkNumOfZones);
3489 35 : ZoneBCCheck.allocate(AirflowNetworkNumOfZones);
3490 35 : ZoneCheck = 0;
3491 35 : ZoneBCCheck = 0;
3492 35 : CurrentModuleObject = "AirflowNetwork:MultiZone:Surface";
3493 526 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3494 491 : if (MultizoneSurfaceData(j).NodeNums[0] <= AirflowNetworkNumOfZones) {
3495 491 : ++ZoneCheck(MultizoneSurfaceData(j).NodeNums[0]);
3496 491 : ZoneBCCheck(MultizoneSurfaceData(j).NodeNums[0]) = MultizoneSurfaceData(j).NodeNums[1];
3497 : }
3498 491 : if (MultizoneSurfaceData(j).NodeNums[1] <= AirflowNetworkNumOfZones) {
3499 163 : ++ZoneCheck(MultizoneSurfaceData(j).NodeNums[1]);
3500 163 : ZoneBCCheck(MultizoneSurfaceData(j).NodeNums[1]) = MultizoneSurfaceData(j).NodeNums[0];
3501 : }
3502 : }
3503 150 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3504 115 : if (ZoneCheck(i) == 0) {
3505 0 : ShowSevereError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3506 0 : ShowContinueError(m_state, " does not have any surfaces defined in " + CurrentModuleObject);
3507 0 : ShowContinueError(m_state, "Each zone should have at least two surfaces defined in " + CurrentModuleObject);
3508 0 : ErrorsFound = true;
3509 : }
3510 115 : if (ZoneCheck(i) == 1) {
3511 0 : ShowSevereError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3512 0 : ShowContinueError(m_state, " has only one surface defined in " + CurrentModuleObject);
3513 0 : ShowContinueError(m_state, " Each zone should have at least two surfaces defined in " + CurrentModuleObject);
3514 0 : ErrorsFound = true;
3515 : }
3516 115 : if (ZoneCheck(i) > 1) {
3517 115 : bool SurfaceFound = false;
3518 509 : for (int j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
3519 509 : if (MultizoneSurfaceData(j).NodeNums[0] == i) {
3520 55 : if (ZoneBCCheck(i) != MultizoneSurfaceData(j).NodeNums[1]) {
3521 53 : SurfaceFound = true;
3522 53 : break;
3523 : }
3524 : }
3525 456 : if (MultizoneSurfaceData(j).NodeNums[1] == i) {
3526 62 : if (ZoneBCCheck(i) != MultizoneSurfaceData(j).NodeNums[0]) {
3527 62 : SurfaceFound = true;
3528 62 : break;
3529 : }
3530 : }
3531 : }
3532 115 : if (!SurfaceFound) {
3533 0 : ShowWarningError(m_state, format(RoutineName) + "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(i).ZoneName);
3534 0 : ShowContinueError(m_state,
3535 0 : "has more than one surface defined in " + CurrentModuleObject + ", but has the same boundary conditions");
3536 0 : ShowContinueError(m_state, "Please check inputs of " + CurrentModuleObject);
3537 : }
3538 : }
3539 : }
3540 35 : ZoneCheck.deallocate();
3541 35 : ZoneBCCheck.deallocate();
3542 :
3543 : // Validate CP Value number
3544 35 : if (simulation_control.iWPCCnt == iWPCCntr::Input) { // Surface-Average does not need inputs of external nodes
3545 : // Ensure different curve is used to avoid a single side boundary condition
3546 27 : found = false;
3547 27 : bool differentAngle = false;
3548 27 : for (int j = 2; j <= AirflowNetworkNumOfExtNode; ++j) {
3549 27 : if (MultizoneExternalNodeData(j - 1).curve != MultizoneExternalNodeData(j).curve) {
3550 27 : found = true;
3551 27 : break;
3552 : } else {
3553 : // If the curves are the same, then check to see if the azimuths are different
3554 0 : if (MultizoneExternalNodeData(j - 1).azimuth != MultizoneExternalNodeData(j).azimuth) {
3555 0 : differentAngle = MultizoneExternalNodeData(j - 1).symmetricCurve || MultizoneExternalNodeData(j).symmetricCurve;
3556 : }
3557 : }
3558 : }
3559 27 : if (!found && !differentAngle) {
3560 0 : ShowSevereError(m_state,
3561 : "The same Wind Pressure Coefficient Curve name is used in all AirflowNetwork:MultiZone:ExternalNode objects.");
3562 0 : ShowContinueError(
3563 : m_state, "Please input at least two different Wind Pressure Coefficient Curve names to avoid single side boundary condition.");
3564 0 : ErrorsFound = true;
3565 : }
3566 : }
3567 :
3568 : // Assign occupant ventilation control number from zone to surface
3569 526 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
3570 491 : int j = MultizoneSurfaceData(i).SurfNum;
3571 491 : auto const &surf = m_state.dataSurface->Surface(j);
3572 491 : if (surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
3573 397 : surf.OriginalClass == SurfaceClass::GlassDoor) {
3574 453 : for (n = 1; n <= AirflowNetworkNumOfZones; ++n) {
3575 359 : if (MultizoneZoneData(n).ZoneNum == m_state.dataSurface->Surface(j).Zone) {
3576 94 : if (MultizoneZoneData(n).OccupantVentilationControlNum > 0 && MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) {
3577 2 : MultizoneSurfaceData(i).OccupantVentilationControlNum = MultizoneZoneData(n).OccupantVentilationControlNum;
3578 : }
3579 : }
3580 : }
3581 : }
3582 : }
3583 :
3584 : // Read AirflowNetwork Intra zone node
3585 35 : CurrentModuleObject = "AirflowNetwork:IntraZone:Node";
3586 35 : IntraZoneNumOfNodes = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3587 35 : if (IntraZoneNumOfNodes > 0) {
3588 1 : IntraZoneNodeData.allocate(IntraZoneNumOfNodes);
3589 6 : for (int i = 1; i <= IntraZoneNumOfNodes; ++i) {
3590 5 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3591 : CurrentModuleObject,
3592 : i,
3593 : Alphas,
3594 : NumAlphas,
3595 : Numbers,
3596 : NumNumbers,
3597 : IOStatus,
3598 : lNumericBlanks,
3599 : lAlphaBlanks,
3600 : cAlphaFields,
3601 : cNumericFields);
3602 5 : IntraZoneNodeData(i).Name = Alphas(1); // Name of node
3603 5 : IntraZoneNodeData(i).RAFNNodeName = Alphas(2); // Name of RoomAir node
3604 5 : IntraZoneNodeData(i).Height = Numbers(1); // Nodal height
3605 : // verify RoomAir model node names(May be too early to check and move to another subroutine)
3606 : bool Errorfound1;
3607 5 : GetRAFNNodeNum(
3608 5 : m_state, IntraZoneNodeData(i).RAFNNodeName, IntraZoneNodeData(i).ZoneNum, IntraZoneNodeData(i).RAFNNodeNum, Errorfound1);
3609 5 : if (Errorfound1) ErrorsFound = true;
3610 5 : if (IntraZoneNodeData(i).RAFNNodeNum == 0) {
3611 0 : ShowSevereError(m_state,
3612 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "' invalid name " + cAlphaFields(2) + "='" +
3613 0 : Alphas(2));
3614 0 : ErrorsFound = true;
3615 : }
3616 10 : IntraZoneNodeData(i).AFNZoneNum =
3617 5 : Util::FindItemInList(Alphas(3), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3618 5 : if (MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).RAFNNodeNum == 0) {
3619 1 : GetRAFNNodeNum(m_state,
3620 1 : MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).ZoneName,
3621 1 : IntraZoneNodeData(i).ZoneNum,
3622 1 : MultizoneZoneData(IntraZoneNodeData(i).AFNZoneNum).RAFNNodeNum,
3623 : Errorfound1);
3624 : }
3625 5 : if (IntraZoneNodeData(i).ZoneNum == 0) {
3626 0 : ShowSevereError(m_state,
3627 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "' the Zone is not defined for " +
3628 0 : cAlphaFields(3) + "='" + Alphas(3));
3629 0 : ErrorsFound = true;
3630 : }
3631 : }
3632 : }
3633 :
3634 : // check model compatibility
3635 35 : if (IntraZoneNumOfNodes > 0) {
3636 1 : if (!Util::SameString(SimAirNetworkKey, "MultizoneWithoutDistribution")) {
3637 0 : ShowSevereError(m_state,
3638 0 : format(RoutineName) + CurrentModuleObject +
3639 0 : " model requires Simulation Control = MultizoneWithoutDistribution, while the input choice is " +
3640 0 : SimAirNetworkKey + ".");
3641 0 : ErrorsFound = true;
3642 0 : ShowFatalError(
3643 : m_state,
3644 0 : format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
3645 : }
3646 : }
3647 :
3648 35 : NumOfNodesIntraZone = IntraZoneNumOfNodes;
3649 : // check zone node
3650 35 : IntraZoneNumOfZones = 0;
3651 150 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
3652 115 : if (MultizoneZoneData(i).RAFNNodeNum > 0) {
3653 1 : IntraZoneNumOfZones += 1;
3654 : }
3655 : }
3656 :
3657 : // Override error check due to RoomAirNode for the time being
3658 :
3659 : // Read AirflowNetwork Intra linkage
3660 35 : CurrentModuleObject = "AirflowNetwork:IntraZone:Linkage";
3661 35 : IntraZoneNumOfLinks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3662 35 : if (IntraZoneNumOfLinks > 0) {
3663 1 : IntraZoneLinkageData.allocate(IntraZoneNumOfLinks);
3664 1 : UniqueAirflowNetworkSurfaceName.reserve(IntraZoneNumOfLinks);
3665 10 : for (int i = 1; i <= IntraZoneNumOfLinks; ++i) {
3666 9 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3667 : CurrentModuleObject,
3668 : i,
3669 : Alphas,
3670 : NumAlphas,
3671 : Numbers,
3672 : NumNumbers,
3673 : IOStatus,
3674 : lNumericBlanks,
3675 : lAlphaBlanks,
3676 : cAlphaFields,
3677 : cNumericFields);
3678 9 : IntraZoneLinkageData(i).Name = Alphas(1); // Name of linkage
3679 9 : IntraZoneLinkageData(i).NodeNames[0] = Alphas(2);
3680 9 : IntraZoneLinkageData(i).NodeHeights[0] = 0.0;
3681 9 : IntraZoneLinkageData(i).NodeNames[1] = Alphas(3);
3682 9 : IntraZoneLinkageData(i).NodeHeights[1] = 0.0;
3683 9 : IntraZoneLinkageData(i).CompName = Alphas(4);
3684 9 : if (!lAlphaBlanks(5)) {
3685 : // Perform simple test first.The comprehensive input validation will occur later
3686 : // Check valid surface name
3687 2 : IntraZoneLinkageData(i).SurfaceName = Alphas(5);
3688 4 : IntraZoneLinkageData(i).LinkNum =
3689 2 : Util::FindItemInList(Alphas(5), MultizoneSurfaceData, &MultizoneSurfaceProp::SurfName, AirflowNetworkNumOfSurfaces);
3690 2 : if (IntraZoneLinkageData(i).LinkNum == 0) {
3691 0 : ShowSevereError(m_state,
3692 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(5) +
3693 0 : " given = " + Alphas(5) + " in AirflowNetwork:MultiZone:Surface objects");
3694 0 : ErrorsFound = true;
3695 : }
3696 2 : GlobalNames::VerifyUniqueInterObjectName(
3697 4 : m_state, UniqueAirflowNetworkSurfaceName, Alphas(5), CurrentModuleObject, cAlphaFields(5), ErrorsFound);
3698 : }
3699 9 : if (Util::SameString(Alphas(2), Alphas(3))) {
3700 0 : ShowSevereError(m_state,
3701 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid inputs of both node name with " +
3702 0 : Alphas(2) + " = " + Alphas(3));
3703 0 : ErrorsFound = true;
3704 : }
3705 : // Check valid node names
3706 9 : IntraZoneLinkageData(i).NodeNums[0] = Util::FindItemInList(Alphas(2), IntraZoneNodeData, IntraZoneNumOfNodes);
3707 9 : if (IntraZoneLinkageData(i).NodeNums[0] == 0) {
3708 0 : IntraZoneLinkageData(i).NodeNums[0] =
3709 0 : Util::FindItemInList(Alphas(2), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3710 0 : IntraZoneLinkageData(i).NodeHeights[0] = Zone(MultizoneZoneData(IntraZoneLinkageData(i).NodeNums[0]).ZoneNum).Centroid.z;
3711 0 : if (IntraZoneLinkageData(i).NodeNums[0] == 0) {
3712 0 : ShowSevereError(m_state,
3713 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(2) +
3714 0 : " given = " + Alphas(2) + " in AirflowNetwork:IntraZone:Node and AirflowNetwork:MultiZone:Zone objects");
3715 0 : ErrorsFound = true;
3716 : }
3717 : } else {
3718 9 : IntraZoneLinkageData(i).NodeHeights[0] = IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0]).Height;
3719 9 : IntraZoneLinkageData(i).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0] + AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
3720 : }
3721 9 : IntraZoneLinkageData(i).NodeNums[1] = Util::FindItemInList(Alphas(3), IntraZoneNodeData, IntraZoneNumOfNodes);
3722 9 : if (IntraZoneLinkageData(i).NodeNums[1] == 0) {
3723 5 : IntraZoneLinkageData(i).NodeNums[1] =
3724 5 : Util::FindItemInList(Alphas(3), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
3725 5 : if (IntraZoneLinkageData(i).NodeNums[1] > 0) {
3726 5 : IntraZoneLinkageData(i).NodeHeights[1] = Zone(MultizoneZoneData(IntraZoneLinkageData(i).NodeNums[1]).ZoneNum).Centroid.z;
3727 : } else {
3728 0 : if (simulation_control.iWPCCnt == iWPCCntr::Input) { // Surface-Average does not need inputs of external nodes
3729 0 : IntraZoneLinkageData(i).NodeNums[1] = MultizoneSurfaceData(IntraZoneLinkageData(i).LinkNum).NodeNums[1];
3730 0 : if (IntraZoneLinkageData(i).NodeNums[1] == 0) {
3731 0 : ShowSevereError(m_state,
3732 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid " + cAlphaFields(3) +
3733 0 : " given = " + Alphas(3) +
3734 : " in AirflowNetwork:IntraZone:Node or AirflowNetwork:MultiZone:Zone or "
3735 : "AirflowNetwork:MultiZone:ExternalNode objects");
3736 0 : ErrorsFound = true;
3737 : }
3738 : }
3739 0 : if (simulation_control.iWPCCnt == iWPCCntr::SurfAvg) {
3740 0 : if (!lAlphaBlanks(3)) {
3741 0 : ShowWarningError(m_state,
3742 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + " The input of " + cAlphaFields(3) +
3743 : " is not needed, ");
3744 0 : ShowContinueError(m_state,
3745 : " since AirflowNetwork Wind Pressure Coefficient Type = SURFACE-AVERAGE CALCULATION. The "
3746 : "simulation continues...");
3747 : }
3748 0 : IntraZoneLinkageData(i).NodeNums[1] = MultizoneSurfaceData(IntraZoneLinkageData(i).LinkNum).NodeNums[1];
3749 : }
3750 : }
3751 : } else {
3752 4 : IntraZoneLinkageData(i).NodeHeights[1] = IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1]).Height;
3753 4 : IntraZoneLinkageData(i).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1] + AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
3754 : }
3755 : // Ensure the both linked nodes for a surface are not zone nodes.One of nodes has to be an intrazone node
3756 14 : if (IntraZoneLinkageData(i).NodeNums[1] <= AirflowNetworkNumOfZones &&
3757 5 : IntraZoneLinkageData(i).NodeNums[0] <= AirflowNetworkNumOfZones) {
3758 0 : ShowSevereError(m_state,
3759 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + "': Invalid node inputs " + Alphas(2) + " and " +
3760 0 : Alphas(3) + " are zone nodes");
3761 0 : ErrorsFound = true;
3762 : }
3763 9 : if (IntraZoneLinkageData(i).NodeNums[0] <= AirflowNetworkNumOfZones &&
3764 9 : IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode && lAlphaBlanks(5)) {
3765 0 : if (IntraZoneLinkageData(i).NodeNums[0] !=
3766 0 : m_state.afn->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3767 0 : .AFNZoneNum) {
3768 0 : ShowSevereError(
3769 : m_state,
3770 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + ": Invalid zone inputs between Node and Link " +
3771 0 : Alphas(2) + " and " +
3772 0 : m_state.afn->MultizoneZoneData(IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0]).AFNZoneNum).ZoneName);
3773 0 : ErrorsFound = true;
3774 : }
3775 : }
3776 9 : if (IntraZoneLinkageData(i).NodeNums[1] <= AirflowNetworkNumOfZones &&
3777 9 : IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode && lAlphaBlanks(5)) {
3778 3 : if (IntraZoneLinkageData(i).NodeNums[1] !=
3779 3 : m_state.afn->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3780 3 : .AFNZoneNum) {
3781 0 : ShowSevereError(
3782 : m_state,
3783 0 : format(RoutineName) + CurrentModuleObject + "='" + Alphas(1) + ": Invalid zone inputs between Node and Link " +
3784 0 : Alphas(3) + " and " +
3785 0 : m_state.afn->MultizoneZoneData(IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[1]).AFNZoneNum).ZoneName);
3786 0 : ErrorsFound = true;
3787 : }
3788 : }
3789 : }
3790 :
3791 : // Reset the number of intrazone links for a given surface
3792 1 : NumOfLinksIntraZone = IntraZoneNumOfLinks;
3793 10 : for (int i = 1; i <= IntraZoneNumOfLinks; ++i) {
3794 9 : int j = IntraZoneLinkageData(i).LinkNum;
3795 9 : if (j > 0) {
3796 : // Revise data in multizone object
3797 2 : NumOfLinksIntraZone = NumOfLinksIntraZone - 1;
3798 2 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond == 0) {
3799 : // Exterior surface NodeNums[1] should be equal
3800 0 : if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3801 0 : MultizoneSurfaceData(j).RAFNflag = true;
3802 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3803 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3804 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3805 0 : MultizoneSurfaceData(j).RAFNflag = true;
3806 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3807 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3808 : } else {
3809 0 : ShowSevereError(m_state,
3810 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3811 0 : IntraZoneLinkageData(i).Name +
3812 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3813 0 : ErrorsFound = true;
3814 : }
3815 : } else {
3816 : // Interior surface
3817 4 : if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode &&
3818 2 : IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3819 0 : MultizoneSurfaceData(j).RAFNflag = true;
3820 0 : if (MultizoneZoneData(MultizoneSurfaceData(j).NodeNums[0]).ZoneNum ==
3821 0 : m_state.afn
3822 0 : ->IntraZoneNodeData(IntraZoneLinkageData(i).NodeNums[0] - AirflowNetworkNumOfZones - AirflowNetworkNumOfExtNode)
3823 0 : .ZoneNum) {
3824 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3825 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3826 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1];
3827 : } else {
3828 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3829 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3830 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[0];
3831 : }
3832 2 : } else if (IntraZoneLinkageData(i).NodeNums[0] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3833 2 : MultizoneSurfaceData(j).RAFNflag = true;
3834 2 : if (IntraZoneLinkageData(i).NodeNums[1] == MultizoneSurfaceData(j).NodeNums[0]) {
3835 2 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[0];
3836 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] == MultizoneSurfaceData(j).NodeNums[1]) {
3837 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3838 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[0];
3839 : } else {
3840 0 : ShowSevereError(m_state,
3841 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3842 0 : IntraZoneLinkageData(i).Name +
3843 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3844 0 : ErrorsFound = true;
3845 : }
3846 0 : } else if (IntraZoneLinkageData(i).NodeNums[1] > AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode) {
3847 0 : MultizoneSurfaceData(j).RAFNflag = true;
3848 0 : if (IntraZoneLinkageData(i).NodeNums[0] == MultizoneSurfaceData(j).NodeNums[0]) {
3849 0 : MultizoneSurfaceData(j).NodeNums[1] = IntraZoneLinkageData(i).NodeNums[1];
3850 0 : } else if (IntraZoneLinkageData(i).NodeNums[0] == MultizoneSurfaceData(j).NodeNums[1]) {
3851 0 : MultizoneSurfaceData(j).ZonePtr = MultizoneSurfaceData(j).NodeNums[0];
3852 0 : MultizoneSurfaceData(j).NodeNums[0] = IntraZoneLinkageData(i).NodeNums[1];
3853 : } else {
3854 0 : ShowSevereError(m_state,
3855 0 : format(RoutineName) + "The InterZone link is not found between AirflowNetwork:IntraZone:Linkage =" +
3856 0 : IntraZoneLinkageData(i).Name +
3857 0 : " and AirflowNetwork:Multizone:Surface = " + MultizoneSurfaceData(j).SurfName);
3858 0 : ErrorsFound = true;
3859 : }
3860 : }
3861 : }
3862 : }
3863 : }
3864 : // Remove links with surface defined in Multizone : Surface objects
3865 1 : if (NumOfLinksIntraZone < IntraZoneNumOfLinks) {
3866 1 : int link = 1;
3867 8 : while (link <= NumOfLinksIntraZone) {
3868 7 : if (IntraZoneLinkageData(link).LinkNum > 0) {
3869 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3870 0 : ShowWarningError(m_state,
3871 0 : format(RoutineName) + CurrentModuleObject + "='" + IntraZoneLinkageData(link).Name +
3872 : " is reomoved from the list due to the surface conncetion from Intrazone to Interzone.");
3873 : }
3874 8 : for (int j = link; j <= IntraZoneNumOfLinks - 1; ++j) {
3875 7 : IntraZoneLinkageData(j) = IntraZoneLinkageData(j + 1);
3876 : }
3877 : }
3878 7 : if (IntraZoneLinkageData(link).LinkNum == 0) link = link + 1;
3879 : }
3880 1 : if (IntraZoneLinkageData(link).LinkNum > 0) {
3881 1 : if (m_state.dataGlobal->DisplayExtraWarnings) {
3882 0 : ShowWarningError(m_state,
3883 0 : format(RoutineName) + CurrentModuleObject + "='" + IntraZoneLinkageData(link).Name +
3884 : " is removed from the list due to the surface connection from Intrazone to Interzone.");
3885 : }
3886 : }
3887 : }
3888 : }
3889 :
3890 : // Read AirflowNetwork Distribution system node
3891 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Node";
3892 35 : DisSysNumOfNodes = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3893 35 : if (DisSysNumOfNodes > 0) {
3894 23 : DisSysNodeData.allocate(DisSysNumOfNodes);
3895 551 : for (int i = 1; i <= DisSysNumOfNodes; ++i) {
3896 528 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3897 : CurrentModuleObject,
3898 : i,
3899 : Alphas,
3900 : NumAlphas,
3901 : Numbers,
3902 : NumNumbers,
3903 : IOStatus,
3904 : lNumericBlanks,
3905 : lAlphaBlanks,
3906 : cAlphaFields,
3907 : cNumericFields);
3908 528 : DisSysNodeData(i).Name = Alphas(1); // Name of node
3909 528 : DisSysNodeData(i).EPlusName = Alphas(2); // Name of associated EnergyPlus node
3910 528 : DisSysNodeData(i).EPlusType = Alphas(3); // Name of associated EnergyPlus type
3911 528 : DisSysNodeData(i).Height = Numbers(1); // Nodal height
3912 528 : DisSysNodeData(i).EPlusNodeNum = 0; // EPlus node number
3913 : // verify EnergyPlus object type
3914 1512 : if (Util::SameString(Alphas(3), "AirLoopHVAC:ZoneMixer") || Util::SameString(Alphas(3), "AirLoopHVAC:ZoneSplitter") ||
3915 1398 : Util::SameString(Alphas(3), "AirLoopHVAC:OutdoorAirSystem") || Util::SameString(Alphas(3), "OAMixerOutdoorAirStreamNode") ||
3916 1356 : Util::SameString(Alphas(3), "OutdoorAir:NodeList") || Util::SameString(Alphas(3), "OutdoorAir:Node") ||
3917 1484 : Util::SameString(Alphas(3), "Other") || lAlphaBlanks(3)) {
3918 : } else {
3919 0 : ShowSevereError(m_state,
3920 0 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" invalid " + cAlphaFields(3) + "=\"" +
3921 0 : Alphas(3) + "\" illegal key.");
3922 0 : ShowContinueError(m_state,
3923 : "Valid keys are: AirLoopHVAC:ZoneMixer, AirLoopHVAC:ZoneSplitter, AirLoopHVAC:OutdoorAirSystem, "
3924 : "OAMixerOutdoorAirStreamNode, OutdoorAir:NodeList, OutdoorAir:Node or Other.");
3925 0 : ErrorsFound = true;
3926 : }
3927 : // Avoid duplication of EPlusName
3928 7036 : for (int j = 1; j < i; ++j) {
3929 6508 : if (!Util::SameString(Alphas(2), "")) {
3930 4531 : if (Util::SameString(DisSysNodeData(j).EPlusName, Alphas(2))) {
3931 0 : ShowSevereError(m_state,
3932 0 : format(RoutineName) + CurrentModuleObject + "=\"" + Alphas(1) + "\" Duplicated " + cAlphaFields(2) +
3933 0 : "=\"" + Alphas(2) + "\". Please make a correction.");
3934 0 : ErrorsFound = true;
3935 : }
3936 : }
3937 : }
3938 : }
3939 : } else {
3940 12 : if (distribution_simulated) {
3941 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
3942 0 : ErrorsFound = true;
3943 : }
3944 : }
3945 :
3946 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Duct";
3947 35 : if (DisSysNumOfDucts == 0) {
3948 12 : if (distribution_simulated) {
3949 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
3950 0 : ErrorsFound = true;
3951 : }
3952 : }
3953 :
3954 : // Read AirflowNetwork distribution system component: DuctViewFactors
3955 35 : CurrentModuleObject = "AirflowNetwork:Distribution:DuctViewFactors";
3956 35 : DisSysNumOfDuctViewFactors = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
3957 35 : if (DisSysNumOfDuctViewFactors > 0) {
3958 1 : AirflowNetworkLinkageViewFactorData.allocate(DisSysNumOfDuctViewFactors);
3959 2 : for (int i = 1; i <= DisSysNumOfDuctViewFactors; ++i) {
3960 1 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
3961 : CurrentModuleObject,
3962 : i,
3963 : Alphas,
3964 : NumAlphas,
3965 : Numbers,
3966 : NumNumbers,
3967 : IOStatus,
3968 : lNumericBlanks,
3969 : lAlphaBlanks,
3970 : cAlphaFields,
3971 : cNumericFields);
3972 :
3973 1 : auto &this_VF_object(AirflowNetworkLinkageViewFactorData(i));
3974 :
3975 1 : this_VF_object.LinkageName = Alphas(1); // Name of linkage
3976 :
3977 : // Surface exposure fraction
3978 1 : if (Numbers(2) > 1) {
3979 0 : ShowWarningError(m_state,
3980 0 : "Duct surface exposure fraction greater than 1. Check input in: " + CurrentModuleObject + " " +
3981 0 : this_VF_object.LinkageName);
3982 0 : ShowContinueError(m_state, "Using value of 1 for surface exposure fraction");
3983 0 : this_VF_object.DuctExposureFraction = 1;
3984 1 : } else if (Numbers(2) < 0) {
3985 0 : ShowWarningError(
3986 0 : m_state, "Surface exposure fraction less than 0. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
3987 0 : ShowContinueError(m_state, "Using value of 0 for surface exposure fraction");
3988 0 : this_VF_object.DuctExposureFraction = 0;
3989 : } else {
3990 1 : this_VF_object.DuctExposureFraction = Numbers(1);
3991 : }
3992 :
3993 : // Duct surface emittance
3994 1 : if (Numbers(2) > 1) {
3995 0 : ShowWarningError(
3996 0 : m_state, "Duct surface emittance greater than 1. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
3997 0 : ShowContinueError(m_state, "Using value of 1 for surface emittance");
3998 0 : this_VF_object.DuctEmittance = 1;
3999 1 : } else if (Numbers(2) < 0) {
4000 0 : ShowWarningError(
4001 0 : m_state, "Surface exposure fraction less than 0. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4002 0 : ShowContinueError(m_state, "Using value of 0 for surface exposure fraction");
4003 0 : this_VF_object.DuctEmittance = 0;
4004 : } else {
4005 1 : this_VF_object.DuctEmittance = Numbers(2);
4006 : }
4007 :
4008 1 : this_VF_object.ObjectNum = i;
4009 :
4010 1 : int numSurfaces = NumAlphas - 1;
4011 :
4012 1 : this_VF_object.LinkageSurfaceData.allocate(numSurfaces);
4013 :
4014 6 : for (int surfNum = 1; surfNum < NumAlphas; ++surfNum) {
4015 5 : this_VF_object.LinkageSurfaceData(surfNum).SurfaceName = Alphas(surfNum + 1); // Surface name
4016 5 : this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum = Util::FindItemInList(Alphas(surfNum + 1), m_state.dataSurface->Surface);
4017 :
4018 5 : if (this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum == 0) {
4019 0 : ShowFatalError(
4020 0 : m_state, "Surface " + Alphas(surfNum + 1) + " not found. See: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4021 : }
4022 :
4023 : // Surface view factor
4024 5 : if (!m_state.dataSurface->Surface(this_VF_object.LinkageSurfaceData(surfNum).SurfaceNum).HeatTransSurf) {
4025 0 : ShowWarningError(m_state,
4026 0 : "Surface=" + Alphas(surfNum + 1) + " is not a heat transfer surface. Check input in: " +
4027 0 : CurrentModuleObject + " " + this_VF_object.LinkageName);
4028 0 : ShowContinueError(m_state, "Using value of 0 for view factor");
4029 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 0;
4030 5 : } else if (Numbers(surfNum + 2) > 1) {
4031 0 : ShowWarningError(m_state,
4032 0 : "View factor for surface " + Alphas(surfNum + 1) +
4033 0 : " greater than 1. Check input in: " + CurrentModuleObject + " " + this_VF_object.LinkageName);
4034 0 : ShowContinueError(m_state, "Using value of 1 for view factor");
4035 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 1;
4036 5 : } else if (Numbers(surfNum + 2) < 0) {
4037 0 : ShowWarningError(m_state,
4038 0 : "View factor for surface " + Alphas(surfNum + 1) + " less than 0. Check input in: " + CurrentModuleObject +
4039 0 : " " + this_VF_object.LinkageName);
4040 0 : ShowContinueError(m_state, "Using value of 0 for view factor");
4041 0 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = 0;
4042 : } else {
4043 5 : this_VF_object.LinkageSurfaceData(surfNum).ViewFactor = Numbers(surfNum + 2);
4044 : }
4045 : }
4046 : }
4047 : }
4048 :
4049 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Fan";
4050 35 : if (DisSysNumOfCVFs == 0) {
4051 12 : if (distribution_simulated) {
4052 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
4053 0 : ErrorsFound = true;
4054 : }
4055 : }
4056 :
4057 : // Read PressureController
4058 35 : CurrentModuleObject = "AirflowNetwork:ZoneControl:PressureController";
4059 35 : NumOfPressureControllers = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
4060 35 : if (NumOfPressureControllers > 1) {
4061 0 : ShowSevereError(m_state,
4062 0 : format(RoutineName) + "More " + CurrentModuleObject + " are found. Currently only one( \"1\") " + CurrentModuleObject +
4063 : " object per simulation is allowed when using AirflowNetwork Distribution Systems.");
4064 0 : ShowFatalError(
4065 0 : m_state, format("{}Errors found getting {} object. Previous error(s) cause program termination.", RoutineName, CurrentModuleObject));
4066 : }
4067 :
4068 35 : if (NumOfPressureControllers > 0) {
4069 1 : PressureControllerData.allocate(NumOfPressureControllers);
4070 2 : for (int i = 1; i <= NumOfPressureControllers; ++i) {
4071 1 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
4072 : CurrentModuleObject,
4073 : i,
4074 : Alphas,
4075 : NumAlphas,
4076 : Numbers,
4077 : NumNumbers,
4078 : IOStatus,
4079 : lNumericBlanks,
4080 : lAlphaBlanks,
4081 : cAlphaFields,
4082 : cNumericFields);
4083 1 : PressureControllerData(i).Name = Alphas(1); // Object Name
4084 1 : PressureControllerData(i).ZoneName = Alphas(2); // Zone name
4085 1 : PressureControllerData(i).ZoneNum = Util::FindItemInList(Alphas(2), Zone);
4086 2 : PressureControllerData(i).AFNNodeNum =
4087 1 : Util::FindItemInList(Alphas(2), MultizoneZoneData, &MultizoneZoneProp::ZoneName, AirflowNetworkNumOfZones);
4088 1 : if (PressureControllerData(i).ZoneNum == 0) {
4089 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, invalid " + cAlphaFields(2) + " given.");
4090 0 : ShowContinueError(m_state, "..invalid " + cAlphaFields(2) + " = \"" + PressureControllerData(i).ZoneName + "\"");
4091 0 : ErrorsFound = true;
4092 : }
4093 :
4094 1 : PressureControllerData(i).ControlObjectType = Alphas(3); // Control Object Type
4095 1 : PressureControllerData(i).ControlObjectName = Alphas(4); // Control Object Name
4096 :
4097 : {
4098 : // This SELECT_CASE_var will go on input refactor, no need to fix
4099 1 : auto const SELECT_CASE_var(Util::makeUPPER(Alphas(3)));
4100 1 : if (SELECT_CASE_var == "AIRFLOWNETWORK:MULTIZONE:COMPONENT:ZONEEXHAUSTFAN") {
4101 0 : PressureControllerData(i).ControlTypeSet = PressureCtrlExhaust;
4102 1 : } else if (SELECT_CASE_var == "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT:RELIEFAIRFLOW") {
4103 1 : PressureControllerData(i).ControlTypeSet = PressureCtrlRelief;
4104 : } else { // Error
4105 0 : ShowSevereError(m_state,
4106 0 : format(RoutineName) + CurrentModuleObject + " object, The entered choice for " + cAlphaFields(3) +
4107 0 : " is not valid = \"" + PressureControllerData(i).Name + "\"");
4108 0 : ShowContinueError(m_state,
4109 : "Valid choices are "
4110 : "\"AirflowNetwork:MultiZone:Component:ZoneExhaustFan\",\"AirflowNetwork:Distribution:Component:"
4111 : "ReliefAirFlow\"");
4112 0 : ShowContinueError(m_state, "The input choice is " + Alphas(3));
4113 0 : ErrorsFound = true;
4114 : }
4115 1 : }
4116 :
4117 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlExhaust) {
4118 : // This is not great
4119 0 : bool is_EXF{false};
4120 0 : auto afe = elements.find(Alphas(4));
4121 0 : if (afe != elements.end()) {
4122 0 : is_EXF = afe->second->type() == ComponentType::EXF;
4123 : }
4124 0 : if (!is_EXF) {
4125 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, an invalid name is given:");
4126 0 : ShowContinueError(m_state, ".. invalid " + cAlphaFields(4) + " = \"" + Alphas(4) + "\".");
4127 0 : ErrorsFound = true;
4128 : }
4129 0 : }
4130 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlRelief) {
4131 : // This is not great
4132 1 : bool is_REL{false};
4133 1 : auto afe = elements.find(Alphas(4));
4134 1 : if (afe != elements.end()) {
4135 1 : is_REL = afe->second->type() == ComponentType::REL;
4136 : }
4137 1 : if (!is_REL) {
4138 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " object, an invalid name is given:");
4139 0 : ShowContinueError(m_state, ".. invalid " + cAlphaFields(4) + " = \"" + Alphas(4) + "\".");
4140 0 : ErrorsFound = true;
4141 : }
4142 1 : }
4143 :
4144 1 : if (lAlphaBlanks(5)) {
4145 1 : PressureControllerData(i).AvailSchedPtr = ScheduleManager::ScheduleAlwaysOn;
4146 : } else {
4147 0 : PressureControllerData(i).AvailSchedPtr = GetScheduleIndex(m_state, Alphas(5));
4148 0 : if (PressureControllerData(i).AvailSchedPtr == 0) {
4149 0 : ShowSevereError(m_state,
4150 0 : CurrentModuleObject + ", \"" + PressureControllerData(i).Name + "\" " + cAlphaFields(5) +
4151 0 : " not found: " + Alphas(5));
4152 0 : ErrorsFound = true;
4153 : }
4154 : }
4155 1 : PressureControllerData(i).PresSetpointSchedPtr = GetScheduleIndex(m_state, Alphas(6));
4156 1 : if (PressureControllerData(i).PresSetpointSchedPtr == 0) {
4157 0 : ShowSevereError(m_state,
4158 0 : CurrentModuleObject + ", \"" + PressureControllerData(i).Name + "\" " + cAlphaFields(6) +
4159 0 : " not found: " + Alphas(6));
4160 0 : ErrorsFound = true;
4161 : }
4162 : }
4163 : }
4164 :
4165 : // Assign numbers of nodes and linkages
4166 35 : if (simulation_control.type != ControlType::NoMultizoneOrDistribution) {
4167 35 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
4168 27 : NumOfNodesMultiZone = AirflowNetworkNumOfZones + AirflowNetworkNumOfExtNode;
4169 : } else {
4170 8 : NumOfNodesMultiZone = AirflowNetworkNumOfZones + NumOfExtNodes;
4171 : }
4172 35 : NumOfLinksMultiZone = AirflowNetworkNumOfSurfaces;
4173 35 : AirflowNetworkNumOfNodes = NumOfNodesMultiZone;
4174 35 : if (NumOfNodesIntraZone > 0) AirflowNetworkNumOfNodes = AirflowNetworkNumOfNodes + NumOfNodesIntraZone;
4175 35 : AirflowNetworkNumOfLinks = NumOfLinksMultiZone;
4176 35 : if (NumOfLinksIntraZone > 0) AirflowNetworkNumOfLinks = AirflowNetworkNumOfLinks + NumOfLinksIntraZone;
4177 : }
4178 35 : if (distribution_simulated) {
4179 23 : AirflowNetworkNumOfNodes = NumOfNodesMultiZone + DisSysNumOfNodes + NumOfNodesIntraZone;
4180 : }
4181 :
4182 : // Assign node data
4183 35 : AirflowNetworkNodeData.allocate(AirflowNetworkNumOfNodes);
4184 : // Zone node
4185 150 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
4186 115 : AirflowNetworkNodeData(i).Name = MultizoneZoneData(i).ZoneName;
4187 115 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4188 115 : AirflowNetworkNodeData(i).EPlusZoneNum = MultizoneZoneData(i).ZoneNum;
4189 115 : AirflowNetworkNodeData(i).NodeHeight = MultizoneZoneData(i).Height;
4190 : }
4191 : // External node
4192 35 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
4193 143 : for (int i = AirflowNetworkNumOfZones + 1; i <= NumOfNodesMultiZone; ++i) {
4194 116 : AirflowNetworkNodeData(i).Name = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).Name;
4195 116 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4196 116 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4197 116 : AirflowNetworkNodeData(i).NodeHeight = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).height;
4198 116 : AirflowNetworkNodeData(i).ExtNodeNum = i - AirflowNetworkNumOfZones;
4199 116 : AirflowNetworkNodeData(i).OutAirNodeNum = MultizoneExternalNodeData(i - AirflowNetworkNumOfZones).OutAirNodeNum;
4200 : }
4201 : } else { // Surface-Average input
4202 89 : for (int i = AirflowNetworkNumOfZones + 1; i <= NumOfNodesMultiZone; ++i) {
4203 81 : n = i - AirflowNetworkNumOfZones;
4204 81 : AirflowNetworkNodeData(i).Name = MultizoneExternalNodeData(n).Name;
4205 81 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4206 81 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4207 81 : AirflowNetworkNodeData(i).ExtNodeNum = n;
4208 : }
4209 : }
4210 :
4211 : // Intrazone node
4212 35 : if (NumOfNodesIntraZone > 0) {
4213 6 : for (int i = NumOfNodesMultiZone + 1; i <= NumOfNodesMultiZone + NumOfNodesIntraZone; ++i) {
4214 5 : n = i - NumOfNodesMultiZone;
4215 5 : AirflowNetworkNodeData(i).Name = IntraZoneNodeData(n).Name;
4216 5 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4217 5 : AirflowNetworkNodeData(i).EPlusZoneNum = IntraZoneNodeData(n).ZoneNum;
4218 5 : AirflowNetworkNodeData(i).NodeHeight = IntraZoneNodeData(n).Height;
4219 5 : AirflowNetworkNodeData(i).RAFNNodeNum = IntraZoneNodeData(n).RAFNNodeNum;
4220 : }
4221 6 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
4222 5 : if (MultizoneZoneData(i).RAFNNodeNum > 0) {
4223 1 : AirflowNetworkNodeData(i).RAFNNodeNum = MultizoneZoneData(i).RAFNNodeNum;
4224 : }
4225 : }
4226 : }
4227 35 : NumOfNodesMultiZone = NumOfNodesMultiZone + NumOfNodesIntraZone;
4228 :
4229 : // Check whether Distribution system is simulated
4230 35 : if (AirflowNetworkNumOfNodes > NumOfNodesMultiZone) {
4231 : // Search node types: OAMixerOutdoorAirStreamNode, OutdoorAir:NodeList, and OutdoorAir:Node
4232 23 : int j = 0;
4233 551 : for (int i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
4234 528 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
4235 14 : ++j;
4236 : }
4237 528 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:NodeList")) {
4238 0 : ++j;
4239 : }
4240 528 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:Node")) {
4241 0 : ++j;
4242 : }
4243 : }
4244 :
4245 551 : for (int i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
4246 528 : AirflowNetworkNodeData(i).Name = DisSysNodeData(i - NumOfNodesMultiZone).Name;
4247 528 : AirflowNetworkNodeData(i).NodeTypeNum = 0;
4248 528 : AirflowNetworkNodeData(i).EPlusZoneNum = 0;
4249 528 : AirflowNetworkNodeData(i).NodeHeight = DisSysNodeData(i - NumOfNodesMultiZone).Height;
4250 528 : AirflowNetworkNodeData(i).EPlusNodeNum = DisSysNodeData(i - NumOfNodesMultiZone).EPlusNodeNum;
4251 : // Get mixer information
4252 528 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:ZoneMixer")) {
4253 24 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::MIX;
4254 : }
4255 : // Get splitter information
4256 528 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:ZoneSplitter")) {
4257 24 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPL;
4258 : }
4259 : // Get outside air system information
4260 528 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
4261 14 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::OAN;
4262 : }
4263 : // Get OA system inlet information 'OAMixerOutdoorAirStreamNode' was specified as an outdoor air node implicitly
4264 528 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
4265 14 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::EXT;
4266 14 : AirflowNetworkNodeData(i).ExtNodeNum = AirflowNetworkNumOfExtNode + 1;
4267 14 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4268 : }
4269 1056 : if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:NodeList") ||
4270 1056 : Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "OutdoorAir:Node")) {
4271 0 : if (j > 1) {
4272 0 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::EXT;
4273 0 : AirflowNetworkNodeData(i).ExtNodeNum = AirflowNetworkNumOfExtNode + 1;
4274 0 : AirflowNetworkNodeData(i).NodeTypeNum = 1;
4275 : } else {
4276 0 : ShowSevereError(m_state,
4277 0 : format(RoutineName) + "AirflowNetwork:Distribution:Node: The outdoor air node is found at " +
4278 0 : AirflowNetworkNodeData(i).Name);
4279 0 : ShowContinueError(m_state,
4280 : "The node with Component Object Type = OAMixerOutdoorAirStreamNode is not found. Please check inputs.");
4281 0 : ErrorsFound = true;
4282 : }
4283 : }
4284 : }
4285 : }
4286 :
4287 : // Start to assembly AirflowNetwork Components
4288 35 : AirflowNetworkNumOfComps = AirflowNetworkNumOfDetOpenings + AirflowNetworkNumOfSimOpenings + AirflowNetworkNumOfSurCracks +
4289 35 : AirflowNetworkNumOfSurELA + DisSysNumOfLeaks + DisSysNumOfELRs + DisSysNumOfDucts + DisSysNumOfDampers +
4290 35 : DisSysNumOfCVFs + DisSysNumOfDetFans + DisSysNumOfCPDs + DisSysNumOfCoils + DisSysNumOfTermUnits +
4291 35 : AirflowNetworkNumOfExhFan + DisSysNumOfHXs + AirflowNetworkNumOfHorOpenings + NumOfOAFans + NumOfReliefFans +
4292 35 : AirflowNetworkNumOfSFR;
4293 35 : AirflowNetworkCompData.allocate(AirflowNetworkNumOfComps);
4294 :
4295 66 : for (int i = 1; i <= AirflowNetworkNumOfDetOpenings; ++i) { // Detailed opening component
4296 31 : AirflowNetworkCompData(i).Name = MultizoneCompDetOpeningData(i).name;
4297 31 : compnum[AirflowNetworkCompData(i).Name] = i;
4298 31 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DOP;
4299 31 : AirflowNetworkCompData(i).TypeNum = i;
4300 31 : AirflowNetworkCompData(i).EPlusName = "";
4301 31 : AirflowNetworkCompData(i).EPlusCompName = "";
4302 31 : AirflowNetworkCompData(i).EPlusType = "";
4303 31 : AirflowNetworkCompData(i).CompNum = i;
4304 : }
4305 :
4306 35 : int j = AirflowNetworkNumOfDetOpenings;
4307 47 : for (int i = 1 + j; i <= AirflowNetworkNumOfSimOpenings + j; ++i) { // Simple opening component
4308 12 : n = i - j;
4309 12 : AirflowNetworkCompData(i).Name = MultizoneCompSimpleOpeningData(n).name;
4310 12 : compnum[AirflowNetworkCompData(i).Name] = i;
4311 12 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SOP;
4312 12 : AirflowNetworkCompData(i).TypeNum = n;
4313 12 : AirflowNetworkCompData(i).EPlusName = "";
4314 12 : AirflowNetworkCompData(i).EPlusCompName = "";
4315 12 : AirflowNetworkCompData(i).EPlusType = "";
4316 12 : AirflowNetworkCompData(i).CompNum = i;
4317 : }
4318 :
4319 35 : j += AirflowNetworkNumOfSimOpenings;
4320 118 : for (int i = 1 + j; i <= AirflowNetworkNumOfSurCracks + j; ++i) { // Surface crack component
4321 83 : n = i - j;
4322 83 : AirflowNetworkCompData(i).Name = MultizoneSurfaceCrackData(n).name;
4323 83 : compnum[AirflowNetworkCompData(i).Name] = i;
4324 83 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SCR;
4325 83 : AirflowNetworkCompData(i).TypeNum = n;
4326 83 : AirflowNetworkCompData(i).EPlusName = "";
4327 83 : AirflowNetworkCompData(i).EPlusCompName = "";
4328 83 : AirflowNetworkCompData(i).EPlusType = "";
4329 83 : AirflowNetworkCompData(i).CompNum = i;
4330 : }
4331 :
4332 35 : j += AirflowNetworkNumOfSurCracks;
4333 66 : for (int i = 1 + j; i <= AirflowNetworkNumOfSurELA + j; ++i) { // Surface crack component
4334 31 : n = i - j;
4335 31 : AirflowNetworkCompData(i).Name = MultizoneSurfaceELAData(n).name;
4336 31 : compnum[AirflowNetworkCompData(i).Name] = i;
4337 31 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::SEL;
4338 31 : AirflowNetworkCompData(i).TypeNum = n;
4339 31 : AirflowNetworkCompData(i).EPlusName = "";
4340 31 : AirflowNetworkCompData(i).EPlusCompName = "";
4341 31 : AirflowNetworkCompData(i).EPlusType = "";
4342 31 : AirflowNetworkCompData(i).CompNum = i;
4343 : }
4344 :
4345 35 : j += AirflowNetworkNumOfSurELA;
4346 49 : for (int i = 1 + j; i <= AirflowNetworkNumOfExhFan + j; ++i) { // Zone exhaust fan component
4347 14 : n = i - j;
4348 14 : AirflowNetworkCompData(i).Name = MultizoneCompExhaustFanData(n).name;
4349 14 : compnum[AirflowNetworkCompData(i).Name] = i;
4350 14 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::EXF;
4351 14 : AirflowNetworkCompData(i).TypeNum = n;
4352 14 : AirflowNetworkCompData(i).EPlusName = "";
4353 14 : AirflowNetworkCompData(i).EPlusCompName = "";
4354 14 : AirflowNetworkCompData(i).EPlusType = "";
4355 14 : AirflowNetworkCompData(i).CompNum = i;
4356 : }
4357 :
4358 35 : j += AirflowNetworkNumOfExhFan;
4359 37 : for (int i = 1 + j; i <= AirflowNetworkNumOfHorOpenings + j; ++i) { // Distribution system crack component
4360 2 : n = i - j;
4361 2 : AirflowNetworkCompData(i).Name = MultizoneCompHorOpeningData(n).name;
4362 2 : compnum[AirflowNetworkCompData(i).Name] = i;
4363 2 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::HOP;
4364 2 : AirflowNetworkCompData(i).TypeNum = n;
4365 2 : AirflowNetworkCompData(i).EPlusName = "";
4366 2 : AirflowNetworkCompData(i).EPlusCompName = "";
4367 2 : AirflowNetworkCompData(i).EPlusType = "";
4368 2 : AirflowNetworkCompData(i).CompNum = i;
4369 : }
4370 :
4371 35 : j += AirflowNetworkNumOfHorOpenings;
4372 49 : for (int i = 1 + j; i <= DisSysNumOfLeaks + j; ++i) { // Distribution system crack component
4373 14 : n = i - j;
4374 14 : AirflowNetworkCompData(i).Name = DisSysCompLeakData(n).name;
4375 14 : compnum[AirflowNetworkCompData(i).Name] = i;
4376 14 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::PLR;
4377 14 : AirflowNetworkCompData(i).TypeNum = n;
4378 14 : AirflowNetworkCompData(i).EPlusName = "";
4379 14 : AirflowNetworkCompData(i).EPlusCompName = "";
4380 14 : AirflowNetworkCompData(i).EPlusType = "";
4381 14 : AirflowNetworkCompData(i).CompNum = i;
4382 : }
4383 :
4384 35 : j += DisSysNumOfLeaks;
4385 135 : for (int i = 1 + j; i <= DisSysNumOfELRs + j; ++i) { // Distribution system effective leakage ratio component
4386 100 : n = i - j;
4387 100 : AirflowNetworkCompData(i).Name = DisSysCompELRData(n).name;
4388 100 : compnum[AirflowNetworkCompData(i).Name] = i;
4389 100 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::ELR;
4390 100 : AirflowNetworkCompData(i).TypeNum = n;
4391 100 : AirflowNetworkCompData(i).EPlusName = "";
4392 100 : AirflowNetworkCompData(i).EPlusCompName = "";
4393 100 : AirflowNetworkCompData(i).EPlusType = "";
4394 100 : AirflowNetworkCompData(i).CompNum = i;
4395 : }
4396 :
4397 35 : j += DisSysNumOfELRs;
4398 290 : for (int i = 1 + j; i <= DisSysNumOfDucts + j; ++i) { // Distribution system effective leakage ratio component
4399 255 : n = i - j;
4400 255 : AirflowNetworkCompData(i).Name = DisSysCompDuctData(n).name;
4401 255 : compnum[AirflowNetworkCompData(i).Name] = i;
4402 255 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DWC;
4403 255 : AirflowNetworkCompData(i).TypeNum = n;
4404 255 : AirflowNetworkCompData(i).EPlusName = "";
4405 255 : AirflowNetworkCompData(i).EPlusCompName = "";
4406 255 : AirflowNetworkCompData(i).EPlusType = "";
4407 255 : AirflowNetworkCompData(i).CompNum = i;
4408 : }
4409 :
4410 35 : j += DisSysNumOfDucts;
4411 35 : for (int i = 1 + j; i <= DisSysNumOfDampers + j; ++i) { // Distribution system effective leakage ratio component
4412 0 : n = i - j;
4413 0 : AirflowNetworkCompData(i).Name = DisSysCompDamperData(n).name;
4414 0 : compnum[AirflowNetworkCompData(i).Name] = i;
4415 0 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::DMP;
4416 0 : AirflowNetworkCompData(i).TypeNum = n;
4417 0 : AirflowNetworkCompData(i).EPlusName = "";
4418 0 : AirflowNetworkCompData(i).EPlusCompName = "";
4419 0 : AirflowNetworkCompData(i).EPlusType = "";
4420 0 : AirflowNetworkCompData(i).CompNum = i;
4421 : }
4422 :
4423 35 : j += DisSysNumOfDampers;
4424 59 : for (int i = 1 + j; i <= DisSysNumOfCVFs + j; ++i) { // Distribution system constant volume fan component
4425 24 : n = i - j;
4426 24 : AirflowNetworkCompData(i).Name = DisSysCompCVFData(n).name;
4427 24 : compnum[AirflowNetworkCompData(i).Name] = i;
4428 24 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::CVF;
4429 24 : AirflowNetworkCompData(i).TypeNum = n;
4430 24 : AirflowNetworkCompData(i).EPlusName = "";
4431 24 : AirflowNetworkCompData(i).EPlusCompName = "";
4432 24 : AirflowNetworkCompData(i).EPlusType = "";
4433 24 : AirflowNetworkCompData(i).CompNum = i;
4434 24 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::FAN;
4435 : }
4436 :
4437 35 : j += DisSysNumOfCVFs;
4438 35 : for (int i = 1 + j; i <= DisSysNumOfDetFans + j; ++i) { // Distribution system fan component
4439 0 : n = i - j;
4440 0 : AirflowNetworkCompData(i).Name = DisSysCompDetFanData(n).name;
4441 0 : compnum[AirflowNetworkCompData(i).Name] = i;
4442 0 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::FAN;
4443 0 : AirflowNetworkCompData(i).TypeNum = n;
4444 0 : AirflowNetworkCompData(i).EPlusName = "";
4445 0 : AirflowNetworkCompData(i).EPlusCompName = "";
4446 0 : AirflowNetworkCompData(i).EPlusType = "";
4447 0 : AirflowNetworkCompData(i).CompNum = i;
4448 0 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::FAN;
4449 : }
4450 :
4451 35 : j += DisSysNumOfDetFans;
4452 47 : for (int i = 1 + j; i <= DisSysNumOfCPDs + j; ++i) { // Distribution system constant pressure drop component
4453 12 : n = i - j;
4454 12 : AirflowNetworkCompData(i).Name = DisSysCompCPDData(n).name;
4455 12 : compnum[AirflowNetworkCompData(i).Name] = i;
4456 12 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::CPD;
4457 12 : AirflowNetworkCompData(i).TypeNum = n;
4458 12 : AirflowNetworkCompData(i).EPlusName = "";
4459 12 : AirflowNetworkCompData(i).EPlusCompName = "";
4460 12 : AirflowNetworkCompData(i).EPlusType = "";
4461 12 : AirflowNetworkCompData(i).CompNum = i;
4462 : }
4463 :
4464 35 : j += DisSysNumOfCPDs;
4465 92 : for (int i = 1 + j; i <= DisSysNumOfCoils + j; ++i) { // Distribution system coil component
4466 57 : n = i - j;
4467 57 : AirflowNetworkCompData(i).Name = DisSysCompCoilData(n).name;
4468 57 : compnum[AirflowNetworkCompData(i).Name] = i;
4469 57 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::COI;
4470 57 : AirflowNetworkCompData(i).TypeNum = n;
4471 57 : AirflowNetworkCompData(i).EPlusName = "";
4472 57 : AirflowNetworkCompData(i).EPlusCompName = "";
4473 57 : AirflowNetworkCompData(i).EPlusType = "";
4474 57 : AirflowNetworkCompData(i).CompNum = i;
4475 57 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::COI;
4476 : }
4477 :
4478 35 : j += DisSysNumOfCoils;
4479 59 : for (int i = 1 + j; i <= DisSysNumOfTermUnits + j; ++i) { // Terminal unit component
4480 24 : n = i - j;
4481 24 : AirflowNetworkCompData(i).Name = DisSysCompTermUnitData(n).name;
4482 24 : compnum[AirflowNetworkCompData(i).Name] = i;
4483 24 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::TMU;
4484 24 : AirflowNetworkCompData(i).TypeNum = n;
4485 24 : AirflowNetworkCompData(i).EPlusName = "";
4486 24 : AirflowNetworkCompData(i).EPlusCompName = "";
4487 24 : AirflowNetworkCompData(i).EPlusType = "";
4488 24 : AirflowNetworkCompData(i).CompNum = i;
4489 24 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::RHT;
4490 : }
4491 :
4492 35 : j += DisSysNumOfTermUnits;
4493 36 : for (int i = 1 + j; i <= DisSysNumOfHXs + j; ++i) { // Distribution system heat exchanger component
4494 1 : n = i - j;
4495 1 : AirflowNetworkCompData(i).Name = DisSysCompHXData(n).name;
4496 1 : compnum[AirflowNetworkCompData(i).Name] = i;
4497 1 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::HEX;
4498 1 : AirflowNetworkCompData(i).TypeNum = n;
4499 1 : AirflowNetworkCompData(i).EPlusName = "";
4500 1 : AirflowNetworkCompData(i).EPlusCompName = "";
4501 1 : AirflowNetworkCompData(i).EPlusType = "";
4502 1 : AirflowNetworkCompData(i).CompNum = i;
4503 1 : AirflowNetworkCompData(i).EPlusTypeNum = iEPlusComponentType::HEX;
4504 : }
4505 :
4506 35 : j += DisSysNumOfHXs;
4507 37 : for (int i = 1 + j; i <= NumOfOAFans + j; ++i) { // OA fan component
4508 2 : n = i - j;
4509 2 : AirflowNetworkCompData(i).Name = DisSysCompOutdoorAirData(n).name;
4510 2 : compnum[AirflowNetworkCompData(i).Name] = i;
4511 2 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::OAF;
4512 2 : AirflowNetworkCompData(i).TypeNum = n;
4513 2 : AirflowNetworkCompData(i).EPlusName = "";
4514 2 : AirflowNetworkCompData(i).EPlusCompName = "";
4515 2 : AirflowNetworkCompData(i).EPlusType = "";
4516 2 : AirflowNetworkCompData(i).CompNum = i;
4517 : }
4518 :
4519 35 : j += NumOfOAFans;
4520 37 : for (int i = 1 + j; i <= NumOfReliefFans + j; ++i) { // OA fan component
4521 2 : n = i - j;
4522 2 : AirflowNetworkCompData(i).Name = DisSysCompReliefAirData(n).name;
4523 2 : compnum[AirflowNetworkCompData(i).Name] = i;
4524 2 : AirflowNetworkCompData(i).CompTypeNum = iComponentTypeNum::REL;
4525 2 : AirflowNetworkCompData(i).TypeNum = n;
4526 2 : AirflowNetworkCompData(i).EPlusName = "";
4527 2 : AirflowNetworkCompData(i).EPlusCompName = "";
4528 2 : AirflowNetworkCompData(i).EPlusType = "";
4529 2 : AirflowNetworkCompData(i).CompNum = i;
4530 : }
4531 :
4532 : // This is also a bit of a hack to keep things working, this needs to be removed ASAP
4533 35 : j += NumOfReliefFans;
4534 35 : int ii = 1 + j;
4535 35 : int type_i = 1;
4536 36 : for (auto const &el : SpecifiedMassFlowData) {
4537 1 : AirflowNetworkCompData(ii).Name = el.name;
4538 1 : compnum[el.name] = ii;
4539 1 : AirflowNetworkCompData(ii).CompTypeNum = iComponentTypeNum::SMF;
4540 1 : AirflowNetworkCompData(ii).TypeNum = type_i;
4541 1 : AirflowNetworkCompData(ii).EPlusName = "";
4542 1 : AirflowNetworkCompData(ii).EPlusCompName = "";
4543 1 : AirflowNetworkCompData(ii).EPlusType = "";
4544 1 : AirflowNetworkCompData(ii).CompNum = ii;
4545 1 : ++ii;
4546 1 : ++type_i;
4547 : }
4548 :
4549 35 : type_i = 1;
4550 35 : for (auto const &el : SpecifiedVolumeFlowData) {
4551 0 : AirflowNetworkCompData(ii).Name = el.name;
4552 0 : compnum[el.name] = ii;
4553 0 : AirflowNetworkCompData(ii).CompTypeNum = iComponentTypeNum::SVF;
4554 0 : AirflowNetworkCompData(ii).TypeNum = type_i;
4555 0 : AirflowNetworkCompData(ii).EPlusName = "";
4556 0 : AirflowNetworkCompData(ii).EPlusCompName = "";
4557 0 : AirflowNetworkCompData(ii).EPlusType = "";
4558 0 : AirflowNetworkCompData(ii).CompNum = ii;
4559 0 : ++ii;
4560 0 : ++type_i;
4561 : }
4562 :
4563 : // Assign linkage data
4564 :
4565 : // Read AirflowNetwork linkage data
4566 35 : CurrentModuleObject = "AirflowNetwork:Distribution:Linkage";
4567 35 : DisSysNumOfLinks = m_state.dataInputProcessing->inputProcessor->getNumObjectsFound(m_state, CurrentModuleObject);
4568 35 : if (DisSysNumOfLinks > 0 && distribution_simulated) { // Multizone + Distribution
4569 23 : AirflowNetworkNumOfLinks = NumOfLinksMultiZone + DisSysNumOfLinks;
4570 23 : AirflowNetworkLinkageData.allocate(DisSysNumOfLinks + AirflowNetworkNumOfSurfaces);
4571 : } else { // Multizone + IntraZone only
4572 : // AirflowNetworkLinkageData.allocate( AirflowNetworkNumOfSurfaces );
4573 12 : AirflowNetworkLinkageData.allocate(AirflowNetworkNumOfLinks);
4574 : }
4575 :
4576 : // Assign Multizone linkage based on surfaces, by assuming every surface has a crack or opening
4577 35 : j = 0;
4578 526 : for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
4579 491 : if (MultizoneSurfaceData(count).SurfNum == 0) continue;
4580 491 : AirflowNetworkLinkageData(count).Name = MultizoneSurfaceData(count).SurfName;
4581 491 : AirflowNetworkLinkageData(count).NodeNums[0] = MultizoneSurfaceData(count).NodeNums[0];
4582 491 : AirflowNetworkLinkageData(count).NodeNums[1] = MultizoneSurfaceData(count).NodeNums[1];
4583 491 : AirflowNetworkLinkageData(count).CompName = MultizoneSurfaceData(count).OpeningName;
4584 491 : AirflowNetworkLinkageData(count).ZoneNum = 0;
4585 491 : AirflowNetworkLinkageData(count).LinkNum = count;
4586 491 : AirflowNetworkLinkageData(count).NodeHeights[0] = MultizoneSurfaceData(count).CHeight;
4587 491 : AirflowNetworkLinkageData(count).NodeHeights[1] = MultizoneSurfaceData(count).CHeight;
4588 491 : if (!m_state.dataSurface->WorldCoordSystem) {
4589 76 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum > 0) {
4590 76 : AirflowNetworkLinkageData(count).NodeHeights[0] -=
4591 76 : Zone(AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum).OriginZ;
4592 : }
4593 76 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum > 0) {
4594 4 : AirflowNetworkLinkageData(count).NodeHeights[1] -=
4595 4 : Zone(AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum).OriginZ;
4596 : }
4597 : }
4598 : // Find component number
4599 491 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4600 491 : if (afe != elements.end()) {
4601 : // found = false;
4602 : // for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
4603 491 : AirflowNetworkLinkageData(count).element = afe->second;
4604 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4605 491 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4606 491 : assert(compnum_iter != compnum.end());
4607 491 : int compnum = compnum_iter->second;
4608 491 : AirflowNetworkLinkageData(count).CompNum = compnum;
4609 :
4610 491 : auto &surf = m_state.dataSurface->Surface(MultizoneSurfaceData(count).SurfNum);
4611 :
4612 491 : switch (AirflowNetworkLinkageData(count).element->type()) {
4613 70 : case ComponentType::DOP: {
4614 : // if (AirflowNetworkLinkageData(count).CompName ==
4615 : // AirflowNetworkCompData(i).Name) {
4616 : // AirflowNetworkLinkageData(count).CompNum = i;
4617 : // found = true;
4618 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::DOP) {
4619 70 : ++j;
4620 70 : AirflowNetworkLinkageData(count).DetOpenNum = j;
4621 70 : MultizoneSurfaceData(count).Multiplier = surf.Multiplier;
4622 70 : if (surf.Tilt < 10.0 || surf.Tilt > 170.0) {
4623 0 : ShowWarningError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4624 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is within ");
4625 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through large horizontal openings are poorly");
4626 0 : ShowContinueError(m_state, "modeled in the AirflowNetwork model resulting in only one-way airflow.");
4627 : }
4628 70 : if (!(surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::GlassDoor ||
4629 7 : surf.OriginalClass == SurfaceClass::Door || surf.IsAirBoundarySurf)) {
4630 0 : ShowSevereError(m_state,
4631 0 : format(RoutineName) +
4632 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4633 0 : AirflowNetworkLinkageData(count).Name);
4634 0 : ErrorsFound = true;
4635 : }
4636 :
4637 70 : if (surf.OriginalClass == SurfaceClass::Door || surf.OriginalClass == SurfaceClass::GlassDoor) {
4638 7 : if (MultizoneCompDetOpeningData(AirflowNetworkCompData(compnum).TypeNum).LVOType == 2) {
4639 0 : ShowSevereError(m_state,
4640 0 : format(RoutineName) +
4641 : "AirflowNetworkComponent: The opening with horizontally pivoted type must be assigned to a "
4642 0 : "window surface at " +
4643 0 : AirflowNetworkLinkageData(count).Name);
4644 0 : ErrorsFound = true;
4645 : }
4646 : }
4647 70 : } break;
4648 17 : case ComponentType::SOP: {
4649 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SOP) {
4650 17 : MultizoneSurfaceData(count).Multiplier = surf.Multiplier;
4651 17 : if (surf.Tilt < 10.0 || surf.Tilt > 170.0) {
4652 0 : ShowSevereError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4653 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is within");
4654 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through horizontal openings are not allowed.");
4655 0 : ShowContinueError(m_state, "AirflowNetwork:Multizone:Component:SimpleOpening = " + AirflowNetworkCompData(compnum).Name);
4656 0 : ErrorsFound = true;
4657 : }
4658 :
4659 17 : if (!(surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::GlassDoor ||
4660 17 : surf.OriginalClass == SurfaceClass::Door || surf.IsAirBoundarySurf)) {
4661 0 : ShowSevereError(m_state,
4662 0 : format(RoutineName) +
4663 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4664 0 : AirflowNetworkLinkageData(count).Name);
4665 0 : ErrorsFound = true;
4666 : }
4667 17 : } break;
4668 1 : case ComponentType::HOP: {
4669 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::HOP) {
4670 1 : MultizoneSurfaceData(count).Multiplier = surf.Multiplier;
4671 : // Get linkage height from upper and lower zones
4672 1 : if (MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum > 0) {
4673 1 : AirflowNetworkLinkageData(count).NodeHeights[0] =
4674 1 : Zone(MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum).Centroid.z;
4675 : }
4676 1 : if (AirflowNetworkLinkageData(count).NodeNums[1] <= AirflowNetworkNumOfZones) {
4677 1 : if (MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum > 0) {
4678 1 : AirflowNetworkLinkageData(count).NodeHeights[1] =
4679 1 : Zone(m_state.afn->MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum).Centroid.z;
4680 : }
4681 : }
4682 1 : if (AirflowNetworkLinkageData(count).NodeNums[1] > AirflowNetworkNumOfZones) {
4683 0 : ShowSevereError(m_state,
4684 0 : format(RoutineName) +
4685 0 : "AirflowNetworkComponent: The horizontal opening must be located between two thermal zones at " +
4686 0 : AirflowNetworkLinkageData(count).Name);
4687 0 : ShowContinueError(m_state, "This component is exposed to outdoors.");
4688 0 : ErrorsFound = true;
4689 : } else {
4690 2 : if (!(MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[0]).ZoneNum > 0 &&
4691 1 : MultizoneZoneData(AirflowNetworkLinkageData(count).NodeNums[1]).ZoneNum > 0)) {
4692 0 : ShowSevereError(m_state,
4693 0 : format(RoutineName) +
4694 0 : "AirflowNetworkComponent: The horizontal opening must be located between two thermal zones at " +
4695 0 : AirflowNetworkLinkageData(count).Name);
4696 0 : ErrorsFound = true;
4697 : }
4698 : }
4699 1 : if (!(surf.Tilt > 170.0 && surf.Tilt < 190.0) && !(surf.Tilt > -10.0 && surf.Tilt < 10.0)) {
4700 0 : ShowWarningError(m_state, "An AirflowNetwork:Multizone:Surface object has an air-flow opening corresponding to");
4701 0 : ShowContinueError(m_state, "window or door = " + MultizoneSurfaceData(count).SurfName + ", which is above");
4702 0 : ShowContinueError(m_state, "10 deg of being horizontal. Airflows through non-horizontal openings are not modeled");
4703 0 : ShowContinueError(m_state,
4704 0 : "with the object of AirflowNetwork:Multizone:Component:HorizontalOpening = " +
4705 0 : AirflowNetworkCompData(compnum).Name);
4706 : }
4707 1 : if (!(surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::GlassDoor ||
4708 1 : surf.OriginalClass == SurfaceClass::Door || surf.IsAirBoundarySurf)) {
4709 0 : ShowSevereError(m_state,
4710 0 : format(RoutineName) +
4711 0 : "AirflowNetworkComponent: The opening must be assigned to a window, door, glassdoor or air boundary at " +
4712 0 : AirflowNetworkLinkageData(count).Name);
4713 0 : ErrorsFound = true;
4714 : }
4715 1 : } break;
4716 403 : default:
4717 : // Nothing to do here
4718 403 : break;
4719 : }
4720 491 : } else {
4721 0 : ShowSevereError(m_state,
4722 0 : format(RoutineName) + CurrentModuleObject + ": The component is not defined in " +
4723 0 : AirflowNetworkLinkageData(count).Name);
4724 0 : ErrorsFound = true;
4725 : }
4726 491 : }
4727 :
4728 : // Assign intrazone links
4729 42 : for (count = 1 + AirflowNetworkNumOfSurfaces; count <= NumOfLinksIntraZone + AirflowNetworkNumOfSurfaces; ++count) {
4730 7 : AirflowNetworkLinkageData(count).Name = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).Name;
4731 7 : AirflowNetworkLinkageData(count).NodeNums[0] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeNums[0];
4732 7 : AirflowNetworkLinkageData(count).NodeNums[1] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeNums[1];
4733 7 : AirflowNetworkLinkageData(count).CompName = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).CompName;
4734 7 : AirflowNetworkLinkageData(count).ZoneNum = 0;
4735 7 : AirflowNetworkLinkageData(count).LinkNum = count;
4736 7 : AirflowNetworkLinkageData(count).NodeHeights[0] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeHeights[0];
4737 7 : AirflowNetworkLinkageData(count).NodeHeights[1] = IntraZoneLinkageData(count - AirflowNetworkNumOfSurfaces).NodeHeights[1];
4738 : // Find component number
4739 7 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4740 7 : if (afe != elements.end()) {
4741 7 : AirflowNetworkLinkageData(count).element = afe->second;
4742 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4743 7 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4744 7 : assert(compnum_iter != compnum.end());
4745 7 : int compnum = compnum_iter->second;
4746 7 : AirflowNetworkLinkageData(count).CompNum = compnum;
4747 7 : if (AirflowNetworkLinkageData(count).element->type() != ComponentType::SCR &&
4748 0 : AirflowNetworkLinkageData(count).element->type() != ComponentType::SEL) {
4749 :
4750 0 : ShowSevereError(m_state,
4751 0 : format(RoutineName) + AirflowNetworkLinkageData(count).CompName + ": The component is not allowed in " +
4752 0 : AirflowNetworkLinkageData(count).Name);
4753 0 : ShowContinueError(m_state,
4754 : "The allowed component type is either AirflowNetwork:MultiZone:Surface:Crack or "
4755 : "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea.");
4756 0 : ErrorsFound = true;
4757 : }
4758 7 : } else {
4759 0 : ShowSevereError(m_state,
4760 0 : format(RoutineName) + AirflowNetworkLinkageData(count).CompName + ": The component is not defined in " +
4761 0 : AirflowNetworkLinkageData(count).Name);
4762 0 : ErrorsFound = true;
4763 : }
4764 7 : }
4765 :
4766 : // Reset AirflowNetworkNumOfSurfaces by including NumOfLinksIntraZone
4767 35 : AirflowNetworkNumOfSurfaces = AirflowNetworkNumOfSurfaces + NumOfLinksIntraZone;
4768 35 : if (NumOfLinksIntraZone > 0) NumOfLinksMultiZone = AirflowNetworkNumOfSurfaces;
4769 :
4770 : // Assign AirflowNetwork info in RoomAirflowNetworkZoneInfo
4771 35 : if (NumOfNodesIntraZone > 0) {
4772 15 : for (int i = 1; i <= NumOfNodesMultiZone; ++i) {
4773 14 : n = AirflowNetworkNodeData(i).EPlusZoneNum;
4774 14 : AirflowNetworkNodeData(i).NumOfLinks = 0;
4775 14 : if (n > 0 && AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
4776 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID = i;
4777 216 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
4778 210 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i) {
4779 15 : AirflowNetworkNodeData(i).NumOfLinks = AirflowNetworkNodeData(i).NumOfLinks + 1;
4780 195 : } else if (AirflowNetworkLinkageData(j).NodeNums[1] == i) {
4781 13 : AirflowNetworkNodeData(i).NumOfLinks = AirflowNetworkNodeData(i).NumOfLinks + 1;
4782 : } else {
4783 : }
4784 : }
4785 : }
4786 14 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
4787 42 : for (j = 1; j <= m_state.dataRoomAir->AFNZoneInfo(n).NumOfAirNodes; ++j) {
4788 36 : if (m_state.dataRoomAir->AFNZoneInfo(n).Node(j).AFNNodeID == i) {
4789 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).NumOfAirflowLinks = AirflowNetworkNodeData(i).NumOfLinks;
4790 6 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link.allocate(AirflowNetworkNodeData(i).NumOfLinks);
4791 6 : k = 1;
4792 198 : for (int m = 1; m <= AirflowNetworkNumOfSurfaces; ++m) {
4793 198 : if (AirflowNetworkLinkageData(m).NodeNums[0] == i) {
4794 15 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNSimuID = m;
4795 15 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNDataID = m;
4796 15 : k = k + 1;
4797 15 : if (k > AirflowNetworkNodeData(i).NumOfLinks) break;
4798 : }
4799 195 : if (AirflowNetworkLinkageData(m).NodeNums[1] == i) {
4800 13 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNSimuID = m;
4801 13 : m_state.dataRoomAir->AFNZoneInfo(n).Node(j).Link(k).AFNDataID = m;
4802 13 : k = k + 1;
4803 13 : if (k > AirflowNetworkNodeData(i).NumOfLinks) break;
4804 : }
4805 : }
4806 : }
4807 : }
4808 : }
4809 : }
4810 : }
4811 :
4812 35 : if (DisSysNumOfLinks > 0 && distribution_simulated) { // Distribution
4813 :
4814 1053 : for (auto &e : AirflowNetworkLinkageData)
4815 1030 : e.ZoneNum = 0;
4816 :
4817 724 : for (count = AirflowNetworkNumOfSurfaces + 1; count <= AirflowNetworkNumOfLinks; ++count) {
4818 :
4819 1402 : m_state.dataInputProcessing->inputProcessor->getObjectItem(m_state,
4820 : CurrentModuleObject,
4821 701 : count - AirflowNetworkNumOfSurfaces,
4822 : Alphas,
4823 : NumAlphas,
4824 : Numbers,
4825 : NumNumbers,
4826 : IOStatus,
4827 : lNumericBlanks,
4828 : lAlphaBlanks,
4829 : cAlphaFields,
4830 : cNumericFields);
4831 701 : AirflowNetworkLinkageData(count).Name = Alphas(1);
4832 701 : AirflowNetworkLinkageData(count).NodeNames[0] = Alphas(2);
4833 701 : AirflowNetworkLinkageData(count).NodeHeights[0] = 0.0;
4834 701 : AirflowNetworkLinkageData(count).NodeNames[1] = Alphas(3);
4835 701 : AirflowNetworkLinkageData(count).NodeHeights[1] = 0.0;
4836 701 : AirflowNetworkLinkageData(count).CompName = Alphas(4);
4837 701 : AirflowNetworkLinkageData(count).ZoneName = Alphas(5);
4838 701 : AirflowNetworkLinkageData(count).LinkNum = count;
4839 :
4840 715 : for (int i = 1; i <= DisSysNumOfDuctViewFactors; ++i) {
4841 15 : if (AirflowNetworkLinkageData(count).Name == AirflowNetworkLinkageViewFactorData(i).LinkageName) {
4842 1 : AirflowNetworkLinkageData(count).LinkageViewFactorObjectNum = AirflowNetworkLinkageViewFactorData(i).ObjectNum;
4843 1 : break;
4844 : }
4845 : }
4846 :
4847 701 : if (!lAlphaBlanks(5)) {
4848 292 : AirflowNetworkLinkageData(count).ZoneNum = Util::FindItemInList(AirflowNetworkLinkageData(count).ZoneName, Zone);
4849 292 : if (AirflowNetworkLinkageData(count).ZoneNum == 0) {
4850 0 : ShowSevereError(m_state,
4851 0 : format(RoutineName) + CurrentModuleObject + ": Invalid " + cAlphaFields(5) +
4852 0 : " given = " + AirflowNetworkLinkageData(count).ZoneName);
4853 0 : ErrorsFound = true;
4854 : }
4855 : }
4856 701 : if (Alphas(2) == Alphas(3)) {
4857 0 : ShowSevereError(m_state,
4858 0 : format(RoutineName) + CurrentModuleObject + ", " + cAlphaFields(2) + " = " + cAlphaFields(3) + " in " +
4859 0 : AirflowNetworkLinkageData(count).Name);
4860 0 : ErrorsFound = true;
4861 : }
4862 : // Find component number
4863 701 : auto afe = elements.find(AirflowNetworkLinkageData(count).CompName);
4864 701 : if (afe != elements.end()) {
4865 701 : AirflowNetworkLinkageData(count).element = afe->second;
4866 :
4867 : // Get CompTypeNum here, this is a hack to hold us over until the introspection is dealt with
4868 701 : auto compnum_iter = compnum.find(AirflowNetworkLinkageData(count).CompName);
4869 701 : assert(compnum_iter != compnum.end());
4870 701 : int compnum = compnum_iter->second;
4871 701 : AirflowNetworkLinkageData(count).CompNum = compnum;
4872 701 : } else {
4873 0 : ShowSevereError(m_state,
4874 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(4) + " is not defined in " +
4875 0 : AirflowNetworkLinkageData(count).Name);
4876 0 : ErrorsFound = true;
4877 : }
4878 : // Find Node number
4879 701 : found = false;
4880 14013 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4881 14013 : if (AirflowNetworkLinkageData(count).NodeNames[0] == AirflowNetworkNodeData(i).Name) {
4882 701 : AirflowNetworkLinkageData(count).NodeNums[0] = i;
4883 701 : AirflowNetworkLinkageData(count).NodeHeights[0] += AirflowNetworkNodeData(i).NodeHeight;
4884 701 : found = true;
4885 701 : break;
4886 : }
4887 : }
4888 701 : if (!found) {
4889 0 : ShowSevereError(m_state,
4890 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(2) + " is not found in the node data " +
4891 0 : AirflowNetworkLinkageData(count).Name);
4892 0 : ErrorsFound = true;
4893 : }
4894 13976 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4895 13976 : if (AirflowNetworkLinkageData(count).NodeNames[1] == AirflowNetworkNodeData(i).Name) {
4896 701 : AirflowNetworkLinkageData(count).NodeNums[1] = i;
4897 701 : AirflowNetworkLinkageData(count).NodeHeights[1] += AirflowNetworkNodeData(i).NodeHeight;
4898 701 : found = true;
4899 701 : break;
4900 : }
4901 : }
4902 701 : if (!found) {
4903 0 : ShowSevereError(m_state,
4904 0 : format(RoutineName) + CurrentModuleObject + ": The " + cAlphaFields(3) + " is not found in the node data " +
4905 0 : AirflowNetworkLinkageData(count).Name);
4906 0 : ErrorsFound = true;
4907 : }
4908 701 : }
4909 23 : } else {
4910 :
4911 12 : if (distribution_simulated) {
4912 0 : ShowSevereError(m_state, format(RoutineName) + "An " + CurrentModuleObject + " object is required but not found.");
4913 0 : ErrorsFound = true;
4914 : }
4915 : }
4916 :
4917 : // Ensure no duplicated names in AirflowNetwork component objects
4918 : // for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
4919 : // for (j = i + 1; j <= AirflowNetworkNumOfComps; ++j) {
4920 : // if (Util::SameString(AirflowNetworkCompData(i).Name,
4921 : // AirflowNetworkCompData(j).Name)) {
4922 : // // SurfaceAirflowLeakageNames
4923 : // if (i <= 4 && j <= 4) {
4924 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::DOP)
4925 : // CompName(1) = "AirflowNetwork:MultiZone:Component:DetailedOpening";
4926 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SOP)
4927 : // CompName(1) = "AirflowNetwork:MultiZone:Component:SimpleOpening";
4928 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::SCR) CompName(1) =
4929 : // "AirflowNetwork:MultiZone:Surface:Crack"; if (AirflowNetworkCompData(i).CompTypeNum ==
4930 : // iComponentTypeNum::SEL) CompName(1) = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea"; if
4931 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DOP) CompName(2) =
4932 : // "AirflowNetwork:MultiZone:Component:DetailedOpening"; if (AirflowNetworkCompData(j).CompTypeNum ==
4933 : // iComponentTypeNum::SOP) CompName(2) = "AirflowNetwork:MultiZone:Component:SimpleOpening"; if
4934 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::SCR) CompName(2) =
4935 : // "AirflowNetwork:MultiZone:Surface:Crack"; if (AirflowNetworkCompData(j).CompTypeNum ==
4936 : // iComponentTypeNum::SEL) CompName(2) = "AirflowNetwork:MultiZone:Surface:EffectiveLeakageArea"; ShowSevereError(m_state, RoutineName
4937 : // + "Duplicated component names are found = " + AirflowNetworkCompData(i).Name); ShowContinueError(m_state,
4938 : // "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2)); ErrorsFound = true;
4939 : // }
4940 : // // Distribution component
4941 : // if (i > 4 && j > 4) {
4942 : // if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::PLR) CompName(1) =
4943 : // "AirflowNetwork:Distribution:Component:Leak"; if (AirflowNetworkCompData(i).CompTypeNum ==
4944 : // iComponentTypeNum::DWC) CompName(1) = "AirflowNetwork:Distribution:Component:Duct"; if
4945 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::ELR) CompName(1) =
4946 : // "AirflowNetwork:Distribution:Component:LeakageRatio"; if (AirflowNetworkCompData(i).CompTypeNum ==
4947 : // iComponentTypeNum::DMP) CompName(1) = "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT DAMPER"; if
4948 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::CVF) CompName(1) =
4949 : // "AirflowNetwork:Distribution:Component:Fan"; if (AirflowNetworkCompData(i).CompTypeNum ==
4950 : // iComponentTypeNum::CPD) CompName(1) = "AirflowNetwork:Distribution:Component:ConstantPressureDrop"; if
4951 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::COI) CompName(1) =
4952 : // "AirflowNetwork:Distribution:Component:Coil"; if (AirflowNetworkCompData(i).CompTypeNum ==
4953 : // iComponentTypeNum::TMU) CompName(1) = "AirflowNetwork:Distribution:Component:TerminalUnit"; if
4954 : // (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::HEX) CompName(1) =
4955 : // "AirflowNetwork:Distribution:Component:HeatExchanger"; if (AirflowNetworkCompData(j).CompTypeNum ==
4956 : // iComponentTypeNum::PLR) CompName(2) = "AirflowNetwork:Distribution:Component:Leak"; if
4957 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DWC) CompName(2) =
4958 : // "AirflowNetwork:Distribution:Component:Duct"; if (AirflowNetworkCompData(j).CompTypeNum ==
4959 : // iComponentTypeNum::ELR) CompName(2) = "AirflowNetwork:Distribution:Component:LeakageRatio"; if
4960 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DMP) CompName(2) =
4961 : // "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT DAMPER"; if (AirflowNetworkCompData(j).CompTypeNum ==
4962 : // iComponentTypeNum::CVF) CompName(2) = "AirflowNetwork:Distribution:Component:Fan"; if
4963 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::CPD) CompName(2) =
4964 : // "AirflowNetwork:Distribution:Component:ConstantPressureDrop"; if (AirflowNetworkCompData(j).CompTypeNum
4965 : // == iComponentTypeNum::COI) CompName(2) = "AirflowNetwork:Distribution:Component:Coil"; if
4966 : // (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::TMU) CompName(2) =
4967 : // "AirflowNetwork:Distribution:Component:TerminalUnit"; if (AirflowNetworkCompData(j).CompTypeNum ==
4968 : // iComponentTypeNum::HEX) CompName(2) = "AirflowNetwork:Distribution:Component:HeatExchanger"; ShowSevereError(m_state,
4969 : // format(RoutineName) + "Duplicated component names are found = " + AirflowNetworkCompData(i).Name);
4970 : // ShowContinueError(m_state, "A unique component name is required in both objects " + CompName(1) + " and " + CompName(2));
4971 : // ErrorsFound = true;
4972 : // }
4973 : // }
4974 : // }
4975 : // }
4976 :
4977 : // Node and component validation
4978 1234 : for (count = 1; count <= AirflowNetworkNumOfLinks; ++count) {
4979 1199 : NodeFound = false;
4980 15156 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
4981 15156 : if (i == AirflowNetworkLinkageData(count).NodeNums[0]) {
4982 1199 : NodeFound = true;
4983 1199 : break;
4984 : }
4985 : }
4986 1199 : if (!NodeFound) {
4987 0 : if (count <= AirflowNetworkNumOfSurfaces) {
4988 0 : ShowSevereError(m_state,
4989 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
4990 0 : " in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name + " is not found");
4991 : } else {
4992 0 : ShowSevereError(m_state,
4993 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
4994 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
4995 : " is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE objects.");
4996 : }
4997 0 : ErrorsFound = true;
4998 : }
4999 1199 : NodeFound = false;
5000 17016 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5001 17016 : if (i == AirflowNetworkLinkageData(count).NodeNums[1]) {
5002 1199 : NodeFound = true;
5003 1199 : break;
5004 : }
5005 : }
5006 1199 : if (!NodeFound) {
5007 0 : if (count <= AirflowNetworkNumOfSurfaces) {
5008 0 : ShowSevereError(m_state,
5009 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[0] +
5010 0 : " in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name + " is not found");
5011 : } else {
5012 0 : ShowSevereError(m_state,
5013 0 : format(RoutineName) + AirflowNetworkLinkageData(count).NodeNames[1] +
5014 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
5015 : " is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE objects.");
5016 : }
5017 0 : ErrorsFound = true;
5018 : }
5019 1199 : bool CompFound = false;
5020 32502 : for (int i = 1; i <= AirflowNetworkNumOfComps; ++i) {
5021 31303 : if (i == AirflowNetworkLinkageData(count).CompNum) {
5022 1199 : CompFound = true;
5023 : }
5024 : }
5025 1199 : if (!CompFound) {
5026 0 : ShowSevereError(m_state,
5027 0 : format(RoutineName) + "Component = " + AirflowNetworkLinkageData(count).CompName +
5028 0 : " in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(count).Name +
5029 : " is not found in AirflowNetwork Component Data objects.");
5030 0 : ErrorsFound = true;
5031 : }
5032 : }
5033 :
5034 : // Ensure every AirflowNetworkNode is used in AirflowNetworkLinkage
5035 880 : for (count = 1; count <= AirflowNetworkNumOfNodes; ++count) {
5036 845 : bool NodeFound1 = false;
5037 845 : bool NodeFound2 = false;
5038 39085 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
5039 38240 : if (count == AirflowNetworkLinkageData(i).NodeNums[0]) {
5040 1199 : NodeFound1 = true;
5041 : }
5042 38240 : if (count == AirflowNetworkLinkageData(i).NodeNums[1]) {
5043 1199 : NodeFound2 = true;
5044 : }
5045 : }
5046 845 : if ((!NodeFound1) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum == 0) {
5047 0 : ShowSevereError(m_state,
5048 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5049 : " is not found as Node 1 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5050 0 : ShowContinueError(m_state,
5051 : "Each non-external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined as Node 1 once in "
5052 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5053 0 : ErrorsFound = true;
5054 : }
5055 845 : if ((!NodeFound2) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum == 0) {
5056 0 : ShowSevereError(m_state,
5057 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5058 : " is not found as Node 2 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5059 0 : ShowContinueError(m_state,
5060 : "Each non-external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined as Node 2 once in "
5061 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5062 0 : ErrorsFound = true;
5063 : }
5064 845 : if ((!NodeFound1) && (!NodeFound2) && count > NumOfNodesMultiZone && AirflowNetworkNodeData(count).ExtNodeNum > 0) {
5065 0 : ShowSevereError(m_state,
5066 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:NODE = " + AirflowNetworkNodeData(count).Name +
5067 : " is not found as Node 1 Name or Node 2 Name in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5068 0 : ShowContinueError(m_state, "This external AIRFLOWNETWORK:DISTRIBUTION:NODE has to be defined in AIRFLOWNETWORK:DISTRIBUTION:LINKAGE");
5069 0 : ErrorsFound = true;
5070 : }
5071 : }
5072 :
5073 : // Ensure there is at least one node defined as EXTERNAL node
5074 35 : NodeFound = false;
5075 880 : for (count = 1; count <= AirflowNetworkNumOfNodes; ++count) {
5076 845 : if (AirflowNetworkNodeData(count).ExtNodeNum > 0) {
5077 211 : NodeFound = true;
5078 : }
5079 : }
5080 35 : if (!NodeFound) {
5081 0 : ShowSevereError(m_state,
5082 0 : format(RoutineName) +
5083 : "No External Nodes found in AirflowNetwork:Multizone:ExternalNode. There must be at least 1 external node defined.");
5084 0 : ErrorsFound = true;
5085 : }
5086 :
5087 35 : if (simulation_control.iWPCCnt == iWPCCntr::Input) {
5088 427 : for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
5089 400 : if (AirflowNetworkLinkageData(count).NodeNums[0] == 0) {
5090 0 : ShowSevereError(m_state,
5091 0 : "The surface is not found in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name);
5092 0 : ErrorsFound = true;
5093 : }
5094 400 : if (AirflowNetworkLinkageData(count).NodeNums[1] == 0) {
5095 0 : ShowSevereError(m_state,
5096 0 : "The external node is not found in AIRFLOWNETWORK:MULTIZONE:SURFACE = " + AirflowNetworkLinkageData(count).Name);
5097 0 : ErrorsFound = true;
5098 : }
5099 : }
5100 : }
5101 :
5102 : // Provide a warning when a door component is assigned as envelope leakage
5103 : // if (!ErrorsFound) {
5104 : // for (count = 1; count <= AirflowNetworkNumOfSurfaces; ++count) {
5105 : // if
5106 : // (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).ExtNodeNum
5107 : // > 0 &&
5108 : // AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).EPlusZoneNum
5109 : // > 0 && AirflowNetworkLinkageData(count).CompNum > 0) { if
5110 : // (AirflowNetworkCompData(AirflowNetworkLinkageData(count).CompNum).CompTypeNum
5111 : // == iComponentTypeNum::SOP) {
5112 : // }
5113 : // }
5114 : // if
5115 : // (AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[1]).ExtNodeNum
5116 : // > 0 &&
5117 : // AirflowNetworkNodeData(AirflowNetworkLinkageData(count).NodeNums[0]).EPlusZoneNum
5118 : // > 0 && AirflowNetworkLinkageData(count).CompNum > 0) { if
5119 : // (AirflowNetworkCompData(AirflowNetworkLinkageData(count).CompNum).CompTypeNum
5120 : // == iComponentTypeNum::SOP) {
5121 : // }
5122 : // }
5123 : // }
5124 : // }
5125 :
5126 : // Ensure the name of each heat exchanger is shown either once or twice in the field of
5127 35 : if (distribution_simulated) {
5128 24 : for (int i = 1; i <= DisSysNumOfHXs; ++i) {
5129 1 : count = 0;
5130 61 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
5131 60 : if (Util::SameString(AirflowNetworkLinkageData(j).CompName, DisSysCompHXData(i).name)) {
5132 2 : ++count;
5133 : }
5134 : }
5135 :
5136 1 : if (DisSysCompHXData(i).CoilParentExists && count != 2) {
5137 0 : ShowSevereError(m_state,
5138 0 : format(RoutineName) + "The inputs of component name field as a heat exchanger in "
5139 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE is not correct");
5140 0 : ShowContinueError(m_state,
5141 0 : "The entered name of heat exchanger is " + DisSysCompHXData(i).name +
5142 : " in AirflowNetwork:Distribution:Component:HeatExchanger objects");
5143 0 : ShowContinueError(m_state, format("The correct appearance number is 2. The entered appearance number is {}", count));
5144 0 : ErrorsFound = true;
5145 : }
5146 1 : if ((!DisSysCompHXData(i).CoilParentExists) && count != 1) {
5147 0 : ShowSevereError(m_state,
5148 0 : format(RoutineName) + "The inputs of component name field as a heat exchanger in "
5149 : "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE is not correct");
5150 0 : ShowContinueError(m_state,
5151 0 : "The entered name of heat exchanger is " + DisSysCompHXData(i).name +
5152 : " in AirflowNetwork:Distribution:Component:HeatExchanger objects");
5153 0 : ShowContinueError(m_state, format("The correct appearance number is 1. The entered appearance number is {}", count));
5154 0 : ErrorsFound = true;
5155 : }
5156 : }
5157 : }
5158 :
5159 : // Check node assignments using AirflowNetwork:Distribution:Component:OutdoorAirFlow or
5160 : // AirflowNetwork:Distribution:Component:ReliefAirFlow
5161 736 : for (count = AirflowNetworkNumOfSurfaces + 1; count <= AirflowNetworkNumOfLinks; ++count) {
5162 701 : int i = AirflowNetworkLinkageData(count).CompNum;
5163 701 : j = AirflowNetworkLinkageData(count).NodeNums[0];
5164 701 : k = AirflowNetworkLinkageData(count).NodeNums[1];
5165 :
5166 701 : if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::OAF) {
5167 2 : if (!Util::SameString(DisSysNodeData(j - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
5168 0 : ShowSevereError(m_state,
5169 0 : format(RoutineName) +
5170 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5171 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5172 0 : AirflowNetworkNodeData(j).Name + ",");
5173 0 : ShowContinueError(
5174 0 : m_state, "the component type in the first node should be OAMixerOutdoorAirStreamNode at " + AirflowNetworkNodeData(j).Name);
5175 0 : ErrorsFound = true;
5176 : }
5177 2 : if (!Util::SameString(DisSysNodeData(k - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
5178 0 : ShowSevereError(m_state,
5179 0 : format(RoutineName) +
5180 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5181 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5182 0 : AirflowNetworkNodeData(k).Name + ",");
5183 0 : ShowContinueError(m_state,
5184 0 : "the component object type in the second node should be AirLoopHVAC:OutdoorAirSystem at " +
5185 0 : AirflowNetworkNodeData(k).Name);
5186 0 : ErrorsFound = true;
5187 : }
5188 : }
5189 :
5190 701 : if (AirflowNetworkCompData(i).CompTypeNum == iComponentTypeNum::REL) {
5191 2 : if (!Util::SameString(DisSysNodeData(j - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:OutdoorAirSystem")) {
5192 0 : ShowSevereError(m_state,
5193 0 : format(RoutineName) +
5194 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5195 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5196 0 : AirflowNetworkNodeData(j).Name + ",");
5197 0 : ShowContinueError(m_state,
5198 0 : "the component object type in the first node should be AirLoopHVAC:OutdoorAirSystem at " +
5199 0 : AirflowNetworkNodeData(j).Name);
5200 0 : ErrorsFound = true;
5201 : }
5202 2 : if (!Util::SameString(DisSysNodeData(k - NumOfNodesMultiZone).EPlusType, "OAMixerOutdoorAirStreamNode")) {
5203 0 : ShowSevereError(m_state,
5204 0 : format(RoutineName) +
5205 : "AirflowNetwork:Distribution:Linkage: When the component type is "
5206 0 : "AirflowNetwork:Distribution:Component:OutdoorAirFlow at " +
5207 0 : AirflowNetworkNodeData(k).Name + ",");
5208 0 : ShowContinueError(
5209 0 : m_state, "the component type in the second node should be OAMixerOutdoorAirStreamNode at " + AirflowNetworkNodeData(k).Name);
5210 0 : ErrorsFound = true;
5211 : }
5212 : }
5213 : }
5214 :
5215 35 : if (ErrorsFound) {
5216 0 : ShowFatalError(m_state, format("{}Errors found getting inputs. Previous error(s) cause program termination.", RoutineName));
5217 : }
5218 :
5219 35 : Alphas.deallocate();
5220 35 : cAlphaFields.deallocate();
5221 35 : cNumericFields.deallocate();
5222 35 : Numbers.deallocate();
5223 35 : lAlphaBlanks.deallocate();
5224 35 : lNumericBlanks.deallocate();
5225 :
5226 35 : if (!ErrorsFound) {
5227 35 : allocate_and_initialize();
5228 : }
5229 8406 : }
5230 :
5231 541114 : void Solver::initialize()
5232 : {
5233 : // SUBROUTINE INFORMATION:
5234 : // AUTHOR Lixing Gu
5235 : // DATE WRITTEN Aug. 2003
5236 : // MODIFIED na
5237 : // RE-ENGINEERED na
5238 :
5239 : // PURPOSE OF THIS SUBROUTINE:
5240 : // This subroutine initializes variables of additional zone loads caused by ADS.
5241 :
5242 : // USE STATEMENTS:
5243 541114 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
5244 :
5245 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5246 : int i;
5247 : int ZoneNum;
5248 541114 : auto &Zone(m_state.dataHeatBal->Zone);
5249 :
5250 541114 : if (initializeOneTimeFlag) {
5251 35 : exchangeData.allocate(m_state.dataGlobal->NumOfZones); // AirflowNetwork exchange data due to air-forced system
5252 50 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5253 24 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
5254 9 : multiExchangeData.allocate(m_state.dataGlobal->NumOfZones);
5255 9 : break;
5256 : }
5257 : }
5258 :
5259 35 : initializeOneTimeFlag = false;
5260 35 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5261 5 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5262 8 : SetupOutputVariable(m_state,
5263 : "AFN Zone Outdoor Air Mass Flow Rate",
5264 : Constant::Units::kg_s,
5265 4 : exchangeData(i).SumMHr,
5266 : OutputProcessor::TimeStepType::System,
5267 : OutputProcessor::StoreType::Average,
5268 4 : Zone(i).Name);
5269 8 : SetupOutputVariable(m_state,
5270 : "AFN Zone Mixing Mass Flow Rate",
5271 : Constant::Units::kg_s,
5272 4 : exchangeData(i).SumMMHr,
5273 : OutputProcessor::TimeStepType::System,
5274 : OutputProcessor::StoreType::Average,
5275 4 : Zone(i).Name);
5276 8 : SetupOutputVariable(m_state,
5277 : "AFN Zone Outdoor Air CO2 Mass Flow Rate",
5278 : Constant::Units::kg_s,
5279 4 : exchangeData(i).SumMHrCO,
5280 : OutputProcessor::TimeStepType::System,
5281 : OutputProcessor::StoreType::Average,
5282 4 : Zone(i).Name);
5283 8 : SetupOutputVariable(m_state,
5284 : "AFN Zone Mixing CO2 Mass Flow Rate",
5285 : Constant::Units::kg_s,
5286 4 : exchangeData(i).SumMMHrCO,
5287 : OutputProcessor::TimeStepType::System,
5288 : OutputProcessor::StoreType::Average,
5289 4 : Zone(i).Name);
5290 8 : SetupOutputVariable(m_state,
5291 : "AFN Zone Total CO2 Mass Flow Rate",
5292 : Constant::Units::kg_s,
5293 4 : exchangeData(i).TotalCO2,
5294 : OutputProcessor::TimeStepType::System,
5295 : OutputProcessor::StoreType::Average,
5296 4 : Zone(i).Name);
5297 : }
5298 : }
5299 35 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5300 5 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5301 4 : if (!m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5302 8 : SetupOutputVariable(m_state,
5303 : "AFN Zone Outdoor Air Mass Flow Rate",
5304 : Constant::Units::kg_s,
5305 4 : exchangeData(i).SumMHr,
5306 : OutputProcessor::TimeStepType::System,
5307 : OutputProcessor::StoreType::Average,
5308 4 : Zone(i).Name);
5309 8 : SetupOutputVariable(m_state,
5310 : "AFN Zone Mixing Mass Flow Rate",
5311 : Constant::Units::kg_s,
5312 4 : exchangeData(i).SumMMHr,
5313 : OutputProcessor::TimeStepType::System,
5314 : OutputProcessor::StoreType::Average,
5315 4 : Zone(i).Name);
5316 : }
5317 8 : SetupOutputVariable(m_state,
5318 : "AFN Zone Outdoor Air Generic Air Contaminant Mass Flow Rate",
5319 : Constant::Units::kg_s,
5320 4 : exchangeData(i).SumMHrGC,
5321 : OutputProcessor::TimeStepType::System,
5322 : OutputProcessor::StoreType::Average,
5323 4 : Zone(i).Name);
5324 8 : SetupOutputVariable(m_state,
5325 : "AFN Zone Mixing Generic Air Contaminant Mass Flow Rate",
5326 : Constant::Units::kg_s,
5327 4 : exchangeData(i).SumMMHrGC,
5328 : OutputProcessor::TimeStepType::System,
5329 : OutputProcessor::StoreType::Average,
5330 4 : Zone(i).Name);
5331 8 : SetupOutputVariable(m_state,
5332 : "AFN Zone Total Generic Air Contaminant Mass Flow Rate",
5333 : Constant::Units::kg_s,
5334 4 : exchangeData(i).TotalGC,
5335 : OutputProcessor::TimeStepType::System,
5336 : OutputProcessor::StoreType::Average,
5337 4 : Zone(i).Name);
5338 : }
5339 : }
5340 : }
5341 :
5342 541114 : if (m_state.dataGlobal->BeginEnvrnFlag && initializeMyEnvrnFlag) {
5343 : // Assign node values
5344 5627 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5345 5406 : AirflowNetworkNodeSimu(i).TZ = 23.0;
5346 5406 : AirflowNetworkNodeSimu(i).WZ = 0.00084;
5347 5406 : AirflowNetworkNodeSimu(i).PZ = 0.0;
5348 5406 : AirflowNetworkNodeSimu(i).TZlast = AirflowNetworkNodeSimu(i).TZ;
5349 5406 : AirflowNetworkNodeSimu(i).WZlast = AirflowNetworkNodeSimu(i).WZ;
5350 5406 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5351 222 : AirflowNetworkNodeSimu(i).CO2Z = m_state.dataContaminantBalance->OutdoorCO2;
5352 222 : AirflowNetworkNodeSimu(i).CO2Zlast = AirflowNetworkNodeSimu(i).CO2Z;
5353 : }
5354 5406 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5355 222 : AirflowNetworkNodeSimu(i).GCZ = m_state.dataContaminantBalance->OutdoorGC;
5356 222 : AirflowNetworkNodeSimu(i).GCZlast = AirflowNetworkNodeSimu(i).GCZ;
5357 : }
5358 5406 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
5359 54 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
5360 54 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp = 23.0;
5361 54 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat = 0.0;
5362 : }
5363 : }
5364 :
5365 7884 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
5366 7663 : AirflowNetworkLinkSimu(i).FLOW = 0.0;
5367 7663 : AirflowNetworkLinkSimu(i).FLOW2 = 0.0;
5368 : }
5369 :
5370 951 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5371 730 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT;
5372 730 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).airHumRat;
5373 730 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5374 24 : ANCO(i) = m_state.dataContaminantBalance->ZoneAirCO2(i);
5375 : }
5376 730 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5377 24 : ANGC(i) = m_state.dataContaminantBalance->ZoneAirGC(i);
5378 : }
5379 : }
5380 221 : if (AirflowNetworkNumOfOccuVentCtrls > 0) {
5381 70 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5382 65 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5383 10 : MultizoneSurfaceData(i).PrevOpeningstatus = AirflowNetwork::OpenStatus::FreeOperation;
5384 10 : MultizoneSurfaceData(i).CloseElapsedTime = 0.0;
5385 10 : MultizoneSurfaceData(i).OpenElapsedTime = 0.0;
5386 10 : MultizoneSurfaceData(i).OpeningStatus = AirflowNetwork::OpenStatus::FreeOperation;
5387 10 : MultizoneSurfaceData(i).OpeningProbStatus = AirflowNetwork::ProbabilityCheck::NoAction;
5388 10 : MultizoneSurfaceData(i).ClosingProbStatus = 0;
5389 : }
5390 : }
5391 : }
5392 :
5393 221 : initializeMyEnvrnFlag = false;
5394 : }
5395 541114 : if (!m_state.dataGlobal->BeginEnvrnFlag) {
5396 538772 : initializeMyEnvrnFlag = true;
5397 538772 : if (simulation_control.type != ControlType::NoMultizoneOrDistribution) {
5398 538772 : if (RollBackFlag) {
5399 0 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5400 0 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).XMAT[0];
5401 0 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).WPrevZoneTS[0];
5402 0 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) ANCO(i) = m_state.dataContaminantBalance->CO2ZoneTimeMinus1(i);
5403 0 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5404 0 : ANGC(i) = m_state.dataContaminantBalance->GCZoneTimeMinus1(i);
5405 : }
5406 : } else {
5407 2260675 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5408 1721903 : ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT;
5409 1721903 : ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).airHumRat;
5410 1721903 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) ANCO(i) = m_state.dataContaminantBalance->ZoneAirCO2(i);
5411 1721903 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5412 35952 : ANGC(i) = m_state.dataContaminantBalance->ZoneAirGC(i);
5413 : }
5414 : }
5415 :
5416 14863389 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5417 14324617 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0) {
5418 1795518 : AirflowNetworkNodeSimu(i).TZ = ANZT(AirflowNetworkNodeData(i).EPlusZoneNum);
5419 1795518 : AirflowNetworkNodeSimu(i).WZ = ANZW(AirflowNetworkNodeData(i).EPlusZoneNum);
5420 1795518 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5421 45132 : AirflowNetworkNodeSimu(i).CO2Z = ANCO(AirflowNetworkNodeData(i).EPlusZoneNum);
5422 1795518 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5423 35952 : AirflowNetworkNodeSimu(i).GCZ = ANGC(AirflowNetworkNodeData(i).EPlusZoneNum);
5424 : }
5425 14324617 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
5426 3647212 : if (AirflowNetworkNodeData(i).OutAirNodeNum > 0 &&
5427 16662 : m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).IsLocalNode) {
5428 16662 : AirflowNetworkNodeSimu(i).TZ = m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).OutAirDryBulb;
5429 16662 : AirflowNetworkNodeSimu(i).WZ = m_state.dataLoopNodes->Node(AirflowNetworkNodeData(i).OutAirNodeNum).HumRat;
5430 : } else {
5431 3613888 : AirflowNetworkNodeSimu(i).TZ = AirflowNetwork::OutDryBulbTempAt(m_state, AirflowNetworkNodeData(i).NodeHeight);
5432 3613888 : AirflowNetworkNodeSimu(i).WZ = m_state.dataEnvrn->OutHumRat;
5433 : }
5434 :
5435 3630550 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5436 67698 : AirflowNetworkNodeSimu(i).CO2Z = m_state.dataContaminantBalance->OutdoorCO2;
5437 3630550 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5438 53928 : AirflowNetworkNodeSimu(i).GCZ = m_state.dataContaminantBalance->OutdoorGC;
5439 : }
5440 :
5441 14324617 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0) {
5442 88338 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
5443 88338 : if (m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID == i) {
5444 176676 : AirflowNetworkNodeSimu(i).TZ =
5445 88338 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp;
5446 88338 : AirflowNetworkNodeSimu(i).WZ =
5447 88338 : m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat;
5448 : }
5449 : }
5450 : }
5451 : }
5452 : }
5453 :
5454 2270332 : for (auto &e : exchangeData) {
5455 1729218 : e.TotalSen = 0.0;
5456 1729218 : e.TotalLat = 0.0;
5457 1729218 : e.MultiZoneSen = 0.0;
5458 1729218 : e.MultiZoneLat = 0.0;
5459 1729218 : e.LeakSen = 0.0;
5460 1729218 : e.LeakLat = 0.0;
5461 1729218 : e.CondSen = 0.0;
5462 1729218 : e.DiffLat = 0.0;
5463 1729218 : e.RadGain = 0.0;
5464 541114 : }
5465 541114 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5466 56655 : for (auto &e : exchangeData)
5467 56655 : e.TotalCO2 = 0.0;
5468 541114 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5469 45180 : for (auto &e : exchangeData)
5470 45180 : e.TotalGC = 0.0;
5471 :
5472 : // Occupant ventilation control
5473 541114 : Real64 CurrentEndTime = m_state.dataGlobal->CurrentTime + m_state.dataHVACGlobal->SysTimeElapsed;
5474 541114 : if (CurrentEndTime > CurrentEndTimeLast && TimeStepSys >= TimeStepSysLast) {
5475 2156059 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5476 2022759 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) continue;
5477 1974501 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5478 5192 : MultizoneSurfaceData(i).PrevOpeningstatus = MultizoneSurfaceData(i).OpeningStatus;
5479 5192 : MultizoneSurfaceData(i).OpenFactorLast = MultizoneSurfaceData(i).OpenFactor;
5480 5192 : if (MultizoneSurfaceData(i).OpenFactor > 0.0) {
5481 1832 : MultizoneSurfaceData(i).OpenElapsedTime += (CurrentEndTime - CurrentEndTimeLast) * 60.0;
5482 1832 : MultizoneSurfaceData(i).CloseElapsedTime = 0.0;
5483 : } else {
5484 3360 : MultizoneSurfaceData(i).OpenElapsedTime = 0.0;
5485 3360 : MultizoneSurfaceData(i).CloseElapsedTime += (CurrentEndTime - CurrentEndTimeLast) * 60.0;
5486 : }
5487 5192 : int j = MultizoneSurfaceData(i).SurfNum;
5488 5192 : OccupantVentilationControl(MultizoneSurfaceData(i).OccupantVentilationControlNum)
5489 15576 : .calc(m_state,
5490 5192 : m_state.dataSurface->Surface(j).Zone,
5491 5192 : MultizoneSurfaceData(i).OpenElapsedTime,
5492 5192 : MultizoneSurfaceData(i).CloseElapsedTime,
5493 5192 : MultizoneSurfaceData(i).OpeningStatus,
5494 5192 : MultizoneSurfaceData(i).OpeningProbStatus,
5495 5192 : MultizoneSurfaceData(i).ClosingProbStatus);
5496 5192 : if (MultizoneSurfaceData(i).OpeningStatus == AirflowNetwork::OpenStatus::MinCheckForceOpen) {
5497 210 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).OpenFactorLast;
5498 : }
5499 5192 : if (MultizoneSurfaceData(i).OpeningStatus == AirflowNetwork::OpenStatus::MinCheckForceClose) {
5500 236 : MultizoneSurfaceData(i).OpenFactor = 0.0;
5501 : }
5502 : }
5503 : }
5504 : }
5505 541114 : TimeStepSysLast = TimeStepSys;
5506 541114 : CurrentEndTimeLast = CurrentEndTime;
5507 541114 : }
5508 :
5509 35 : void Solver::allocate_and_initialize()
5510 : {
5511 :
5512 : // SUBROUTINE INFORMATION:
5513 : // AUTHOR Lixing Gu
5514 : // DATE WRITTEN Aug. 2003
5515 : // MODIFIED na
5516 : // RE-ENGINEERED na
5517 :
5518 : // PURPOSE OF THIS SUBROUTINE:
5519 : // This subroutine initializes variables and allocates dynamic arrays.
5520 :
5521 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5522 : int i;
5523 : int SurfNum;
5524 35 : auto &Zone(m_state.dataHeatBal->Zone);
5525 :
5526 35 : AirflowNetworkNodeSimu.allocate(AirflowNetworkNumOfNodes); // Node simulation variable in air distribution system
5527 35 : AirflowNetworkLinkSimu.allocate(AirflowNetworkNumOfLinks); // Link simulation variable in air distribution system
5528 35 : linkReport.allocate(AirflowNetworkNumOfLinks); // Report link simulation variable in air distribution system
5529 :
5530 50 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5531 24 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
5532 9 : nodeReport.allocate(AirflowNetworkNumOfZones);
5533 9 : linkReport1.allocate(AirflowNetworkNumOfSurfaces);
5534 9 : break;
5535 : }
5536 : }
5537 :
5538 35 : MA.allocate(AirflowNetworkNumOfNodes * AirflowNetworkNumOfNodes);
5539 35 : MV.allocate(AirflowNetworkNumOfNodes);
5540 35 : IVEC.allocate(AirflowNetworkNumOfNodes + 20);
5541 :
5542 35 : AirflowNetworkReportData.allocate(m_state.dataGlobal->NumOfZones); // Report variables
5543 35 : AirflowNetworkZnRpt.allocate(m_state.dataGlobal->NumOfZones); // Report variables
5544 :
5545 35 : ANZT.allocate(m_state.dataGlobal->NumOfZones); // Local zone air temperature for rollback use
5546 35 : ANZW.allocate(m_state.dataGlobal->NumOfZones); // Local zone humidity ratio for rollback use
5547 35 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation)
5548 1 : ANCO.allocate(m_state.dataGlobal->NumOfZones); // Local zone CO2 for rollback use
5549 35 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5550 1 : ANGC.allocate(m_state.dataGlobal->NumOfZones); // Local zone generic contaminant for rollback use
5551 35 : allocate();
5552 :
5553 35 : bool OnOffFanFlag = false;
5554 59 : for (i = 1; i <= DisSysNumOfCVFs; i++) {
5555 24 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
5556 9 : OnOffFanFlag = true;
5557 : }
5558 : }
5559 :
5560 : // CurrentModuleObject='AirflowNetwork Simulations'
5561 880 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
5562 1690 : SetupOutputVariable(m_state,
5563 : "AFN Node Temperature",
5564 : Constant::Units::C,
5565 845 : AirflowNetworkNodeSimu(i).TZ,
5566 : OutputProcessor::TimeStepType::System,
5567 : OutputProcessor::StoreType::Average,
5568 845 : AirflowNetworkNodeData(i).Name);
5569 1690 : SetupOutputVariable(m_state,
5570 : "AFN Node Humidity Ratio",
5571 : Constant::Units::kgWater_kgDryAir,
5572 845 : AirflowNetworkNodeSimu(i).WZ,
5573 : OutputProcessor::TimeStepType::System,
5574 : OutputProcessor::StoreType::Average,
5575 845 : AirflowNetworkNodeData(i).Name);
5576 845 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
5577 74 : SetupOutputVariable(m_state,
5578 : "AFN Node CO2 Concentration",
5579 : Constant::Units::ppm,
5580 37 : AirflowNetworkNodeSimu(i).CO2Z,
5581 : OutputProcessor::TimeStepType::System,
5582 : OutputProcessor::StoreType::Average,
5583 37 : AirflowNetworkNodeData(i).Name);
5584 : }
5585 845 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
5586 74 : SetupOutputVariable(m_state,
5587 : "AFN Node Generic Air Contaminant Concentration",
5588 : Constant::Units::ppm,
5589 37 : AirflowNetworkNodeSimu(i).GCZ,
5590 : OutputProcessor::TimeStepType::System,
5591 : OutputProcessor::StoreType::Average,
5592 37 : AirflowNetworkNodeData(i).Name);
5593 : }
5594 845 : if (!(supplyFanType == HVAC::FanType::OnOff && i <= AirflowNetworkNumOfZones)) {
5595 1636 : SetupOutputVariable(m_state,
5596 : "AFN Node Total Pressure",
5597 : Constant::Units::Pa,
5598 818 : AirflowNetworkNodeSimu(i).PZ,
5599 : OutputProcessor::TimeStepType::System,
5600 : OutputProcessor::StoreType::Average,
5601 818 : AirflowNetworkNodeData(i).Name);
5602 : }
5603 845 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
5604 422 : SetupOutputVariable(m_state,
5605 : "AFN Node Wind Pressure",
5606 : Constant::Units::Pa,
5607 211 : AirflowNetworkNodeSimu(i).PZ,
5608 : OutputProcessor::TimeStepType::System,
5609 : OutputProcessor::StoreType::Average,
5610 211 : AirflowNetworkNodeData(i).Name);
5611 : }
5612 : }
5613 :
5614 1234 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
5615 1199 : if (!(supplyFanType == HVAC::FanType::OnOff && i <= AirflowNetworkNumOfSurfaces)) {
5616 2228 : SetupOutputVariable(m_state,
5617 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
5618 : Constant::Units::kg_s,
5619 1114 : linkReport(i).FLOW,
5620 : OutputProcessor::TimeStepType::System,
5621 : OutputProcessor::StoreType::Average,
5622 1114 : AirflowNetworkLinkageData(i).Name);
5623 2228 : SetupOutputVariable(m_state,
5624 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
5625 : Constant::Units::kg_s,
5626 1114 : linkReport(i).FLOW2,
5627 : OutputProcessor::TimeStepType::System,
5628 : OutputProcessor::StoreType::Average,
5629 1114 : AirflowNetworkLinkageData(i).Name);
5630 2228 : SetupOutputVariable(m_state,
5631 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
5632 : Constant::Units::m3_s,
5633 1114 : linkReport(i).VolFLOW,
5634 : OutputProcessor::TimeStepType::System,
5635 : OutputProcessor::StoreType::Average,
5636 1114 : AirflowNetworkLinkageData(i).Name);
5637 2228 : SetupOutputVariable(m_state,
5638 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
5639 : Constant::Units::m3_s,
5640 1114 : linkReport(i).VolFLOW2,
5641 : OutputProcessor::TimeStepType::System,
5642 : OutputProcessor::StoreType::Average,
5643 1114 : AirflowNetworkLinkageData(i).Name);
5644 2228 : SetupOutputVariable(m_state,
5645 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
5646 : Constant::Units::Pa,
5647 1114 : AirflowNetworkLinkSimu(i).DP,
5648 : OutputProcessor::TimeStepType::System,
5649 : OutputProcessor::StoreType::Average,
5650 1114 : AirflowNetworkLinkageData(i).Name);
5651 : }
5652 : }
5653 :
5654 533 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
5655 498 : if (AirflowNetworkLinkageData(i).element == nullptr) {
5656 : // This is not great
5657 0 : continue;
5658 : }
5659 498 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::DOP ||
5660 909 : AirflowNetworkLinkageData(i).element->type() == ComponentType::SOP ||
5661 411 : AirflowNetworkLinkageData(i).element->type() == ComponentType::HOP) {
5662 88 : SurfNum = MultizoneSurfaceData(i).SurfNum;
5663 176 : SetupOutputVariable(m_state,
5664 : "AFN Surface Venting Window or Door Opening Factor",
5665 : Constant::Units::None,
5666 88 : MultizoneSurfaceData(i).OpenFactor,
5667 : OutputProcessor::TimeStepType::System,
5668 : OutputProcessor::StoreType::Average,
5669 88 : MultizoneSurfaceData(i).SurfName);
5670 88 : if (m_state.dataGlobal->AnyEnergyManagementSystemInModel) {
5671 20 : SetupEMSActuator(m_state,
5672 : "AirFlow Network Window/Door Opening",
5673 10 : MultizoneSurfaceData(i).SurfName,
5674 : "Venting Opening Factor",
5675 : "[Fraction]",
5676 10 : MultizoneSurfaceData(i).EMSOpenFactorActuated,
5677 10 : MultizoneSurfaceData(i).EMSOpenFactor);
5678 : }
5679 176 : SetupOutputVariable(m_state,
5680 : "AFN Surface Venting Window or Door Opening Modulation Multiplier",
5681 : Constant::Units::None,
5682 88 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum),
5683 : OutputProcessor::TimeStepType::System,
5684 : OutputProcessor::StoreType::Average,
5685 88 : m_state.dataSurface->Surface(SurfNum).Name);
5686 176 : SetupOutputVariable(m_state,
5687 : "AFN Surface Venting Inside Setpoint Temperature",
5688 : Constant::Units::C,
5689 88 : m_state.dataSurface->SurfWinInsideTempForVentingRep(SurfNum),
5690 : OutputProcessor::TimeStepType::System,
5691 : OutputProcessor::StoreType::Average,
5692 88 : m_state.dataSurface->Surface(SurfNum).Name);
5693 176 : SetupOutputVariable(m_state,
5694 : "AFN Surface Venting Availability Status",
5695 : Constant::Units::None,
5696 88 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum),
5697 : OutputProcessor::TimeStepType::System,
5698 : OutputProcessor::StoreType::Average,
5699 88 : m_state.dataSurface->Surface(SurfNum).Name);
5700 88 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
5701 4 : SetupOutputVariable(m_state,
5702 : "AFN Surface Venting Window or Door Opening Factor at Previous Time Step",
5703 : Constant::Units::None,
5704 2 : MultizoneSurfaceData(i).OpenFactorLast,
5705 : OutputProcessor::TimeStepType::System,
5706 : OutputProcessor::StoreType::Average,
5707 2 : MultizoneSurfaceData(i).SurfName);
5708 4 : SetupOutputVariable(m_state,
5709 : "AFN Surface Opening Elapsed Time",
5710 : Constant::Units::min,
5711 2 : MultizoneSurfaceData(i).OpenElapsedTime,
5712 : OutputProcessor::TimeStepType::System,
5713 : OutputProcessor::StoreType::Average,
5714 2 : MultizoneSurfaceData(i).SurfName);
5715 4 : SetupOutputVariable(m_state,
5716 : "AFN Surface Closing Elapsed Time",
5717 : Constant::Units::min,
5718 2 : MultizoneSurfaceData(i).CloseElapsedTime,
5719 : OutputProcessor::TimeStepType::System,
5720 : OutputProcessor::StoreType::Average,
5721 2 : MultizoneSurfaceData(i).SurfName);
5722 2 : SetupOutputVariable(m_state,
5723 : "AFN Surface Opening Status at Previous Time Step",
5724 : Constant::Units::None,
5725 2 : MultizoneSurfaceData(i).PrevOpeningstatus,
5726 : OutputProcessor::TimeStepType::System,
5727 : OutputProcessor::StoreType::Average,
5728 2 : MultizoneSurfaceData(i).SurfName);
5729 2 : SetupOutputVariable(m_state,
5730 : "AFN Surface Opening Status",
5731 : Constant::Units::None,
5732 2 : MultizoneSurfaceData(i).OpeningStatus,
5733 : OutputProcessor::TimeStepType::System,
5734 : OutputProcessor::StoreType::Average,
5735 2 : MultizoneSurfaceData(i).SurfName);
5736 2 : SetupOutputVariable(m_state,
5737 : "AFN Surface Opening Probability Status",
5738 : Constant::Units::None,
5739 2 : MultizoneSurfaceData(i).OpeningProbStatus,
5740 : OutputProcessor::TimeStepType::System,
5741 : OutputProcessor::StoreType::Average,
5742 2 : MultizoneSurfaceData(i).SurfName);
5743 2 : SetupOutputVariable(m_state,
5744 : "AFN Surface Closing Probability Status",
5745 : Constant::Units::None,
5746 2 : MultizoneSurfaceData(i).ClosingProbStatus,
5747 : OutputProcessor::TimeStepType::System,
5748 : OutputProcessor::StoreType::Average,
5749 2 : MultizoneSurfaceData(i).SurfName);
5750 : }
5751 : }
5752 : }
5753 :
5754 150 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
5755 : // Multizone losses due to force air systems
5756 230 : SetupOutputVariable(m_state,
5757 : "AFN Zone Infiltration Sensible Heat Gain Rate",
5758 : Constant::Units::W,
5759 115 : AirflowNetworkReportData(i).MultiZoneInfiSenGainW,
5760 : OutputProcessor::TimeStepType::System,
5761 : OutputProcessor::StoreType::Average,
5762 115 : Zone(i).Name);
5763 230 : SetupOutputVariable(m_state,
5764 : "AFN Zone Infiltration Sensible Heat Gain Energy",
5765 : Constant::Units::J,
5766 115 : AirflowNetworkReportData(i).MultiZoneInfiSenGainJ,
5767 : OutputProcessor::TimeStepType::System,
5768 : OutputProcessor::StoreType::Sum,
5769 115 : Zone(i).Name);
5770 230 : SetupOutputVariable(m_state,
5771 : "AFN Zone Ventilation Sensible Heat Gain Rate",
5772 : Constant::Units::W,
5773 115 : AirflowNetworkReportData(i).MultiZoneVentSenGainW,
5774 : OutputProcessor::TimeStepType::System,
5775 : OutputProcessor::StoreType::Average,
5776 115 : Zone(i).Name);
5777 230 : SetupOutputVariable(m_state,
5778 : "AFN Zone Ventilation Sensible Heat Gain Energy",
5779 : Constant::Units::J,
5780 115 : AirflowNetworkReportData(i).MultiZoneVentSenGainJ,
5781 : OutputProcessor::TimeStepType::System,
5782 : OutputProcessor::StoreType::Sum,
5783 115 : Zone(i).Name);
5784 230 : SetupOutputVariable(m_state,
5785 : "AFN Zone Mixing Sensible Heat Gain Rate",
5786 : Constant::Units::W,
5787 115 : AirflowNetworkReportData(i).MultiZoneMixSenGainW,
5788 : OutputProcessor::TimeStepType::System,
5789 : OutputProcessor::StoreType::Average,
5790 115 : Zone(i).Name);
5791 230 : SetupOutputVariable(m_state,
5792 : "AFN Zone Mixing Sensible Heat Gain Energy",
5793 : Constant::Units::J,
5794 115 : AirflowNetworkReportData(i).MultiZoneMixSenGainJ,
5795 : OutputProcessor::TimeStepType::System,
5796 : OutputProcessor::StoreType::Sum,
5797 115 : Zone(i).Name);
5798 230 : SetupOutputVariable(m_state,
5799 : "AFN Zone Infiltration Sensible Heat Loss Rate",
5800 : Constant::Units::W,
5801 115 : AirflowNetworkReportData(i).MultiZoneInfiSenLossW,
5802 : OutputProcessor::TimeStepType::System,
5803 : OutputProcessor::StoreType::Average,
5804 115 : Zone(i).Name);
5805 230 : SetupOutputVariable(m_state,
5806 : "AFN Zone Infiltration Sensible Heat Loss Energy",
5807 : Constant::Units::J,
5808 115 : AirflowNetworkReportData(i).MultiZoneInfiSenLossJ,
5809 : OutputProcessor::TimeStepType::System,
5810 : OutputProcessor::StoreType::Sum,
5811 115 : Zone(i).Name);
5812 230 : SetupOutputVariable(m_state,
5813 : "AFN Zone Ventilation Sensible Heat Loss Rate",
5814 : Constant::Units::W,
5815 115 : AirflowNetworkReportData(i).MultiZoneVentSenLossW,
5816 : OutputProcessor::TimeStepType::System,
5817 : OutputProcessor::StoreType::Average,
5818 115 : Zone(i).Name);
5819 230 : SetupOutputVariable(m_state,
5820 : "AFN Zone Ventilation Sensible Heat Loss Energy",
5821 : Constant::Units::J,
5822 115 : AirflowNetworkReportData(i).MultiZoneVentSenLossJ,
5823 : OutputProcessor::TimeStepType::System,
5824 : OutputProcessor::StoreType::Sum,
5825 115 : Zone(i).Name);
5826 230 : SetupOutputVariable(m_state,
5827 : "AFN Zone Mixing Sensible Heat Loss Rate",
5828 : Constant::Units::W,
5829 115 : AirflowNetworkReportData(i).MultiZoneMixSenLossW,
5830 : OutputProcessor::TimeStepType::System,
5831 : OutputProcessor::StoreType::Average,
5832 115 : Zone(i).Name);
5833 230 : SetupOutputVariable(m_state,
5834 : "AFN Zone Mixing Sensible Heat Loss Energy",
5835 : Constant::Units::J,
5836 115 : AirflowNetworkReportData(i).MultiZoneMixSenLossJ,
5837 : OutputProcessor::TimeStepType::System,
5838 : OutputProcessor::StoreType::Sum,
5839 115 : Zone(i).Name);
5840 230 : SetupOutputVariable(m_state,
5841 : "AFN Zone Infiltration Latent Heat Gain Rate",
5842 : Constant::Units::W,
5843 115 : AirflowNetworkReportData(i).MultiZoneInfiLatGainW,
5844 : OutputProcessor::TimeStepType::System,
5845 : OutputProcessor::StoreType::Average,
5846 115 : Zone(i).Name);
5847 230 : SetupOutputVariable(m_state,
5848 : "AFN Zone Infiltration Latent Heat Gain Energy",
5849 : Constant::Units::J,
5850 115 : AirflowNetworkReportData(i).MultiZoneInfiLatGainJ,
5851 : OutputProcessor::TimeStepType::System,
5852 : OutputProcessor::StoreType::Sum,
5853 115 : Zone(i).Name);
5854 230 : SetupOutputVariable(m_state,
5855 : "AFN Zone Infiltration Latent Heat Loss Rate",
5856 : Constant::Units::W,
5857 115 : AirflowNetworkReportData(i).MultiZoneInfiLatLossW,
5858 : OutputProcessor::TimeStepType::System,
5859 : OutputProcessor::StoreType::Average,
5860 115 : Zone(i).Name);
5861 230 : SetupOutputVariable(m_state,
5862 : "AFN Zone Infiltration Latent Heat Loss Energy",
5863 : Constant::Units::J,
5864 115 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ,
5865 : OutputProcessor::TimeStepType::System,
5866 : OutputProcessor::StoreType::Sum,
5867 115 : Zone(i).Name);
5868 230 : SetupOutputVariable(m_state,
5869 : "AFN Zone Ventilation Latent Heat Gain Rate",
5870 : Constant::Units::W,
5871 115 : AirflowNetworkReportData(i).MultiZoneVentLatGainW,
5872 : OutputProcessor::TimeStepType::System,
5873 : OutputProcessor::StoreType::Average,
5874 115 : Zone(i).Name);
5875 230 : SetupOutputVariable(m_state,
5876 : "AFN Zone Ventilation Latent Heat Gain Energy",
5877 : Constant::Units::J,
5878 115 : AirflowNetworkReportData(i).MultiZoneVentLatGainJ,
5879 : OutputProcessor::TimeStepType::System,
5880 : OutputProcessor::StoreType::Sum,
5881 115 : Zone(i).Name);
5882 230 : SetupOutputVariable(m_state,
5883 : "AFN Zone Ventilation Latent Heat Loss Rate",
5884 : Constant::Units::W,
5885 115 : AirflowNetworkReportData(i).MultiZoneVentLatLossW,
5886 : OutputProcessor::TimeStepType::System,
5887 : OutputProcessor::StoreType::Average,
5888 115 : Zone(i).Name);
5889 230 : SetupOutputVariable(m_state,
5890 : "AFN Zone Ventilation Latent Heat Loss Energy",
5891 : Constant::Units::J,
5892 115 : AirflowNetworkReportData(i).MultiZoneVentLatLossJ,
5893 : OutputProcessor::TimeStepType::System,
5894 : OutputProcessor::StoreType::Sum,
5895 115 : Zone(i).Name);
5896 230 : SetupOutputVariable(m_state,
5897 : "AFN Zone Mixing Latent Heat Gain Rate",
5898 : Constant::Units::W,
5899 115 : AirflowNetworkReportData(i).MultiZoneMixLatGainW,
5900 : OutputProcessor::TimeStepType::System,
5901 : OutputProcessor::StoreType::Average,
5902 115 : Zone(i).Name);
5903 230 : SetupOutputVariable(m_state,
5904 : "AFN Zone Mixing Latent Heat Gain Energy",
5905 : Constant::Units::J,
5906 115 : AirflowNetworkReportData(i).MultiZoneMixLatGainJ,
5907 : OutputProcessor::TimeStepType::System,
5908 : OutputProcessor::StoreType::Sum,
5909 115 : Zone(i).Name);
5910 230 : SetupOutputVariable(m_state,
5911 : "AFN Zone Mixing Latent Heat Loss Rate",
5912 : Constant::Units::W,
5913 115 : AirflowNetworkReportData(i).MultiZoneMixLatLossW,
5914 : OutputProcessor::TimeStepType::System,
5915 : OutputProcessor::StoreType::Average,
5916 115 : Zone(i).Name);
5917 230 : SetupOutputVariable(m_state,
5918 : "AFN Zone Mixing Latent Heat Loss Energy",
5919 : Constant::Units::J,
5920 115 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ,
5921 : OutputProcessor::TimeStepType::System,
5922 : OutputProcessor::StoreType::Sum,
5923 115 : Zone(i).Name);
5924 : // Supply leak losses due to force air systems
5925 230 : SetupOutputVariable(m_state,
5926 : "AFN Zone Duct Leaked Air Sensible Heat Gain Rate",
5927 : Constant::Units::W,
5928 115 : AirflowNetworkReportData(i).LeakSenGainW,
5929 : OutputProcessor::TimeStepType::System,
5930 : OutputProcessor::StoreType::Average,
5931 115 : Zone(i).Name);
5932 230 : SetupOutputVariable(m_state,
5933 : "AFN Zone Duct Leaked Air Sensible Heat Gain Energy",
5934 : Constant::Units::J,
5935 115 : AirflowNetworkReportData(i).LeakSenGainJ,
5936 : OutputProcessor::TimeStepType::System,
5937 : OutputProcessor::StoreType::Sum,
5938 115 : Zone(i).Name);
5939 230 : SetupOutputVariable(m_state,
5940 : "AFN Zone Duct Leaked Air Sensible Heat Loss Rate",
5941 : Constant::Units::W,
5942 115 : AirflowNetworkReportData(i).LeakSenLossW,
5943 : OutputProcessor::TimeStepType::System,
5944 : OutputProcessor::StoreType::Average,
5945 115 : Zone(i).Name);
5946 230 : SetupOutputVariable(m_state,
5947 : "AFN Zone Duct Leaked Air Sensible Heat Loss Energy",
5948 : Constant::Units::J,
5949 115 : AirflowNetworkReportData(i).LeakSenLossJ,
5950 : OutputProcessor::TimeStepType::System,
5951 : OutputProcessor::StoreType::Sum,
5952 115 : Zone(i).Name);
5953 230 : SetupOutputVariable(m_state,
5954 : "AFN Zone Duct Leaked Air Latent Heat Gain Rate",
5955 : Constant::Units::W,
5956 115 : AirflowNetworkReportData(i).LeakLatGainW,
5957 : OutputProcessor::TimeStepType::System,
5958 : OutputProcessor::StoreType::Average,
5959 115 : Zone(i).Name);
5960 230 : SetupOutputVariable(m_state,
5961 : "AFN Zone Duct Leaked Air Latent Heat Gain Energy",
5962 : Constant::Units::J,
5963 115 : AirflowNetworkReportData(i).LeakLatGainJ,
5964 : OutputProcessor::TimeStepType::System,
5965 : OutputProcessor::StoreType::Sum,
5966 115 : Zone(i).Name);
5967 230 : SetupOutputVariable(m_state,
5968 : "AFN Zone Duct Leaked Air Latent Heat Loss Rate",
5969 : Constant::Units::W,
5970 115 : AirflowNetworkReportData(i).LeakLatLossW,
5971 : OutputProcessor::TimeStepType::System,
5972 : OutputProcessor::StoreType::Average,
5973 115 : Zone(i).Name);
5974 230 : SetupOutputVariable(m_state,
5975 : "AFN Zone Duct Leaked Air Latent Heat Loss Energy",
5976 : Constant::Units::J,
5977 115 : AirflowNetworkReportData(i).LeakLatLossJ,
5978 : OutputProcessor::TimeStepType::System,
5979 : OutputProcessor::StoreType::Sum,
5980 115 : Zone(i).Name);
5981 : // Conduction losses due to force air systems
5982 230 : SetupOutputVariable(m_state,
5983 : "AFN Zone Duct Conduction Sensible Heat Gain Rate",
5984 : Constant::Units::W,
5985 115 : AirflowNetworkReportData(i).CondSenGainW,
5986 : OutputProcessor::TimeStepType::System,
5987 : OutputProcessor::StoreType::Average,
5988 115 : Zone(i).Name);
5989 230 : SetupOutputVariable(m_state,
5990 : "AFN Zone Duct Conduction Sensible Heat Gain Energy",
5991 : Constant::Units::J,
5992 115 : AirflowNetworkReportData(i).CondSenGainJ,
5993 : OutputProcessor::TimeStepType::System,
5994 : OutputProcessor::StoreType::Sum,
5995 115 : Zone(i).Name);
5996 230 : SetupOutputVariable(m_state,
5997 : "AFN Zone Duct Conduction Sensible Heat Loss Rate",
5998 : Constant::Units::W,
5999 115 : AirflowNetworkReportData(i).CondSenLossW,
6000 : OutputProcessor::TimeStepType::System,
6001 : OutputProcessor::StoreType::Average,
6002 115 : Zone(i).Name);
6003 230 : SetupOutputVariable(m_state,
6004 : "AFN Zone Duct Conduction Sensible Heat Loss Energy",
6005 : Constant::Units::J,
6006 115 : AirflowNetworkReportData(i).CondSenLossJ,
6007 : OutputProcessor::TimeStepType::System,
6008 : OutputProcessor::StoreType::Sum,
6009 115 : Zone(i).Name);
6010 230 : SetupOutputVariable(m_state,
6011 : "AFN Zone Duct Diffusion Latent Heat Gain Rate",
6012 : Constant::Units::W,
6013 115 : AirflowNetworkReportData(i).DiffLatGainW,
6014 : OutputProcessor::TimeStepType::System,
6015 : OutputProcessor::StoreType::Average,
6016 115 : Zone(i).Name);
6017 230 : SetupOutputVariable(m_state,
6018 : "AFN Zone Duct Diffusion Latent Heat Gain Energy",
6019 : Constant::Units::J,
6020 115 : AirflowNetworkReportData(i).DiffLatGainJ,
6021 : OutputProcessor::TimeStepType::System,
6022 : OutputProcessor::StoreType::Sum,
6023 115 : Zone(i).Name);
6024 230 : SetupOutputVariable(m_state,
6025 : "AFN Zone Duct Diffusion Latent Heat Loss Rate",
6026 : Constant::Units::W,
6027 115 : AirflowNetworkReportData(i).DiffLatLossW,
6028 : OutputProcessor::TimeStepType::System,
6029 : OutputProcessor::StoreType::Average,
6030 115 : Zone(i).Name);
6031 230 : SetupOutputVariable(m_state,
6032 : "AFN Zone Duct Diffusion Latent Heat Loss Energy",
6033 : Constant::Units::J,
6034 115 : AirflowNetworkReportData(i).DiffLatLossJ,
6035 : OutputProcessor::TimeStepType::System,
6036 : OutputProcessor::StoreType::Sum,
6037 115 : Zone(i).Name);
6038 : // Radiation losses due to forced air systems
6039 230 : SetupOutputVariable(m_state,
6040 : "AFN Zone Duct Radiation Heat Gain Rate",
6041 : Constant::Units::W,
6042 115 : AirflowNetworkReportData(i).RadGainW,
6043 : OutputProcessor::TimeStepType::System,
6044 : OutputProcessor::StoreType::Average,
6045 115 : Zone(i).Name);
6046 230 : SetupOutputVariable(m_state,
6047 : "AFN Zone Duct Radiation Sensible Heat Gain Energy",
6048 : Constant::Units::J,
6049 115 : AirflowNetworkReportData(i).RadGainJ,
6050 : OutputProcessor::TimeStepType::System,
6051 : OutputProcessor::StoreType::Sum,
6052 115 : Zone(i).Name);
6053 230 : SetupOutputVariable(m_state,
6054 : "AFN Zone Duct Radiation Heat Loss Rate",
6055 : Constant::Units::W,
6056 115 : AirflowNetworkReportData(i).RadLossW,
6057 : OutputProcessor::TimeStepType::System,
6058 : OutputProcessor::StoreType::Average,
6059 115 : Zone(i).Name);
6060 230 : SetupOutputVariable(m_state,
6061 : "AFN Zone Duct Radiation Sensible Heat Loss Energy",
6062 : Constant::Units::J,
6063 115 : AirflowNetworkReportData(i).RadLossJ,
6064 : OutputProcessor::TimeStepType::System,
6065 : OutputProcessor::StoreType::Sum,
6066 115 : Zone(i).Name);
6067 : // Total losses due to force air systems
6068 230 : SetupOutputVariable(m_state,
6069 : "AFN Distribution Sensible Heat Gain Rate",
6070 : Constant::Units::W,
6071 115 : AirflowNetworkReportData(i).TotalSenGainW,
6072 : OutputProcessor::TimeStepType::System,
6073 : OutputProcessor::StoreType::Average,
6074 115 : Zone(i).Name);
6075 230 : SetupOutputVariable(m_state,
6076 : "AFN Distribution Sensible Heat Gain Energy",
6077 : Constant::Units::J,
6078 115 : AirflowNetworkReportData(i).TotalSenGainJ,
6079 : OutputProcessor::TimeStepType::System,
6080 : OutputProcessor::StoreType::Sum,
6081 115 : Zone(i).Name);
6082 230 : SetupOutputVariable(m_state,
6083 : "AFN Distribution Sensible Heat Loss Rate",
6084 : Constant::Units::W,
6085 115 : AirflowNetworkReportData(i).TotalSenLossW,
6086 : OutputProcessor::TimeStepType::System,
6087 : OutputProcessor::StoreType::Average,
6088 115 : Zone(i).Name);
6089 230 : SetupOutputVariable(m_state,
6090 : "AFN Distribution Sensible Heat Loss Energy",
6091 : Constant::Units::J,
6092 115 : AirflowNetworkReportData(i).TotalSenLossJ,
6093 : OutputProcessor::TimeStepType::System,
6094 : OutputProcessor::StoreType::Sum,
6095 115 : Zone(i).Name);
6096 230 : SetupOutputVariable(m_state,
6097 : "AFN Distribution Latent Heat Gain Rate",
6098 : Constant::Units::W,
6099 115 : AirflowNetworkReportData(i).TotalLatGainW,
6100 : OutputProcessor::TimeStepType::System,
6101 : OutputProcessor::StoreType::Average,
6102 115 : Zone(i).Name);
6103 230 : SetupOutputVariable(m_state,
6104 : "AFN Distribution Latent Heat Gain Energy",
6105 : Constant::Units::J,
6106 115 : AirflowNetworkReportData(i).TotalLatGainJ,
6107 : OutputProcessor::TimeStepType::System,
6108 : OutputProcessor::StoreType::Sum,
6109 115 : Zone(i).Name);
6110 230 : SetupOutputVariable(m_state,
6111 : "AFN Distribution Latent Heat Loss Rate",
6112 : Constant::Units::W,
6113 115 : AirflowNetworkReportData(i).TotalLatLossW,
6114 : OutputProcessor::TimeStepType::System,
6115 : OutputProcessor::StoreType::Average,
6116 115 : Zone(i).Name);
6117 230 : SetupOutputVariable(m_state,
6118 : "AFN Distribution Latent Heat Loss Energy",
6119 : Constant::Units::J,
6120 115 : AirflowNetworkReportData(i).TotalLatLossJ,
6121 : OutputProcessor::TimeStepType::System,
6122 : OutputProcessor::StoreType::Sum,
6123 115 : Zone(i).Name);
6124 : }
6125 :
6126 150 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
6127 230 : SetupOutputVariable(m_state,
6128 : "AFN Zone Infiltration Volume",
6129 : Constant::Units::m3,
6130 115 : AirflowNetworkZnRpt(i).InfilVolume,
6131 : OutputProcessor::TimeStepType::System,
6132 : OutputProcessor::StoreType::Sum,
6133 115 : Zone(i).Name);
6134 230 : SetupOutputVariable(m_state,
6135 : "AFN Zone Infiltration Mass",
6136 : Constant::Units::kg,
6137 115 : AirflowNetworkZnRpt(i).InfilMass,
6138 : OutputProcessor::TimeStepType::System,
6139 : OutputProcessor::StoreType::Sum,
6140 115 : Zone(i).Name);
6141 230 : SetupOutputVariable(m_state,
6142 : "AFN Zone Infiltration Air Change Rate",
6143 : Constant::Units::ach,
6144 115 : AirflowNetworkZnRpt(i).InfilAirChangeRate,
6145 : OutputProcessor::TimeStepType::System,
6146 : OutputProcessor::StoreType::Average,
6147 115 : Zone(i).Name);
6148 230 : SetupOutputVariable(m_state,
6149 : "AFN Zone Ventilation Volume",
6150 : Constant::Units::m3,
6151 115 : AirflowNetworkZnRpt(i).VentilVolume,
6152 : OutputProcessor::TimeStepType::System,
6153 : OutputProcessor::StoreType::Sum,
6154 115 : Zone(i).Name);
6155 230 : SetupOutputVariable(m_state,
6156 : "AFN Zone Ventilation Mass",
6157 : Constant::Units::kg,
6158 115 : AirflowNetworkZnRpt(i).VentilMass,
6159 : OutputProcessor::TimeStepType::System,
6160 : OutputProcessor::StoreType::Sum,
6161 115 : Zone(i).Name);
6162 230 : SetupOutputVariable(m_state,
6163 : "AFN Zone Ventilation Air Change Rate",
6164 : Constant::Units::ach,
6165 115 : AirflowNetworkZnRpt(i).VentilAirChangeRate,
6166 : OutputProcessor::TimeStepType::System,
6167 : OutputProcessor::StoreType::Average,
6168 115 : Zone(i).Name);
6169 230 : SetupOutputVariable(m_state,
6170 : "AFN Zone Mixing Volume",
6171 : Constant::Units::m3,
6172 115 : AirflowNetworkZnRpt(i).MixVolume,
6173 : OutputProcessor::TimeStepType::System,
6174 : OutputProcessor::StoreType::Sum,
6175 115 : Zone(i).Name);
6176 230 : SetupOutputVariable(m_state,
6177 : "AFN Zone Mixing Mass",
6178 : Constant::Units::kg,
6179 115 : AirflowNetworkZnRpt(i).MixMass,
6180 : OutputProcessor::TimeStepType::System,
6181 : OutputProcessor::StoreType::Sum,
6182 115 : Zone(i).Name);
6183 :
6184 230 : SetupOutputVariable(m_state,
6185 : "AFN Zone Exfiltration Heat Transfer Rate",
6186 : Constant::Units::W,
6187 115 : AirflowNetworkZnRpt(i).ExfilTotalLoss,
6188 : OutputProcessor::TimeStepType::System,
6189 : OutputProcessor::StoreType::Average,
6190 115 : Zone(i).Name);
6191 230 : SetupOutputVariable(m_state,
6192 : "AFN Zone Exfiltration Sensible Heat Transfer Rate",
6193 : Constant::Units::W,
6194 115 : AirflowNetworkZnRpt(i).ExfilSensiLoss,
6195 : OutputProcessor::TimeStepType::System,
6196 : OutputProcessor::StoreType::Average,
6197 115 : Zone(i).Name);
6198 230 : SetupOutputVariable(m_state,
6199 : "AFN Zone Exfiltration Latent Heat Transfer Rate",
6200 : Constant::Units::W,
6201 115 : AirflowNetworkZnRpt(i).ExfilLatentLoss,
6202 : OutputProcessor::TimeStepType::System,
6203 : OutputProcessor::StoreType::Average,
6204 115 : Zone(i).Name);
6205 : }
6206 :
6207 35 : if (OnOffFanFlag) {
6208 36 : for (i = 1; i <= AirflowNetworkNumOfZones; ++i) {
6209 54 : SetupOutputVariable(m_state,
6210 : "AFN Zone Average Pressure",
6211 : Constant::Units::Pa,
6212 27 : nodeReport(i).PZ,
6213 : OutputProcessor::TimeStepType::System,
6214 : OutputProcessor::StoreType::Average,
6215 27 : Zone(i).Name);
6216 54 : SetupOutputVariable(m_state,
6217 : "AFN Zone On Cycle Pressure",
6218 : Constant::Units::Pa,
6219 27 : nodeReport(i).PZON,
6220 : OutputProcessor::TimeStepType::System,
6221 : OutputProcessor::StoreType::Average,
6222 27 : Zone(i).Name);
6223 54 : SetupOutputVariable(m_state,
6224 : "AFN Zone Off Cycle Pressure",
6225 : Constant::Units::Pa,
6226 27 : nodeReport(i).PZOFF,
6227 : OutputProcessor::TimeStepType::System,
6228 : OutputProcessor::StoreType::Average,
6229 27 : Zone(i).Name);
6230 : }
6231 94 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6232 170 : SetupOutputVariable(m_state,
6233 : "AFN Linkage Node 1 to 2 Average Mass Flow Rate",
6234 : Constant::Units::kg_s,
6235 85 : linkReport1(i).FLOW,
6236 : OutputProcessor::TimeStepType::System,
6237 : OutputProcessor::StoreType::Average,
6238 85 : MultizoneSurfaceData(i).SurfName);
6239 170 : SetupOutputVariable(m_state,
6240 : "AFN Linkage Node 2 to 1 Average Mass Flow Rate",
6241 : Constant::Units::kg_s,
6242 85 : linkReport1(i).FLOW2,
6243 : OutputProcessor::TimeStepType::System,
6244 : OutputProcessor::StoreType::Average,
6245 85 : MultizoneSurfaceData(i).SurfName);
6246 170 : SetupOutputVariable(m_state,
6247 : "AFN Linkage Node 1 to 2 Average Volume Flow Rate",
6248 : Constant::Units::m3_s,
6249 85 : linkReport1(i).VolFLOW,
6250 : OutputProcessor::TimeStepType::System,
6251 : OutputProcessor::StoreType::Average,
6252 85 : MultizoneSurfaceData(i).SurfName);
6253 170 : SetupOutputVariable(m_state,
6254 : "AFN Linkage Node 2 to 1 Average Volume Flow Rate",
6255 : Constant::Units::m3_s,
6256 85 : linkReport1(i).VolFLOW2,
6257 : OutputProcessor::TimeStepType::System,
6258 : OutputProcessor::StoreType::Average,
6259 85 : MultizoneSurfaceData(i).SurfName);
6260 170 : SetupOutputVariable(m_state,
6261 : "AFN Surface Average Pressure Difference",
6262 : Constant::Units::Pa,
6263 85 : linkReport1(i).DP,
6264 : OutputProcessor::TimeStepType::System,
6265 : OutputProcessor::StoreType::Average,
6266 85 : MultizoneSurfaceData(i).SurfName);
6267 170 : SetupOutputVariable(m_state,
6268 : "AFN Surface On Cycle Pressure Difference",
6269 : Constant::Units::Pa,
6270 85 : linkReport1(i).DPON,
6271 : OutputProcessor::TimeStepType::System,
6272 : OutputProcessor::StoreType::Average,
6273 85 : MultizoneSurfaceData(i).SurfName);
6274 170 : SetupOutputVariable(m_state,
6275 : "AFN Surface Off Cycle Pressure Difference",
6276 : Constant::Units::Pa,
6277 85 : linkReport1(i).DPOFF,
6278 : OutputProcessor::TimeStepType::System,
6279 : OutputProcessor::StoreType::Average,
6280 85 : MultizoneSurfaceData(i).SurfName);
6281 : }
6282 : }
6283 :
6284 : // Assign node reference height
6285 880 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
6286 845 : if (!simulation_control.temperature_height_dependence) AirflowNetworkNodeData(i).NodeHeight = 0.0;
6287 845 : int ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
6288 845 : if (ZoneNum > 0) {
6289 120 : if (m_state.dataSurface->WorldCoordSystem) {
6290 103 : AirflowNetworkNodeData(i).NodeHeight = 0.0;
6291 : } else {
6292 17 : AirflowNetworkNodeData(i).NodeHeight = Zone(ZoneNum).OriginZ;
6293 : }
6294 : }
6295 : }
6296 35 : }
6297 :
6298 541114 : void Solver::calculate_balance()
6299 : {
6300 : // SUBROUTINE INFORMATION:
6301 : // AUTHOR Lixing Gu
6302 : // DATE WRITTEN Oct. 2005
6303 : // MODIFIED na
6304 : // RE-ENGINEERED na
6305 :
6306 : // PURPOSE OF THIS SUBROUTINE:
6307 : // This subroutine performs simulations of nodal pressures and linkage airflows.
6308 :
6309 : // Using/Aliasing
6310 : using General::SolveRoot;
6311 : using HVAC::VerySmallMassFlow;
6312 :
6313 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6314 : int i;
6315 : int j;
6316 : int n;
6317 : int NodeNum;
6318 : Real64 GlobalOpenFactor;
6319 : Real64 ZonePressure1;
6320 : Real64 ZonePressure2;
6321 : Real64 PressureSet;
6322 : Real64 LocalAzimuth;
6323 : Real64 LocalWindSpeed;
6324 : Real64 LocalWindDir;
6325 : Real64 LocalHumRat;
6326 : Real64 LocalDryBulb;
6327 541114 : Array1D<Real64> Par; // Pressure setpoint
6328 541114 : Real64 constexpr ErrorToler(0.00001);
6329 541114 : int constexpr MaxIte(20);
6330 : int SolFla;
6331 : Real64 MinExhaustMassFlowrate;
6332 : Real64 MaxExhaustMassFlowrate;
6333 : Real64 MinReliefMassFlowrate;
6334 : Real64 MaxReliefMassFlowrate;
6335 : int AirLoopNum;
6336 :
6337 541114 : auto &Node(m_state.dataLoopNodes->Node);
6338 :
6339 : // Validate supply and return connections
6340 541114 : if (CalcAirflowNetworkAirBalanceOneTimeFlag) {
6341 35 : CalcAirflowNetworkAirBalanceOneTimeFlag = false;
6342 35 : if (CalcAirflowNetworkAirBalanceErrorsFound) {
6343 0 : ShowFatalError(m_state, "GetAirflowNetworkInput: Program terminates for preceding reason(s).");
6344 : }
6345 : }
6346 :
6347 11009333 : for (n = 1; n <= ActualNumOfNodes; ++n) {
6348 10468219 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
6349 6930929 : AirflowNetworkNodeSimu(n).PZ = 0.0;
6350 : } else {
6351 : // Assigning ambient conditions to external nodes
6352 3537290 : i = AirflowNetworkNodeData(n).ExtNodeNum;
6353 3537290 : if (i > 0) {
6354 3537290 : AirflowNetworkNodeSimu(n).TZ = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(n).NodeHeight);
6355 3537290 : AirflowNetworkNodeSimu(n).WZ = m_state.dataEnvrn->OutHumRat;
6356 3537290 : if (i <= AirflowNetworkNumOfExtNode) {
6357 3445503 : if (MultizoneExternalNodeData(i).OutAirNodeNum == 0) {
6358 3428784 : LocalWindSpeed = DataEnvironment::WindSpeedAt(m_state, MultizoneExternalNodeData(i).height);
6359 3428784 : LocalDryBulb = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(n).NodeHeight);
6360 3428784 : LocalAzimuth = MultizoneExternalNodeData(i).azimuth;
6361 3428784 : AirflowNetworkNodeSimu(n).PZ = calculate_wind_pressure(MultizoneExternalNodeData(i).curve,
6362 3428784 : MultizoneExternalNodeData(i).symmetricCurve,
6363 3428784 : MultizoneExternalNodeData(i).useRelativeAngle,
6364 : LocalAzimuth,
6365 : LocalWindSpeed,
6366 3428784 : m_state.dataEnvrn->WindDir,
6367 : LocalDryBulb,
6368 3428784 : m_state.dataEnvrn->OutHumRat);
6369 : } else {
6370 : // If and outdoor air node object is defined as the External Node Name in AirflowNetwork:MultiZone:Surface,
6371 : // the node object requires to define the Wind Pressure Coefficient Curve Name.
6372 16719 : NodeNum = MultizoneExternalNodeData(i).OutAirNodeNum;
6373 16719 : LocalWindSpeed = Node((NodeNum)).OutAirWindSpeed;
6374 16719 : LocalWindDir = Node((NodeNum)).OutAirWindDir;
6375 16719 : LocalHumRat = Node((NodeNum)).HumRat;
6376 16719 : LocalDryBulb = Node((NodeNum)).OutAirDryBulb;
6377 16719 : LocalAzimuth = MultizoneExternalNodeData(i).azimuth;
6378 16719 : AirflowNetworkNodeSimu(n).PZ = calculate_wind_pressure(MultizoneExternalNodeData(i).curve,
6379 16719 : MultizoneExternalNodeData(i).symmetricCurve,
6380 16719 : MultizoneExternalNodeData(i).useRelativeAngle,
6381 : LocalAzimuth,
6382 : LocalWindSpeed,
6383 : LocalWindDir,
6384 : LocalDryBulb,
6385 : LocalHumRat);
6386 16719 : AirflowNetworkNodeSimu(n).TZ = LocalDryBulb;
6387 16719 : AirflowNetworkNodeSimu(n).WZ = LocalHumRat;
6388 : }
6389 : }
6390 :
6391 : } else {
6392 0 : ShowSevereError(m_state,
6393 0 : "GetAirflowNetworkInput: AIRFLOWNETWORK:DISTRIBUTION:NODE: Invalid external node = " +
6394 0 : AirflowNetworkNodeData(n).Name);
6395 0 : CalcAirflowNetworkAirBalanceErrorsFound = true;
6396 : }
6397 : }
6398 : }
6399 :
6400 8184068 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6401 7642954 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) {
6402 103537 : continue;
6403 : }
6404 7539417 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::SCR) {
6405 4633267 : AirflowNetworkLinkageData(i).control = MultizoneSurfaceData(i).Factor;
6406 : }
6407 7539417 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum == 0) MultizoneSurfaceData(i).OpenFactor = 0.0;
6408 7539417 : j = MultizoneSurfaceData(i).SurfNum;
6409 7539417 : auto const &surf = m_state.dataSurface->Surface(j);
6410 7539417 : if (surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
6411 6467208 : surf.OriginalClass == SurfaceClass::GlassDoor || surf.IsAirBoundarySurf) {
6412 1072209 : if (MultizoneSurfaceData(i).OccupantVentilationControlNum > 0) {
6413 16182 : if (MultizoneSurfaceData(i).OpeningStatus == OpenStatus::FreeOperation) {
6414 14712 : if (MultizoneSurfaceData(i).OpeningProbStatus == ProbabilityCheck::ForceChange) {
6415 54 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).Factor;
6416 14658 : } else if (MultizoneSurfaceData(i).ClosingProbStatus == ProbabilityCheck::ForceChange) {
6417 336 : MultizoneSurfaceData(i).OpenFactor = 0.0;
6418 20400 : } else if (MultizoneSurfaceData(i).ClosingProbStatus == ProbabilityCheck::KeepStatus ||
6419 6078 : MultizoneSurfaceData(i).OpeningProbStatus == ProbabilityCheck::KeepStatus) {
6420 10536 : MultizoneSurfaceData(i).OpenFactor = MultizoneSurfaceData(i).OpenFactorLast;
6421 : } else {
6422 3786 : venting_control(i, MultizoneSurfaceData(i).OpenFactor);
6423 : }
6424 : }
6425 : } else {
6426 1056027 : venting_control(i, MultizoneSurfaceData(i).OpenFactor);
6427 : }
6428 1072209 : MultizoneSurfaceData(i).OpenFactor *= MultizoneSurfaceData(i).WindModifier;
6429 1072209 : if (MultizoneSurfaceData(i).HybridVentClose) {
6430 181546 : MultizoneSurfaceData(i).OpenFactor = 0.0;
6431 181546 : if (m_state.dataSurface->SurfWinVentingOpenFactorMultRep(j) > 0.0) m_state.dataSurface->SurfWinVentingOpenFactorMultRep(j) = 0.0;
6432 : }
6433 1072209 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DOP ||
6434 1165518 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SOP ||
6435 93309 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
6436 222947 : if (AirflowNetworkFanActivated && distribution_simulated && MultizoneSurfaceData(i).OpenFactor > 0.0 &&
6437 877 : (m_state.dataSurface->Surface(j).ExtBoundCond == ExternalEnvironment ||
6438 18 : (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
6439 1209179 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) &&
6440 859 : !m_state.dataGlobal->WarmupFlag) {
6441 : // Exterior Large opening only
6442 462 : ++MultizoneSurfaceData(i).ExtLargeOpeningErrCount;
6443 462 : if (MultizoneSurfaceData(i).ExtLargeOpeningErrCount < 2) {
6444 8 : ShowWarningError(m_state,
6445 4 : "AirflowNetwork: The window or door is open during HVAC system operation " +
6446 4 : MultizoneSurfaceData(i).SurfName);
6447 4 : ShowContinueError(m_state, format("The window or door opening factor is {:.2R}", MultizoneSurfaceData(i).OpenFactor));
6448 4 : ShowContinueErrorTimeStamp(m_state, "");
6449 : } else {
6450 1374 : ShowRecurringWarningErrorAtEnd(m_state,
6451 916 : "AirFlowNetwork: " + MultizoneSurfaceData(i).SurfName +
6452 : " The window or door is open during HVAC system operation error continues...",
6453 458 : MultizoneSurfaceData(i).ExtLargeOpeningErrIndex,
6454 458 : MultizoneSurfaceData(i).OpenFactor,
6455 458 : MultizoneSurfaceData(i).OpenFactor);
6456 : }
6457 : }
6458 : }
6459 1072209 : if (MultizoneSurfaceData(i).OpenFactor > 1.0) {
6460 0 : ++MultizoneSurfaceData(i).OpenFactorErrCount;
6461 0 : if (MultizoneSurfaceData(i).OpenFactorErrCount < 2) {
6462 0 : ShowWarningError(m_state,
6463 0 : "AirflowNetwork: The window or door opening factor is greater than 1.0 " + MultizoneSurfaceData(i).SurfName);
6464 0 : ShowContinueErrorTimeStamp(m_state, "");
6465 : } else {
6466 0 : ShowRecurringWarningErrorAtEnd(m_state,
6467 0 : "AirFlowNetwork: " + MultizoneSurfaceData(i).SurfName +
6468 : " The window or door opening factor is greater than 1.0 error continues...",
6469 0 : MultizoneSurfaceData(i).OpenFactorErrIndex,
6470 0 : MultizoneSurfaceData(i).OpenFactor,
6471 0 : MultizoneSurfaceData(i).OpenFactor);
6472 : }
6473 : }
6474 : }
6475 : }
6476 :
6477 : // Check if the global ventilation control is applied or not
6478 541114 : GlobalOpenFactor = -1.0;
6479 8025096 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6480 7493500 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) continue;
6481 7389963 : if (MultizoneSurfaceData(i).HybridCtrlMaster) {
6482 9518 : GlobalOpenFactor = MultizoneSurfaceData(i).OpenFactor;
6483 9518 : break;
6484 : }
6485 : }
6486 541114 : if (GlobalOpenFactor >= 0.0) {
6487 209396 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
6488 199878 : if (i > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) continue;
6489 199878 : j = MultizoneSurfaceData(i).SurfNum;
6490 199878 : auto const &surf = m_state.dataSurface->Surface(j);
6491 199878 : if (surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
6492 152288 : surf.OriginalClass == SurfaceClass::GlassDoor) {
6493 47590 : if (MultizoneSurfaceData(i).HybridCtrlGlobal) {
6494 36676 : MultizoneSurfaceData(i).OpenFactor = GlobalOpenFactor;
6495 : }
6496 : }
6497 : }
6498 : }
6499 :
6500 541114 : if (!Par.allocated()) {
6501 541114 : Par.allocate(1);
6502 541114 : Par = 0.0;
6503 : }
6504 :
6505 541114 : PressureSetFlag = 0;
6506 :
6507 541114 : if (NumOfPressureControllers == 1) {
6508 12264 : if (PressureControllerData(1).AvailSchedPtr == ScheduleManager::ScheduleAlwaysOn) {
6509 12264 : PressureSetFlag = PressureControllerData(1).ControlTypeSet;
6510 : } else {
6511 0 : if (GetCurrentScheduleValue(m_state, PressureControllerData(1).AvailSchedPtr) > 0.0) {
6512 0 : PressureSetFlag = PressureControllerData(1).ControlTypeSet;
6513 : }
6514 : }
6515 12264 : if (PressureSetFlag > 0) {
6516 12264 : PressureSet = GetCurrentScheduleValue(m_state, PressureControllerData(1).PresSetpointSchedPtr);
6517 : }
6518 : }
6519 :
6520 541114 : initialize_calculation();
6521 :
6522 541114 : if (!(PressureSetFlag > 0 && AirflowNetworkFanActivated)) {
6523 535359 : airmov();
6524 5755 : } else if (PressureSetFlag == PressureCtrlExhaust) {
6525 0 : AirLoopNum = AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).AirLoopNum;
6526 0 : MinExhaustMassFlowrate = 2.0 * VerySmallMassFlow;
6527 0 : MaxExhaustMassFlowrate = Node(PressureControllerData(1).OANodeNum).MassFlowRate;
6528 0 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling &&
6529 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio > 0.0) {
6530 0 : MaxExhaustMassFlowrate = MaxExhaustMassFlowrate / m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
6531 : }
6532 0 : ExhaustFanMassFlowRate = MinExhaustMassFlowrate;
6533 0 : airmov();
6534 0 : ZonePressure1 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6535 0 : if (ZonePressure1 <= PressureSet) {
6536 : // The highest pressure due to minimum flow rate could not reach Pressure set, bypass pressure set calculation
6537 0 : if (!m_state.dataGlobal->WarmupFlag) {
6538 0 : if (ErrCountLowPre == 0) {
6539 0 : ++ErrCountLowPre;
6540 0 : ShowWarningError(m_state,
6541 : "The calculated pressure with minimum exhaust fan rate is lower than the pressure setpoint. The pressure "
6542 : "control is unable to perform.");
6543 0 : ShowContinueErrorTimeStamp(m_state,
6544 0 : format("Calculated pressure = {:.2R}[Pa], Pressure setpoint ={:.2R}", ZonePressure1, PressureSet));
6545 : } else {
6546 0 : ++ErrCountLowPre;
6547 0 : ShowRecurringWarningErrorAtEnd(m_state,
6548 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6549 : ": The AFN model continues not to perform pressure control due to lower zone pressure...",
6550 0 : ErrIndexLowPre,
6551 : ZonePressure1,
6552 : ZonePressure1);
6553 : }
6554 : }
6555 : } else {
6556 0 : ExhaustFanMassFlowRate = MaxExhaustMassFlowrate;
6557 0 : airmov();
6558 0 : ZonePressure2 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6559 0 : if (ZonePressure2 >= PressureSet) {
6560 : // The lowest pressure due to maximum flow rate is still higher than Pressure set, bypass pressure set calculation
6561 0 : if (!m_state.dataGlobal->WarmupFlag) {
6562 0 : if (ErrCountHighPre == 0) {
6563 0 : ++ErrCountHighPre;
6564 0 : ShowWarningError(m_state,
6565 : "The calculated pressure with maximum exhaust fan rate is higher than the pressure setpoint. The "
6566 : "pressure control is unable to perform.");
6567 0 : ShowContinueErrorTimeStamp(
6568 0 : m_state, format("Calculated pressure = {:.2R}[Pa], Pressure setpoint = {:.2R}", ZonePressure2, PressureSet));
6569 : } else {
6570 0 : ++ErrCountHighPre;
6571 0 : ShowRecurringWarningErrorAtEnd(
6572 : m_state,
6573 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6574 : ": The AFN model continues not to perform pressure control due to higher zone pressure...",
6575 0 : ErrIndexHighPre,
6576 : ZonePressure2,
6577 : ZonePressure2);
6578 : }
6579 : }
6580 : } else {
6581 : // if ( ZonePressure1 > PressureSet && ZonePressure2 < PressureSet ) {
6582 0 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
6583 0 : auto f = [&thisState, PressureSet](Real64 const ControllerMassFlowRate) {
6584 0 : return AFNPressureResidual(thisState, ControllerMassFlowRate, PressureSet);
6585 0 : };
6586 0 : General::SolveRoot(
6587 0 : m_state, ErrorToler, MaxIte, SolFla, ExhaustFanMassFlowRate, f, MinExhaustMassFlowrate, MaxExhaustMassFlowrate);
6588 0 : if (SolFla == -1) {
6589 0 : if (!m_state.dataGlobal->WarmupFlag) {
6590 0 : if (ErrCountVar == 0) {
6591 0 : ++ErrCountVar;
6592 0 : ShowWarningError(m_state, "Iteration limit exceeded pressure setpoint using an exhaust fan. Simulation continues.");
6593 0 : ShowContinueErrorTimeStamp(m_state, format("Exhaust fan flow rate = {:.4R}", ExhaustFanMassFlowRate));
6594 : } else {
6595 0 : ++ErrCountVar;
6596 0 : ShowRecurringWarningErrorAtEnd(m_state,
6597 0 : PressureControllerData(1).Name +
6598 : "\": Iteration limit warning exceeding pressure setpoint continues...",
6599 0 : ErrIndexVar,
6600 0 : ExhaustFanMassFlowRate,
6601 0 : ExhaustFanMassFlowRate);
6602 : }
6603 : }
6604 0 : } else if (SolFla == -2) {
6605 0 : ShowFatalError(m_state,
6606 0 : "Zone pressure control failed using an exhaust fan: no solution is reached, for " +
6607 0 : PressureControllerData(1).Name);
6608 : }
6609 : }
6610 : }
6611 : } else { // PressureCtrlRelief - Pressure control type is Relief Flow
6612 5755 : AirLoopNum = AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).AirLoopNum;
6613 5755 : MinReliefMassFlowrate = 2.0 * VerySmallMassFlow;
6614 5755 : MaxReliefMassFlowrate = Node(PressureControllerData(1).OANodeNum).MassFlowRate;
6615 5755 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling &&
6616 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio > 0.0) {
6617 0 : MaxReliefMassFlowrate = MaxReliefMassFlowrate / m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
6618 : }
6619 5755 : ReliefMassFlowRate = MinReliefMassFlowrate;
6620 5755 : initialize_calculation();
6621 5755 : airmov();
6622 5755 : ZonePressure1 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6623 :
6624 5755 : if (ZonePressure1 <= PressureSet) {
6625 : // The highest pressure due to minimum flow rate could not reach Pressure set, bypass pressure set calculation
6626 0 : if (!m_state.dataGlobal->WarmupFlag) {
6627 0 : if (ErrCountLowPre == 0) {
6628 0 : ++ErrCountLowPre;
6629 0 : ShowWarningError(m_state,
6630 : "The calculated pressure with minimum relief air rate is lower than the pressure setpoint. The pressure "
6631 : "control is unable to perform.");
6632 0 : ShowContinueErrorTimeStamp(m_state,
6633 0 : format("Calculated pressure = {:.2R}[Pa], Pressure setpoint ={:.2R}", ZonePressure1, PressureSet));
6634 : } else {
6635 0 : ++ErrCountLowPre;
6636 0 : ShowRecurringWarningErrorAtEnd(m_state,
6637 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6638 : ": The AFN model continues not to perform pressure control due to lower zone pressure...",
6639 0 : ErrIndexLowPre,
6640 : ZonePressure1,
6641 : ZonePressure1);
6642 : }
6643 : }
6644 : } else {
6645 5755 : ReliefMassFlowRate = MaxReliefMassFlowrate;
6646 5755 : initialize_calculation();
6647 5755 : airmov();
6648 5755 : ZonePressure2 = AirflowNetworkNodeSimu(PressureControllerData(1).AFNNodeNum).PZ;
6649 5755 : if (ZonePressure2 >= PressureSet) {
6650 : // The lowest pressure due to maximum flow rate is still higher than Pressure set, bypass pressure set calculation
6651 0 : if (!m_state.dataGlobal->WarmupFlag) {
6652 0 : if (ErrCountHighPre == 0) {
6653 0 : ++ErrCountHighPre;
6654 0 : ShowWarningError(m_state,
6655 : "The calculated pressure with maximum relief air rate is higher than the pressure setpoint. The "
6656 : "pressure control is unable to perform.");
6657 0 : ShowContinueErrorTimeStamp(
6658 0 : m_state, format("Calculated pressure = {:.2R}[Pa], Pressure setpoint = {:.2R}", ZonePressure2, PressureSet));
6659 : } else {
6660 0 : ++ErrCountHighPre;
6661 0 : ShowRecurringWarningErrorAtEnd(
6662 : m_state,
6663 0 : AirflowNetworkNodeData(PressureControllerData(1).AFNNodeNum).Name +
6664 : ": The AFN model continues not to perform pressure control due to higher zone pressure...",
6665 0 : ErrIndexHighPre,
6666 : ZonePressure2,
6667 : ZonePressure2);
6668 : }
6669 : }
6670 : } else {
6671 : // if ( ZonePressure1 > PressureSet && ZonePressure2 < PressureSet ) {
6672 5755 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
6673 30352 : auto f = [&thisState, PressureSet](Real64 const ControllerMassFlowRate) {
6674 30352 : return AFNPressureResidual(thisState, ControllerMassFlowRate, PressureSet);
6675 5755 : };
6676 5755 : General::SolveRoot(m_state, ErrorToler, MaxIte, SolFla, ReliefMassFlowRate, f, MinReliefMassFlowrate, MaxReliefMassFlowrate);
6677 5755 : if (SolFla == -1) {
6678 0 : if (!m_state.dataGlobal->WarmupFlag) {
6679 0 : if (ErrCountVar == 0) {
6680 0 : ++ErrCountVar;
6681 0 : ShowWarningError(m_state, "Iteration limit exceeded pressure setpoint using relief air. Simulation continues.");
6682 0 : ShowContinueErrorTimeStamp(m_state, format("Relief air flow rate = {:.4R}", ReliefMassFlowRate));
6683 : } else {
6684 0 : ++ErrCountVar;
6685 0 : ShowRecurringWarningErrorAtEnd(m_state,
6686 0 : PressureControllerData(1).Name +
6687 : "\": Iteration limit warning exceeding pressure setpoint continues...",
6688 0 : ErrIndexVar,
6689 0 : ReliefMassFlowRate,
6690 0 : ReliefMassFlowRate);
6691 : }
6692 : }
6693 5755 : } else if (SolFla == -2) {
6694 0 : ShowFatalError(
6695 0 : m_state, "Zone pressure control failed using relief air: no solution is reached, for " + PressureControllerData(1).Name);
6696 : }
6697 : }
6698 : }
6699 : }
6700 541114 : }
6701 :
6702 30352 : Real64 AFNPressureResidual(EnergyPlusData &state,
6703 : Real64 const ControllerMassFlowRate, // Pressure setpoint
6704 : Real64 PressureSet)
6705 : {
6706 : // FUNCTION INFORMATION:
6707 : // AUTHOR Lixing Gu
6708 : // DATE WRITTEN April 2016
6709 : // MODIFIED NA
6710 : // RE-ENGINEERED NA
6711 :
6712 : // PURPOSE OF THIS FUNCTION:
6713 : // Calculates residual function ((ZonePressure - PressureSet)/PressureSet)
6714 :
6715 : // METHODOLOGY EMPLOYED:
6716 : // Calls AIRMOV to get the pressure in the controlled zone and calculates the residual as defined above
6717 :
6718 : // Return value
6719 : Real64 AFNPressureResidual;
6720 :
6721 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
6722 : Real64 ZonePressure;
6723 :
6724 30352 : if (state.afn->PressureSetFlag == PressureCtrlExhaust) {
6725 0 : state.afn->ExhaustFanMassFlowRate = ControllerMassFlowRate;
6726 : }
6727 :
6728 30352 : if (state.afn->PressureSetFlag == PressureCtrlRelief) {
6729 30352 : state.afn->ReliefMassFlowRate = ControllerMassFlowRate;
6730 : }
6731 30352 : auto &solver = state.afn;
6732 30352 : solver->initialize_calculation();
6733 30352 : solver->airmov();
6734 :
6735 30352 : ZonePressure = state.afn->AirflowNetworkNodeSimu(state.afn->PressureControllerData(1).AFNNodeNum).PZ;
6736 :
6737 30352 : if (PressureSet != 0.0) {
6738 30352 : AFNPressureResidual = (ZonePressure - PressureSet) / PressureSet;
6739 : } else {
6740 0 : AFNPressureResidual = (ZonePressure - PressureSet);
6741 : }
6742 30352 : return AFNPressureResidual;
6743 : }
6744 :
6745 46 : static int makeTable(EnergyPlusData &state, const std::string &name, const int gridIndex, const std::vector<Real64> &y)
6746 : {
6747 : // Add a new table and performance curve
6748 46 : std::string contextString = "CalcWindPressureCoeffs: Creating table \"" + name + "\"";
6749 46 : std::pair<EnergyPlusData *, std::string> callbackPair{&state, contextString};
6750 46 : state.dataCurveManager->btwxtManager.setLoggingContext(&callbackPair);
6751 :
6752 46 : int CurveNum = static_cast<int>(state.dataCurveManager->PerfCurve.size()) + 1;
6753 46 : state.dataCurveManager->PerfCurve.push_back(new Curve::Curve());
6754 :
6755 46 : state.dataCurveManager->PerfCurve(CurveNum)->Name = name;
6756 46 : state.dataCurveManager->PerfCurve(CurveNum)->numDims = 1;
6757 :
6758 46 : state.dataCurveManager->PerfCurve(CurveNum)->interpolationType = Curve::InterpType::BtwxtMethod;
6759 :
6760 46 : state.dataCurveManager->PerfCurve(CurveNum)->inputLimits[0].min = 0.0;
6761 46 : state.dataCurveManager->PerfCurve(CurveNum)->inputLimits[0].minPresent = true;
6762 46 : state.dataCurveManager->PerfCurve(CurveNum)->inputLimits[0].max = 360.0;
6763 46 : state.dataCurveManager->PerfCurve(CurveNum)->inputLimits[0].maxPresent = true;
6764 :
6765 46 : state.dataCurveManager->PerfCurve(CurveNum)->TableIndex = gridIndex;
6766 46 : state.dataCurveManager->PerfCurve(CurveNum)->GridValueIndex = state.dataCurveManager->btwxtManager.addOutputValues(gridIndex, y);
6767 :
6768 46 : state.dataCurveManager->NumCurves += 1;
6769 46 : return CurveNum;
6770 46 : }
6771 :
6772 8 : void Solver::calculate_Cps()
6773 : {
6774 :
6775 : // SUBROUTINE INFORMATION:
6776 : // AUTHOR Fred Winkelmann
6777 : // DATE WRITTEN May 2003
6778 : // MODIFIED Revised by L. Gu, Nov. 2005, to meet requirements of AirflowNetwork
6779 : // MODIFIED Revised by L. Gu, Dec. 2008, to set the number of external nodes based on
6780 : // the number of external surfaces
6781 : // MODIFIED Revised by J. DeGraw, Feb. 2017, to use tables
6782 : // RE-ENGINEERED na
6783 :
6784 : // PURPOSE OF THIS SUBROUTINE:
6785 : // Calculates surface-average wind pressure coefficients for
6786 : // the walls and roof of a rectangular building.
6787 :
6788 : // METHODOLOGY EMPLOYED:
6789 : // Interpolates correlations between surface-average wind pressure coefficient and wind direction based on
6790 : // measurements (see REFERENCES). Applicable only to rectangular buildings.
6791 :
6792 : // REFERENCES:
6793 : // For low-rise buildings: M.V. Swami and S. Chandra, Correlations for Pressure Distribution
6794 : // on Buildings and Calculation of Natural-Ventilation Airflow. ASHRAE Transactions 94 (1): 243-266.
6795 : // For high-rise buildings: 2001 ASHRAE Fundamentals Handbook, p. 16.5, Fig. 7, "Surface Averaged
6796 : // Wall Pressure Coefficients for Tall Buildings" and p.16.6, Fig. 9, "Surface Averaged Roof Pressure
6797 : // Coefficients for Tall Buildings; from R.E. Akins, J.A. Peterka, and J.E. Cermak. 1979.
6798 : // Averaged Pressure Coefficients for Rectangular Buildings. Wind Engineering. Proc. Fifth
6799 : // International Conference 7:369-80, Fort Collins, CO. Pergamon Press, NY.
6800 :
6801 : // Using/Aliasing
6802 : using namespace DataSurfaces;
6803 :
6804 : // index 1 is wind incidence angle (0,30,60,...,300,330 deg)
6805 : // index 2 is side ratio (0.25,1.0,4.0)
6806 : // Surface-averaged wind-pressure coefficient array for walls
6807 : static constexpr std::array<std::array<Real64, 12>, 3> CPHighRiseWall = {{
6808 : {0.60, 0.54, 0.23, -0.25, -0.61, -0.55, -0.51, -0.55, -0.61, -0.25, 0.23, 0.54},
6809 : {0.60, 0.48, 0.04, -0.56, -0.56, -0.42, -0.37, -0.42, -0.56, -0.56, 0.04, 0.48},
6810 : {0.60, 0.44, -0.26, -0.70, -0.53, -0.32, -0.22, -0.32, -0.53, -0.70, -0.26, 0.44},
6811 : }};
6812 :
6813 : // index 1 is wind incidence angle (0,30,60,...,300,330 deg)
6814 : // index 2 is side ratio (0.25,0.5,1.0)
6815 : // Surface-averaged wind-pressure coefficient array for roof
6816 : static constexpr std::array<std::array<Real64, 12>, 3> CPHighRiseRoof = {{
6817 : {-0.28, -0.69, -0.72, -0.76, -0.72, -0.69, -0.28, -0.69, -0.72, -0.76, -0.72, -0.69},
6818 : {-0.47, -0.52, -0.70, -0.76, -0.70, -0.52, -0.47, -0.52, -0.70, -0.76, -0.70, -0.52},
6819 : {-0.70, -0.55, -0.55, -0.70, -0.55, -0.55, -0.70, -0.55, -0.55, -0.70, -0.55, -0.55},
6820 : }};
6821 :
6822 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6823 : int FacadeNum; // Facade number
6824 : int ExtNum; // External number
6825 : int AFNZnNum; // Zone number
6826 : Real64 SideRatio; // For vertical facades, width of facade / width of adjacent facade
6827 : Real64 SR; // SideRatio restricted to 0.25 to 4.0 range
6828 : Real64 SideRatioFac; // LOG(SideRatio)
6829 : Real64 IncRad; // IncAng in radians
6830 : int IAng; // Incidence angle index; used in interpolation
6831 : Real64 DelAng; // Incidence angle difference; used in interpolation
6832 : Real64 WtAng; // Incidence angle weighting factor; used in interpolation
6833 : int ISR; // Side ratio index, for interpolation
6834 : Real64 WtSR; // Side ratio weighting factor; used in interpolation
6835 : int SurfNum; // Surface number
6836 : int SurfDatNum; // Surface data number
6837 : Real64 SurfAng; // Azimuth angle of surface normal (degrees clockwise from North)
6838 : int FacadeNumThisSurf; // Facade number for a particular surface
6839 : Real64 AngDiff; // Angle difference between wind and surface direction (deg)
6840 : Real64 AngDiffMin; // Minimum angle difference between wind and surface direction (deg)
6841 8 : std::vector<int> curveIndex = {0, 0, 0, 0, 0};
6842 :
6843 : // Facade azimuth angle
6844 40 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
6845 32 : FacadeAng(FacadeNum) = m_state.afn->simulation_control.azimuth + (FacadeNum - 1) * 90.0;
6846 32 : if (FacadeAng(FacadeNum) >= 360.0) {
6847 1 : FacadeAng(FacadeNum) -= 360.0;
6848 : }
6849 : }
6850 :
6851 8 : FacadeAng(5) = simulation_control.azimuth + 90.0;
6852 :
6853 : // Create AirflowNetwork external node objects -- one for each of the external surfaces
6854 :
6855 8 : MultizoneExternalNodeData.allocate(AirflowNetworkNumOfExtSurfaces);
6856 8 : AirflowNetworkNumOfExtNode = AirflowNetworkNumOfExtSurfaces;
6857 8 : NumOfExtNodes = AirflowNetworkNumOfExtSurfaces;
6858 89 : for (ExtNum = 1; ExtNum <= NumOfExtNodes; ++ExtNum) {
6859 81 : MultizoneExternalNodeData(ExtNum).ExtNum = AirflowNetworkNumOfZones + ExtNum;
6860 81 : MultizoneExternalNodeData(ExtNum).Name = format("ExtNode{:4}", ExtNum);
6861 : }
6862 :
6863 : // Associate each external node with SurfaceData
6864 :
6865 8 : ExtNum = 0;
6866 106 : for (SurfDatNum = 1; SurfDatNum <= AirflowNetworkNumOfSurfaces; ++SurfDatNum) {
6867 98 : if (SurfDatNum > AirflowNetworkNumOfSurfaces - NumOfLinksIntraZone) {
6868 0 : continue;
6869 : }
6870 98 : SurfNum = MultizoneSurfaceData(SurfDatNum).SurfNum;
6871 98 : if (SurfNum == 0) {
6872 0 : continue; // Error caught earlier
6873 : }
6874 115 : if (m_state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment ||
6875 17 : (m_state.dataSurface->Surface(SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt && m_state.dataSurface->Surface(SurfNum).ExtWind)) {
6876 81 : ++ExtNum;
6877 81 : if (m_state.dataSurface->Surface(SurfNum).Tilt >= 45.0) { // "Vertical" surface
6878 73 : SurfAng = m_state.dataSurface->Surface(SurfNum).Azimuth;
6879 73 : FacadeNumThisSurf = 1;
6880 73 : AngDiffMin = std::abs(SurfAng - FacadeAng(1));
6881 73 : if (AngDiffMin > 359.0) {
6882 0 : AngDiffMin = std::abs(AngDiffMin - 360.0);
6883 : }
6884 292 : for (FacadeNum = 2; FacadeNum <= 4; ++FacadeNum) {
6885 219 : AngDiff = std::abs(SurfAng - FacadeAng(FacadeNum));
6886 219 : if (AngDiff > 359.0) {
6887 0 : AngDiff = std::abs(AngDiff - 360.0);
6888 : }
6889 219 : if (AngDiff < AngDiffMin) {
6890 104 : AngDiffMin = AngDiff;
6891 104 : FacadeNumThisSurf = FacadeNum;
6892 : }
6893 : }
6894 73 : MultizoneExternalNodeData(ExtNum).facadeNum = FacadeNumThisSurf;
6895 : } else { // "Roof" surface
6896 8 : MultizoneExternalNodeData(ExtNum).facadeNum = 5;
6897 : }
6898 81 : MultizoneSurfaceData(SurfDatNum).NodeNums[1] = MultizoneExternalNodeData(ExtNum).ExtNum;
6899 81 : MultizoneSurfaceData(SurfDatNum).ExternalNodeName = MultizoneExternalNodeData(ExtNum).Name;
6900 : }
6901 : }
6902 :
6903 : // Check if using the advanced single sided model
6904 31 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
6905 23 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
6906 3 : ++AirflowNetworkNumOfSingleSideZones;
6907 : }
6908 : }
6909 :
6910 8 : std::vector<Real64> dirs30 = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360};
6911 8 : std::vector<Btwxt::GridAxis> dirs30Axes;
6912 8 : dirs30Axes.emplace_back(dirs30,
6913 : "30 Degree Increment",
6914 0 : Btwxt::InterpolationMethod::linear,
6915 8 : Btwxt::ExtrapolationMethod::linear,
6916 8 : std::pair<double, double>{0.0, 360.0});
6917 :
6918 8 : auto dirs30GridIndex = m_state.dataCurveManager->btwxtManager.addGrid("30 Degree Increments", dirs30Axes);
6919 :
6920 8 : if (AirflowNetworkNumOfSingleSideZones == 0) { // do the standard surface average coefficient calculation
6921 : // Create the array of wind directions
6922 :
6923 : // Create a curve for each facade
6924 42 : for (FacadeNum = 1; FacadeNum <= 5; ++FacadeNum) {
6925 35 : if (FacadeNum == 1 || FacadeNum == 3 || FacadeNum == 5) {
6926 21 : SideRatio = simulation_control.aspect_ratio;
6927 : } else { // FacadeNum = 2 or 4
6928 14 : SideRatio = 1.0 / simulation_control.aspect_ratio;
6929 : }
6930 35 : if (Util::SameString(simulation_control.BldgType, "HighRise") && FacadeNum != 5) {
6931 0 : SideRatio = 1.0 / SideRatio;
6932 : }
6933 35 : SideRatioFac = std::log(SideRatio);
6934 35 : std::vector<Real64> vals(13);
6935 455 : for (int windDirNum = 1; windDirNum <= 12; ++windDirNum) {
6936 420 : Real64 WindAng = (windDirNum - 1) * 30.0;
6937 420 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
6938 420 : if (IncAng > 180.0) IncAng = 360.0 - IncAng;
6939 420 : IAng = int(IncAng / 30.0) + 1;
6940 420 : DelAng = mod(IncAng, 30.0);
6941 420 : WtAng = 1.0 - DelAng / 30.0;
6942 :
6943 : // Wind-pressure coefficients for vertical facades, low-rise building
6944 :
6945 420 : if (Util::SameString(simulation_control.BldgType, "LowRise") && FacadeNum <= 4) {
6946 336 : IncRad = IncAng * Constant::DegToRadians;
6947 336 : Real64 const cos_IncRad_over_2(std::cos(IncRad / 2.0));
6948 672 : vals[windDirNum - 1] = 0.6 * std::log(1.248 - 0.703 * std::sin(IncRad / 2.0) - 1.175 * pow_2(std::sin(IncRad)) +
6949 336 : 0.131 * pow_3(std::sin(2.0 * IncRad * SideRatioFac)) + 0.769 * cos_IncRad_over_2 +
6950 336 : 0.07 * pow_2(SideRatioFac * std::sin(IncRad / 2.0)) + 0.717 * pow_2(cos_IncRad_over_2));
6951 : }
6952 :
6953 : // Wind-pressure coefficients for vertical facades, high-rise building
6954 :
6955 84 : else if (Util::SameString(simulation_control.BldgType, "HighRise") && FacadeNum <= 4) {
6956 0 : SR = min(max(SideRatio, 0.25), 4.0);
6957 0 : if (SR >= 0.25 && SR < 1.0) {
6958 0 : ISR = 1;
6959 0 : WtSR = (1.0 - SR) / 0.75;
6960 : } else { // 1.0 <= SR <= 4.0
6961 0 : ISR = 2;
6962 0 : WtSR = (4.0 - SR) / 3.0;
6963 : }
6964 0 : vals[windDirNum - 1] = WtSR * (WtAng * CPHighRiseWall[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseWall[ISR - 1][IAng]) +
6965 0 : (1.0 - WtSR) * (WtAng * CPHighRiseWall[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseWall[ISR][IAng]);
6966 : }
6967 :
6968 : // Wind-pressure coefficients for roof (assumed same for low-rise and high-rise buildings)
6969 :
6970 168 : else if ((Util::SameString(simulation_control.BldgType, "HighRise") ||
6971 168 : Util::SameString(simulation_control.BldgType, "LowRise")) &&
6972 84 : FacadeNum == 5) {
6973 84 : SR = min(max(SideRatio, 0.25), 1.0);
6974 84 : if (SR >= 0.25 && SR < 0.5) {
6975 0 : ISR = 1;
6976 0 : WtSR = (0.5 - SR) / 0.25;
6977 : } else { // 0.5 <= SR <= 1.0
6978 84 : ISR = 2;
6979 84 : WtSR = (1.0 - SR) / 0.5;
6980 : }
6981 168 : vals[windDirNum - 1] = WtSR * (WtAng * CPHighRiseRoof[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR - 1][IAng]) +
6982 84 : (1.0 - WtSR) * (WtAng * CPHighRiseRoof[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR][IAng]);
6983 : }
6984 :
6985 : } // End of wind direction loop
6986 : // Add new table
6987 35 : vals[12] = vals[0]; // Enforce periodicity
6988 35 : curveIndex[FacadeNum - 1] = AirflowNetwork::makeTable(m_state, format("!WPCTABLE{}", FacadeNum), dirs30GridIndex, vals);
6989 35 : } // End of facade number loop
6990 :
6991 : } else { //-calculate the advanced single sided wind pressure coefficients
6992 :
6993 : // Calculate the wind pressure coefficients vs. wind direction for each external node
6994 : // The wind pressure coeffients are stored temporarily in the "valsByFacade" vector and then
6995 : // converted into a table near the end of this else. There will be at least seven profiles
6996 : // (four sides plus one roof plus two for each pair of windows). The name is thus a little
6997 : // misleading, as it isn't really the values by facade once you get beyond the first five.
6998 1 : std::vector<std::vector<Real64>> valsByFacade(5);
6999 5 : for (FacadeNum = 0; FacadeNum < 4; ++FacadeNum) {
7000 4 : valsByFacade[FacadeNum] = std::vector<Real64>(36);
7001 : }
7002 1 : FacadeNum = 4;
7003 1 : valsByFacade[FacadeNum] = std::vector<Real64>(12);
7004 5 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
7005 4 : if (FacadeNum == 1 || FacadeNum == 3) {
7006 2 : SideRatio = simulation_control.aspect_ratio;
7007 : } else { // FacadeNum = 2 or 4
7008 2 : SideRatio = 1.0 / simulation_control.aspect_ratio;
7009 : }
7010 4 : if (Util::SameString(simulation_control.BldgType, "HighRise")) {
7011 0 : SideRatio = 1.0 / SideRatio;
7012 : }
7013 4 : SideRatioFac = std::log(SideRatio);
7014 148 : for (int windDirNum = 1; windDirNum <= 36; ++windDirNum) {
7015 144 : Real64 WindAng = (windDirNum - 1) * 10.0;
7016 144 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
7017 144 : if (IncAng > 180.0) IncAng = 360.0 - IncAng;
7018 : // IAng = int(IncAng / 10.0) + 1;
7019 144 : DelAng = mod(IncAng, 10.0);
7020 144 : WtAng = 1.0 - DelAng / 10.0;
7021 : // Wind-pressure coefficients for vertical facades, low-rise building
7022 144 : IncRad = IncAng * Constant::DegToRadians;
7023 144 : valsByFacade[FacadeNum - 1][windDirNum - 1] =
7024 144 : 0.6 * std::log(1.248 - 0.703 * std::sin(IncRad / 2.0) - 1.175 * pow_2(std::sin(IncRad)) +
7025 144 : 0.131 * pow_3(std::sin(2.0 * IncRad * SideRatioFac)) + 0.769 * std::cos(IncRad / 2.0) +
7026 144 : 0.07 * pow_2(SideRatioFac * std::sin(IncRad / 2.0)) + 0.717 * pow_2(std::cos(IncRad / 2.0)));
7027 : } // End of wind direction loop
7028 : } // End of facade number loop
7029 : // Add a roof
7030 1 : FacadeNum = 5;
7031 1 : SR = min(max(SideRatio, 0.25), 1.0);
7032 1 : if (SR >= 0.25 && SR < 0.5) {
7033 0 : ISR = 1;
7034 0 : WtSR = (0.5 - SR) / 0.25;
7035 : } else { // 0.5 <= SR <= 1.0
7036 1 : ISR = 2;
7037 1 : WtSR = (1.0 - SR) / 0.5;
7038 : }
7039 13 : for (int windDirNum = 1; windDirNum <= 12; ++windDirNum) {
7040 12 : Real64 WindAng = (windDirNum - 1) * 30.0;
7041 12 : IncAng = std::abs(WindAng - FacadeAng(FacadeNum));
7042 12 : if (IncAng > 180.0) IncAng = 360.0 - IncAng;
7043 12 : IAng = int(IncAng / 30.0) + 1;
7044 12 : DelAng = mod(IncAng, 30.0);
7045 12 : WtAng = 1.0 - DelAng / 30.0;
7046 : // Wind-pressure coefficients for roof (assumed same for low-rise and high-rise buildings)
7047 12 : valsByFacade[FacadeNum - 1][windDirNum - 1] =
7048 12 : WtSR * (WtAng * CPHighRiseRoof[ISR - 1][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR - 1][IAng]) +
7049 12 : (1.0 - WtSR) * (WtAng * CPHighRiseRoof[ISR][IAng - 1] + (1.0 - WtAng) * CPHighRiseRoof[ISR][IAng]);
7050 : }
7051 1 : single_sided_Cps(valsByFacade); // run the advanced single sided subroutine if at least one zone calls for it
7052 : // Resize the curve index array
7053 1 : curveIndex.resize(valsByFacade.size());
7054 : // Create the curves
7055 :
7056 : std::vector<Real64> dirs10 = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180,
7057 1 : 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360};
7058 :
7059 1 : std::vector<Btwxt::GridAxis> dirs10Axes;
7060 1 : dirs10Axes.emplace_back(dirs10,
7061 : "10 Degree Increments",
7062 0 : Btwxt::InterpolationMethod::linear,
7063 1 : Btwxt::ExtrapolationMethod::linear,
7064 1 : std::pair<double, double>{0.0, 360.0});
7065 :
7066 1 : auto dirs10GridIndex = m_state.dataCurveManager->btwxtManager.addGrid("10 Degree Increments", dirs10Axes);
7067 :
7068 5 : for (FacadeNum = 1; FacadeNum <= 4; ++FacadeNum) {
7069 4 : valsByFacade[FacadeNum - 1].push_back(valsByFacade[FacadeNum - 1][0]); // Enforce periodicity
7070 8 : curveIndex[FacadeNum - 1] =
7071 4 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLEFACADE{}", FacadeNum), dirs10GridIndex, valsByFacade[FacadeNum - 1]);
7072 : }
7073 1 : FacadeNum = 5;
7074 1 : valsByFacade[FacadeNum - 1].push_back(valsByFacade[FacadeNum - 1][0]); // Enforce periodicity
7075 2 : curveIndex[FacadeNum - 1] =
7076 1 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLEFACADE{}", FacadeNum), dirs30GridIndex, valsByFacade[FacadeNum - 1]);
7077 7 : for (unsigned facadeNum = 6; facadeNum <= valsByFacade.size(); ++facadeNum) {
7078 6 : valsByFacade[facadeNum - 1].push_back(valsByFacade[facadeNum - 1][0]); // Enforce periodicity
7079 12 : curveIndex[facadeNum - 1] =
7080 6 : AirflowNetwork::makeTable(m_state, format("!SSWPCTABLE{}", facadeNum), dirs10GridIndex, valsByFacade[facadeNum - 1]);
7081 : }
7082 1 : }
7083 : // Connect the external nodes to the new curves
7084 89 : for (ExtNum = 1; ExtNum <= NumOfExtNodes; ++ExtNum) {
7085 81 : MultizoneExternalNodeData(ExtNum).curve = curveIndex[MultizoneExternalNodeData(ExtNum).facadeNum - 1];
7086 : }
7087 8 : }
7088 :
7089 3445503 : Real64 Solver::calculate_wind_pressure(int const curve, // Curve index, change this to pointer after curve refactor
7090 : bool const symmetricCurve, // True if the curve is symmetric (0 to 180)
7091 : bool const relativeAngle, // True if the Cp curve angle is measured relative to the surface
7092 : Real64 const azimuth, // Azimuthal angle of surface
7093 : Real64 const windSpeed, // Wind velocity
7094 : Real64 const windDir, // Wind direction
7095 : Real64 const dryBulbTemp, // Air node dry bulb temperature
7096 : Real64 const humRat // Air node humidity ratio
7097 : )
7098 : {
7099 :
7100 : // SUBROUTINE INFORMATION:
7101 : // AUTHOR Lixing Gu
7102 : // DATE WRITTEN Oct. 2005
7103 : // MODIFIED Jason DeGraw, Feb. 2017, modify to use curves
7104 : // MODIFIED Xuan Luo, Aug. 2017, modify to use local air condition
7105 : // RE-ENGINEERED na
7106 :
7107 : // PURPOSE OF THIS SUBROUTINE:
7108 : // Calculates surface wind pressure based on given CP values
7109 :
7110 : // REFERENCES:
7111 : // COMIS Fundamentals
7112 :
7113 : // Return value is wind pressure[Pa]
7114 :
7115 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
7116 3445503 : Real64 angle(windDir);
7117 : Real64 rho; // Outdoor air density
7118 : Real64 Cp; // Cp value at given wind direction
7119 :
7120 : // Calculate outdoor density
7121 3445503 : rho = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, dryBulbTemp, humRat);
7122 :
7123 : // Calculate pressure coefficient
7124 3445503 : if (relativeAngle) {
7125 0 : angle = angle - azimuth;
7126 0 : if (angle < 0.0) {
7127 0 : angle += 360.0;
7128 : }
7129 : }
7130 3445503 : if (symmetricCurve) {
7131 0 : if (angle > 180.0) {
7132 0 : angle = 360.0 - angle;
7133 : }
7134 : }
7135 3445503 : Cp = Curve::CurveValue(m_state, curve, angle);
7136 :
7137 3445503 : return Cp * 0.5 * rho * windSpeed * windSpeed;
7138 : }
7139 :
7140 7159423 : Real64 Solver::duct_inside_convection_resistance(Real64 const Tair, // Average air temperature
7141 : Real64 const mdot, // Mass flow rate
7142 : Real64 const Dh, // Hydraulic diameter
7143 : Real64 const hIn // User defined convection coefficient
7144 : )
7145 : {
7146 : // SUBROUTINE INFORMATION:
7147 : // AUTHOR Matt Mitchell, Tony Fontanini
7148 : // DATE WRITTEN Feb. 2017
7149 : // MODIFIED na
7150 : // RE-ENGINEERED na
7151 :
7152 : // PURPOSE OF THIS SUBROUTINE:
7153 : // Calculates duct inside convection coefficients
7154 :
7155 : // REFERENCES:
7156 : // ASTM C1340
7157 : // Jakob, F.E., Fischer, R.D., Flanigan, L.J. 1987. "Experimental Validation of the Duct Submodel for the SP43 Simulation Model."
7158 : // ASHRAE Trans. pp 1499-1514.
7159 :
7160 7159423 : Real64 hIn_final = 0;
7161 :
7162 7159423 : if (hIn == 0) {
7163 :
7164 3823285 : Real64 Tair_IP = Tair * 1.8 + 32.0; // Convert C to F
7165 3823285 : Real64 mdot_IP = mdot * 2.20462 * 3600; // Convert kg/s to lb/hr
7166 3823285 : Real64 Dh_IP = Dh * 3.28084; // Convert m to ft
7167 3823285 : Real64 Ai_IP = pow_2(Dh_IP) * Constant::Pi / 4;
7168 :
7169 3823285 : Real64 CorrelationCoeff = 0.00368 + 1.5e-6 * (Tair_IP - 80);
7170 3823285 : Real64 MassFlux = mdot_IP / Ai_IP; // lb/hr-ft2
7171 :
7172 3823285 : Real64 DuctInsideConvCoeff_IP = CorrelationCoeff * pow(MassFlux, 0.8) / pow(Dh_IP, 0.2); // BTU/hr-ft2-F
7173 :
7174 3823285 : hIn_final = DuctInsideConvCoeff_IP * pow_2(3.28084) * 1.8 * 1055.06 / 3600; // Convert BTU/hr-ft2-F to W/m2-K
7175 :
7176 : } else {
7177 3336138 : hIn_final = hIn;
7178 : }
7179 :
7180 7159423 : if (hIn_final == 0) {
7181 0 : return 0;
7182 : } else {
7183 7159423 : return 1 / hIn_final;
7184 : }
7185 : }
7186 :
7187 7159423 : Real64 Solver::duct_outside_convection_resistance(Real64 const Ts, // Surface temperature
7188 : Real64 const Tamb, // Free air temperature
7189 : Real64 const Wamb, // Free air humidity ratio
7190 : Real64 const Pamb, // Free air barometric pressure
7191 : Real64 const Dh, // Hydraulic diameter
7192 : int const ZoneNum, // Zone number
7193 : Real64 const hOut // User defined convection coefficient
7194 : )
7195 : {
7196 : // SUBROUTINE INFORMATION:
7197 : // AUTHOR Matt Mitchell, Tony Fontanini
7198 : // DATE WRITTEN Feb. 2017
7199 : // MODIFIED na
7200 : // RE-ENGINEERED na
7201 :
7202 : // PURPOSE OF THIS SUBROUTINE:
7203 : // Calculates duct outside convection coefficients
7204 :
7205 : // REFERENCES:
7206 : // ASTM C1340
7207 :
7208 7159423 : Real64 k = properties.thermal_conductivity(Ts);
7209 7159423 : auto &Zone(m_state.dataHeatBal->Zone);
7210 :
7211 7159423 : Real64 hOut_final = 0;
7212 :
7213 7159423 : if (hOut == 0) {
7214 :
7215 : // Free convection
7216 3823285 : Real64 Pr = properties.prandtl_number(Pamb, (Ts + Tamb) / 2, Wamb);
7217 3823285 : Real64 KinVisc = properties.kinematic_viscosity(Pamb, (Ts + Tamb) / 2, Wamb);
7218 3823285 : Real64 Beta = 2.0 / ((Tamb + Constant::Kelvin) + (Ts + Constant::Kelvin));
7219 3823285 : Real64 Gr = Constant::GravityConstant * Beta * std::abs(Ts - Tamb) * pow_3(Dh) / pow_2(KinVisc);
7220 3823285 : Real64 Ra = Gr * Pr;
7221 3823285 : Real64 Nu_free(0);
7222 :
7223 3823285 : if (Ra < 10e9) {
7224 3823285 : Nu_free = 0.53 * pow(Ra, 0.25);
7225 : } else {
7226 0 : Nu_free = 0.13 * pow(Ra, 0.333);
7227 : }
7228 :
7229 3823285 : Real64 V = 0;
7230 : // Forced convection
7231 3823285 : if (ZoneNum > 0) {
7232 2970493 : Real64 ACH = zone_OA_change_rate(ZoneNum); // Zone air change rate [1/hr]
7233 2970493 : Real64 Vol = Zone(ZoneNum).Volume; // Zone volume [m3]
7234 2970493 : V = pow(Vol, 0.333) * ACH / 3600; // Average air speed in zone [m/s]
7235 : } else {
7236 852792 : V = m_state.dataEnvrn->WindSpeed;
7237 : }
7238 :
7239 3823285 : Real64 Re = V * Dh / KinVisc; // Reynolds number
7240 3823285 : Real64 c = 0;
7241 3823285 : Real64 n = 0;
7242 :
7243 3823285 : if (Re <= 4) {
7244 364968 : c = 0.989;
7245 364968 : n = 0.33;
7246 3458317 : } else if (4 < Re && Re <= 40) {
7247 84 : c = 0.911;
7248 84 : n = 0.385;
7249 3458233 : } else if (40 < Re && Re <= 4000) {
7250 2605441 : c = 0.683;
7251 2605441 : n = 0.466;
7252 852792 : } else if (4000 < Re && Re <= 40000) {
7253 243340 : c = 0.193;
7254 243340 : n = 0.618;
7255 609452 : } else if (40000 < Re) {
7256 609452 : c = 0.0266;
7257 609452 : n = 0.805;
7258 : }
7259 :
7260 3823285 : Real64 Nu_forced = c * pow(Re, n) * pow(Pr, 0.333);
7261 :
7262 3823285 : Real64 Nu_combined = pow(pow_3(Nu_free) + pow_3(Nu_forced), 0.333);
7263 3823285 : hOut_final = Nu_combined * k / Dh;
7264 :
7265 : } else {
7266 3336138 : hOut_final = hOut;
7267 : }
7268 :
7269 7159423 : if (hOut_final == 0) {
7270 97 : return 0;
7271 : } else {
7272 7159326 : return 1 / hOut_final;
7273 : }
7274 : }
7275 :
7276 270514 : void Solver::calculate_heat_balance()
7277 : {
7278 : // SUBROUTINE INFORMATION:
7279 : // AUTHOR Lixing Gu
7280 : // DATE WRITTEN Oct. 2005
7281 : // MODIFIED na
7282 : // RE-ENGINEERED Revised based on Subroutine CalcADSHeatBalance
7283 :
7284 : // PURPOSE OF THIS SUBROUTINE:
7285 : // This subroutine performs AirflowNetwork thermal simulations.
7286 :
7287 : // USE STATEMENTS:
7288 270514 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
7289 :
7290 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7291 : int i;
7292 : int LF;
7293 : int LT;
7294 : int CompNum;
7295 : int NF;
7296 : int NT;
7297 : iComponentTypeNum CompTypeNum;
7298 : int ExtNodeNum;
7299 : Real64 Ei;
7300 : Real64 DirSign;
7301 : Real64 Tamb;
7302 : Real64 Wamb;
7303 : Real64 Pamb;
7304 : Real64 CpAir;
7305 : Real64 TZON;
7306 : Real64 load;
7307 : int ZoneNum;
7308 :
7309 270514 : auto &Node(m_state.dataLoopNodes->Node);
7310 :
7311 270514 : MA = 0.0;
7312 270514 : MV = 0.0;
7313 :
7314 10315184 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
7315 10044670 : CompNum = AirflowNetworkLinkageData(i).CompNum;
7316 10044670 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
7317 10044670 : std::string CompName = AirflowNetworkCompData(CompNum).EPlusName;
7318 10044670 : CpAir = PsyCpAirFnW((AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i).NodeNums[0]).WZ +
7319 10044670 : AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i).NodeNums[1]).WZ) /
7320 : 2.0);
7321 : // Calculate duct conduction loss
7322 10044670 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct element only
7323 4446679 : int TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7324 4446679 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7325 4439923 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7326 4439923 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7327 4439923 : DirSign = 1.0;
7328 : } else { // flow direction is the opposite as input from node 2 to node 1
7329 6756 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7330 6756 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7331 6756 : DirSign = -1.0;
7332 : }
7333 : // Fatal error when return flow is opposite to the desired direction
7334 4446679 : if (AirflowNetworkLinkSimu(i).FLOW == 0.0 && AirflowNetworkLinkSimu(i).FLOW2 > 0.0) {
7335 6756 : if (LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) {
7336 0 : ShowSevereError(m_state,
7337 : "AirflowNetwork: The airflow direction is opposite to the intended direction (from node 1 to node 2) in "
7338 0 : "AirflowNetwork:Distribution:Linkage = " +
7339 0 : AirflowNetworkLinkageData(i).Name);
7340 0 : ShowContinueErrorTimeStamp(m_state, "");
7341 0 : ShowContinueError(m_state,
7342 : "The sum of the airflows entering the zone is greater than the airflows leaving the zone (e.g., wind "
7343 : "and stack effect).");
7344 0 : ShowContinueError(m_state,
7345 : "Please check wind speed or reduce values of \"Window/Door Opening Factor, or Crack Factor\" defined in "
7346 : "AirflowNetwork:MultiZone:Surface objects.");
7347 : // ShowFatalError(state, "AirflowNetwork: The previous error causes termination." );
7348 : }
7349 : }
7350 :
7351 4446679 : if (AirflowNetworkLinkageData(i).ZoneNum < 0) {
7352 0 : ExtNodeNum = AirflowNetworkLinkageData(i).NodeNums[1];
7353 0 : if (AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum > 0 && Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).IsLocalNode) {
7354 0 : Tamb = Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).OutAirDryBulb;
7355 0 : Wamb = Node(AirflowNetworkNodeData(ExtNodeNum).OutAirNodeNum).HumRat;
7356 : } else {
7357 0 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(ExtNodeNum).NodeHeight);
7358 0 : Wamb = m_state.dataEnvrn->OutHumRat;
7359 : }
7360 4446679 : } else if (AirflowNetworkLinkageData(i).ZoneNum == 0) {
7361 1611742 : Tamb = AirflowNetworkNodeSimu(LT).TZ;
7362 1611742 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7363 : } else {
7364 2834937 : Tamb = ANZT(AirflowNetworkLinkageData(i).ZoneNum);
7365 2834937 : Wamb = ANZW(AirflowNetworkLinkageData(i).ZoneNum);
7366 : }
7367 :
7368 4446679 : Pamb = m_state.dataEnvrn->OutBaroPress;
7369 :
7370 4446679 : Real64 constexpr tolerance = 0.001;
7371 4446679 : Real64 UThermal(10); // Initialize. This will get updated.
7372 4446679 : Real64 UThermal_iter = 0;
7373 4446679 : Real64 Tsurr = Tamb;
7374 4446679 : Real64 Tsurr_K = Tsurr + Constant::Kelvin;
7375 4446679 : Real64 Tin = AirflowNetworkNodeSimu(LF).TZ;
7376 4446679 : Real64 TDuctSurf = (Tamb + Tin) / 2.0;
7377 4446679 : Real64 TDuctSurf_K = TDuctSurf + Constant::Kelvin;
7378 4446679 : Real64 DuctSurfArea = DisSysCompDuctData(TypeNum).L * DisSysCompDuctData(TypeNum).hydraulicDiameter * Constant::Pi;
7379 :
7380 : // If user defined view factors not present, calculate air-to-air heat transfer
7381 4446679 : if (AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum == 0) {
7382 :
7383 : // Calculate convection coefficient if one or both not present
7384 4438402 : if (DisSysCompDuctData(TypeNum).InsideConvCoeff == 0 && DisSysCompDuctData(TypeNum).OutsideConvCoeff == 0) {
7385 4893111 : while (std::abs(UThermal - UThermal_iter) > tolerance) {
7386 3790847 : UThermal_iter = UThermal;
7387 :
7388 15163388 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin,
7389 3790847 : AirflowNetworkLinkSimu(i).FLOW,
7390 3790847 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7391 3790847 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7392 15163388 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7393 : Tamb,
7394 : Wamb,
7395 : Pamb,
7396 3790847 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7397 3790847 : AirflowNetworkLinkageData(i).ZoneNum,
7398 3790847 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7399 3790847 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7400 3790847 : Real64 RThermTotal = RThermConvIn + RThermConvOut + RThermConduct;
7401 3790847 : UThermal = pow(RThermTotal, -1);
7402 :
7403 : // Duct conduction, assuming effectiveness = 1 - exp(-NTU)
7404 3790847 : Ei = General::epexp(-UThermal * DuctSurfArea, (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7405 3790847 : Real64 QCondDuct = std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * (Tamb - Tin) * (1 - Ei);
7406 :
7407 3790847 : TDuctSurf = Tamb - QCondDuct * RThermConvOut / DuctSurfArea;
7408 : }
7409 : } else { // Air-to-air only. U and h values are all known
7410 13344552 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin,
7411 3336138 : AirflowNetworkLinkSimu(i).FLOW,
7412 3336138 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7413 3336138 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7414 13344552 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7415 : Tamb,
7416 : Wamb,
7417 : Pamb,
7418 3336138 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7419 3336138 : AirflowNetworkLinkageData(i).ZoneNum,
7420 3336138 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7421 3336138 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7422 3336138 : Real64 RThermTotal = RThermConvIn + RThermConvOut + RThermConduct;
7423 3336138 : UThermal = pow(RThermTotal, -1);
7424 : }
7425 :
7426 4438402 : Tsurr = Tamb;
7427 :
7428 : } else { // Air-to-air + radiation heat transfer
7429 :
7430 8277 : auto &VFObj(AirflowNetworkLinkageViewFactorData(AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum));
7431 8277 : VFObj.QRad = 0;
7432 8277 : VFObj.QConv = 0;
7433 :
7434 8277 : Real64 Tin_ave = Tin;
7435 8277 : Real64 hOut = 0;
7436 :
7437 40715 : while (std::abs(UThermal - UThermal_iter) > tolerance) {
7438 32438 : UThermal_iter = UThermal;
7439 :
7440 129752 : Real64 RThermConvIn = duct_inside_convection_resistance(Tin_ave,
7441 32438 : AirflowNetworkLinkSimu(i).FLOW,
7442 32438 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7443 32438 : DisSysCompDuctData(TypeNum).InsideConvCoeff);
7444 129752 : Real64 RThermConvOut = duct_outside_convection_resistance(TDuctSurf,
7445 : Tamb,
7446 : Wamb,
7447 : Pamb,
7448 32438 : DisSysCompDuctData(TypeNum).hydraulicDiameter,
7449 32438 : AirflowNetworkLinkageData(i).ZoneNum,
7450 32438 : DisSysCompDuctData(TypeNum).OutsideConvCoeff);
7451 :
7452 32438 : if (RThermConvOut > 0.0) {
7453 32437 : hOut = 1 / RThermConvOut;
7454 : }
7455 :
7456 32438 : Real64 RThermConduct = 1.0 / DisSysCompDuctData(TypeNum).UThermConduct;
7457 :
7458 32438 : Real64 hrjTj_sum = 0;
7459 32438 : Real64 hrj_sum = 0;
7460 :
7461 194628 : for (int j = 1; j <= VFObj.LinkageSurfaceData.u(); ++j) {
7462 :
7463 162190 : int ZoneSurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7464 :
7465 162190 : Real64 TSurfj = m_state.dataHeatBalSurf->SurfOutsideTempHist(1)(ZoneSurfNum);
7466 162190 : Real64 TSurfj_K = TSurfj + Constant::Kelvin;
7467 :
7468 : Real64 ZoneSurfEmissivity =
7469 162190 : m_state.dataConstruction->Construct(m_state.dataSurface->Surface(ZoneSurfNum).Construction).InsideAbsorpThermal;
7470 162190 : Real64 ZoneSurfArea = m_state.dataSurface->Surface(ZoneSurfNum).Area;
7471 :
7472 162190 : Real64 DuctEmissivity = VFObj.DuctEmittance;
7473 162190 : Real64 DuctExposureFrac = VFObj.DuctExposureFraction;
7474 162190 : Real64 DuctToZoneSurfViewFactor = VFObj.LinkageSurfaceData(j).ViewFactor;
7475 :
7476 162190 : Real64 DuctSurfResistance = (1 - DuctEmissivity) / (DuctExposureFrac * DuctSurfArea * DuctEmissivity);
7477 162190 : Real64 SpaceResistance = 1 / (DuctExposureFrac * DuctSurfArea * DuctToZoneSurfViewFactor);
7478 162190 : Real64 ZoneSurfResistance = (1 - ZoneSurfEmissivity) / (ZoneSurfArea * ZoneSurfEmissivity);
7479 :
7480 324380 : VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor =
7481 162190 : Constant::StefanBoltzmann / (DuctSurfResistance + SpaceResistance + ZoneSurfResistance);
7482 :
7483 162190 : Real64 hrj = VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor * (TDuctSurf_K + TSurfj_K) *
7484 162190 : (pow_2(TDuctSurf_K) + pow_2(TSurfj_K)) / DuctSurfArea;
7485 :
7486 162190 : hrjTj_sum += hrj * TSurfj;
7487 162190 : hrj_sum += hrj;
7488 : }
7489 :
7490 32438 : Tsurr = (hOut * Tamb + hrjTj_sum) / (hOut + hrj_sum); // Surroundings temperature [C]
7491 32438 : Tsurr_K = Tsurr + Constant::Kelvin;
7492 :
7493 32438 : Real64 RThermTotal = RThermConvIn + RThermConduct + 1 / (hOut + hrj_sum);
7494 32438 : UThermal = pow(RThermTotal, -1);
7495 :
7496 32438 : Real64 NTU = UThermal * DuctSurfArea / (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir);
7497 32438 : Tin_ave = Tsurr + (Tin - Tsurr) * (1 / NTU) * (1 - exp(-NTU));
7498 :
7499 32438 : TDuctSurf = Tin_ave - UThermal * (RThermConvIn + RThermConduct) * (Tin_ave - Tsurr);
7500 32438 : TDuctSurf_K = TDuctSurf + Constant::Kelvin;
7501 : }
7502 :
7503 49662 : for (int j = 1; j <= VFObj.LinkageSurfaceData.u(); ++j) {
7504 41385 : int ZoneSurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7505 41385 : Real64 TSurfj = m_state.dataHeatBalSurf->SurfOutsideTempHist(1)(ZoneSurfNum);
7506 41385 : Real64 TSurfj_K = TSurfj + Constant::Kelvin;
7507 41385 : VFObj.LinkageSurfaceData(j).SurfaceRadLoad = VFObj.LinkageSurfaceData(j).SurfaceResistanceFactor *
7508 41385 : (pow_4(TDuctSurf_K) - pow_4(TSurfj_K)); // Radiant load for this surface [W]
7509 41385 : int SurfNum = VFObj.LinkageSurfaceData(j).SurfaceNum;
7510 41385 : Real64 ZoneSurfaceArea = m_state.dataSurface->Surface(SurfNum).Area;
7511 82770 : m_state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) += VFObj.LinkageSurfaceData(j).SurfaceRadLoad * TimeStepSys *
7512 41385 : Constant::SecInHour /
7513 : ZoneSurfaceArea; // Energy to each surface per unit area [J/m2]
7514 41385 : VFObj.QRad += VFObj.LinkageSurfaceData(j).SurfaceRadLoad; // Total radiant load from all surfaces for this system timestep [W]
7515 : }
7516 :
7517 8277 : VFObj.QConv = hOut * DuctSurfArea * (TDuctSurf - Tamb);
7518 8277 : UThermal = (VFObj.QRad + VFObj.QConv) / (DuctSurfArea * std::abs(Tsurr - Tin));
7519 : }
7520 :
7521 4446679 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7522 6756 : Ei = General::epexp(-UThermal * DuctSurfArea, (AirflowNetworkLinkSimu(i).FLOW2 * CpAir));
7523 6756 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7524 6756 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * Ei;
7525 6756 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Tsurr * (1.0 - Ei) * CpAir;
7526 : } else {
7527 4439923 : Ei = General::epexp(-UThermal * DuctSurfArea, (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7528 4439923 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7529 4439923 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * Ei;
7530 4439923 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Tsurr * (1.0 - Ei) * CpAir;
7531 : }
7532 : }
7533 10044670 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
7534 108490 : int TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7535 108490 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7536 108490 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7537 108490 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7538 108490 : DirSign = 1.0;
7539 : } else { // flow direction is the opposite as input from node 2 to node 1
7540 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7541 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7542 0 : DirSign = -1.0;
7543 : }
7544 108490 : Ei = General::epexp(-0.001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7545 108490 : (DirSign * AirflowNetworkLinkSimu(i).FLOW * CpAir));
7546 108490 : Tamb = AirflowNetworkNodeSimu(LT).TZ;
7547 108490 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7548 0 : Ei = General::epexp(-0.001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7549 0 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir));
7550 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7551 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * Ei;
7552 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Tamb * (1.0 - Ei) * CpAir;
7553 : } else {
7554 108490 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7555 108490 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir * Ei;
7556 108490 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Tamb * (1.0 - Ei) * CpAir;
7557 : }
7558 : }
7559 10044670 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
7560 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7561 746861 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7562 745118 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7563 745118 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7564 745118 : DirSign = 1.0;
7565 : } else { // flow direction is the opposite as input from node 2 to node 1
7566 1743 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7567 1743 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7568 1743 : DirSign = -1.0;
7569 : }
7570 : }
7571 : // Calculate temp in a constant pressure drop element
7572 10044670 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
7573 77172 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7574 77172 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7575 77172 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7576 : } else { // flow direction is the opposite as input from node 2 to node 1
7577 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7578 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7579 : }
7580 77172 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7581 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7582 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7583 : } else {
7584 77172 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7585 77172 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7586 : }
7587 77172 : MV(LT) = 0.0;
7588 : }
7589 : // Calculate return leak
7590 10044670 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
7591 : // Return leak element only
7592 930819 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
7593 930819 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7594 176924 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7595 176924 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7596 176924 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7597 176924 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7598 : }
7599 930819 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
7600 930819 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7601 6003 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7602 6003 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7603 6003 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7604 6003 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * CpAir;
7605 : }
7606 930819 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
7607 930819 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7608 93 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7609 93 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7610 93 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7611 93 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7612 : }
7613 930819 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
7614 930819 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7615 236353 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7616 236353 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7617 236353 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7618 236353 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir;
7619 : }
7620 : }
7621 : // Check reheat unit or coil
7622 10044670 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(i).VAVTermDamper)) {
7623 101692 : NF = 0;
7624 101692 : NT = 0;
7625 101692 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
7626 101692 : NF = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum;
7627 : }
7628 101692 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
7629 101692 : NT = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum;
7630 : }
7631 101692 : if ((NF == 0) || (NT == 0)) {
7632 0 : ShowFatalError(m_state,
7633 0 : "Node number in the primary air loop is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " +
7634 0 : AirflowNetworkLinkageData(i).Name);
7635 : }
7636 101692 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) {
7637 101692 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7638 101692 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7639 101692 : load = Node(NT).Temp - Node(NF).Temp;
7640 : } else {
7641 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7642 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7643 0 : load = Node(NF).Temp - Node(NT).Temp;
7644 : }
7645 101692 : CpAir = PsyCpAirFnW(Node(NT).HumRat);
7646 101692 : MV(LT) += AirflowNetworkLinkSimu(i).FLOW * CpAir * load;
7647 : }
7648 10044670 : }
7649 :
7650 : // Prescribe temperature for EPlus nodes
7651 8231330 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7652 7960816 : bool found = false;
7653 7960816 : bool OANode = false;
7654 319979931 : for (int j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
7655 313240687 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7656 19423532 : CompNum = AirflowNetworkLinkageData(j).CompNum;
7657 19423532 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
7658 203384 : found = true;
7659 203384 : break;
7660 : }
7661 : // Overwrite fan outlet node
7662 19220148 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7663 281032 : found = false;
7664 281032 : break;
7665 : }
7666 : // Overwrite return connection outlet
7667 18939116 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
7668 348064 : found = true;
7669 348064 : break;
7670 : }
7671 19153116 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
7672 562064 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
7673 281032 : found = true;
7674 281032 : break;
7675 : }
7676 : }
7677 321316792 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
7678 9189617 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
7679 108060 : OANode = true;
7680 108060 : break;
7681 : }
7682 : }
7683 7960816 : if (found) continue;
7684 7128336 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
7685 6796976 : int j = AirflowNetworkNodeData(i).EPlusNodeNum;
7686 :
7687 9479299 : if (j > 0 &&
7688 2682323 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
7689 1968239 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
7690 1513539 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7691 1513539 : MV(i) = Node(j).Temp * 1.0e10;
7692 : }
7693 6796976 : if (j > 0 && OANode) {
7694 108060 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7695 108060 : MV(i) = Node(j).Temp * 1.0e10;
7696 : }
7697 6796976 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7698 379755 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
7699 379755 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7700 379755 : MV(i) = ANZT(ZoneNum) * 1.0e10;
7701 : }
7702 6796976 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7703 2003980 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7704 2003980 : if (AirflowNetworkNodeData(i).OutAirNodeNum > 0) {
7705 12645 : MV(i) = Node(AirflowNetworkNodeData(i).OutAirNodeNum).OutAirDryBulb * 1.0e10;
7706 : } else {
7707 1991335 : MV(i) = OutDryBulbTempAt(m_state, AirflowNetworkNodeData(i).NodeHeight) * 1.0e10;
7708 : }
7709 : }
7710 6796976 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7711 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7712 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
7713 0 : if (m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID == i) {
7714 0 : MV(i) = m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AirTemp * 1.0e10;
7715 : }
7716 : }
7717 : }
7718 :
7719 : // Assign node value to distribution nodes with fan off
7720 5490057 : for (i = 1 + NumOfNodesMultiZone; i <= AirflowNetworkNumOfNodes; ++i) {
7721 5219543 : int j = AirflowNetworkNodeData(i).EPlusNodeNum;
7722 5219543 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
7723 3936 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7724 3936 : MV(i) = Node(j).Temp * 1.0e10;
7725 : }
7726 5219543 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
7727 4592 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7728 4592 : MV(i) = AirflowNetworkNodeSimu(i).TZlast * 1.0e10;
7729 : }
7730 : }
7731 :
7732 : // Check singularity
7733 8231330 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7734 7960816 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
7735 0 : if (i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
7736 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7737 0 : MV(i) = AirflowNetworkNodeSimu(i).TZlast * 1.0e10;
7738 : } else {
7739 0 : ShowFatalError(m_state,
7740 0 : "CalcAirflowNetworkHeatBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
7741 0 : AirflowNetworkNodeData(i).Name);
7742 : }
7743 : }
7744 : }
7745 :
7746 : // Get an inverse matrix
7747 270514 : mrxinv(AirflowNetworkNumOfNodes);
7748 :
7749 : // Calculate node temperatures
7750 8231330 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7751 7960816 : TZON = 0.0;
7752 258945116 : for (int j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
7753 250984300 : TZON += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
7754 : }
7755 7960816 : AirflowNetworkNodeSimu(i).TZ = TZON;
7756 : }
7757 270514 : }
7758 :
7759 270514 : void Solver::calculate_moisture_balance()
7760 : {
7761 : // SUBROUTINE INFORMATION:
7762 : // AUTHOR Lixing Gu
7763 : // DATE WRITTEN Oct. 2005
7764 : // MODIFIED na
7765 : // RE-ENGINEERED Revised based on Subroutine CalcADSMoistureBalance
7766 :
7767 : // PURPOSE OF THIS SUBROUTINE:
7768 : // This subroutine performs AirflowNetwork moisture simulations.
7769 :
7770 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7771 : int i;
7772 : int j;
7773 : int LF;
7774 : int LT;
7775 : int CompNum;
7776 : int NF;
7777 : int NT;
7778 : iComponentTypeNum CompTypeNum;
7779 : int TypeNum;
7780 : Real64 Ei;
7781 : Real64 DirSign;
7782 : Real64 Wamb;
7783 : Real64 WZON;
7784 : Real64 load;
7785 : int ZoneNum;
7786 :
7787 270514 : auto &Node(m_state.dataLoopNodes->Node);
7788 :
7789 270514 : MA = 0.0;
7790 270514 : MV = 0.0;
7791 10315184 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
7792 10044670 : CompNum = AirflowNetworkLinkageData(i).CompNum;
7793 10044670 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
7794 10044670 : std::string CompName = AirflowNetworkCompData(CompNum).EPlusName;
7795 : // Calculate duct moisture diffusion loss
7796 10044670 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct component only
7797 4446679 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7798 4446679 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7799 4439923 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7800 4439923 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7801 4439923 : DirSign = 1.0;
7802 : } else { // flow direction is the opposite as input from node 2 to node 1
7803 6756 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7804 6756 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7805 6756 : DirSign = -1.0;
7806 : }
7807 4446679 : Ei = General::epexp(-DisSysCompDuctData(TypeNum).UMoisture * DisSysCompDuctData(TypeNum).L *
7808 4446679 : DisSysCompDuctData(TypeNum).hydraulicDiameter * Constant::Pi,
7809 4446679 : (DirSign * AirflowNetworkLinkSimu(i).FLOW));
7810 4446679 : if (AirflowNetworkLinkageData(i).ZoneNum < 0) {
7811 0 : Wamb = m_state.dataEnvrn->OutHumRat;
7812 4446679 : } else if (AirflowNetworkLinkageData(i).ZoneNum == 0) {
7813 1611742 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7814 : } else {
7815 2834937 : Wamb = ANZW(AirflowNetworkLinkageData(i).ZoneNum);
7816 : }
7817 4446679 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7818 6756 : Ei = General::epexp(-DisSysCompDuctData(TypeNum).UMoisture * DisSysCompDuctData(TypeNum).L *
7819 6756 : DisSysCompDuctData(TypeNum).hydraulicDiameter * Constant::Pi,
7820 6756 : (AirflowNetworkLinkSimu(i).FLOW2));
7821 6756 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7822 6756 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Ei;
7823 6756 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Wamb * (1.0 - Ei);
7824 : } else {
7825 4439923 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7826 4439923 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * Ei;
7827 4439923 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Wamb * (1.0 - Ei);
7828 : }
7829 : }
7830 10044670 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
7831 108490 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7832 108490 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7833 108490 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7834 108490 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7835 108490 : DirSign = 1.0;
7836 : } else { // flow direction is the opposite as input from node 2 to node 1
7837 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7838 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7839 0 : DirSign = -1.0;
7840 : }
7841 108490 : Ei = General::epexp(-0.0001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7842 108490 : (DirSign * AirflowNetworkLinkSimu(i).FLOW));
7843 108490 : Wamb = AirflowNetworkNodeSimu(LT).WZ;
7844 108490 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7845 :
7846 : Ei =
7847 0 : General::epexp(-0.0001 * DisSysCompTermUnitData(TypeNum).L * DisSysCompTermUnitData(TypeNum).hydraulicDiameter * Constant::Pi,
7848 0 : (AirflowNetworkLinkSimu(i).FLOW2));
7849 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7850 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Ei;
7851 0 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * Wamb * (1.0 - Ei);
7852 : } else {
7853 108490 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7854 108490 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW) * Ei;
7855 108490 : MV(LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW) * Wamb * (1.0 - Ei);
7856 : }
7857 : }
7858 10044670 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
7859 746861 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
7860 746861 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7861 745118 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7862 745118 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7863 745118 : DirSign = 1.0;
7864 : } else { // flow direction is the opposite as input from node 2 to node 1
7865 1743 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7866 1743 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7867 1743 : DirSign = -1.0;
7868 : }
7869 : }
7870 : // Calculate temp in a constant pressure drop component
7871 10044670 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
7872 77172 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
7873 77172 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7874 77172 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7875 : } else { // flow direction is the opposite as input from node 2 to node 1
7876 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7877 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7878 : }
7879 77172 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum) && AirflowNetworkLinkSimu(i).FLOW <= 0.0) {
7880 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7881 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7882 : } else {
7883 77172 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7884 77172 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7885 : }
7886 77172 : MV(LT) = 0.0;
7887 : }
7888 : // Calculate return leak
7889 10044670 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
7890 : // Return leak component only
7891 930819 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
7892 930819 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7893 176924 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7894 176924 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7895 176924 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7896 176924 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7897 : }
7898 930819 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
7899 930819 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
7900 6003 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7901 6003 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7902 6003 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
7903 6003 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
7904 : }
7905 930819 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
7906 930819 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7907 93 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7908 93 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7909 93 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7910 93 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7911 : }
7912 930819 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
7913 930819 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
7914 236353 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7915 236353 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7916 236353 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7917 236353 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
7918 : }
7919 : }
7920 : // Check reheat unit
7921 10044670 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(i).VAVTermDamper)) {
7922 101692 : NF = 0;
7923 101692 : NT = 0;
7924 101692 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
7925 101692 : NF = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum;
7926 : }
7927 101692 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
7928 101692 : NT = AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum;
7929 : }
7930 101692 : if ((NF == 0) || (NT == 0)) {
7931 0 : ShowFatalError(m_state,
7932 0 : "Node number in the primary air loop is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " +
7933 0 : AirflowNetworkLinkageData(i).Name);
7934 : }
7935 101692 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) {
7936 101692 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
7937 101692 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
7938 101692 : load = Node(NT).HumRat - Node(NF).HumRat;
7939 : } else {
7940 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
7941 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
7942 0 : load = Node(NF).HumRat - Node(NT).HumRat;
7943 : }
7944 101692 : MV(LT) += AirflowNetworkLinkSimu(i).FLOW * load;
7945 : }
7946 10044670 : }
7947 :
7948 : // Prescribe temperature for EPlus nodes
7949 8231330 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
7950 7960816 : bool found = false;
7951 7960816 : bool OANode = false;
7952 319979931 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
7953 313240687 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7954 19423532 : CompNum = AirflowNetworkLinkageData(j).CompNum;
7955 19423532 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
7956 203384 : found = true;
7957 203384 : break;
7958 : }
7959 : // Overwrite fan outlet node
7960 19220148 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
7961 281032 : found = false;
7962 281032 : break;
7963 : }
7964 : // Overwrite return connection outlet
7965 18939116 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
7966 348064 : found = true;
7967 348064 : break;
7968 : }
7969 19153116 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
7970 562064 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
7971 281032 : found = true;
7972 281032 : break;
7973 : }
7974 : }
7975 321316792 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
7976 9189617 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
7977 108060 : OANode = true;
7978 108060 : break;
7979 : }
7980 : }
7981 7960816 : if (found) continue;
7982 7128336 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
7983 6796976 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
7984 9479299 : if (j > 0 &&
7985 2682323 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
7986 1968239 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
7987 1513539 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7988 1513539 : MV(i) = Node(j).HumRat * 1.0e10;
7989 : }
7990 6796976 : if (j > 0 && OANode) {
7991 108060 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7992 108060 : MV(i) = Node(j).HumRat * 1.0e10;
7993 : }
7994 6796976 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
7995 379755 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
7996 379755 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
7997 379755 : MV(i) = ANZW(ZoneNum) * 1.0e10;
7998 : }
7999 6796976 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
8000 2020253 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8001 2020253 : MV(i) = m_state.dataEnvrn->OutHumRat * 1.0e10;
8002 : }
8003 6796976 : if (AirflowNetworkNodeData(i).RAFNNodeNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8004 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8005 0 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8006 0 : if (m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).AFNNodeID == i) {
8007 0 : MV(i) = m_state.dataRoomAir->AFNZoneInfo(ZoneNum).Node(AirflowNetworkNodeData(i).RAFNNodeNum).HumRat * 1.0e10;
8008 : }
8009 : }
8010 : }
8011 :
8012 : // Assign node value to distribution nodes with fan off
8013 8231330 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8014 7960816 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8015 7960816 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
8016 3936 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8017 3936 : MV(i) = Node(j).HumRat * 1.0e10;
8018 : }
8019 7960816 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
8020 4592 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8021 4592 : MV(i) = AirflowNetworkNodeSimu(i).WZlast * 1.0e10;
8022 : }
8023 : }
8024 :
8025 : // Check singularity
8026 8231330 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8027 7960816 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-8) {
8028 0 : ShowFatalError(m_state,
8029 0 : "CalcAirflowNetworkMoisBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
8030 0 : AirflowNetworkNodeData(i).Name);
8031 : }
8032 : }
8033 :
8034 : // Get an inverse matrix
8035 270514 : mrxinv(AirflowNetworkNumOfNodes);
8036 :
8037 : // Calculate node temperatures
8038 8231330 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8039 7960816 : WZON = 0.0;
8040 258945116 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
8041 250984300 : WZON += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
8042 : }
8043 7960816 : AirflowNetworkNodeSimu(i).WZ = WZON;
8044 : }
8045 270514 : }
8046 :
8047 4158 : void Solver::calculate_CO2_balance()
8048 : {
8049 : // SUBROUTINE INFORMATION:
8050 : // AUTHOR Lixing Gu
8051 : // DATE WRITTEN June. 2010
8052 : // MODIFIED na
8053 : // RE-ENGINEERED Revised based on Subroutine CalcAirflowNetworkMoisBalance
8054 :
8055 : // PURPOSE OF THIS SUBROUTINE:
8056 : // This subroutine performs AirflowNetwork CO2 simulations.
8057 :
8058 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8059 : int i;
8060 : int j;
8061 : int LF;
8062 : int LT;
8063 : int CompNum;
8064 : iComponentTypeNum CompTypeNum;
8065 : Real64 DirSign;
8066 : Real64 COZN;
8067 : int ZoneNum;
8068 :
8069 4158 : MA = 0.0;
8070 4158 : MV = 0.0;
8071 253638 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
8072 249480 : CompNum = AirflowNetworkLinkageData(i).CompNum;
8073 249480 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
8074 249480 : std::string CompName = AirflowNetworkCompData(CompNum).EPlusName;
8075 : // Calculate duct moisture diffusion loss
8076 249480 : if (CompTypeNum == iComponentTypeNum::DWC && CompName == std::string()) { // Duct component only
8077 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8078 108108 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8079 108108 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8080 108108 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8081 108108 : DirSign = 1.0;
8082 : } else { // flow direction is the opposite as input from node 2 to node 1
8083 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8084 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8085 0 : DirSign = -1.0;
8086 : }
8087 108108 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8088 108108 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8089 : }
8090 249480 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
8091 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8092 8316 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8093 8316 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8094 8316 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8095 8316 : DirSign = 1.0;
8096 : } else { // flow direction is the opposite as input from node 2 to node 1
8097 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8098 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8099 0 : DirSign = -1.0;
8100 : }
8101 8316 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8102 8316 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8103 : }
8104 249480 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
8105 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8106 8316 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8107 8316 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8108 8316 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8109 8316 : DirSign = 1.0;
8110 : } else { // flow direction is the opposite as input from node 2 to node 1
8111 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8112 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8113 0 : DirSign = -1.0;
8114 : }
8115 : }
8116 : // Calculate temp in a constant pressure drop component
8117 249480 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
8118 4158 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8119 4158 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8120 4158 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8121 : } else { // flow direction is the opposite as input from node 2 to node 1
8122 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8123 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8124 : }
8125 4158 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8126 4158 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8127 4158 : MV(LT) = 0.0;
8128 : }
8129 : // Calculate return leak
8130 249480 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
8131 : // Return leak component only
8132 29106 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
8133 29106 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8134 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8135 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8136 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8137 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8138 : }
8139 29106 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
8140 29106 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8141 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8142 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8143 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8144 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8145 : }
8146 29106 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
8147 29106 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8148 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8149 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8150 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8151 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8152 : }
8153 29106 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
8154 29106 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8155 12474 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8156 12474 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8157 12474 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8158 12474 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8159 : }
8160 : }
8161 249480 : }
8162 :
8163 : // Prescribe temperature for EPlus nodes
8164 158004 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8165 153846 : bool found = false;
8166 153846 : bool OANode = false;
8167 8615376 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
8168 8498952 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8169 478170 : CompNum = AirflowNetworkLinkageData(j).CompNum;
8170 478170 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
8171 16632 : found = true;
8172 16632 : break;
8173 : }
8174 : // Overwrite fan outlet node
8175 461538 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8176 4158 : found = false;
8177 4158 : break;
8178 : }
8179 : // Overwrite return connection outlet
8180 457380 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
8181 8316 : found = true;
8182 8316 : break;
8183 : }
8184 457380 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
8185 8316 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
8186 4158 : found = true;
8187 4158 : break;
8188 : }
8189 : }
8190 8694378 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
8191 228690 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
8192 4158 : OANode = true;
8193 4158 : break;
8194 : }
8195 : }
8196 153846 : if (found) continue;
8197 124740 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
8198 120582 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8199 170478 : if (j > 0 &&
8200 49896 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
8201 33264 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
8202 24948 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8203 24948 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8204 : }
8205 120582 : if (j > 0 && OANode) {
8206 4158 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8207 4158 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8208 : }
8209 120582 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8210 4158 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8211 4158 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8212 4158 : MV(i) = ANCO(ZoneNum) * 1.0e10;
8213 : }
8214 120582 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
8215 24948 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8216 24948 : MV(i) = m_state.dataContaminantBalance->OutdoorCO2 * 1.0e10;
8217 : }
8218 : }
8219 :
8220 : // Assign node value to distribution nodes with fan off
8221 158004 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8222 153846 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8223 153846 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
8224 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8225 0 : MV(i) = m_state.dataLoopNodes->Node(j).CO2 * 1.0e10;
8226 : }
8227 153846 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
8228 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8229 0 : MV(i) = AirflowNetworkNodeSimu(i).CO2Zlast * 1.0e10;
8230 : }
8231 : }
8232 :
8233 : // Check singularity
8234 158004 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8235 153846 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
8236 0 : ShowFatalError(m_state,
8237 0 : "CalcAirflowNetworkCO2Balance: A diagonal entity is zero in AirflowNetwork matrix at node " +
8238 0 : AirflowNetworkNodeData(i).Name);
8239 : }
8240 : }
8241 :
8242 : // Get an inverse matrix
8243 4158 : mrxinv(AirflowNetworkNumOfNodes);
8244 :
8245 : // Calculate node temperatures
8246 158004 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8247 153846 : COZN = 0.0;
8248 5846148 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
8249 5692302 : COZN += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
8250 : }
8251 153846 : AirflowNetworkNodeSimu(i).CO2Z = COZN;
8252 : }
8253 4158 : }
8254 :
8255 4075 : void Solver::calculate_GC_balance()
8256 : {
8257 : // SUBROUTINE INFORMATION:
8258 : // AUTHOR Lixing Gu
8259 : // DATE WRITTEN Jan. 2012
8260 : // MODIFIED na
8261 : // RE-ENGINEERED Revised based on Subroutine CalcAirflowNetworkCO2Balance
8262 :
8263 : // PURPOSE OF THIS SUBROUTINE:
8264 : // This subroutine performs AirflowNetwork generic contaminant simulations.
8265 :
8266 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8267 : int i;
8268 : int j;
8269 : int LF;
8270 : int LT;
8271 : int CompNum;
8272 : iComponentTypeNum CompTypeNum;
8273 : Real64 DirSign;
8274 : Real64 COZN;
8275 : int ZoneNum;
8276 :
8277 4075 : MA = 0.0;
8278 4075 : MV = 0.0;
8279 240425 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
8280 236350 : CompNum = AirflowNetworkLinkageData(i).CompNum;
8281 236350 : CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
8282 236350 : std::string_view CompName = AirflowNetworkCompData(CompNum).EPlusName;
8283 : // Calculate duct moisture diffusion loss
8284 236350 : if (CompTypeNum == iComponentTypeNum::DWC && CompName.empty()) { // Duct component only
8285 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8286 105950 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8287 105950 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8288 105950 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8289 105950 : DirSign = 1.0;
8290 : } else { // flow direction is the opposite as input from node 2 to node 1
8291 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8292 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8293 0 : DirSign = -1.0;
8294 : }
8295 105950 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8296 105950 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8297 : }
8298 236350 : if (CompTypeNum == iComponentTypeNum::TMU) { // Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
8299 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8300 8150 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8301 8150 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8302 8150 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8303 8150 : DirSign = 1.0;
8304 : } else { // flow direction is the opposite as input from node 2 to node 1
8305 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8306 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8307 0 : DirSign = -1.0;
8308 : }
8309 8150 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8310 8150 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8311 : }
8312 236350 : if (CompTypeNum == iComponentTypeNum::COI) { // heating or cooling coil
8313 : // TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
8314 8150 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8315 8150 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8316 8150 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8317 8150 : DirSign = 1.0;
8318 : } else { // flow direction is the opposite as input from node 2 to node 1
8319 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8320 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8321 0 : DirSign = -1.0;
8322 : }
8323 : }
8324 : // Calculate temp in a constant pressure drop component
8325 236350 : if (CompTypeNum == iComponentTypeNum::CPD && CompName == std::string()) { // constant pressure element only
8326 4075 : if (AirflowNetworkLinkSimu(i).FLOW > 0.0) { // flow direction is the same as input from node 1 to node 2
8327 4075 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8328 4075 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8329 : } else { // flow direction is the opposite as input from node 2 to node 1
8330 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8331 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8332 : }
8333 4075 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8334 4075 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8335 4075 : MV(LT) = 0.0;
8336 : }
8337 : // Calculate return leak
8338 236350 : if ((CompTypeNum == iComponentTypeNum::PLR || CompTypeNum == iComponentTypeNum::ELR) && CompName == std::string()) {
8339 : // Return leak component only
8340 28525 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) &&
8341 28525 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8342 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8343 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8344 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8345 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8346 : }
8347 28525 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).ExtNodeNum > 0) &&
8348 28525 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
8349 0 : LF = AirflowNetworkLinkageData(i).NodeNums[0];
8350 0 : LT = AirflowNetworkLinkageData(i).NodeNums[1];
8351 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW);
8352 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW);
8353 : }
8354 28525 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) &&
8355 28525 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8356 0 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8357 0 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8358 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8359 0 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8360 : }
8361 28525 : if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).ExtNodeNum > 0) &&
8362 28525 : (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum == 0) && (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
8363 12225 : LF = AirflowNetworkLinkageData(i).NodeNums[1];
8364 12225 : LT = AirflowNetworkLinkageData(i).NodeNums[0];
8365 12225 : MA((LT - 1) * AirflowNetworkNumOfNodes + LT) += std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8366 12225 : MA((LT - 1) * AirflowNetworkNumOfNodes + LF) = -std::abs(AirflowNetworkLinkSimu(i).FLOW2);
8367 : }
8368 : }
8369 : }
8370 :
8371 : // Prescribe temperature for EPlus nodes
8372 154850 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8373 150775 : bool found = false;
8374 150775 : bool OANode = false;
8375 8141850 : for (j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
8376 8027750 : if (AirflowNetworkLinkageData(j).NodeNums[0] == i || AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8377 452325 : CompNum = AirflowNetworkLinkageData(j).CompNum;
8378 452325 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::RHT && (!AirflowNetworkLinkageData(j).VAVTermDamper)) {
8379 16300 : found = true;
8380 16300 : break;
8381 : }
8382 : // Overwrite fan outlet node
8383 436025 : if (AirflowNetworkCompData(CompNum).EPlusTypeNum == iEPlusComponentType::FAN && AirflowNetworkLinkageData(j).NodeNums[1] == i) {
8384 4075 : found = false;
8385 4075 : break;
8386 : }
8387 : // Overwrite return connection outlet
8388 431950 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::RCN) { // Modified on 9/2/09
8389 8150 : found = true;
8390 8150 : break;
8391 : }
8392 431950 : if (AirflowNetworkLinkageData(j).ConnectionFlag == iEPlusComponentType::SCN &&
8393 8150 : AirflowNetworkLinkageData(j).NodeNums[1] == i) { // Modified on 9/2/09
8394 4075 : found = true;
8395 4075 : break;
8396 : }
8397 : }
8398 8211125 : if (AirflowNetworkLinkageData(j).NodeNums[1] == i &&
8399 215975 : AirflowNetworkNodeData(AirflowNetworkLinkageData(j).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::OAN) {
8400 4075 : OANode = true;
8401 4075 : break;
8402 : }
8403 : }
8404 150775 : if (found) continue;
8405 122250 : if (AirflowNetworkNodeData(i).EPlusZoneNum == 0 && AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::ZIN) continue;
8406 118175 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8407 167075 : if (j > 0 &&
8408 48900 : (AirflowNetworkNodeData(i).EPlusZoneNum > 0 || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::FOU ||
8409 32600 : AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::COU || AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::HXO)) {
8410 24450 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8411 24450 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8412 : }
8413 118175 : if (j > 0 && OANode) {
8414 4075 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8415 4075 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8416 : }
8417 118175 : if (AirflowNetworkNodeData(i).EPlusZoneNum > 0 && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 0.9e10) {
8418 4075 : ZoneNum = AirflowNetworkNodeData(i).EPlusZoneNum;
8419 4075 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8420 4075 : MV(i) = ANGC(ZoneNum) * 1.0e10;
8421 : }
8422 118175 : if (AirflowNetworkNodeData(i).ExtNodeNum > 0) {
8423 24450 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8424 24450 : MV(i) = m_state.dataContaminantBalance->OutdoorGC * 1.0e10;
8425 : }
8426 : }
8427 :
8428 : // Assign node value to distribution nodes with fan off
8429 154850 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8430 150775 : j = AirflowNetworkNodeData(i).EPlusNodeNum;
8431 150775 : if (j > 0 && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum) && MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e9) {
8432 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8433 0 : MV(i) = m_state.dataLoopNodes->Node(j).GenContam * 1.0e10;
8434 : }
8435 150775 : if (j == 0 && i > NumOfNodesMultiZone && !LoopOnOffFlag(AirflowNetworkNodeData(i).AirLoopNum)) {
8436 0 : MA((i - 1) * AirflowNetworkNumOfNodes + i) = 1.0e10;
8437 0 : MV(i) = AirflowNetworkNodeSimu(i).GCZlast * 1.0e10;
8438 : }
8439 : }
8440 :
8441 : // Check singularity
8442 154850 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8443 150775 : if (MA((i - 1) * AirflowNetworkNumOfNodes + i) < 1.0e-6) {
8444 0 : ShowFatalError(m_state,
8445 0 : "CalcAirflowNetworkGCBalance: A diagonal entity is zero in AirflowNetwork matrix at node " +
8446 0 : AirflowNetworkNodeData(i).Name);
8447 : }
8448 : }
8449 :
8450 : // Get an inverse matrix
8451 4075 : mrxinv(AirflowNetworkNumOfNodes);
8452 :
8453 : // Calculate node temperatures
8454 154850 : for (i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
8455 150775 : COZN = 0.0;
8456 5729450 : for (j = 1; j <= AirflowNetworkNumOfNodes; ++j) {
8457 5578675 : COZN += MA((i - 1) * AirflowNetworkNumOfNodes + j) * MV(j);
8458 : }
8459 150775 : AirflowNetworkNodeSimu(i).GCZ = COZN;
8460 : }
8461 4075 : }
8462 :
8463 549261 : void Solver::mrxinv(int const NORDER)
8464 : {
8465 :
8466 : // SUBROUTINE INFORMATION:
8467 : // AUTHOR Lixing Gu
8468 : // DATE WRITTEN Oct. 2005
8469 : // MODIFIED na
8470 : // RE-ENGINEERED Revised based on Subroutine ADSINV
8471 :
8472 : // PURPOSE OF THIS SUBROUTINE:
8473 : // This subroutine inverses a matrix
8474 :
8475 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8476 : int i;
8477 : int j;
8478 : int K;
8479 : int M;
8480 : Real64 R1;
8481 : Real64 S;
8482 :
8483 549261 : IVEC = 0;
8484 16775514 : for (i = 1; i <= NORDER; ++i) {
8485 16226253 : IVEC(i + 20) = i;
8486 : }
8487 16775514 : for (i = 1; i <= NORDER; ++i) {
8488 16226253 : R1 = 0.0;
8489 16226253 : M = i;
8490 280959168 : for (j = i; j <= NORDER; ++j) {
8491 264732915 : if (std::abs(R1) < std::abs(MA((i - 1) * NORDER + j))) {
8492 16231836 : M = j;
8493 16231836 : R1 = MA((i - 1) * NORDER + j);
8494 : }
8495 : }
8496 16226253 : if (i != M) {
8497 5583 : K = IVEC(M + 20);
8498 5583 : IVEC(M + 20) = IVEC(i + 20);
8499 5583 : IVEC(i + 20) = K;
8500 117243 : for (j = 1; j <= NORDER; ++j) {
8501 111660 : S = MA((j - 1) * NORDER + i);
8502 111660 : MA((j - 1) * NORDER + i) = MA((j - 1) * NORDER + M);
8503 111660 : MA((j - 1) * NORDER + M) = S;
8504 : }
8505 : }
8506 16226253 : MA((i - 1) * NORDER + i) = 1.0;
8507 529465830 : for (j = 1; j <= NORDER; ++j) {
8508 513239577 : MA((i - 1) * NORDER + j) /= R1;
8509 : }
8510 529465830 : for (j = 1; j <= NORDER; ++j) {
8511 513239577 : if (i == j) continue;
8512 497013324 : R1 = MA((j - 1) * NORDER + i);
8513 497013324 : if (std::abs(R1) <= 1.0E-20) continue;
8514 20777029 : MA((j - 1) * NORDER + i) = 0.0;
8515 714365373 : for (K = 1; K <= NORDER; ++K) {
8516 693588344 : MA((j - 1) * NORDER + K) -= R1 * MA((i - 1) * NORDER + K);
8517 : }
8518 : }
8519 : }
8520 16775514 : for (i = 1; i <= NORDER; ++i) {
8521 16226253 : if (IVEC(i + 20) == i) continue;
8522 5583 : M = i;
8523 66996 : while (NORDER > M) {
8524 66996 : ++M;
8525 66996 : if (IVEC(M + 20) == i) break;
8526 : }
8527 5583 : IVEC(M + 20) = IVEC(i + 20);
8528 117243 : for (j = 1; j <= NORDER; ++j) {
8529 111660 : R1 = MA((i - 1) * NORDER + j);
8530 111660 : MA((i - 1) * NORDER + j) = MA((M - 1) * NORDER + j);
8531 111660 : MA((M - 1) * NORDER + j) = R1;
8532 : }
8533 5583 : IVEC(i + 20) = i;
8534 : }
8535 549261 : }
8536 :
8537 13265 : void Solver::report()
8538 : {
8539 :
8540 : // SUBROUTINE INFORMATION:
8541 : // AUTHOR Lixing Gu
8542 : // DATE WRITTEN 2/1/04
8543 : // MODIFIED na
8544 : // RE-ENGINEERED na
8545 :
8546 : // PURPOSE OF THIS SUBROUTINE:
8547 : // This subroutine reports outputs of air distribution systems
8548 :
8549 : // Using/Aliasing
8550 13265 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
8551 13265 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
8552 :
8553 13265 : auto &Zone(m_state.dataHeatBal->Zone);
8554 :
8555 : // SUBROUTINE PARAMETER DEFINITIONS:
8556 13265 : constexpr Real64 Lam(2.5e6); // Heat of vaporization (J/kg)
8557 :
8558 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8559 : int i;
8560 : int n;
8561 : int M;
8562 : int ZN1;
8563 : int ZN2;
8564 : Real64 AirDensity;
8565 : Real64 CpAir;
8566 : Real64 Tamb;
8567 : Real64 hg; // latent heat of vaporization
8568 : Real64 ReportingConstant;
8569 : Real64 ReportingFraction;
8570 : int AirLoopNum;
8571 : int FanNum;
8572 : Real64 RepOnOffFanRunTimeFraction;
8573 :
8574 13265 : if (simulation_control.type == ControlType::NoMultizoneOrDistribution) return;
8575 :
8576 13265 : if (!onetime) {
8577 35 : onceZoneFlag.dimension(m_state.dataGlobal->NumOfZones, false);
8578 35 : onceSurfFlag.dimension(AirflowNetworkNumOfLinks, false);
8579 35 : onetime = true;
8580 : }
8581 13265 : ReportingConstant = TimeStepSys * Constant::SecInHour;
8582 :
8583 13265 : m_state.dataHeatBal->ZoneTotalExfiltrationHeatLoss = 0.0;
8584 :
8585 57602 : for (auto &e : AirflowNetworkReportData) {
8586 44337 : e.MultiZoneInfiSenGainW = 0.0;
8587 44337 : e.MultiZoneInfiSenGainJ = 0.0;
8588 44337 : e.MultiZoneInfiSenLossW = 0.0;
8589 44337 : e.MultiZoneInfiSenLossJ = 0.0;
8590 44337 : e.MultiZoneInfiLatGainW = 0.0;
8591 44337 : e.MultiZoneInfiLatGainJ = 0.0;
8592 44337 : e.MultiZoneInfiLatLossW = 0.0;
8593 44337 : e.MultiZoneInfiLatLossJ = 0.0;
8594 44337 : e.MultiZoneVentSenGainW = 0.0;
8595 44337 : e.MultiZoneVentSenGainJ = 0.0;
8596 44337 : e.MultiZoneVentSenLossW = 0.0;
8597 44337 : e.MultiZoneVentSenLossJ = 0.0;
8598 44337 : e.MultiZoneVentLatGainW = 0.0;
8599 44337 : e.MultiZoneVentLatGainJ = 0.0;
8600 44337 : e.MultiZoneVentLatLossW = 0.0;
8601 44337 : e.MultiZoneVentLatLossJ = 0.0;
8602 44337 : e.MultiZoneMixSenGainW = 0.0;
8603 44337 : e.MultiZoneMixSenGainJ = 0.0;
8604 44337 : e.MultiZoneMixSenLossW = 0.0;
8605 44337 : e.MultiZoneMixSenLossJ = 0.0;
8606 44337 : e.MultiZoneMixLatGainW = 0.0;
8607 44337 : e.MultiZoneMixLatGainJ = 0.0;
8608 44337 : e.MultiZoneMixLatLossW = 0.0;
8609 44337 : e.MultiZoneMixLatLossJ = 0.0;
8610 44337 : e.LeakSenGainW = 0.0;
8611 44337 : e.LeakSenGainJ = 0.0;
8612 44337 : e.LeakSenLossW = 0.0;
8613 44337 : e.LeakSenLossJ = 0.0;
8614 44337 : e.LeakLatGainW = 0.0;
8615 44337 : e.LeakLatGainJ = 0.0;
8616 44337 : e.LeakLatLossW = 0.0;
8617 44337 : e.LeakLatLossJ = 0.0;
8618 44337 : e.CondSenGainW = 0.0;
8619 44337 : e.CondSenGainJ = 0.0;
8620 44337 : e.CondSenLossW = 0.0;
8621 44337 : e.CondSenLossJ = 0.0;
8622 44337 : e.DiffLatGainW = 0.0;
8623 44337 : e.DiffLatGainJ = 0.0;
8624 44337 : e.DiffLatLossW = 0.0;
8625 44337 : e.DiffLatLossJ = 0.0;
8626 44337 : e.RadGainW = 0.0;
8627 44337 : e.RadGainJ = 0.0;
8628 44337 : e.RadLossW = 0.0;
8629 44337 : e.RadLossJ = 0.0;
8630 44337 : e.TotalSenGainW = 0.0;
8631 44337 : e.TotalSenGainJ = 0.0;
8632 44337 : e.TotalSenLossW = 0.0;
8633 44337 : e.TotalSenLossJ = 0.0;
8634 44337 : e.TotalLatGainW = 0.0;
8635 44337 : e.TotalLatGainJ = 0.0;
8636 44337 : e.TotalLatLossW = 0.0;
8637 44337 : e.TotalLatLossJ = 0.0;
8638 : }
8639 :
8640 : // Calculate sensible and latent loads in each zone from multizone airflows
8641 13265 : if (multizone_always_simulated ||
8642 772 : (simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation && AirflowNetworkFanActivated)) {
8643 202150 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
8644 189015 : n = AirflowNetworkLinkageData(i).NodeNums[0];
8645 189015 : M = AirflowNetworkLinkageData(i).NodeNums[1];
8646 189015 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
8647 189015 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
8648 : // Find a linkage from a zone to outdoors
8649 189015 : if (ZN1 > 0 && ZN2 == 0) {
8650 122705 : auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
8651 122705 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfLinkedOutAirNode > 0) {
8652 0 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(MultizoneSurfaceData(i).SurfNum);
8653 0 : CpAir = PsyCpAirFnW(Psychrometrics::PsyWFnTdbTwbPb(m_state,
8654 : Tamb,
8655 0 : m_state.dataSurface->SurfOutWetBulbTemp(MultizoneSurfaceData(i).SurfNum),
8656 0 : m_state.dataEnvrn->OutBaroPress));
8657 : } else {
8658 122705 : Tamb = Zone(ZN1).OutDryBulbTemp;
8659 122705 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
8660 : }
8661 122705 : hg = Psychrometrics::PsyHgAirFnWTdb(zn1HB.airHumRat, zn1HB.MAT);
8662 :
8663 169631 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
8664 46926 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
8665 94897 : if (Tamb > zn1HB.MAT) {
8666 20056 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT));
8667 20056 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainJ +=
8668 20056 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant;
8669 : } else {
8670 74841 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb));
8671 74841 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossJ +=
8672 74841 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant;
8673 : }
8674 94897 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
8675 97302 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainW +=
8676 48651 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg;
8677 48651 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainJ +=
8678 48651 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8679 : } else {
8680 92492 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossW +=
8681 46246 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8682 46246 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossJ +=
8683 46246 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8684 : }
8685 : } else {
8686 27808 : if (Tamb > zn1HB.MAT) {
8687 6448 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT));
8688 6448 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainJ +=
8689 6448 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant;
8690 : } else {
8691 21360 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb));
8692 21360 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossJ +=
8693 21360 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant;
8694 : }
8695 27808 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
8696 26640 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainW +=
8697 13320 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg;
8698 13320 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainJ +=
8699 13320 : (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8700 : } else {
8701 28976 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossW +=
8702 14488 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8703 14488 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossJ +=
8704 14488 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8705 : }
8706 : }
8707 : }
8708 189015 : if (ZN1 == 0 && ZN2 > 0) {
8709 0 : auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
8710 0 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfLinkedOutAirNode > 0) {
8711 0 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(MultizoneSurfaceData(i).SurfNum);
8712 0 : CpAir = PsyCpAirFnW(Psychrometrics::PsyWFnTdbTwbPb(m_state,
8713 : Tamb,
8714 0 : m_state.dataSurface->SurfOutWetBulbTemp(MultizoneSurfaceData(i).SurfNum),
8715 0 : m_state.dataEnvrn->OutBaroPress));
8716 : } else {
8717 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
8718 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
8719 : }
8720 0 : hg = Psychrometrics::PsyHgAirFnWTdb(zn2HB.airHumRat, zn2HB.MAT);
8721 :
8722 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
8723 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
8724 0 : if (Tamb > zn2HB.MAT) {
8725 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT));
8726 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainJ +=
8727 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant;
8728 : } else {
8729 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb));
8730 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossJ +=
8731 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant;
8732 : }
8733 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
8734 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainW +=
8735 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg;
8736 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainJ +=
8737 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8738 : } else {
8739 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossW +=
8740 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8741 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossJ +=
8742 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8743 : }
8744 : } else {
8745 0 : if (Tamb > zn2HB.MAT) {
8746 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT));
8747 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainJ +=
8748 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant;
8749 : } else {
8750 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb));
8751 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossJ +=
8752 0 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant;
8753 : }
8754 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
8755 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainW +=
8756 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg;
8757 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainJ +=
8758 0 : (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8759 : } else {
8760 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossW +=
8761 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg;
8762 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossJ +=
8763 0 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant;
8764 : }
8765 : }
8766 : }
8767 :
8768 189015 : if (ZN1 > 0 && ZN2 > 0) {
8769 66310 : auto const &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
8770 66310 : auto const &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
8771 66310 : CpAir = PsyCpAirFnW((zn1HB.airHumRat + zn2HB.airHumRat) / 2.0);
8772 66310 : hg = Psychrometrics::PsyHgAirFnWTdb((zn1HB.airHumRat + zn2HB.airHumRat) / 2.0, (zn1HB.MAT + zn2HB.MAT) / 2.0);
8773 66310 : if (zn1HB.MAT > zn2HB.MAT) {
8774 29570 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn1HB.MAT - zn2HB.MAT));
8775 29570 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainJ +=
8776 29570 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant;
8777 : } else {
8778 36740 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - zn1HB.MAT));
8779 36740 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossJ +=
8780 36740 : (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant;
8781 : }
8782 66310 : if (zn1HB.airHumRat > zn2HB.airHumRat) {
8783 60106 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainW +=
8784 30053 : (AirflowNetworkLinkSimu(i).FLOW * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg;
8785 30053 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainJ +=
8786 30053 : (AirflowNetworkLinkSimu(i).FLOW * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8787 : } else {
8788 72514 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossW +=
8789 36257 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg;
8790 36257 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossJ +=
8791 36257 : (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8792 : }
8793 66310 : if (zn2HB.MAT > zn1HB.MAT) {
8794 34248 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn2HB.MAT - zn1HB.MAT));
8795 34248 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainJ +=
8796 34248 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant;
8797 : } else {
8798 32062 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - zn2HB.MAT));
8799 32062 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossJ +=
8800 32062 : (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant;
8801 : }
8802 66310 : if (zn2HB.airHumRat > zn1HB.airHumRat) {
8803 65980 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainW +=
8804 32990 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg;
8805 32990 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainJ +=
8806 32990 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn2HB.airHumRat - zn1HB.airHumRat)) * hg * ReportingConstant;
8807 : } else {
8808 66640 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossW +=
8809 33320 : std::abs(AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg;
8810 33320 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossJ +=
8811 33320 : (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.airHumRat - zn2HB.airHumRat)) * hg * ReportingConstant;
8812 : }
8813 : }
8814 : }
8815 : }
8816 :
8817 : // Assign data for report
8818 13265 : if (distribution_simulated) {
8819 42923 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
8820 33353 : if (exchangeData(i).LeakSen > 0.0) {
8821 4113 : AirflowNetworkReportData(i).LeakSenGainW = exchangeData(i).LeakSen;
8822 4113 : AirflowNetworkReportData(i).LeakSenGainJ = exchangeData(i).LeakSen * ReportingConstant;
8823 : } else {
8824 29240 : AirflowNetworkReportData(i).LeakSenLossW = -exchangeData(i).LeakSen;
8825 29240 : AirflowNetworkReportData(i).LeakSenLossJ = -exchangeData(i).LeakSen * ReportingConstant;
8826 : }
8827 33353 : if (exchangeData(i).LeakLat > 0.0) {
8828 2803 : AirflowNetworkReportData(i).LeakLatGainW = exchangeData(i).LeakLat * Lam;
8829 2803 : AirflowNetworkReportData(i).LeakLatGainJ = exchangeData(i).LeakLat * Lam * ReportingConstant;
8830 : } else {
8831 30550 : AirflowNetworkReportData(i).LeakLatLossW = -exchangeData(i).LeakLat * Lam;
8832 30550 : AirflowNetworkReportData(i).LeakLatLossJ = -exchangeData(i).LeakLat * Lam * ReportingConstant;
8833 : }
8834 33353 : if (exchangeData(i).CondSen > 0.0) {
8835 5877 : AirflowNetworkReportData(i).CondSenGainW = exchangeData(i).CondSen;
8836 5877 : AirflowNetworkReportData(i).CondSenGainJ = exchangeData(i).CondSen * ReportingConstant;
8837 : } else {
8838 27476 : AirflowNetworkReportData(i).CondSenLossW = -exchangeData(i).CondSen;
8839 27476 : AirflowNetworkReportData(i).CondSenLossJ = -exchangeData(i).CondSen * ReportingConstant;
8840 : }
8841 33353 : if (exchangeData(i).DiffLat > 0.0) {
8842 5887 : AirflowNetworkReportData(i).DiffLatGainW = exchangeData(i).DiffLat * Lam;
8843 5887 : AirflowNetworkReportData(i).DiffLatGainJ = exchangeData(i).DiffLat * Lam * ReportingConstant;
8844 : } else {
8845 27466 : AirflowNetworkReportData(i).DiffLatLossW = -exchangeData(i).DiffLat * Lam;
8846 27466 : AirflowNetworkReportData(i).DiffLatLossJ = -exchangeData(i).DiffLat * Lam * ReportingConstant;
8847 : }
8848 33353 : if (exchangeData(i).RadGain < 0.0) {
8849 235 : AirflowNetworkReportData(i).RadGainW = -exchangeData(i).RadGain;
8850 235 : AirflowNetworkReportData(i).RadGainJ = -exchangeData(i).RadGain * ReportingConstant;
8851 : } else {
8852 33118 : AirflowNetworkReportData(i).RadLossW = exchangeData(i).RadGain;
8853 33118 : AirflowNetworkReportData(i).RadLossJ = exchangeData(i).RadGain * ReportingConstant;
8854 : }
8855 33353 : if (exchangeData(i).TotalSen > 0.0) {
8856 5861 : AirflowNetworkReportData(i).TotalSenGainW = exchangeData(i).TotalSen;
8857 5861 : AirflowNetworkReportData(i).TotalSenGainJ = exchangeData(i).TotalSen * ReportingConstant;
8858 : } else {
8859 27492 : AirflowNetworkReportData(i).TotalSenLossW = -exchangeData(i).TotalSen;
8860 27492 : AirflowNetworkReportData(i).TotalSenLossJ = -exchangeData(i).TotalSen * ReportingConstant;
8861 : }
8862 33353 : if (exchangeData(i).TotalLat > 0.0) {
8863 5443 : AirflowNetworkReportData(i).TotalLatGainW = exchangeData(i).TotalLat * Lam;
8864 5443 : AirflowNetworkReportData(i).TotalLatGainJ = exchangeData(i).TotalLat * Lam * ReportingConstant;
8865 : } else {
8866 27910 : AirflowNetworkReportData(i).TotalLatLossW = -exchangeData(i).TotalLat * Lam;
8867 27910 : AirflowNetworkReportData(i).TotalLatLossJ = -exchangeData(i).TotalLat * Lam * ReportingConstant;
8868 : }
8869 : }
8870 : }
8871 :
8872 : // Zone report
8873 :
8874 57602 : for (auto &e : AirflowNetworkZnRpt) {
8875 44337 : e.InfilVolume = 0.0;
8876 44337 : e.InfilMass = 0.0;
8877 44337 : e.InfilAirChangeRate = 0.0;
8878 44337 : e.VentilVolume = 0.0;
8879 44337 : e.VentilMass = 0.0;
8880 44337 : e.VentilAirChangeRate = 0.0;
8881 44337 : e.MixVolume = 0.0;
8882 44337 : e.MixMass = 0.0;
8883 13265 : }
8884 :
8885 23682 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
8886 10417 : if (DisSysNumOfCVFs == 0) continue;
8887 10366 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
8888 10366 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
8889 : }
8890 12036 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
8891 2068 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
8892 : // ON Cycle calculation
8893 2068 : onceZoneFlag = false;
8894 8270 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
8895 6202 : if (AirflowNetworkNodeData(i).AirLoopNum > 0 && AirflowNetworkNodeData(i).AirLoopNum != AirLoopNum) continue;
8896 5551 : if (AirflowNetworkNodeData(i).AirLoopNum == AirLoopNum) {
8897 5551 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
8898 : }
8899 5551 : if (AirflowNetworkNodeData(i).AirLoopNum == 0) {
8900 0 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
8901 : }
8902 5551 : if (AirflowNetworkNodeData(i).AirLoopNum == 0 && onceZoneFlag(i)) continue;
8903 5551 : AirflowNetworkReportData(i).MultiZoneInfiSenGainW *= RepOnOffFanRunTimeFraction;
8904 5551 : AirflowNetworkReportData(i).MultiZoneInfiSenGainJ *= RepOnOffFanRunTimeFraction;
8905 5551 : AirflowNetworkReportData(i).MultiZoneInfiSenLossW *= RepOnOffFanRunTimeFraction;
8906 5551 : AirflowNetworkReportData(i).MultiZoneInfiSenLossJ *= RepOnOffFanRunTimeFraction;
8907 5551 : AirflowNetworkReportData(i).MultiZoneInfiLatGainW *= RepOnOffFanRunTimeFraction;
8908 5551 : AirflowNetworkReportData(i).MultiZoneInfiLatGainJ *= RepOnOffFanRunTimeFraction;
8909 5551 : AirflowNetworkReportData(i).MultiZoneInfiLatLossW *= RepOnOffFanRunTimeFraction;
8910 5551 : AirflowNetworkReportData(i).MultiZoneInfiLatLossJ *= RepOnOffFanRunTimeFraction;
8911 5551 : AirflowNetworkReportData(i).MultiZoneVentSenGainW *= RepOnOffFanRunTimeFraction;
8912 5551 : AirflowNetworkReportData(i).MultiZoneVentSenGainJ *= RepOnOffFanRunTimeFraction;
8913 5551 : AirflowNetworkReportData(i).MultiZoneVentSenLossW *= RepOnOffFanRunTimeFraction;
8914 5551 : AirflowNetworkReportData(i).MultiZoneVentSenLossJ *= RepOnOffFanRunTimeFraction;
8915 5551 : AirflowNetworkReportData(i).MultiZoneVentLatGainW *= RepOnOffFanRunTimeFraction;
8916 5551 : AirflowNetworkReportData(i).MultiZoneVentLatGainJ *= RepOnOffFanRunTimeFraction;
8917 5551 : AirflowNetworkReportData(i).MultiZoneVentLatLossW *= RepOnOffFanRunTimeFraction;
8918 5551 : AirflowNetworkReportData(i).MultiZoneVentLatLossJ *= RepOnOffFanRunTimeFraction;
8919 5551 : AirflowNetworkReportData(i).MultiZoneMixSenGainW *= RepOnOffFanRunTimeFraction;
8920 5551 : AirflowNetworkReportData(i).MultiZoneMixSenGainJ *= RepOnOffFanRunTimeFraction;
8921 5551 : AirflowNetworkReportData(i).MultiZoneMixSenLossW *= RepOnOffFanRunTimeFraction;
8922 5551 : AirflowNetworkReportData(i).MultiZoneMixSenLossJ *= RepOnOffFanRunTimeFraction;
8923 5551 : AirflowNetworkReportData(i).MultiZoneMixLatGainW *= RepOnOffFanRunTimeFraction;
8924 5551 : AirflowNetworkReportData(i).MultiZoneMixLatGainJ *= RepOnOffFanRunTimeFraction;
8925 5551 : AirflowNetworkReportData(i).MultiZoneMixLatLossW *= RepOnOffFanRunTimeFraction;
8926 5551 : AirflowNetworkReportData(i).MultiZoneMixLatLossJ *= RepOnOffFanRunTimeFraction;
8927 5551 : if (AirflowNetworkNodeData(i).AirLoopNum == 0) {
8928 0 : onceZoneFlag(i) = true;
8929 : }
8930 : }
8931 : // Off Cycle addon
8932 2068 : onceSurfFlag = false;
8933 21219 : for (i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
8934 19151 : n = AirflowNetworkLinkageData(i).NodeNums[0];
8935 19151 : M = AirflowNetworkLinkageData(i).NodeNums[1];
8936 19151 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
8937 19151 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
8938 : // Find a linkage from a zone to outdoors
8939 19151 : if (ZN1 > 0 && ZN2 == 0) {
8940 12517 : auto const &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
8941 12517 : if (AirflowNetworkNodeData(n).AirLoopNum > 0 && AirflowNetworkNodeData(n).AirLoopNum != AirLoopNum) continue;
8942 10998 : if (AirflowNetworkNodeData(n).AirLoopNum == AirLoopNum) {
8943 10998 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
8944 : }
8945 10998 : if (AirflowNetworkNodeData(n).AirLoopNum == 0) {
8946 0 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
8947 : }
8948 10998 : if (AirflowNetworkNodeData(n).AirLoopNum == 0 && onceSurfFlag(i)) continue;
8949 10998 : ReportingFraction = (1.0 - RepOnOffFanRunTimeFraction);
8950 10998 : Tamb = Zone(ZN1).OutDryBulbTemp;
8951 10998 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
8952 16666 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
8953 5668 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
8954 10562 : if (Tamb > zn1HB.MAT) {
8955 6594 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainW +=
8956 3297 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * (1.0 - RepOnOffFanRunTimeFraction);
8957 3297 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainJ +=
8958 3297 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
8959 : } else {
8960 14530 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossW +=
8961 7265 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * (1.0 - RepOnOffFanRunTimeFraction);
8962 7265 : AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossJ +=
8963 7265 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
8964 : }
8965 10562 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
8966 10660 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainW +=
8967 5330 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingFraction;
8968 5330 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainJ +=
8969 5330 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingConstant *
8970 : ReportingFraction;
8971 : } else {
8972 10464 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossW +=
8973 5232 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
8974 5232 : AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossJ +=
8975 5232 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
8976 : ReportingFraction;
8977 : }
8978 : } else {
8979 436 : if (Tamb > zn1HB.MAT) {
8980 304 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainW +=
8981 152 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * (1.0 - RepOnOffFanRunTimeFraction);
8982 152 : AirflowNetworkReportData(ZN1).MultiZoneVentSenGainJ +=
8983 152 : (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
8984 : } else {
8985 568 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossW +=
8986 284 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * (1.0 - RepOnOffFanRunTimeFraction);
8987 284 : AirflowNetworkReportData(ZN1).MultiZoneVentSenLossJ +=
8988 284 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
8989 : }
8990 436 : if (m_state.dataEnvrn->OutHumRat > zn1HB.airHumRat) {
8991 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainW +=
8992 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingFraction;
8993 0 : AirflowNetworkReportData(ZN1).MultiZoneVentLatGainJ +=
8994 0 : (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.airHumRat)) * ReportingConstant *
8995 : ReportingFraction;
8996 : } else {
8997 872 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossW +=
8998 436 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
8999 436 : AirflowNetworkReportData(ZN1).MultiZoneVentLatLossJ +=
9000 436 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9001 : ReportingFraction;
9002 : }
9003 : }
9004 10998 : if (AirflowNetworkNodeData(n).AirLoopNum == 0) {
9005 0 : onceSurfFlag(i) = true;
9006 : }
9007 : }
9008 17632 : if (ZN1 == 0 && ZN2 > 0) {
9009 0 : auto const &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
9010 0 : if (AirflowNetworkNodeData(M).AirLoopNum > 0 && AirflowNetworkNodeData(M).AirLoopNum != AirLoopNum) continue;
9011 0 : if (AirflowNetworkNodeData(M).AirLoopNum == AirLoopNum) {
9012 0 : RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum);
9013 : }
9014 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0) {
9015 0 : RepOnOffFanRunTimeFraction = MaxOnOffFanRunTimeFraction;
9016 : }
9017 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0 && onceSurfFlag(i)) continue;
9018 0 : ReportingFraction = (1.0 - RepOnOffFanRunTimeFraction);
9019 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
9020 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9021 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9022 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9023 0 : if (Tamb > zn2HB.MAT) {
9024 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainW +=
9025 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingFraction;
9026 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainJ +=
9027 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9028 : } else {
9029 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossW +=
9030 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingFraction;
9031 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossJ +=
9032 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
9033 : }
9034 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
9035 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainW +=
9036 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingFraction;
9037 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainJ +=
9038 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingConstant *
9039 : ReportingFraction;
9040 : } else {
9041 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossW +=
9042 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
9043 0 : AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossJ +=
9044 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9045 : ReportingFraction;
9046 : }
9047 : } else {
9048 0 : if (Tamb > zn2HB.MAT) {
9049 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainW +=
9050 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingFraction;
9051 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenGainJ +=
9052 0 : (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9053 : } else {
9054 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossW +=
9055 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingFraction;
9056 0 : AirflowNetworkReportData(ZN2).MultiZoneVentSenLossJ +=
9057 0 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant * ReportingFraction;
9058 : }
9059 0 : if (m_state.dataEnvrn->OutHumRat > zn2HB.airHumRat) {
9060 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainW +=
9061 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingFraction;
9062 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatGainJ +=
9063 0 : (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.airHumRat)) * ReportingConstant *
9064 : ReportingFraction;
9065 : } else {
9066 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossW +=
9067 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction;
9068 0 : AirflowNetworkReportData(ZN2).MultiZoneVentLatLossJ +=
9069 0 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant *
9070 : ReportingFraction;
9071 : }
9072 : }
9073 0 : if (AirflowNetworkNodeData(M).AirLoopNum == 0) {
9074 0 : onceSurfFlag(i) = true;
9075 : }
9076 : }
9077 :
9078 17632 : if (ZN1 > 0 && ZN2 > 0) {
9079 6634 : auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1);
9080 6634 : auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2);
9081 6634 : ReportingFraction = (1.0 - MaxOnOffFanRunTimeFraction);
9082 6634 : CpAir = PsyCpAirFnW(zn1HB.airHumRat);
9083 6634 : if (zn1HB.MAT > zn2HB.MAT) {
9084 4290 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainW +=
9085 2145 : (linkReport1(i).FLOWOFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingFraction;
9086 2145 : AirflowNetworkReportData(ZN2).MultiZoneMixSenGainJ +=
9087 2145 : (linkReport1(i).FLOWOFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9088 : } else {
9089 8978 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossW +=
9090 4489 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingFraction;
9091 4489 : AirflowNetworkReportData(ZN2).MultiZoneMixSenLossJ +=
9092 4489 : (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9093 : }
9094 6634 : if (zn1HB.airHumRat > zn2HB.airHumRat) {
9095 4412 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainW +=
9096 2206 : (linkReport1(i).FLOWOFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingFraction;
9097 2206 : AirflowNetworkReportData(ZN2).MultiZoneMixLatGainJ +=
9098 2206 : (linkReport1(i).FLOWOFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingConstant * ReportingFraction;
9099 : } else {
9100 8856 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossW +=
9101 4428 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingFraction;
9102 4428 : AirflowNetworkReportData(ZN2).MultiZoneMixLatLossJ +=
9103 4428 : (linkReport1(i).FLOWOFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingConstant * ReportingFraction;
9104 : }
9105 6634 : CpAir = PsyCpAirFnW(zn2HB.airHumRat);
9106 6634 : if (zn2HB.MAT > zn1HB.MAT) {
9107 8978 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainW +=
9108 4489 : (linkReport1(i).FLOW2OFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingFraction;
9109 4489 : AirflowNetworkReportData(ZN1).MultiZoneMixSenGainJ +=
9110 4489 : (linkReport1(i).FLOW2OFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant * ReportingFraction;
9111 : } else {
9112 4290 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossW +=
9113 2145 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingFraction;
9114 2145 : AirflowNetworkReportData(ZN1).MultiZoneMixSenLossJ +=
9115 2145 : (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant * ReportingFraction;
9116 : }
9117 :
9118 6634 : if (zn2HB.airHumRat > zn1HB.airHumRat) {
9119 8856 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainW +=
9120 4428 : (linkReport1(i).FLOW2OFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingFraction;
9121 4428 : AirflowNetworkReportData(ZN1).MultiZoneMixLatGainJ +=
9122 4428 : (linkReport1(i).FLOW2OFF * (zn2HB.airHumRat - zn1HB.airHumRat)) * ReportingConstant * ReportingFraction;
9123 : } else {
9124 4412 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossW +=
9125 2206 : std::abs(linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingFraction;
9126 2206 : AirflowNetworkReportData(ZN1).MultiZoneMixLatLossJ +=
9127 2206 : (linkReport1(i).FLOW2OFF * (zn1HB.airHumRat - zn2HB.airHumRat)) * ReportingConstant * ReportingFraction;
9128 : }
9129 : }
9130 : }
9131 : }
9132 : }
9133 :
9134 13265 : if (!multizone_always_simulated) {
9135 772 : return;
9136 : }
9137 :
9138 54138 : for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) { // Start of zone loads report variable update loop ...
9139 41645 : auto &thisZoneHB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i);
9140 41645 : Tamb = Zone(i).OutDryBulbTemp;
9141 41645 : CpAir = PsyCpAirFnW(thisZoneHB.airHumRatAvg);
9142 41645 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.airHumRatAvg);
9143 :
9144 41645 : AirflowNetworkZnRpt(i).InfilMass = (exchangeData(i).SumMCp / CpAir) * ReportingConstant;
9145 41645 : AirflowNetworkZnRpt(i).InfilVolume = AirflowNetworkZnRpt(i).InfilMass / AirDensity;
9146 41645 : AirflowNetworkZnRpt(i).InfilAirChangeRate = AirflowNetworkZnRpt(i).InfilVolume / (TimeStepSys * Zone(i).Volume);
9147 41645 : AirflowNetworkZnRpt(i).VentilMass = (exchangeData(i).SumMVCp / CpAir) * ReportingConstant;
9148 41645 : AirflowNetworkZnRpt(i).VentilVolume = AirflowNetworkZnRpt(i).VentilMass / AirDensity;
9149 41645 : AirflowNetworkZnRpt(i).VentilAirChangeRate = AirflowNetworkZnRpt(i).VentilVolume / (TimeStepSys * Zone(i).Volume);
9150 41645 : AirflowNetworkZnRpt(i).MixMass = (exchangeData(i).SumMMCp / CpAir) * ReportingConstant;
9151 41645 : AirflowNetworkZnRpt(i).MixVolume = AirflowNetworkZnRpt(i).MixMass / AirDensity;
9152 : // save values for predefined report
9153 41645 : Real64 stdDensAFNInfilVolume = AirflowNetworkZnRpt(i).InfilMass / m_state.dataEnvrn->StdRhoAir;
9154 41645 : Real64 stdDensAFNNatVentVolume = AirflowNetworkZnRpt(i).VentilMass / m_state.dataEnvrn->StdRhoAir;
9155 41645 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolStdDen = stdDensAFNNatVentVolume;
9156 41645 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolTotalStdDen += stdDensAFNNatVentVolume;
9157 41645 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalStdDen += stdDensAFNInfilVolume;
9158 41645 : if (m_state.dataHeatBal->ZonePreDefRep(i).isOccupied) {
9159 3675 : m_state.dataHeatBal->ZonePreDefRep(i).AFNVentVolTotalOccStdDen += stdDensAFNNatVentVolume;
9160 3675 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalOccStdDen += stdDensAFNInfilVolume;
9161 3675 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolTotalOcc +=
9162 3675 : (AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) * Zone(i).Multiplier * Zone(i).ListMultiplier;
9163 3675 : if ((AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) <
9164 3675 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolMin) {
9165 794 : m_state.dataHeatBal->ZonePreDefRep(i).AFNInfilVolMin =
9166 794 : (AirflowNetworkZnRpt(i).InfilVolume + AirflowNetworkZnRpt(i).VentilVolume) * Zone(i).Multiplier * Zone(i).ListMultiplier;
9167 : }
9168 : }
9169 :
9170 41645 : Real64 H2OHtOfVap = Psychrometrics::PsyHgAirFnWTdb(m_state.dataEnvrn->OutHumRat, Zone(i).OutDryBulbTemp);
9171 41645 : AirflowNetworkZnRpt(i).InletMass = 0;
9172 41645 : AirflowNetworkZnRpt(i).OutletMass = 0;
9173 41645 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).IsControlled) {
9174 43702 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumInletNodes; ++j) {
9175 22756 : AirflowNetworkZnRpt(i).InletMass +=
9176 22756 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).InletNode(j)).MassFlowRate * ReportingConstant;
9177 : }
9178 28988 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumExhaustNodes; ++j) {
9179 8042 : AirflowNetworkZnRpt(i).OutletMass +=
9180 8042 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).ExhaustNode(j)).MassFlowRate * ReportingConstant;
9181 : }
9182 41892 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumReturnNodes; ++j) {
9183 20946 : AirflowNetworkZnRpt(i).OutletMass +=
9184 20946 : m_state.dataLoopNodes->Node(m_state.dataZoneEquip->ZoneEquipConfig(i).ReturnNode(j)).MassFlowRate * ReportingConstant;
9185 : }
9186 : }
9187 41645 : AirflowNetworkZnRpt(i).ExfilMass = AirflowNetworkZnRpt(i).InfilMass + AirflowNetworkZnRpt(i).VentilMass + AirflowNetworkZnRpt(i).MixMass +
9188 41645 : AirflowNetworkZnRpt(i).InletMass - AirflowNetworkZnRpt(i).OutletMass;
9189 41645 : AirflowNetworkZnRpt(i).ExfilSensiLoss = AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * (thisZoneHB.MAT - Tamb) * CpAir;
9190 83290 : AirflowNetworkZnRpt(i).ExfilLatentLoss =
9191 41645 : AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * (thisZoneHB.airHumRat - m_state.dataEnvrn->OutHumRat) * H2OHtOfVap;
9192 41645 : AirflowNetworkZnRpt(i).ExfilTotalLoss = AirflowNetworkZnRpt(i).ExfilSensiLoss + AirflowNetworkZnRpt(i).ExfilLatentLoss;
9193 :
9194 41645 : m_state.dataHeatBal->ZoneTotalExfiltrationHeatLoss += AirflowNetworkZnRpt(i).ExfilTotalLoss * ReportingConstant;
9195 : } // ... end of zone loads report variable update loop.
9196 :
9197 : // Rewrite AirflowNetwork airflow rate
9198 22138 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9199 9645 : if (DisSysNumOfCVFs == 0) continue;
9200 9594 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9201 9594 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9202 : }
9203 9196 : onceSurfFlag = false;
9204 :
9205 145821 : for (i = 1; i <= NumOfLinksMultiZone; ++i) {
9206 136625 : if (onceSurfFlag(i)) continue;
9207 136625 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9208 136625 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkLinkageData(i).NodeHeights[0]);
9209 136625 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, Tamb, m_state.dataEnvrn->OutHumRat);
9210 155776 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
9211 19151 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
9212 19151 : linkReport(i).VolFLOW = linkReport1(i).FLOW / AirDensity;
9213 19151 : linkReport(i).VolFLOW2 = linkReport1(i).FLOW2 / AirDensity;
9214 : } else {
9215 117474 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity;
9216 117474 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity;
9217 : }
9218 136625 : onceSurfFlag(i) = true;
9219 : }
9220 : }
9221 :
9222 9196 : if (AirflowNetworkNumOfLinks > NumOfLinksMultiZone) {
9223 302106 : for (i = NumOfLinksMultiZone + 1; i <= AirflowNetworkNumOfLinks; ++i) {
9224 292910 : if (onceSurfFlag(i)) continue;
9225 292910 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) {
9226 292910 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9227 292910 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9228 : AirDensity =
9229 292910 : PsyRhoAirFnPbTdbW(m_state,
9230 292910 : (AirflowNetworkNodeSimu(n).PZ + AirflowNetworkNodeSimu(M).PZ) / 2.0 + m_state.dataEnvrn->OutBaroPress,
9231 292910 : (AirflowNetworkNodeSimu(n).TZ + AirflowNetworkNodeSimu(M).TZ) / 2.0,
9232 292910 : (AirflowNetworkNodeSimu(n).WZ + AirflowNetworkNodeSimu(M).WZ) / 2.0);
9233 337293 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopOnOffFanRunTimeFraction(AirLoopNum) < 1.0 &&
9234 44383 : LoopOnOffFanRunTimeFraction(AirLoopNum) > 0.0) {
9235 44383 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity * (1.0 - LoopOnOffFanRunTimeFraction(AirLoopNum));
9236 44383 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity * (1.0 - LoopOnOffFanRunTimeFraction(AirLoopNum));
9237 44383 : onceSurfFlag(i) = true;
9238 : } else {
9239 248527 : linkReport(i).VolFLOW = linkReport(i).FLOW / AirDensity;
9240 248527 : linkReport(i).VolFLOW2 = linkReport(i).FLOW2 / AirDensity;
9241 : }
9242 : }
9243 : }
9244 : }
9245 : }
9246 : }
9247 :
9248 541114 : void Solver::update(ObjexxFCL::Optional_bool_const FirstHVACIteration) // True when solution technique on first iteration
9249 : {
9250 :
9251 : // SUBROUTINE INFORMATION:
9252 : // AUTHOR Lixing Gu
9253 : // DATE WRITTEN 12/10/05
9254 : // MODIFIED na
9255 : // RE-ENGINEERED na
9256 :
9257 : // PURPOSE OF THIS SUBROUTINE:
9258 : // This subroutine update variables used in the AirflowNetwork model.
9259 :
9260 : // Using/Aliasing
9261 541114 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
9262 : using HVAC::VerySmallMassFlow;
9263 :
9264 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9265 : int n;
9266 : int M;
9267 : int ZN1;
9268 : int ZN2;
9269 : int Node1;
9270 : int Node2;
9271 : Real64 CpAir;
9272 : Real64 Qsen;
9273 : Real64 Qlat;
9274 : Real64 AirDensity;
9275 : Real64 Tamb;
9276 : Real64 PartLoadRatio;
9277 : Real64 OnOffRatio;
9278 : Real64 NodeMass;
9279 : Real64 AFNMass;
9280 :
9281 541114 : auto &Zone(m_state.dataHeatBal->Zone);
9282 541114 : auto &Node(m_state.dataLoopNodes->Node);
9283 :
9284 2270332 : for (auto &e : exchangeData) {
9285 1729218 : e.SumMCp = 0.0;
9286 1729218 : e.SumMCpT = 0.0;
9287 1729218 : e.SumMVCp = 0.0;
9288 1729218 : e.SumMVCpT = 0.0;
9289 1729218 : e.SumMHr = 0.0;
9290 1729218 : e.SumMHrW = 0.0;
9291 1729218 : e.SumMMCp = 0.0;
9292 1729218 : e.SumMMCpT = 0.0;
9293 1729218 : e.SumMMHr = 0.0;
9294 1729218 : e.SumMMHrW = 0.0;
9295 541114 : }
9296 541114 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9297 56655 : for (auto &e : exchangeData) {
9298 45324 : e.SumMHrCO = 0.0;
9299 45324 : e.SumMMHrCO = 0.0;
9300 11331 : }
9301 : }
9302 541114 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9303 45180 : for (auto &e : exchangeData) {
9304 36144 : e.SumMHrGC = 0.0;
9305 36144 : e.SumMMHrGC = 0.0;
9306 9036 : }
9307 : }
9308 :
9309 : // Calculate sensible and latent loads in each zone from multizone airflows
9310 541114 : if (multizone_always_simulated ||
9311 19953 : (simulation_control.type == ControlType::MultizoneWithDistributionOnlyDuringFanOperation && AirflowNetworkFanActivated)) {
9312 8070006 : for (int i = 1; i <= NumOfLinksMultiZone; ++i) { // Multizone airflow energy
9313 7538059 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9314 7538059 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9315 7538059 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
9316 7538059 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
9317 7538059 : if (ZN1 > 0 && ZN2 == 0) {
9318 : // Find a linkage from outdoors to this zone
9319 5105718 : Tamb = Zone(ZN1).OutDryBulbTemp;
9320 5105718 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9321 7584505 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9322 2478787 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9323 4143735 : exchangeData(ZN1).SumMCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9324 4143735 : exchangeData(ZN1).SumMCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * Tamb;
9325 : } else {
9326 961983 : exchangeData(ZN1).SumMVCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9327 961983 : exchangeData(ZN1).SumMVCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * Tamb;
9328 : }
9329 5105718 : exchangeData(ZN1).SumMHr += AirflowNetworkLinkSimu(i).FLOW2;
9330 5105718 : exchangeData(ZN1).SumMHrW += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataEnvrn->OutHumRat;
9331 5105718 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9332 147303 : exchangeData(ZN1).SumMHrCO += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataContaminantBalance->OutdoorCO2;
9333 : }
9334 5105718 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9335 108432 : exchangeData(ZN1).SumMHrGC += AirflowNetworkLinkSimu(i).FLOW2 * m_state.dataContaminantBalance->OutdoorGC;
9336 : }
9337 : }
9338 7538059 : if (ZN1 == 0 && ZN2 > 0) {
9339 : // Find a linkage from outdoors to this zone
9340 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
9341 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9342 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR ||
9343 0 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) {
9344 0 : exchangeData(ZN2).SumMCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9345 0 : exchangeData(ZN2).SumMCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * Tamb;
9346 : } else {
9347 0 : exchangeData(ZN2).SumMVCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9348 0 : exchangeData(ZN2).SumMVCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * Tamb;
9349 : }
9350 0 : exchangeData(ZN2).SumMHr += AirflowNetworkLinkSimu(i).FLOW;
9351 0 : exchangeData(ZN2).SumMHrW += AirflowNetworkLinkSimu(i).FLOW * m_state.dataEnvrn->OutHumRat;
9352 0 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9353 0 : exchangeData(ZN2).SumMHrCO += AirflowNetworkLinkSimu(i).FLOW * m_state.dataContaminantBalance->OutdoorCO2;
9354 : }
9355 0 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9356 0 : exchangeData(ZN2).SumMHrGC += AirflowNetworkLinkSimu(i).FLOW * m_state.dataContaminantBalance->OutdoorGC;
9357 : }
9358 : }
9359 7538059 : if (ZN1 > 0 && ZN2 > 0) {
9360 : // Find a linkage from outdoors to this zone
9361 2432341 : CpAir = PsyCpAirFnW(ANZW(ZN1));
9362 2432341 : exchangeData(ZN2).SumMMCp += AirflowNetworkLinkSimu(i).FLOW * CpAir;
9363 2432341 : exchangeData(ZN2).SumMMCpT += AirflowNetworkLinkSimu(i).FLOW * CpAir * ANZT(ZN1);
9364 2432341 : exchangeData(ZN2).SumMMHr += AirflowNetworkLinkSimu(i).FLOW;
9365 2432341 : exchangeData(ZN2).SumMMHrW += AirflowNetworkLinkSimu(i).FLOW * ANZW(ZN1);
9366 2432341 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9367 90648 : exchangeData(ZN2).SumMMHrCO += AirflowNetworkLinkSimu(i).FLOW * ANCO(ZN1);
9368 : }
9369 2432341 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9370 63252 : exchangeData(ZN2).SumMMHrGC += AirflowNetworkLinkSimu(i).FLOW * ANGC(ZN1);
9371 : }
9372 2432341 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9373 2432341 : exchangeData(ZN1).SumMMCp += AirflowNetworkLinkSimu(i).FLOW2 * CpAir;
9374 2432341 : exchangeData(ZN1).SumMMCpT += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * ANZT(ZN2);
9375 2432341 : exchangeData(ZN1).SumMMHr += AirflowNetworkLinkSimu(i).FLOW2;
9376 2432341 : exchangeData(ZN1).SumMMHrW += AirflowNetworkLinkSimu(i).FLOW2 * ANZW(ZN2);
9377 2432341 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9378 90648 : exchangeData(ZN1).SumMMHrCO += AirflowNetworkLinkSimu(i).FLOW2 * ANCO(ZN2);
9379 : }
9380 2432341 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9381 63252 : exchangeData(ZN1).SumMMHrGC += AirflowNetworkLinkSimu(i).FLOW2 * ANGC(ZN2);
9382 : }
9383 : }
9384 : }
9385 : }
9386 : // End of update of multizone airflow calculations
9387 :
9388 : // Initialize these values
9389 2270332 : for (auto &e : exchangeData) {
9390 1729218 : e.LeakSen = 0.0;
9391 1729218 : e.CondSen = 0.0;
9392 1729218 : e.LeakLat = 0.0;
9393 1729218 : e.DiffLat = 0.0;
9394 1729218 : e.MultiZoneSen = 0.0;
9395 1729218 : e.MultiZoneLat = 0.0;
9396 1729218 : e.RadGain = 0.0;
9397 541114 : }
9398 :
9399 : // Rewrite AirflowNetwork airflow rate
9400 8184068 : for (int i = 1; i <= NumOfLinksMultiZone; ++i) {
9401 7642954 : Tamb = OutDryBulbTempAt(m_state, AirflowNetworkLinkageData(i).NodeHeights[0]);
9402 7642954 : AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, Tamb, m_state.dataEnvrn->OutHumRat);
9403 7642954 : AirflowNetworkLinkSimu(i).VolFLOW = AirflowNetworkLinkSimu(i).FLOW / AirDensity;
9404 7642954 : AirflowNetworkLinkSimu(i).VolFLOW2 = AirflowNetworkLinkSimu(i).FLOW2 / AirDensity;
9405 : }
9406 :
9407 20098200 : for (std::size_t i = 0; i < linkReport.size(); ++i) {
9408 19557086 : auto &r = linkReport[i];
9409 19557086 : auto const &s = AirflowNetworkLinkSimu[i];
9410 19557086 : r.FLOW = s.FLOW;
9411 19557086 : r.FLOW2 = s.FLOW2;
9412 19557086 : r.VolFLOW = s.VolFLOW;
9413 19557086 : r.VolFLOW2 = s.VolFLOW2;
9414 : }
9415 :
9416 : // Save zone loads from multizone calculation for later summation
9417 541114 : bool OnOffFanFlag = false;
9418 750050 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
9419 446071 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
9420 237135 : OnOffFanFlag = true;
9421 237135 : break;
9422 : }
9423 : }
9424 541114 : if (present(FirstHVACIteration)) {
9425 541114 : if (FirstHVACIteration && OnOffFanFlag) {
9426 34837 : multiExchangeData = exchangeData;
9427 139236 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
9428 104399 : nodeReport(i).PZ = AirflowNetworkNodeSimu(i).PZ;
9429 104399 : nodeReport(i).PZOFF = AirflowNetworkNodeSimu(i).PZ;
9430 104399 : nodeReport(i).PZON = 0.0;
9431 : }
9432 354929 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
9433 320092 : linkReport1(i).FLOW = AirflowNetworkLinkSimu(i).FLOW;
9434 320092 : linkReport1(i).FLOW2 = AirflowNetworkLinkSimu(i).FLOW2;
9435 320092 : linkReport1(i).VolFLOW = AirflowNetworkLinkSimu(i).VolFLOW;
9436 320092 : linkReport1(i).VolFLOW2 = AirflowNetworkLinkSimu(i).VolFLOW2;
9437 320092 : linkReport1(i).FLOWOFF = AirflowNetworkLinkSimu(i).FLOW;
9438 320092 : linkReport1(i).FLOW2OFF = AirflowNetworkLinkSimu(i).FLOW2;
9439 320092 : linkReport1(i).VolFLOWOFF = AirflowNetworkLinkSimu(i).VolFLOW;
9440 320092 : linkReport1(i).VolFLOW2OFF = AirflowNetworkLinkSimu(i).VolFLOW2;
9441 320092 : linkReport1(i).DP = AirflowNetworkLinkSimu(i).DP;
9442 320092 : linkReport1(i).DPOFF = AirflowNetworkLinkSimu(i).DP;
9443 320092 : linkReport1(i).DPON = 0.0;
9444 : }
9445 : }
9446 : }
9447 :
9448 541114 : if (!AirflowNetworkFanActivated && distribution_simulated) {
9449 4073201 : for (int i = NumOfNodesMultiZone + NumOfNodesIntraZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
9450 3914039 : AirflowNetworkNodeSimu(i).PZ = 0.0;
9451 : }
9452 5397101 : for (int i = AirflowNetworkNumOfSurfaces + 1; i <= AirflowNetworkNumOfLinks; ++i) {
9453 5237939 : AirflowNetworkLinkSimu(i).DP = 0.0;
9454 5237939 : linkReport(i).FLOW = 0.0;
9455 5237939 : linkReport(i).FLOW2 = 0.0;
9456 5237939 : linkReport(i).VolFLOW = 0.0;
9457 5237939 : linkReport(i).VolFLOW2 = 0.0;
9458 : }
9459 : }
9460 :
9461 541114 : if (!(AirflowNetworkFanActivated && distribution_simulated)) return;
9462 :
9463 270514 : if (distribution_simulated) {
9464 3638991 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) { // Multizone airflow energy
9465 3368477 : n = AirflowNetworkLinkageData(i).NodeNums[0];
9466 3368477 : M = AirflowNetworkLinkageData(i).NodeNums[1];
9467 3368477 : ZN1 = AirflowNetworkNodeData(n).EPlusZoneNum;
9468 3368477 : ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum;
9469 : // Find a linkage from a zone to outdoors
9470 3368477 : if (ZN1 > 0 && ZN2 == 0) {
9471 2384116 : Tamb = Zone(ZN1).OutDryBulbTemp;
9472 2384116 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9473 2384116 : exchangeData(ZN1).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - ANZT(ZN1));
9474 2384116 : exchangeData(ZN1).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - ANZW(ZN1));
9475 : }
9476 3368477 : if (ZN1 == 0 && ZN2 > 0) {
9477 0 : Tamb = Zone(ZN2).OutDryBulbTemp;
9478 0 : CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat);
9479 0 : exchangeData(ZN2).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - ANZT(ZN2));
9480 0 : exchangeData(ZN2).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - ANZW(ZN2));
9481 : }
9482 :
9483 3368477 : if (ZN1 > 0 && ZN2 > 0) {
9484 984361 : if (AirflowNetworkLinkSimu(i).FLOW > 0) { // Flow from ZN1 to ZN2
9485 328059 : CpAir = PsyCpAirFnW(ANZW(ZN1));
9486 328059 : exchangeData(ZN2).MultiZoneSen += AirflowNetworkLinkSimu(i).FLOW * CpAir * (ANZT(ZN1) - ANZT(ZN2));
9487 328059 : exchangeData(ZN2).MultiZoneLat += AirflowNetworkLinkSimu(i).FLOW * (ANZW(ZN1) - ANZW(ZN2));
9488 328059 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9489 328059 : exchangeData(ZN1).MultiZoneSen += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * (ANZT(ZN2) - ANZT(ZN1));
9490 328059 : exchangeData(ZN1).MultiZoneLat += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * (ANZW(ZN2) - ANZW(ZN1));
9491 : } else {
9492 656302 : CpAir = PsyCpAirFnW(ANZW(ZN2));
9493 656302 : exchangeData(ZN1).MultiZoneSen += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * CpAir * (ANZT(ZN2) - ANZT(ZN1));
9494 656302 : exchangeData(ZN1).MultiZoneLat += std::abs(AirflowNetworkLinkSimu(i).FLOW2) * (ANZW(ZN2) - ANZW(ZN1));
9495 : }
9496 : }
9497 : }
9498 : }
9499 :
9500 : int AirLoopNum;
9501 : int FanNum;
9502 270514 : Real64 MaxPartLoadRatio = 0.0;
9503 270514 : Real64 OnOffFanRunTimeFraction = 0.0;
9504 270514 : MaxOnOffFanRunTimeFraction = 0.0;
9505 551546 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9506 281032 : MaxPartLoadRatio = max(MaxPartLoadRatio, m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio);
9507 281032 : MaxOnOffFanRunTimeFraction = max(MaxOnOffFanRunTimeFraction, LoopOnOffFanRunTimeFraction(AirLoopNum));
9508 : }
9509 551546 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9510 291550 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9511 291550 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9512 : }
9513 281032 : PartLoadRatio = 1.0;
9514 281032 : LoopPartLoadRatio(AirLoopNum) = 1.0;
9515 281032 : OnOffFanRunTimeFraction = 1.0;
9516 281032 : LoopOnOffFanRunTimeFraction(AirLoopNum) = 1.0;
9517 : // Calculate the part load ratio, can't be greater than 1 for a simple ONOFF fan
9518 281032 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff &&
9519 465173 : Node(DisSysCompCVFData(FanNum).InletNode).MassFlowRate > VerySmallMassFlow &&
9520 184141 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling) {
9521 : // Hard code here
9522 170864 : PartLoadRatio = m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
9523 170864 : LoopPartLoadRatio(AirLoopNum) = m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
9524 170864 : OnOffFanRunTimeFraction = max(m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF,
9525 170864 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopOnOffFanRTF,
9526 170864 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF);
9527 170864 : LoopOnOffFanRunTimeFraction(AirLoopNum) = max(m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF,
9528 170864 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopOnOffFanRTF,
9529 170864 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF);
9530 : }
9531 281032 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0;
9532 :
9533 281032 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && LoopPartLoadRatio(AirLoopNum) < 1.0) {
9534 3173512 : for (std::size_t i = 0; i < linkReport.size(); ++i) {
9535 3068964 : auto &r(linkReport[i]);
9536 3068964 : auto const &s(AirflowNetworkLinkSimu[i]);
9537 3068964 : auto const &t(AirflowNetworkLinkageData[i]);
9538 3068964 : if (t.AirLoopNum == AirLoopNum) {
9539 1840312 : r.FLOW = s.FLOW * LoopPartLoadRatio(AirLoopNum);
9540 1840312 : r.FLOW2 = s.FLOW2 * LoopPartLoadRatio(AirLoopNum);
9541 1840312 : r.VolFLOW = s.VolFLOW * LoopPartLoadRatio(AirLoopNum);
9542 1840312 : r.VolFLOW2 = s.VolFLOW2 * LoopPartLoadRatio(AirLoopNum);
9543 : }
9544 3068964 : if (t.AirLoopNum == 0) {
9545 1107436 : r.FLOW = s.FLOW * MaxPartLoadRatio;
9546 1107436 : r.FLOW2 = s.FLOW2 * MaxPartLoadRatio;
9547 1107436 : r.VolFLOW = s.VolFLOW * MaxPartLoadRatio;
9548 1107436 : r.VolFLOW2 = s.VolFLOW2 * MaxPartLoadRatio;
9549 : }
9550 : }
9551 : }
9552 : }
9553 :
9554 : // One time warning
9555 270514 : if (UpdateAirflowNetworkMyOneTimeFlag) {
9556 551546 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9557 291550 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9558 291550 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9559 : }
9560 465829 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff &&
9561 184797 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Continuous) {
9562 13277 : OnOffRatio = std::abs((m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate -
9563 13277 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate) /
9564 13277 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate);
9565 13277 : if (OnOffRatio > 0.1) {
9566 0 : ShowWarningError(m_state,
9567 : "The absolute percent difference of supply air mass flow rate between HVAC operation and No HVAC operation "
9568 : "is above 10% with fan operation mode = ContFanCycCoil.");
9569 0 : ShowContinueError(m_state,
9570 : "The added zone loads using the AirflowNetwork model may not be accurate because the zone loads are "
9571 : "calculated based on the mass flow rate during HVAC operation.");
9572 0 : ShowContinueError(
9573 : m_state,
9574 0 : format("The mass flow rate during HVAC operation = {:.2R} The mass flow rate during no HVAC operation = {:.2R}",
9575 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate,
9576 0 : m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate));
9577 0 : UpdateAirflowNetworkMyOneTimeFlag = false;
9578 : }
9579 : }
9580 : }
9581 : }
9582 :
9583 : // Check mass flow differences in the zone inlet zones and splitter nodes between node and AFN links
9584 270514 : if (UpdateAirflowNetworkMyOneTimeFlag1) {
9585 23 : if ((!VAVSystem) && m_state.dataGlobal->DisplayExtraWarnings) {
9586 1 : bool WriteFlag = false;
9587 75 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9588 74 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9589 74 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9590 74 : if (AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::SPI ||
9591 145 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::SPO ||
9592 71 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::ZIN) {
9593 : int Node3;
9594 6 : if (AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::SPI) {
9595 1 : Node3 = Node1;
9596 : } else {
9597 5 : Node3 = Node2;
9598 : }
9599 6 : if (AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::ZIN) {
9600 3 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::Invalid) continue;
9601 : }
9602 4 : NodeMass = Node(AirflowNetworkNodeData(Node3).EPlusNodeNum).MassFlowRate;
9603 4 : AFNMass = AirflowNetworkLinkSimu(i).FLOW;
9604 4 : if (NodeMass > 0.0 && AFNMass > NodeMass + 0.01) {
9605 2 : ShowWarningError(m_state,
9606 0 : "The mass flow rate difference is found between System Node = '" +
9607 2 : m_state.dataLoopNodes->NodeID(AirflowNetworkNodeData(Node3).EPlusNodeNum) + "' and AFN Link = '" +
9608 3 : AirflowNetworkLinkageData(i).Name + "'.");
9609 2 : ShowContinueError(m_state,
9610 2 : format("The system node max mass flow rate = {:.3R} kg/s. The AFN node mass flow rate = {:.3R} kg.s.",
9611 : NodeMass,
9612 : AFNMass));
9613 1 : WriteFlag = true;
9614 : }
9615 : }
9616 : }
9617 1 : UpdateAirflowNetworkMyOneTimeFlag1 = false;
9618 1 : if (WriteFlag) {
9619 1 : ShowWarningError(m_state,
9620 : "Please adjust the rate of Maximum Air Flow Rate field in the terminal objects or duct pressure resistance.");
9621 : }
9622 : } else {
9623 22 : UpdateAirflowNetworkMyOneTimeFlag1 = false;
9624 : }
9625 : }
9626 :
9627 : // Assign airflows to EPLus nodes
9628 10315184 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9629 15642661 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC ||
9630 5597991 : AirflowNetworkLinkageData(i).VAVTermDamper) {
9631 : // Exclude envelope leakage Crack element
9632 4453477 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9633 4453477 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9634 :
9635 4453477 : int j = AirflowNetworkNodeData(Node1).EPlusNodeNum;
9636 4453477 : if (j > 0 && AirflowNetworkNodeData(Node1).EPlusZoneNum == 0) {
9637 2139145 : Node(j).MassFlowRate = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node1).AirLoopNum);
9638 2139145 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Node(j).MassFlowRate = 0.0;
9639 4271492 : if (!(AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::DIN ||
9640 2132347 : AirflowNetworkNodeData(Node1).EPlusTypeNum == iEPlusNodeType::DOU)) {
9641 2132347 : Node(j).MassFlowRateMaxAvail = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node1).AirLoopNum);
9642 2132347 : Node(j).MassFlowRateMax = AirflowNetworkLinkSimu(i).FLOW;
9643 : }
9644 : }
9645 :
9646 4453477 : j = AirflowNetworkNodeData(Node2).EPlusNodeNum;
9647 4453477 : if (j > 0) {
9648 2572197 : Node(j).MassFlowRate = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node2).AirLoopNum);
9649 2572197 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Node(j).MassFlowRate = 0.0;
9650 5137596 : if (!(AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::DIN ||
9651 2565399 : AirflowNetworkNodeData(Node2).EPlusTypeNum == iEPlusNodeType::DOU)) {
9652 2558601 : Node(j).MassFlowRateMaxAvail = AirflowNetworkLinkSimu(i).FLOW * LoopPartLoadRatio(AirflowNetworkNodeData(Node2).AirLoopNum);
9653 2558601 : Node(j).MassFlowRateMax = AirflowNetworkLinkSimu(i).FLOW;
9654 : }
9655 : }
9656 : }
9657 : }
9658 :
9659 : // Assign AirflowNetwork nodal values to Node array
9660 8231330 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
9661 7960816 : int j = AirflowNetworkNodeData(i).EPlusNodeNum;
9662 7960816 : if (j > 0) {
9663 3846163 : Node(j).Enthalpy = PsyHFnTdbW(AirflowNetworkNodeSimu(i).TZ, AirflowNetworkNodeSimu(i).WZ);
9664 3846163 : Node(j).Temp = AirflowNetworkNodeSimu(i).TZ;
9665 3846163 : Node(j).HumRat = AirflowNetworkNodeSimu(i).WZ;
9666 3846163 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9667 83160 : Node(j).CO2 = AirflowNetworkNodeSimu(i).CO2Z;
9668 : }
9669 3846163 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9670 81500 : Node(j).GenContam = AirflowNetworkNodeSimu(i).GCZ;
9671 : }
9672 : }
9673 : }
9674 :
9675 : // Calculate sensible loads from forced air flow
9676 10315184 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9677 10044670 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9678 10044670 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9679 10044670 : CpAir = PsyCpAirFnW((AirflowNetworkNodeSimu(Node1).WZ + AirflowNetworkNodeSimu(Node2).WZ) / 2.0);
9680 : // Calculate sensible loads from duct conduction losses and loads from duct radiation
9681 12879607 : if (AirflowNetworkLinkageData(i).ZoneNum > 0 &&
9682 2834937 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC) {
9683 2834937 : Qsen = AirflowNetworkLinkSimu(i).FLOW * CpAir * (AirflowNetworkNodeSimu(Node2).TZ - AirflowNetworkNodeSimu(Node1).TZ);
9684 2834937 : if (AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum != 0) {
9685 8277 : auto const &DuctRadObj(AirflowNetworkLinkageViewFactorData(AirflowNetworkLinkageData(i).LinkageViewFactorObjectNum));
9686 8277 : Qsen -= DuctRadObj.QRad;
9687 8277 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).RadGain -= DuctRadObj.QRad;
9688 : }
9689 : // When the Airloop is shut off, no duct sensible losses
9690 2834937 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qsen = 0.0;
9691 2834937 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).CondSen -= Qsen;
9692 : }
9693 : // Calculate sensible leakage losses
9694 20003916 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::PLR ||
9695 9959246 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::ELR) {
9696 : // Calculate supply leak sensible losses
9697 1436863 : if ((AirflowNetworkNodeData(Node2).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node1).EPlusNodeNum == 0) &&
9698 506044 : (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
9699 505951 : ZN2 = AirflowNetworkNodeData(Node2).EPlusZoneNum;
9700 505951 : Qsen = AirflowNetworkLinkSimu(i).FLOW * CpAir * (AirflowNetworkNodeSimu(Node1).TZ - AirflowNetworkNodeSimu(Node2).TZ);
9701 505951 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qsen = 0.0;
9702 505951 : exchangeData(ZN2).LeakSen += Qsen;
9703 : }
9704 1111787 : if ((AirflowNetworkNodeData(Node1).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node2).EPlusNodeNum == 0) &&
9705 180968 : (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
9706 4044 : ZN1 = AirflowNetworkNodeData(Node1).EPlusZoneNum;
9707 4044 : Qsen = AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (AirflowNetworkNodeSimu(Node2).TZ - AirflowNetworkNodeSimu(Node1).TZ);
9708 4044 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qsen = 0.0;
9709 4044 : exchangeData(ZN1).LeakSen += Qsen;
9710 : }
9711 : }
9712 : }
9713 :
9714 : // Calculate latent loads from forced air flow
9715 10315184 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
9716 10044670 : Node1 = AirflowNetworkLinkageData(i).NodeNums[0];
9717 10044670 : Node2 = AirflowNetworkLinkageData(i).NodeNums[1];
9718 : // Calculate latent loads from duct conduction losses
9719 12879607 : if (AirflowNetworkLinkageData(i).ZoneNum > 0 &&
9720 2834937 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::DWC) {
9721 2834937 : Qlat = AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node2).WZ - AirflowNetworkNodeSimu(Node1).WZ);
9722 2834937 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qlat = 0.0;
9723 2834937 : exchangeData(AirflowNetworkLinkageData(i).ZoneNum).DiffLat -= Qlat;
9724 : }
9725 : // Calculate latent leakage losses
9726 20003916 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::PLR ||
9727 9959246 : AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::ELR) {
9728 : // Calculate supply leak latent losses
9729 1436863 : if ((AirflowNetworkNodeData(Node2).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node1).EPlusNodeNum == 0) &&
9730 506044 : (AirflowNetworkLinkSimu(i).FLOW > 0.0)) {
9731 505951 : ZN2 = AirflowNetworkNodeData(Node2).EPlusZoneNum;
9732 505951 : Qlat = AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).WZ - AirflowNetworkNodeSimu(Node2).WZ);
9733 505951 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qlat = 0.0;
9734 505951 : exchangeData(ZN2).LeakLat += Qlat;
9735 505951 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9736 16632 : exchangeData(ZN2).TotalCO2 +=
9737 16632 : AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).CO2Z - AirflowNetworkNodeSimu(Node2).CO2Z);
9738 : }
9739 505951 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9740 16300 : exchangeData(ZN2).TotalGC +=
9741 16300 : AirflowNetworkLinkSimu(i).FLOW * (AirflowNetworkNodeSimu(Node1).GCZ - AirflowNetworkNodeSimu(Node2).GCZ);
9742 : }
9743 : }
9744 1111787 : if ((AirflowNetworkNodeData(Node1).EPlusZoneNum > 0) && (AirflowNetworkNodeData(Node2).EPlusNodeNum == 0) &&
9745 180968 : (AirflowNetworkLinkSimu(i).FLOW2 > 0.0)) {
9746 4044 : ZN1 = AirflowNetworkNodeData(Node1).EPlusZoneNum;
9747 4044 : Qlat = AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).WZ - AirflowNetworkNodeSimu(Node1).WZ);
9748 4044 : if (!LoopOnOffFlag(AirflowNetworkLinkageData(i).AirLoopNum)) Qlat = 0.0;
9749 4044 : exchangeData(ZN1).LeakLat += Qlat;
9750 4044 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9751 0 : exchangeData(ZN1).TotalCO2 +=
9752 0 : AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).CO2Z - AirflowNetworkNodeSimu(Node1).CO2Z);
9753 : }
9754 4044 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9755 0 : exchangeData(ZN1).TotalGC +=
9756 0 : AirflowNetworkLinkSimu(i).FLOW2 * (AirflowNetworkNodeSimu(Node2).GCZ - AirflowNetworkNodeSimu(Node1).GCZ);
9757 : }
9758 : }
9759 : }
9760 : }
9761 :
9762 : // Sum all the loads
9763 1083321 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9764 812807 : exchangeData(i).TotalSen = exchangeData(i).LeakSen + exchangeData(i).CondSen + exchangeData(i).RadGain;
9765 812807 : exchangeData(i).TotalLat = exchangeData(i).LeakLat + exchangeData(i).DiffLat;
9766 : }
9767 :
9768 : // Simple ONOFF fan
9769 551546 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
9770 291550 : for (FanNum = 1; FanNum <= DisSysNumOfCVFs; ++FanNum) {
9771 291550 : if (DisSysCompCVFData(FanNum).AirLoopNum == AirLoopNum) break;
9772 : }
9773 281032 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff && OnOffFanRunTimeFraction < 1.0) {
9774 350606 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9775 251619 : exchangeData(i).MultiZoneSen *= OnOffFanRunTimeFraction;
9776 251619 : exchangeData(i).MultiZoneLat *= OnOffFanRunTimeFraction;
9777 251619 : exchangeData(i).LeakSen *= OnOffFanRunTimeFraction;
9778 251619 : exchangeData(i).LeakLat *= OnOffFanRunTimeFraction;
9779 251619 : exchangeData(i).CondSen *= OnOffFanRunTimeFraction;
9780 251619 : exchangeData(i).DiffLat *= OnOffFanRunTimeFraction;
9781 251619 : exchangeData(i).RadGain *= OnOffFanRunTimeFraction;
9782 251619 : exchangeData(i).TotalSen *= OnOffFanRunTimeFraction;
9783 251619 : exchangeData(i).TotalLat *= OnOffFanRunTimeFraction;
9784 251619 : exchangeData(i).SumMCp *= OnOffFanRunTimeFraction;
9785 251619 : exchangeData(i).SumMCpT *= OnOffFanRunTimeFraction;
9786 251619 : exchangeData(i).SumMVCp *= OnOffFanRunTimeFraction;
9787 251619 : exchangeData(i).SumMVCpT *= OnOffFanRunTimeFraction;
9788 251619 : exchangeData(i).SumMHr *= OnOffFanRunTimeFraction;
9789 251619 : exchangeData(i).SumMHrW *= OnOffFanRunTimeFraction;
9790 251619 : exchangeData(i).SumMMCp *= OnOffFanRunTimeFraction;
9791 251619 : exchangeData(i).SumMMCpT *= OnOffFanRunTimeFraction;
9792 251619 : exchangeData(i).SumMMHr *= OnOffFanRunTimeFraction;
9793 251619 : exchangeData(i).SumMMHrW *= OnOffFanRunTimeFraction;
9794 251619 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9795 0 : exchangeData(i).SumMHrCO *= OnOffFanRunTimeFraction;
9796 0 : exchangeData(i).SumMMHrCO *= OnOffFanRunTimeFraction;
9797 : }
9798 251619 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9799 0 : exchangeData(i).SumMHrGC *= OnOffFanRunTimeFraction;
9800 0 : exchangeData(i).SumMMHrGC *= OnOffFanRunTimeFraction;
9801 : }
9802 : }
9803 98987 : if (m_state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode == HVAC::FanOp::Cycling) {
9804 350606 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
9805 251619 : exchangeData(i).SumMCp += multiExchangeData(i).SumMCp * (1.0 - OnOffFanRunTimeFraction);
9806 251619 : exchangeData(i).SumMCpT += multiExchangeData(i).SumMCpT * (1.0 - OnOffFanRunTimeFraction);
9807 251619 : exchangeData(i).SumMVCp += multiExchangeData(i).SumMVCp * (1.0 - OnOffFanRunTimeFraction);
9808 251619 : exchangeData(i).SumMVCpT += multiExchangeData(i).SumMVCpT * (1.0 - OnOffFanRunTimeFraction);
9809 251619 : exchangeData(i).SumMHr += multiExchangeData(i).SumMHr * (1.0 - OnOffFanRunTimeFraction);
9810 251619 : exchangeData(i).SumMHrW += multiExchangeData(i).SumMHrW * (1.0 - OnOffFanRunTimeFraction);
9811 251619 : exchangeData(i).SumMMCp += multiExchangeData(i).SumMMCp * (1.0 - OnOffFanRunTimeFraction);
9812 251619 : exchangeData(i).SumMMCpT += multiExchangeData(i).SumMMCpT * (1.0 - OnOffFanRunTimeFraction);
9813 251619 : exchangeData(i).SumMMHr += multiExchangeData(i).SumMMHr * (1.0 - OnOffFanRunTimeFraction);
9814 251619 : exchangeData(i).SumMMHrW += multiExchangeData(i).SumMMHrW * (1.0 - OnOffFanRunTimeFraction);
9815 251619 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9816 0 : exchangeData(i).SumMHrCO += multiExchangeData(i).SumMHrCO * (1.0 - OnOffFanRunTimeFraction);
9817 0 : exchangeData(i).SumMMHrCO += multiExchangeData(i).SumMMHrCO * (1.0 - OnOffFanRunTimeFraction);
9818 : }
9819 251619 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9820 0 : exchangeData(i).SumMHrGC += multiExchangeData(i).SumMHrGC * (1.0 - OnOffFanRunTimeFraction);
9821 0 : exchangeData(i).SumMMHrGC += multiExchangeData(i).SumMMHrGC * (1.0 - OnOffFanRunTimeFraction);
9822 : }
9823 : }
9824 : }
9825 : }
9826 :
9827 281032 : if (DisSysCompCVFData(FanNum).fanType == HVAC::FanType::OnOff) {
9828 677979 : for (int i = 1; i <= AirflowNetworkNumOfZones; ++i) {
9829 493182 : if (AirflowNetworkNodeData(i).AirLoopNum == AirLoopNum) {
9830 461628 : nodeReport(i).PZ = AirflowNetworkNodeSimu(i).PZ * LoopPartLoadRatio(AirLoopNum) +
9831 461628 : nodeReport(i).PZOFF * (1.0 - LoopPartLoadRatio(AirLoopNum));
9832 461628 : nodeReport(i).PZON = AirflowNetworkNodeSimu(i).PZ;
9833 : }
9834 : }
9835 2109309 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
9836 1924512 : PartLoadRatio = MaxPartLoadRatio;
9837 6988374 : for (int j = 1; j <= AirflowNetworkNumOfZones; ++j) {
9838 5063862 : if (MultizoneZoneData(j).ZoneNum == MultizoneSurfaceData(i).ZonePtr) {
9839 0 : if (AirflowNetworkNodeData(j).AirLoopNum == AirLoopNum) {
9840 0 : PartLoadRatio = LoopPartLoadRatio(AirLoopNum);
9841 0 : break;
9842 : }
9843 : }
9844 : }
9845 1924512 : linkReport1(i).FLOW = AirflowNetworkLinkSimu(i).FLOW * PartLoadRatio + linkReport1(i).FLOWOFF * (1.0 - PartLoadRatio);
9846 1924512 : linkReport1(i).FLOW2 = AirflowNetworkLinkSimu(i).FLOW2 * PartLoadRatio + linkReport1(i).FLOW2OFF * (1.0 - PartLoadRatio);
9847 1924512 : linkReport1(i).VolFLOW = AirflowNetworkLinkSimu(i).VolFLOW * PartLoadRatio + linkReport1(i).VolFLOWOFF * (1.0 - PartLoadRatio);
9848 1924512 : linkReport1(i).VolFLOW2 = AirflowNetworkLinkSimu(i).VolFLOW2 * PartLoadRatio + linkReport1(i).VolFLOW2OFF * (1.0 - PartLoadRatio);
9849 1924512 : linkReport1(i).DP = AirflowNetworkLinkSimu(i).DP * PartLoadRatio + linkReport1(i).DPOFF * (1.0 - PartLoadRatio);
9850 1924512 : linkReport1(i).DPON = AirflowNetworkLinkSimu(i).DP;
9851 : }
9852 : }
9853 : }
9854 :
9855 : // Save values
9856 8231330 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
9857 7960816 : AirflowNetworkNodeSimu(i).TZlast = AirflowNetworkNodeSimu(i).TZ;
9858 7960816 : AirflowNetworkNodeSimu(i).WZlast = AirflowNetworkNodeSimu(i).WZ;
9859 7960816 : if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) {
9860 153846 : AirflowNetworkNodeSimu(i).CO2Zlast = AirflowNetworkNodeSimu(i).CO2Z;
9861 : }
9862 7960816 : if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
9863 150775 : AirflowNetworkNodeSimu(i).GCZlast = AirflowNetworkNodeSimu(i).GCZ;
9864 : }
9865 : }
9866 : }
9867 :
9868 1059813 : void Solver::venting_control(int const i, // AirflowNetwork surface number
9869 : Real64 &OpenFactor // Window or door opening factor (used to calculate airflow)
9870 : )
9871 : {
9872 : // SUBROUTINE INFORMATION:
9873 : // AUTHOR Fred Winkelmann
9874 : // DATE WRITTEN April 2003
9875 : // MODIFIED Feb 2004, FCW: allow venting control of interior window/door
9876 : // MODIFIED Nov. 2005, LG: to fit the requirement for AirflowNetwork Model
9877 : // RE-ENGINEERED
9878 :
9879 : // PURPOSE OF THIS SUBROUTINE:
9880 : // Determines the venting opening factor for an exterior or interior window or door
9881 : // as determined by the venting control method.
9882 :
9883 : // Using/Aliasing
9884 : using ScheduleManager::GetCurrentScheduleValue;
9885 :
9886 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9887 : Real64 VentTemp; // Venting temperature (C)
9888 : Real64 ZoneAirEnthalpy; // Enthalpy of zone air (J/kg)
9889 : Real64 OpenFactorMult; // Window/door opening modulation multiplier on venting open factor
9890 : Real64 DelTemp; // Inside-outside air temperature difference (K)
9891 : Real64 DelEnthal; // Inside-outside air enthalpy difference (J/kg)
9892 : int IZ; // AirflowNetwork zone number
9893 : int ZoneNum; // EnergyPlus zone number
9894 : int SurfNum; // Heat transfer surface number
9895 : Real64 LimValVentOpenFacMult; // Limiting value of venting opening factor multiplier
9896 : Real64 LowerValInOutTempDiff; // Lower value of inside/outside temperature difference for opening factor modulation
9897 : Real64 UpperValInOutTempDiff; // Upper value of inside/outside temperature difference for opening factor modulation
9898 : Real64 LowerValInOutEnthalDiff; // Lower value of inside/outside enthalpy difference for opening factor modulation
9899 : Real64 UpperValInOutEnthalDiff; // Upper value of inside/outside enthalpy difference for opening factor modulation
9900 : bool VentingAllowed; // True if venting schedule allows venting
9901 : int VentCtrlNum; // Venting control strategy 1: Temperature control; 2: Enthalpy control
9902 : Real64 VentingSchVal; // Current time step value of venting schedule
9903 : Real64 Tamb; // Outdoor dry bulb temperature at surface centroid height
9904 : int PeopleInd;
9905 :
9906 1059813 : if (MultizoneSurfaceData(i).EMSOpenFactorActuated) { // EMS sets value to use
9907 18201 : OpenFactor = MultizoneSurfaceData(i).EMSOpenFactor;
9908 18201 : SurfNum = MultizoneSurfaceData(i).SurfNum;
9909 18201 : if (MultizoneSurfaceData(i).Factor > 0.0) {
9910 18201 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactor / MultizoneSurfaceData(i).Factor;
9911 : } else {
9912 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactor;
9913 : }
9914 18201 : return;
9915 : }
9916 :
9917 1041612 : SurfNum = MultizoneSurfaceData(i).SurfNum;
9918 :
9919 1041612 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
9920 :
9921 : // Get venting temperature and venting strategy for exterior window or door
9922 : // and determine whether venting is allowed
9923 :
9924 1041612 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 1.0;
9925 1041612 : VentingAllowed = true;
9926 1041612 : IZ = MultizoneSurfaceData(i).NodeNums[0];
9927 : // Revise for RoomAirflowNetwork model
9928 1041612 : if (MultizoneSurfaceData(i).RAFNflag) IZ = MultizoneSurfaceData(i).ZonePtr;
9929 1041612 : ZoneNum = MultizoneZoneData(IZ).ZoneNum;
9930 :
9931 : // Note in the following that individual venting control for a window/door takes
9932 : // precedence over zone-level control
9933 1041612 : if (MultizoneSurfaceData(i).IndVentControl) {
9934 32484 : VentTemp = GetCurrentScheduleValue(m_state, MultizoneSurfaceData(i).VentSchNum);
9935 32484 : VentCtrlNum = MultizoneSurfaceData(i).VentSurfCtrNum;
9936 32484 : if (MultizoneSurfaceData(i).VentingSchNum > 0) {
9937 0 : VentingSchVal = GetCurrentScheduleValue(m_state, MultizoneSurfaceData(i).VentingSchNum);
9938 0 : if (VentingSchVal <= 0.0) {
9939 0 : VentingAllowed = false;
9940 0 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 0.0;
9941 : }
9942 : }
9943 : } else {
9944 : // Zone level only by Gu on Nov. 8, 2005
9945 1009128 : VentTemp = GetCurrentScheduleValue(m_state, MultizoneZoneData(IZ).VentSchNum);
9946 1009128 : VentCtrlNum = MultizoneZoneData(IZ).VentCtrNum;
9947 1009128 : if (MultizoneZoneData(IZ).VentingSchNum > 0) {
9948 678954 : VentingSchVal = GetCurrentScheduleValue(m_state, MultizoneZoneData(IZ).VentingSchNum);
9949 678954 : if (VentingSchVal <= 0.0) {
9950 371221 : VentingAllowed = false;
9951 371221 : m_state.dataSurface->SurfWinVentingAvailabilityRep(SurfNum) = 0.0;
9952 : }
9953 : }
9954 : }
9955 :
9956 1041612 : m_state.dataSurface->SurfWinInsideTempForVentingRep(SurfNum) = VentTemp;
9957 1041612 : OpenFactor = 0.0;
9958 :
9959 : // Venting based on inside-outside air temperature difference
9960 :
9961 1041612 : if ((VentCtrlNum == VentControlType::Temp || VentCtrlNum == VentControlType::AdjTemp) && VentingAllowed) {
9962 548663 : Tamb = m_state.dataSurface->SurfOutDryBulbTemp(SurfNum);
9963 : // Check whether this surface is an interior wall or not. If Yes, use adjacent zone conditions
9964 548663 : if (VentCtrlNum == VentControlType::AdjTemp && MultizoneSurfaceData(i).IndVentControl) {
9965 0 : Tamb = ANZT(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum);
9966 : }
9967 548663 : if (ANZT(ZoneNum) > Tamb && ANZT(ZoneNum) > VentTemp) {
9968 240671 : OpenFactor = MultizoneSurfaceData(i).Factor;
9969 240671 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
9970 : // Modulation of OpenFactor
9971 240671 : if (MultizoneSurfaceData(i).IndVentControl) {
9972 0 : LimValVentOpenFacMult = MultizoneSurfaceData(i).ModulateFactor;
9973 0 : LowerValInOutTempDiff = MultizoneSurfaceData(i).LowValueTemp;
9974 0 : UpperValInOutTempDiff = MultizoneSurfaceData(i).UpValueTemp;
9975 : } else {
9976 240671 : LimValVentOpenFacMult = MultizoneZoneData(IZ).OpenFactor;
9977 240671 : LowerValInOutTempDiff = MultizoneZoneData(IZ).LowValueTemp;
9978 240671 : UpperValInOutTempDiff = MultizoneZoneData(IZ).UpValueTemp;
9979 : }
9980 240671 : if (LimValVentOpenFacMult != 1.0) {
9981 150650 : DelTemp = ANZT(ZoneNum) - Tamb;
9982 150650 : if (DelTemp <= LowerValInOutTempDiff) {
9983 132238 : OpenFactorMult = 1.0;
9984 18412 : } else if (DelTemp >= UpperValInOutTempDiff) {
9985 0 : OpenFactorMult = LimValVentOpenFacMult;
9986 : } else {
9987 18412 : OpenFactorMult =
9988 : LimValVentOpenFacMult +
9989 18412 : ((UpperValInOutTempDiff - DelTemp) / (UpperValInOutTempDiff - LowerValInOutTempDiff)) * (1 - LimValVentOpenFacMult);
9990 : }
9991 150650 : OpenFactor *= OpenFactorMult;
9992 150650 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactorMult;
9993 : }
9994 : } else {
9995 307992 : OpenFactor = 0.0;
9996 307992 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
9997 : }
9998 : }
9999 :
10000 : // Venting based on inside-outside air enthalpy difference
10001 :
10002 1041612 : if ((VentCtrlNum == VentControlType::Enth || VentCtrlNum == VentControlType::AdjEnth) && VentingAllowed) {
10003 0 : ZoneAirEnthalpy = PsyHFnTdbW(ANZT(ZoneNum), ANZW(ZoneNum));
10004 : // Check whether this surface is an interior wall or not. If Yes, use adjacent zone conditions
10005 0 : if (VentCtrlNum == VentControlType::AdjEnth && MultizoneSurfaceData(i).IndVentControl) {
10006 0 : m_state.dataEnvrn->OutEnthalpy = PsyHFnTdbW(ANZT(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum),
10007 0 : ANZW(MultizoneZoneData(MultizoneSurfaceData(i).NodeNums[1]).ZoneNum));
10008 : }
10009 0 : if (ZoneAirEnthalpy > m_state.dataEnvrn->OutEnthalpy && ANZT(ZoneNum) > VentTemp) {
10010 0 : OpenFactor = MultizoneSurfaceData(i).Factor;
10011 : // Modulation of OpenFactor
10012 0 : if (MultizoneSurfaceData(i).IndVentControl) {
10013 0 : LimValVentOpenFacMult = MultizoneSurfaceData(i).ModulateFactor;
10014 0 : LowerValInOutEnthalDiff = MultizoneSurfaceData(i).LowValueEnth;
10015 0 : UpperValInOutEnthalDiff = MultizoneSurfaceData(i).UpValueEnth;
10016 : } else {
10017 0 : LimValVentOpenFacMult = MultizoneZoneData(IZ).OpenFactor;
10018 0 : LowerValInOutEnthalDiff = MultizoneZoneData(IZ).LowValueEnth;
10019 0 : UpperValInOutEnthalDiff = MultizoneZoneData(IZ).UpValueEnth;
10020 : }
10021 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10022 :
10023 0 : if (LimValVentOpenFacMult != 1.0) {
10024 0 : DelEnthal = ZoneAirEnthalpy - m_state.dataEnvrn->OutEnthalpy;
10025 0 : if (DelEnthal <= LowerValInOutEnthalDiff) {
10026 0 : OpenFactorMult = 1.0;
10027 0 : } else if (DelEnthal >= UpperValInOutEnthalDiff) {
10028 0 : OpenFactorMult = LimValVentOpenFacMult;
10029 : } else {
10030 0 : OpenFactorMult =
10031 0 : LimValVentOpenFacMult + ((UpperValInOutEnthalDiff - DelEnthal) / (UpperValInOutEnthalDiff - LowerValInOutEnthalDiff)) *
10032 0 : (1 - LimValVentOpenFacMult);
10033 : }
10034 0 : OpenFactor *= OpenFactorMult;
10035 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactorMult;
10036 : }
10037 : } else {
10038 0 : OpenFactor = 0.0;
10039 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10040 : }
10041 : }
10042 :
10043 : // Constant venting (opening factor as specified in IDF) - C-PH - added by Philip Haves 3/8/01
10044 : // subject to venting availability
10045 :
10046 1041612 : if (VentCtrlNum == VentControlType::Const && VentingAllowed) { // Constant
10047 96576 : OpenFactor = MultizoneSurfaceData(i).Factor;
10048 96576 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10049 : }
10050 :
10051 1041612 : if (VentCtrlNum == VentControlType::ASH55) {
10052 25152 : if (VentingAllowed && (!m_state.dataGlobal->BeginEnvrnFlag) && (!m_state.dataGlobal->WarmupFlag)) {
10053 2196 : PeopleInd = MultizoneZoneData(IZ).ASH55PeopleInd;
10054 2196 : if (PeopleInd > 0 && m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortAdaptiveASH5590 != -1) {
10055 726 : if (m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortOpTemp >
10056 726 : m_state.dataThermalComforts->ThermalComfortData(PeopleInd).TComfASH55) {
10057 654 : OpenFactor = MultizoneSurfaceData(i).Factor;
10058 654 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10059 : } else {
10060 72 : OpenFactor = 0.0;
10061 : }
10062 : } else {
10063 1470 : OpenFactor = 0.0;
10064 : }
10065 : } else {
10066 22956 : OpenFactor = 0.0;
10067 : }
10068 : }
10069 :
10070 1041612 : if (VentCtrlNum == VentControlType::CEN15251) {
10071 0 : if (VentingAllowed && (!m_state.dataGlobal->BeginEnvrnFlag) && (!m_state.dataGlobal->WarmupFlag)) {
10072 0 : PeopleInd = MultizoneZoneData(IZ).CEN15251PeopleInd;
10073 0 : if (PeopleInd > 0 && m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortAdaptiveCEN15251CatI != -1) {
10074 0 : if (m_state.dataThermalComforts->ThermalComfortData(PeopleInd).ThermalComfortOpTemp >
10075 0 : m_state.dataThermalComforts->ThermalComfortData(PeopleInd).TComfCEN15251) {
10076 0 : OpenFactor = MultizoneSurfaceData(i).Factor;
10077 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10078 : } else {
10079 0 : OpenFactor = 0.0;
10080 : }
10081 : } else {
10082 0 : OpenFactor = 0.0;
10083 : }
10084 : } else {
10085 0 : OpenFactor = 0.0;
10086 : }
10087 : }
10088 :
10089 : // No venting, i.e, window/door always closed - added YJH 8 Aug 02
10090 :
10091 1041612 : if (VentCtrlNum == VentControlType::NoVent) { // Novent
10092 0 : OpenFactor = 0.0;
10093 0 : m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10094 : }
10095 : }
10096 :
10097 23 : void Solver::validate_distribution()
10098 : {
10099 :
10100 : // SUBROUTINE INFORMATION:
10101 : // AUTHOR Lixing Gu
10102 : // DATE WRITTEN Oct. 2005
10103 : // MODIFIED L. Gu, Jan. 2009: allow a desuperheater coil and three heat exchangers
10104 : // RE-ENGINEERED na
10105 :
10106 : // PURPOSE OF THIS SUBROUTINE:
10107 : // This subroutine validates the inputs of distribution system, since node data from a primary airloop
10108 : // are not available in the first call during reading input data of airflownetwork objects.
10109 : // Note: this routine shouldn't be called more than once
10110 :
10111 : // Using/Aliasing
10112 : using BranchNodeConnections::GetNodeConnectionType;
10113 : using MixedAir::GetNumOAMixers;
10114 : using MixedAir::GetOAMixerInletNodeNumber;
10115 : using MixedAir::GetOAMixerReliefNodeNumber;
10116 : using SingleDuct::GetHVACSingleDuctSysIndex;
10117 : using namespace DataLoopNode;
10118 23 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
10119 : using DXCoils::SetDXCoilAirLoopNumber;
10120 : using HeatingCoils::SetHeatingCoilAirLoopNumber;
10121 : using HVACStandAloneERV::GetStandAloneERVNodeNumber;
10122 : using HVACVariableRefrigerantFlow::getVRFTUNodeNumber;
10123 : using SplitterComponent::GetSplitterNodeNumbers;
10124 : using SplitterComponent::GetSplitterOutletNumber;
10125 : using UnitarySystems::getUnitarySystemNodeNumber;
10126 : using WaterThermalTanks::GetHeatPumpWaterHeaterNodeNumber;
10127 : using WindowAC::getWindowACNodeNumber;
10128 : using ZoneDehumidifier::GetZoneDehumidifierNodeNumber;
10129 :
10130 : // SUBROUTINE PARAMETER DEFINITIONS:
10131 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::validate_distribution: "); // include trailing blank space
10132 :
10133 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10134 : int n;
10135 : bool LocalError;
10136 23 : Array1D_bool NodeFound;
10137 :
10138 23 : bool ErrorsFound(false);
10139 23 : bool IsNotOK(false);
10140 23 : bool errFlag(false);
10141 23 : EPVector<DataLoopNode::ConnectionType> NodeConnectionType; // Specifies the type of node connection
10142 23 : std::string CurrentModuleObject;
10143 :
10144 23 : bool hpwhFound(false); // Flag for HPWH identification
10145 23 : bool standaloneERVFound(false); // Flag for Standalone ERV (ZoneHVAC:EnergyRecoveryVentilator) identification
10146 23 : bool packagedUnitaryFound(false); // Flag for packaged unitary systems (ZoneHVAC:PackagedTerminalAirConditioner,
10147 : // ZoneHVAC:PackagedTerminalHeatPump, ZoneHVAC:WaterToAirHeatPump) identification
10148 23 : bool vrfTUFound(false);
10149 23 : bool windowACFound(false); // Flag for Window AC (ZoneHVAC:WindowAirConditioner) identification
10150 :
10151 : // Validate supply and return connections
10152 23 : NodeFound.dimension(m_state.dataLoopNodes->NumOfNodes, false);
10153 : // Validate inlet and outlet nodes for zone exhaust fans
10154 36 : for (int i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
10155 13 : NodeFound(MultizoneCompExhaustFanData(i).InletNode) = true;
10156 13 : NodeFound(MultizoneCompExhaustFanData(i).OutletNode) = true;
10157 : }
10158 : // Validate EPlus Node names and types
10159 551 : for (int i = 1; i <= DisSysNumOfNodes; ++i) {
10160 528 : if (Util::SameString(DisSysNodeData(i).EPlusName, "") || Util::SameString(DisSysNodeData(i).EPlusName, "Other")) continue;
10161 333 : LocalError = false;
10162 3717 : for (int j = 1; j <= m_state.dataLoopNodes->NumOfNodes; ++j) { // NodeID
10163 3717 : if (DisSysNodeData(i).EPlusName == m_state.dataLoopNodes->NodeID(j)) {
10164 333 : DisSysNodeData(i).AirLoopNum = get_airloop_number(j);
10165 333 : if (DisSysNodeData(i).AirLoopNum == 0) {
10166 0 : ShowSevereError(m_state,
10167 0 : format(RoutineName) + "The Node or Component Name defined in " + DisSysNodeData(i).Name +
10168 : " is not found in the AirLoopHVAC.");
10169 0 : ShowContinueError(m_state,
10170 0 : "The entered name is " + DisSysNodeData(i).EPlusName + " in an AirflowNetwork:Distribution:Node object.");
10171 0 : ErrorsFound = true;
10172 : }
10173 333 : DisSysNodeData(i).EPlusNodeNum = j;
10174 333 : AirflowNetworkNodeData(NumOfNodesMultiZone + i).EPlusNodeNum = j;
10175 333 : AirflowNetworkNodeData(NumOfNodesMultiZone + i).AirLoopNum = DisSysNodeData(i).AirLoopNum;
10176 333 : NodeFound(j) = true;
10177 333 : LocalError = true;
10178 333 : break;
10179 : }
10180 : }
10181 : // Check outdoor air node
10182 666 : if (Util::SameString(DisSysNodeData(i).EPlusType, "OutdoorAir:NodeList") ||
10183 666 : Util::SameString(DisSysNodeData(i).EPlusType, "OutdoorAir:Node")) {
10184 0 : if (!LocalError) {
10185 0 : ShowSevereError(m_state,
10186 0 : format(RoutineName) + "The Node or Component Name defined in " + DisSysNodeData(i).Name +
10187 0 : " is not found in the " + DisSysNodeData(i).EPlusType);
10188 0 : ShowContinueError(m_state,
10189 0 : "The entered name is " + DisSysNodeData(i).EPlusName + " in an AirflowNetwork:Distribution:Node object.");
10190 0 : ErrorsFound = true;
10191 : }
10192 : }
10193 333 : if (DisSysNodeData(i).EPlusNodeNum == 0) {
10194 0 : ShowSevereError(m_state,
10195 0 : format(RoutineName) +
10196 0 : "Primary Air Loop Node is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " + DisSysNodeData(i).Name);
10197 0 : ErrorsFound = true;
10198 : }
10199 : }
10200 :
10201 : // Determine node numbers for zone inlets and outlets
10202 103 : for (int i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) {
10203 80 : if (!m_state.dataZoneEquip->ZoneEquipConfig(i).IsControlled) continue;
10204 103 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumInletNodes; ++j) {
10205 1096 : for (int k = 1; k <= AirflowNetworkNumOfNodes; ++k) {
10206 1091 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).InletNode(j) == AirflowNetworkNodeData(k).EPlusNodeNum) {
10207 49 : AirflowNetworkNodeData(k).EPlusTypeNum = iEPlusNodeType::ZIN;
10208 49 : break;
10209 : }
10210 : }
10211 : }
10212 98 : for (int j = 1; j <= m_state.dataZoneEquip->ZoneEquipConfig(i).NumReturnNodes; ++j) {
10213 995 : for (int k = 1; k <= AirflowNetworkNumOfNodes; ++k) {
10214 995 : if (m_state.dataZoneEquip->ZoneEquipConfig(i).ReturnNode(j) == AirflowNetworkNodeData(k).EPlusNodeNum) {
10215 49 : AirflowNetworkNodeData(k).EPlusTypeNum = iEPlusNodeType::ZOU;
10216 49 : break;
10217 : }
10218 : }
10219 : }
10220 : }
10221 :
10222 : // Eliminate node not related to AirLoopHVAC
10223 1426 : for (int k = 1; k <= m_state.dataBranchNodeConnections->NumOfNodeConnections; ++k) {
10224 1403 : if (NodeFound(m_state.dataBranchNodeConnections->NodeConnections(k).NodeNumber)) continue;
10225 281 : if (m_state.dataBranchNodeConnections->NodeConnections(k).FluidStream == NodeInputManager::CompFluidStream::Secondary) {
10226 12 : NodeFound(m_state.dataBranchNodeConnections->NodeConnections(k).NodeNumber) = true;
10227 : }
10228 : }
10229 :
10230 : // Eliminate nodes with fluidtype = water
10231 514 : for (int k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
10232 491 : if (NodeFound(k)) continue;
10233 120 : if (m_state.dataLoopNodes->Node(k).FluidType == DataLoopNode::NodeFluidType::Water) {
10234 40 : NodeFound(k) = true;
10235 : }
10236 : }
10237 :
10238 : // Eliminate local external air node for network
10239 514 : for (int k = 1; k <= m_state.dataLoopNodes->NumOfNodes; ++k) {
10240 491 : if (NodeFound(k)) continue;
10241 80 : if (m_state.dataLoopNodes->Node(k).IsLocalNode) NodeFound(k) = true;
10242 : }
10243 :
10244 : // Ensure all the nodes used in Eplus are a subset of AirflowNetwork Nodes
10245 514 : for (int i = 1; i <= m_state.dataLoopNodes->NumOfNodes; ++i) {
10246 491 : if (NodeFound(i)) continue;
10247 : // Skip the inlet and outlet nodes of zone dehumidifiers
10248 79 : if (GetZoneDehumidifierNodeNumber(m_state, i)) NodeFound(i) = true;
10249 :
10250 79 : if (simulation_control.allow_unsupported_zone_equipment) {
10251 : // Skip HPWH nodes that don't have to be included in the AFN
10252 16 : if (GetHeatPumpWaterHeaterNodeNumber(m_state, i)) {
10253 6 : NodeFound(i) = true;
10254 6 : hpwhFound = true;
10255 : }
10256 :
10257 : // Skip Standalone ERV nodes that don't have to be included in the AFN
10258 16 : if (GetStandAloneERVNodeNumber(m_state, i)) {
10259 6 : NodeFound(i) = true;
10260 6 : standaloneERVFound = true;
10261 : }
10262 :
10263 : // Skip zonal unitary system based nodes that don't have to be included in the AFN
10264 16 : if (getUnitarySystemNodeNumber(m_state, i)) {
10265 0 : NodeFound(i) = true;
10266 0 : packagedUnitaryFound = true;
10267 : }
10268 :
10269 : // Skip zonal vrf terminal nodes that don't have to be included in the AFN
10270 16 : if (getVRFTUNodeNumber(m_state, i)) {
10271 0 : NodeFound(i) = true;
10272 0 : vrfTUFound = true;
10273 : }
10274 :
10275 : // Skip Window AC with no OA
10276 16 : if (getWindowACNodeNumber(m_state, i)) {
10277 0 : NodeFound(i) = true;
10278 0 : windowACFound = true;
10279 : }
10280 : }
10281 :
10282 213 : for (int zoneNum = 1; zoneNum <= m_state.dataGlobal->NumOfZones; ++zoneNum) {
10283 183 : if (!m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).IsControlled) continue;
10284 148 : if (m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneNode == i) {
10285 49 : if (zoneNum > AirflowNetworkNumOfNodes) {
10286 0 : ShowSevereError(m_state,
10287 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10288 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10289 0 : ShowContinueError(
10290 0 : m_state, "This Node is the zone air node for Zone '" + m_state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneName + "'.");
10291 0 : ErrorsFound = true;
10292 : } else {
10293 49 : NodeFound(i) = true;
10294 235 : for (int iZone = 1; iZone <= AirflowNetworkNumOfZones; iZone++) {
10295 186 : if (MultizoneZoneData(iZone).ZoneNum == zoneNum) {
10296 49 : AirflowNetworkNodeData(iZone).EPlusNodeNum = i;
10297 : }
10298 : }
10299 : }
10300 49 : break;
10301 : }
10302 : }
10303 :
10304 : // skip nodes that are not part of an airflow network
10305 :
10306 : // DX COIL CONDENSER NODE TEST:
10307 : // Outside air nodes are used for DX coil condenser inlet nodes, these are specified in an outside air node or
10308 : // OutdoorAir:NodeList object (and classified with NodeConnectionType as OutsideAir). In addition,
10309 : // this same node is specified in a Coil:DX:CoolingBypassFactorEmpirical object (and classified with
10310 : // NodeConnectionType as OutsideAirReference). In the NodeConnectionType structure, both of these nodes have a
10311 : // unique index but have the same node number. The Outside Air Node will usually be listed first. Search for all
10312 : // indexes with the same node number and check if it is classified as NodeConnectionType = OutsideAirReference.
10313 : // Mark this node as found since it is not used in an airflownetwork simulation.
10314 : // Example (using AirflowNetwork_MultiZone_SmallOffice.idf with a single OA Mixer):
10315 : // (the example shown below is identical to AirflowNetwork_SimpleHouse.idf with no OA Mixer except
10316 : // that the NodeConnections indexes are (7) and (31), respectively and the NodeNumber = 6)
10317 : // The GetNodeConnectionType CALL below returns DataLoopNode::NodeConnectionType::OutsideAir = 7 and
10318 : // DataLoopNode::NodeConnectionType::OutsideAirReference = 14.
10319 : // NodeConnections info from OUTSIDE AIR NODE object read:
10320 : // NodeConnections(9)NodeNumber = 10
10321 : // NodeConnections(9)NodeName = ACDXCOIL 1 CONDENSER NODE
10322 : // NodeConnections(9)ObjectType = OUTSIDE AIR NODE
10323 : // NodeConnections(9)ObjectName = OUTSIDE AIR NODE
10324 : // NodeConnections(9)ConnectionType = OutsideAir
10325 : // NodeConnections info from Coil:DX:CoolingBypassFactorEmpirical object read:
10326 : // NodeConnections(64)NodeNumber = 10
10327 : // NodeConnections(64)NodeName = ACDXCOIL 1 CONDENSER NODE
10328 : // NodeConnections(64)ObjectType = COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
10329 : // NodeConnections(64)ObjectName = ACDXCOIL 1
10330 : // NodeConnections(64)ConnectionType = OutsideAirReference
10331 :
10332 79 : errFlag = false;
10333 79 : GetNodeConnectionType(m_state, i, NodeConnectionType, errFlag); // Gets all connection types for a given node number
10334 79 : if (errFlag) {
10335 0 : ShowContinueError(m_state, "...occurs in Airflow Network simulation.");
10336 : } else {
10337 : // skip nodes for air cooled condensers
10338 212 : for (int j = 1; j <= isize(NodeConnectionType); ++j) {
10339 133 : if (NodeConnectionType(j) == DataLoopNode::ConnectionType::OutsideAirReference) {
10340 2 : NodeFound(i) = true;
10341 : }
10342 : }
10343 : }
10344 :
10345 79 : if (!NodeFound(i)) {
10346 : // Check if this node is the OA relief node. For the time being, OA relief node is not used
10347 14 : if (GetNumOAMixers(m_state) > 1) {
10348 : // ShowSevereError(m_state, format(RoutineName) + "Only one OutdoorAir:Mixer is allowed in the
10349 : // AirflowNetwork model." ); ErrorsFound = true;
10350 : int OAFanNum;
10351 : int OARelNum;
10352 : int OAMixerNum;
10353 :
10354 4 : for (OAFanNum = 1; OAFanNum <= NumOfOAFans; ++OAFanNum) {
10355 2 : DisSysCompOutdoorAirData(OAFanNum).InletNode =
10356 2 : GetOAMixerInletNodeNumber(m_state, DisSysCompOutdoorAirData(OAFanNum).OAMixerNum);
10357 : // NodeFound( DisSysCompOutdoorAirData( OAFanNum ).InletNode
10358 : // ) = true;
10359 : }
10360 4 : for (OARelNum = 1; OARelNum <= NumOfReliefFans; ++OARelNum) {
10361 2 : DisSysCompReliefAirData(OARelNum).OutletNode =
10362 2 : GetOAMixerInletNodeNumber(m_state, DisSysCompReliefAirData(OARelNum).OAMixerNum);
10363 : // NodeFound( DisSysCompOutdoorAirData( OAFanNum ).InletNode
10364 : // ) = true;
10365 : }
10366 : // Check NodeFound status
10367 3 : for (OAMixerNum = 1; OAMixerNum <= GetNumOAMixers(m_state); ++OAMixerNum) {
10368 3 : if (i == GetOAMixerReliefNodeNumber(m_state, OAMixerNum)) {
10369 2 : NodeFound(i) = true;
10370 2 : break;
10371 1 : } else if (i == GetOAMixerInletNodeNumber(m_state, OAMixerNum)) {
10372 0 : NodeFound(i) = true;
10373 0 : break;
10374 : } else {
10375 1 : if (OAMixerNum == GetNumOAMixers(m_state)) {
10376 0 : ShowSevereError(m_state,
10377 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10378 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10379 0 : ErrorsFound = true;
10380 : }
10381 : }
10382 : }
10383 12 : } else if (GetNumOAMixers(m_state) == 0) {
10384 0 : ShowSevereError(m_state,
10385 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10386 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10387 0 : ErrorsFound = true;
10388 : } else {
10389 : // TODO: I fail to see how you could enter this block given than NumOAMixers (returned by GetNumOAMixers())
10390 : // is initialized to zero, and we check above if '> 0' or '== 0'
10391 12 : if (NumOfOAFans == 1 && DisSysCompOutdoorAirData(1).InletNode == 0) {
10392 1 : DisSysCompOutdoorAirData(1).InletNode = GetOAMixerInletNodeNumber(m_state, 1);
10393 : }
10394 12 : if (NumOfReliefFans == 1 && DisSysCompReliefAirData(1).OutletNode == 0) {
10395 1 : DisSysCompReliefAirData(1).OutletNode = GetOAMixerInletNodeNumber(m_state, 1);
10396 : }
10397 12 : if (i == GetOAMixerReliefNodeNumber(m_state, 1)) {
10398 11 : NodeFound(i) = true;
10399 1 : } else if (i == GetOAMixerInletNodeNumber(m_state, 1)) {
10400 1 : NodeFound(i) = true;
10401 : } else {
10402 0 : ShowSevereError(m_state,
10403 0 : format(RoutineName) + "'" + m_state.dataLoopNodes->NodeID(i) +
10404 : "' is not defined as an AirflowNetwork:Distribution:Node object.");
10405 0 : ErrorsFound = true;
10406 : }
10407 : }
10408 : }
10409 : }
10410 23 : if (hpwhFound) {
10411 4 : ShowWarningError(m_state,
10412 4 : format(RoutineName) + "Heat pump water heater is simulated along with an AirflowNetwork but is not included in "
10413 : "the AirflowNetwork.");
10414 : }
10415 23 : if (standaloneERVFound) {
10416 4 : ShowWarningError(m_state,
10417 4 : format(RoutineName) + "A ZoneHVAC:EnergyRecoveryVentilator is simulated along with an AirflowNetwork but is not "
10418 : "included in the AirflowNetwork.");
10419 : }
10420 23 : if (packagedUnitaryFound) {
10421 0 : ShowWarningError(m_state,
10422 0 : format(RoutineName) + "A ZoneHVAC:PackagedTerminalAirConditioner, ZoneHVAC:PackagedTerminalHeatPump, or "
10423 : "ZoneHVAC:WaterToAirHeatPump is simulated along with an AirflowNetwork but is not "
10424 : "included in the AirflowNetwork.");
10425 : }
10426 23 : if (vrfTUFound) {
10427 0 : ShowWarningError(m_state,
10428 0 : format(RoutineName) +
10429 : "A ZoneHVAC:TerminalUnit:VariableRefrigerantFlow is simulated along with an AirflowNetwork but is not "
10430 : "included in the AirflowNetwork.");
10431 : }
10432 23 : if (windowACFound) {
10433 0 : ShowWarningError(m_state,
10434 0 : format(RoutineName) + "A ZoneHVAC:WindowAirConditioner is simulated along with an AirflowNetwork but is not "
10435 : "included in the AirflowNetwork.");
10436 : }
10437 23 : NodeFound.deallocate();
10438 :
10439 : // Assign AirLoop Number to every node and linkage
10440 : // Zone first
10441 103 : for (int i = 1; i <= AirflowNetworkNumOfZones; i++) {
10442 372 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; j++) {
10443 292 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) continue;
10444 186 : if ((MultizoneZoneData(i).ZoneNum == j) && (m_state.dataZoneEquip->ZoneEquipConfig(j).NumInletNodes > 0)) {
10445 : // No multiple Airloop
10446 49 : AirflowNetworkNodeData(i).AirLoopNum = m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(1);
10447 : }
10448 : }
10449 : }
10450 : // Air Distribution system
10451 724 : for (int i = AirflowNetworkNumOfSurfaces + 1; i <= AirflowNetworkNumOfLinks; ++i) {
10452 701 : int j = AirflowNetworkLinkageData(i).NodeNums[0];
10453 701 : int k = AirflowNetworkLinkageData(i).NodeNums[1];
10454 701 : if (AirflowNetworkNodeData(j).AirLoopNum == 0 && AirflowNetworkNodeData(k).AirLoopNum == 0) {
10455 : // Error messaage
10456 0 : ShowSevereError(m_state,
10457 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:LINKAGE = " + AirflowNetworkLinkageData(i).Name +
10458 : " is not valid for AirLoopNum assignment");
10459 0 : ShowContinueError(m_state,
10460 0 : "AirLoopNum is not found in both nodes for the linkage: " + AirflowNetworkLinkageData(i).NodeNames[0] + " and " +
10461 0 : AirflowNetworkLinkageData(i).NodeNames[1]);
10462 0 : ShowContinueError(m_state,
10463 : "Please ensure one of two AIRFLOWNETWORK:DISTRIBUTION:NODEs in the first AIRFLOWNETWORK:DISTRIBUTION:LINKAGE "
10464 : "object should be defined as EnergyPlus NodeID.");
10465 0 : ErrorsFound = true;
10466 : }
10467 701 : if (AirflowNetworkNodeData(j).AirLoopNum > 0 && AirflowNetworkNodeData(k).AirLoopNum == 0) {
10468 218 : AirflowNetworkNodeData(k).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10469 : }
10470 701 : if (AirflowNetworkNodeData(j).AirLoopNum == 0 && AirflowNetworkNodeData(k).AirLoopNum > 0) {
10471 7 : AirflowNetworkNodeData(j).AirLoopNum = AirflowNetworkNodeData(k).AirLoopNum;
10472 : }
10473 701 : if (AirflowNetworkNodeData(j).AirLoopNum == AirflowNetworkNodeData(k).AirLoopNum) {
10474 701 : AirflowNetworkLinkageData(i).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10475 : }
10476 701 : if (AirflowNetworkNodeData(j).AirLoopNum != AirflowNetworkNodeData(k).AirLoopNum && AirflowNetworkNodeData(j).AirLoopNum > 0 &&
10477 0 : AirflowNetworkNodeData(k).AirLoopNum > 0) {
10478 0 : AirflowNetworkLinkageData(i).AirLoopNum = AirflowNetworkNodeData(j).AirLoopNum;
10479 0 : ShowSevereError(m_state,
10480 0 : "The AirLoopNum defined in both AIRFLOWNETWORK:DISTRIBUTION:NODE objects in " + AirflowNetworkLinkageData(i).Name +
10481 : " are not the same. Please make sure both nodes should be listed in the same AirLoop as a valid linkage.");
10482 0 : ShowContinueError(m_state,
10483 0 : "AirLoop defined in " + AirflowNetworkNodeData(j).Name + " is " +
10484 0 : m_state.dataAirSystemsData->PrimaryAirSystems(AirflowNetworkNodeData(j).AirLoopNum).Name +
10485 0 : ", and AirLoop defined in " + AirflowNetworkNodeData(k).Name + " is " +
10486 0 : m_state.dataAirSystemsData->PrimaryAirSystems(AirflowNetworkNodeData(k).AirLoopNum).Name);
10487 0 : ErrorsFound = true;
10488 : }
10489 : // Set AirLoopNum to fans and coils
10490 701 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::FAN) {
10491 24 : n = m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).FanIndex;
10492 24 : m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).AirLoopNum =
10493 24 : AirflowNetworkLinkageData(i).AirLoopNum;
10494 24 : if (m_state.afn->DisSysCompCVFData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).FanModelFlag) {
10495 1 : m_state.dataFans
10496 1 : ->fans(m_state.afn->DisSysCompCVFData(m_state.afn->AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum)
10497 : .FanIndex)
10498 1 : ->airLoopNum = AirflowNetworkLinkageData(i).AirLoopNum;
10499 1 : m_state.dataFans
10500 1 : ->fans(m_state.afn->DisSysCompCVFData(m_state.afn->AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum)
10501 : .FanIndex)
10502 1 : ->isAFNFan = true;
10503 : } else {
10504 23 : m_state.dataFans->fans(n)->airLoopNum = AirflowNetworkLinkageData(i).AirLoopNum;
10505 23 : m_state.dataFans->fans(n)->isAFNFan = true;
10506 : }
10507 : }
10508 701 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).EPlusTypeNum == iEPlusComponentType::COI) {
10509 57 : m_state.afn->DisSysCompCoilData(AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum).AirLoopNum =
10510 57 : AirflowNetworkLinkageData(i).AirLoopNum;
10511 : }
10512 : }
10513 :
10514 : // Validate coil name and type
10515 23 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:Coil";
10516 23 : MultiSpeedHPIndicator = 0;
10517 80 : for (int i = 1; i <= DisSysNumOfCoils; ++i) {
10518 : {
10519 57 : auto const SELECT_CASE_var(Util::makeUPPER(DisSysCompCoilData(i).EPlusType));
10520 :
10521 57 : if (SELECT_CASE_var == "COIL:COOLING:DX") {
10522 0 : ValidateComponent(m_state, "Coil:Cooling:DX", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10523 0 : if (IsNotOK) {
10524 0 : ErrorsFound = true;
10525 : } else {
10526 : // Replace the convenience function with in-place code
10527 0 : std::string mycoil = DisSysCompCoilData(i).name;
10528 0 : auto it = std::find_if(m_state.dataCoilCooingDX->coilCoolingDXs.begin(),
10529 0 : m_state.dataCoilCooingDX->coilCoolingDXs.end(),
10530 0 : [&mycoil](const CoilCoolingDX &coil) { return coil.name == mycoil; });
10531 0 : if (it != m_state.dataCoilCooingDX->coilCoolingDXs.end()) {
10532 : // Set the airloop number on the CoilCoolingDX object, which is used to collect the runtime fraction
10533 0 : it->airLoopNum = DisSysCompCoilData(i).AirLoopNum;
10534 : } else {
10535 0 : ShowSevereError(m_state, "SetDXCoilAirLoopNumber: Could not find Coil \"Name=\"" + DisSysCompCoilData(i).name + "\"");
10536 : }
10537 : // SetDXCoilAirLoopNumber(DisSysCompCoilData(i).name,
10538 : // DisSysCompCoilData(i).AirLoopNum);
10539 0 : }
10540 57 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:SINGLESPEED") {
10541 44 : ValidateComponent(
10542 66 : m_state, "Coil:Cooling:DX:SingleSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10543 22 : if (IsNotOK) {
10544 0 : ErrorsFound = true;
10545 : } else {
10546 22 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10547 : }
10548 :
10549 35 : } else if (SELECT_CASE_var == "COIL:HEATING:DX:SINGLESPEED") {
10550 14 : ValidateComponent(
10551 21 : m_state, "Coil:Heating:DX:SingleSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10552 7 : if (IsNotOK) {
10553 0 : ErrorsFound = true;
10554 : } else {
10555 7 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10556 : }
10557 :
10558 28 : } else if (SELECT_CASE_var == "COIL:HEATING:FUEL") {
10559 22 : ValidateComponent(m_state, "Coil:Heating:Fuel", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10560 22 : if (IsNotOK) {
10561 0 : ErrorsFound = true;
10562 : } else {
10563 22 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10564 : }
10565 :
10566 6 : } else if (SELECT_CASE_var == "COIL:HEATING:ELECTRIC") {
10567 6 : ValidateComponent(
10568 9 : m_state, "Coil:Heating:Electric", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10569 3 : if (IsNotOK) {
10570 0 : ErrorsFound = true;
10571 : } else {
10572 3 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10573 : }
10574 :
10575 3 : } else if (SELECT_CASE_var == "COIL:COOLING:WATER") {
10576 0 : ValidateComponent(m_state, "Coil:Cooling:Water", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10577 0 : if (IsNotOK) {
10578 0 : ErrorsFound = true;
10579 : }
10580 :
10581 3 : } else if (SELECT_CASE_var == "COIL:HEATING:WATER") {
10582 0 : ValidateComponent(m_state, "Coil:Heating:Water", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10583 0 : if (IsNotOK) {
10584 0 : ErrorsFound = true;
10585 : }
10586 :
10587 3 : } else if (SELECT_CASE_var == "COIL:COOLING:WATER:DETAILEDGEOMETRY") {
10588 0 : ValidateComponent(m_state,
10589 : "Coil:Cooling:Water:DetailedGeometry",
10590 0 : DisSysCompCoilData(i).name,
10591 : IsNotOK,
10592 0 : format(RoutineName) + CurrentModuleObject);
10593 0 : if (IsNotOK) {
10594 0 : ErrorsFound = true;
10595 : }
10596 :
10597 3 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:TWOSTAGEWITHHUMIDITYCONTROLMODE") {
10598 0 : ValidateComponent(m_state,
10599 : "Coil:Cooling:DX:TwoStageWithHumidityControlMode",
10600 0 : DisSysCompCoilData(i).name,
10601 : IsNotOK,
10602 0 : format(RoutineName) + CurrentModuleObject);
10603 0 : if (IsNotOK) {
10604 0 : ErrorsFound = true;
10605 : } else {
10606 0 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10607 : }
10608 :
10609 3 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:MULTISPEED") {
10610 2 : ValidateComponent(
10611 3 : m_state, "Coil:Cooling:DX:MultiSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10612 1 : ++MultiSpeedHPIndicator;
10613 1 : if (IsNotOK) {
10614 0 : ErrorsFound = true;
10615 : } else {
10616 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10617 : }
10618 :
10619 2 : } else if (SELECT_CASE_var == "COIL:HEATING:DX:MULTISPEED") {
10620 2 : ValidateComponent(
10621 3 : m_state, "Coil:Heating:DX:MultiSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10622 1 : ++MultiSpeedHPIndicator;
10623 1 : if (IsNotOK) {
10624 0 : ErrorsFound = true;
10625 : } else {
10626 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10627 : }
10628 :
10629 1 : } else if (SELECT_CASE_var == "COIL:HEATING:DESUPERHEATER") {
10630 0 : ValidateComponent(
10631 0 : m_state, "Coil:Heating:Desuperheater", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10632 0 : if (IsNotOK) {
10633 0 : ErrorsFound = true;
10634 : }
10635 :
10636 1 : } else if (SELECT_CASE_var == "COIL:COOLING:DX:TWOSPEED") {
10637 2 : ValidateComponent(
10638 3 : m_state, "Coil:Cooling:DX:TwoSpeed", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10639 1 : if (IsNotOK) {
10640 0 : ErrorsFound = true;
10641 : } else {
10642 1 : SetDXCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum);
10643 : }
10644 0 : } else if (SELECT_CASE_var == "COIL:HEATING:ELECTRIC:MULTISTAGE") {
10645 0 : ValidateComponent(
10646 0 : m_state, "Coil:Heating:Electric:MultiStage", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10647 0 : if (IsNotOK) {
10648 0 : ErrorsFound = true;
10649 : } else {
10650 0 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10651 : }
10652 0 : } else if (SELECT_CASE_var == "COIL:HEATING:GAS:MULTISTAGE") {
10653 0 : ValidateComponent(
10654 0 : m_state, "Coil:Heating:Gas:MultiStage", DisSysCompCoilData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10655 0 : if (IsNotOK) {
10656 0 : ErrorsFound = true;
10657 : } else {
10658 0 : SetHeatingCoilAirLoopNumber(m_state, DisSysCompCoilData(i).name, DisSysCompCoilData(i).AirLoopNum, ErrorsFound);
10659 : }
10660 : } else {
10661 0 : ShowSevereError(m_state, format(RoutineName) + CurrentModuleObject + " Invalid coil type = " + DisSysCompCoilData(i).name);
10662 0 : ErrorsFound = true;
10663 : }
10664 57 : }
10665 : }
10666 :
10667 : // Validate terminal unit name and type
10668 47 : for (int i = 1; i <= DisSysNumOfTermUnits; ++i) {
10669 27 : if (Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:ConstantVolume:Reheat") ||
10670 27 : Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
10671 24 : LocalError = false;
10672 24 : if (Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:ConstantVolume:Reheat"))
10673 42 : GetHVACSingleDuctSysIndex(
10674 21 : m_state, DisSysCompTermUnitData(i).name, n, LocalError, "AirflowNetwork:Distribution:Component:TerminalUnit");
10675 24 : if (Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat"))
10676 6 : GetHVACSingleDuctSysIndex(m_state,
10677 3 : DisSysCompTermUnitData(i).name,
10678 : n,
10679 : LocalError,
10680 : "AirflowNetwork:Distribution:Component:TerminalUnit",
10681 3 : DisSysCompTermUnitData(i).DamperInletNode,
10682 3 : DisSysCompTermUnitData(i).DamperOutletNode);
10683 24 : if (LocalError) ErrorsFound = true;
10684 24 : if (VAVSystem) {
10685 6 : for (int j = 1; j <= DisSysNumOfCVFs; j++) {
10686 3 : if (DisSysCompCVFData(j).fanType == HVAC::FanType::VAV) {
10687 6 : if (DisSysCompCVFData(j).AirLoopNum == DisSysCompTermUnitData(i).AirLoopNum &&
10688 6 : !Util::SameString(DisSysCompTermUnitData(i).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
10689 0 : ShowSevereError(m_state,
10690 0 : format(RoutineName) + CurrentModuleObject +
10691 0 : " Invalid terminal type for a VAV system = " + DisSysCompTermUnitData(i).name);
10692 0 : ShowContinueError(m_state, "The input type = " + DisSysCompTermUnitData(i).EPlusType);
10693 0 : ShowContinueError(m_state, "A VAV system requires all terminal units with type = AirTerminal:SingleDuct:VAV:Reheat");
10694 0 : ErrorsFound = true;
10695 : }
10696 : }
10697 : }
10698 : }
10699 : } else {
10700 0 : ShowSevereError(m_state,
10701 0 : format(RoutineName) + "AIRFLOWNETWORK:DISTRIBUTION:COMPONENT TERMINAL UNIT: Invalid Terminal unit type = " +
10702 0 : DisSysCompTermUnitData(i).name);
10703 0 : ErrorsFound = true;
10704 : }
10705 : }
10706 :
10707 : // Validate heat exchanger name and type
10708 23 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:HeatExchanger";
10709 24 : for (int i = 1; i <= DisSysNumOfHXs; ++i) {
10710 : {
10711 1 : auto const SELECT_CASE_var(Util::makeUPPER(DisSysCompHXData(i).EPlusType));
10712 :
10713 1 : if (SELECT_CASE_var == "HEATEXCHANGER:AIRTOAIR:FLATPLATE") {
10714 0 : ValidateComponent(
10715 0 : m_state, "HeatExchanger:AirToAir:FlatPlate", DisSysCompHXData(i).name, IsNotOK, format(RoutineName) + CurrentModuleObject);
10716 0 : if (IsNotOK) {
10717 0 : ErrorsFound = true;
10718 : }
10719 :
10720 1 : } else if (SELECT_CASE_var == "HEATEXCHANGER:AIRTOAIR:SENSIBLEANDLATENT") {
10721 0 : ValidateComponent(m_state,
10722 : "HeatExchanger:AirToAir:SensibleAndLatent",
10723 0 : DisSysCompHXData(i).name,
10724 : IsNotOK,
10725 0 : format(RoutineName) + CurrentModuleObject);
10726 0 : if (IsNotOK) {
10727 0 : ErrorsFound = true;
10728 : }
10729 :
10730 1 : } else if (SELECT_CASE_var == "HEATEXCHANGER:DESICCANT:BALANCEDFLOW") {
10731 2 : ValidateComponent(m_state,
10732 : "HeatExchanger:Desiccant:BalancedFlow",
10733 1 : DisSysCompHXData(i).name,
10734 : IsNotOK,
10735 2 : format(RoutineName) + CurrentModuleObject);
10736 1 : if (IsNotOK) {
10737 0 : ErrorsFound = true;
10738 : }
10739 :
10740 : } else {
10741 0 : ShowSevereError(m_state,
10742 0 : format(RoutineName) + CurrentModuleObject + " Invalid heat exchanger type = " + DisSysCompHXData(i).EPlusType);
10743 0 : ErrorsFound = true;
10744 : }
10745 1 : }
10746 : }
10747 :
10748 : // Assign supply and return connection
10749 47 : for (int j = 1; j <= NumPrimaryAirSys; ++j) {
10750 24 : int S1 = 0;
10751 24 : int S2 = 0;
10752 24 : int R1 = 0;
10753 24 : int R2 = 0;
10754 811 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
10755 787 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).AirLoopSupplyNodeNum(1)) S1 = i;
10756 787 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).ZoneEquipSupplyNodeNum(1)) S2 = i;
10757 787 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).ZoneEquipReturnNodeNum(1)) R1 = i;
10758 787 : if (AirflowNetworkNodeData(i).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(j).AirLoopReturnNodeNum(1)) R2 = i;
10759 : }
10760 1128 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
10761 1104 : if (AirflowNetworkLinkageData(i).NodeNums[0] == R1 && AirflowNetworkLinkageData(i).NodeNums[1] == R2) {
10762 16 : AirflowNetworkLinkageData(i).ConnectionFlag = iEPlusComponentType::RCN;
10763 : }
10764 1104 : if (AirflowNetworkLinkageData(i).NodeNums[0] == S1 && AirflowNetworkLinkageData(i).NodeNums[1] == S2) {
10765 24 : AirflowNetworkLinkageData(i).ConnectionFlag = iEPlusComponentType::SCN;
10766 : }
10767 : }
10768 : }
10769 :
10770 : // Assign fan inlet and outlet node, and coil outlet
10771 1053 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
10772 1030 : int j = AirflowNetworkLinkageData(i).CompNum;
10773 1030 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::CVF) {
10774 24 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::Invalid)
10775 24 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum = iEPlusNodeType::FIN;
10776 24 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::FOU;
10777 : }
10778 1030 : if (AirflowNetworkCompData(j).EPlusTypeNum == iEPlusComponentType::COI) {
10779 57 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::COU;
10780 : }
10781 1030 : if (AirflowNetworkCompData(j).EPlusTypeNum == iEPlusComponentType::HEX) {
10782 2 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::HXO;
10783 : }
10784 1030 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::TMU) {
10785 27 : if (DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperInletNode > 0) {
10786 6 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum ==
10787 9 : DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperInletNode &&
10788 3 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum ==
10789 3 : DisSysCompTermUnitData(AirflowNetworkCompData(j).TypeNum).DamperOutletNode) {
10790 3 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum = iEPlusNodeType::DIN;
10791 3 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum = iEPlusNodeType::DOU;
10792 3 : AirflowNetworkLinkageData(i).VAVTermDamper = true;
10793 : }
10794 : }
10795 : }
10796 : }
10797 :
10798 : // Validate the position of constant pressure drop component
10799 23 : CurrentModuleObject = "AirflowNetwork:Distribution:Component:ConstantPressureDrop";
10800 1053 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
10801 1030 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::CPD) {
10802 741 : for (int j = 1; j <= AirflowNetworkNumOfLinks; ++j) {
10803 729 : if (AirflowNetworkLinkageData(i).NodeNums[0] == AirflowNetworkLinkageData(j).NodeNums[1]) {
10804 12 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(j).CompNum).CompTypeNum != iComponentTypeNum::DWC) {
10805 0 : ShowSevereError(m_state,
10806 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName +
10807 : ')');
10808 0 : ShowContinueError(m_state, "must connect a duct component upstream and not " + AirflowNetworkLinkageData(j).Name);
10809 0 : ErrorsFound = true;
10810 : }
10811 : }
10812 : }
10813 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::SPL) {
10814 0 : ShowSevereError(m_state,
10815 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10816 0 : ShowContinueError(m_state,
10817 0 : "does not allow a AirLoopHVAC:ZoneSplitter node = " +
10818 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10819 0 : ErrorsFound = true;
10820 : }
10821 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum == iEPlusNodeType::SPL) {
10822 0 : ShowSevereError(m_state,
10823 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10824 0 : ShowContinueError(m_state,
10825 0 : "does not allow a AirLoopHVAC:ZoneSplitter node = " +
10826 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10827 0 : ErrorsFound = true;
10828 : }
10829 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusTypeNum == iEPlusNodeType::MIX) {
10830 0 : ShowSevereError(m_state,
10831 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10832 0 : ShowContinueError(m_state,
10833 0 : "does not allow a AirLoopHVAC:ZoneMixer node = " +
10834 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10835 0 : ErrorsFound = true;
10836 : }
10837 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusTypeNum == iEPlusNodeType::MIX) {
10838 0 : ShowSevereError(m_state,
10839 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10840 0 : ShowContinueError(m_state,
10841 0 : "does not allow a AirLoopHVAC:ZoneMixer node = " +
10842 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10843 0 : ErrorsFound = true;
10844 : }
10845 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusNodeNum > 0) {
10846 0 : ShowSevereError(m_state,
10847 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10848 0 : ShowContinueError(m_state,
10849 0 : "does not allow to connect an EnergyPlus node = " +
10850 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10851 0 : ErrorsFound = true;
10852 : }
10853 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusNodeNum > 0) {
10854 0 : ShowSevereError(m_state,
10855 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10856 0 : ShowContinueError(m_state,
10857 0 : "does not allow to connect an EnergyPlus node = " +
10858 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10859 0 : ErrorsFound = true;
10860 : }
10861 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum > 0) {
10862 0 : ShowSevereError(m_state,
10863 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10864 0 : ShowContinueError(m_state,
10865 0 : "does not allow to connect an EnergyPlus zone = " +
10866 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).Name);
10867 0 : ErrorsFound = true;
10868 : }
10869 12 : if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).EPlusZoneNum > 0) {
10870 0 : ShowSevereError(m_state,
10871 0 : format(RoutineName) + "An " + CurrentModuleObject + " object (" + AirflowNetworkLinkageData(i).CompName + ')');
10872 0 : ShowContinueError(m_state,
10873 0 : "does not allow to connect an EnergyPlus zone = " +
10874 0 : AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[1]).Name);
10875 0 : ErrorsFound = true;
10876 : }
10877 : }
10878 : }
10879 :
10880 551 : for (int i = NumOfNodesMultiZone + 1; i <= AirflowNetworkNumOfNodes; ++i) {
10881 528 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::SPL) {
10882 24 : LocalError = false;
10883 24 : int j = GetSplitterOutletNumber(m_state, "", 1, LocalError);
10884 24 : SplitterNodeNumbers.allocate(j + 2);
10885 24 : SplitterNodeNumbers = GetSplitterNodeNumbers(m_state, "", 1, LocalError);
10886 24 : if (LocalError) ErrorsFound = true;
10887 : }
10888 : }
10889 :
10890 : // Assigning inlet and outlet nodes for a splitter
10891 758 : for (int i = 1; i <= AirflowNetworkNumOfNodes; ++i) {
10892 735 : if (AirflowNetworkNodeData(i).EPlusNodeNum == SplitterNodeNumbers(1)) {
10893 23 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::Invalid) AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPI;
10894 : }
10895 2424 : for (int j = 1; j <= SplitterNodeNumbers(2); ++j) {
10896 1689 : if (AirflowNetworkNodeData(i).EPlusNodeNum == SplitterNodeNumbers(j + 2)) {
10897 48 : if (AirflowNetworkNodeData(i).EPlusTypeNum == iEPlusNodeType::Invalid)
10898 45 : AirflowNetworkNodeData(i).EPlusTypeNum = iEPlusNodeType::SPO;
10899 : }
10900 : }
10901 : }
10902 :
10903 : // Add additional output variables
10904 23 : if (DisSysNumOfCVFs > 1) {
10905 1 : bool OnOffFanFlag = false;
10906 2 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
10907 2 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff && !DisSysCompCVFData(i).FanModelFlag) {
10908 1 : OnOffFanFlag = true;
10909 1 : break;
10910 : }
10911 1 : if (DisSysCompCVFData(i).FanModelFlag && DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff) {
10912 0 : int fanIndex = Fans::GetFanIndex(m_state, DisSysCompCVFData(i).name);
10913 0 : if (m_state.dataFans->fans(fanIndex)->airPathFlag) {
10914 0 : DisSysCompCVFData(i).fanType = HVAC::FanType::Constant;
10915 : } else {
10916 0 : OnOffFanFlag = true;
10917 0 : break;
10918 : }
10919 : }
10920 : }
10921 1 : if (OnOffFanFlag) {
10922 6 : for (int j = 1; j <= AirflowNetworkNumOfZones; ++j) {
10923 5 : if (!m_state.dataZoneEquip->ZoneEquipConfig(AirflowNetworkNodeData(j).EPlusZoneNum).IsControlled) continue;
10924 9 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
10925 9 : if (DisSysCompCVFData(i).AirLoopNum == AirflowNetworkNodeData(j).AirLoopNum &&
10926 3 : DisSysCompCVFData(i).fanType != HVAC::FanType::OnOff) {
10927 4 : SetupOutputVariable(m_state,
10928 : "AFN Node Total Pressure",
10929 : Constant::Units::Pa,
10930 2 : AirflowNetworkNodeSimu(j).PZ,
10931 : OutputProcessor::TimeStepType::System,
10932 : OutputProcessor::StoreType::Average,
10933 2 : AirflowNetworkNodeData(j).Name);
10934 : }
10935 : }
10936 : }
10937 22 : for (int i = 1; i <= NumOfLinksMultiZone; ++i) {
10938 21 : if (!m_state.dataZoneEquip->ZoneEquipConfig(AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).EPlusZoneNum)
10939 21 : .IsControlled)
10940 5 : continue;
10941 48 : for (int j = 1; j <= DisSysNumOfCVFs; j++) {
10942 48 : if (DisSysCompCVFData(j).AirLoopNum == AirflowNetworkNodeData(AirflowNetworkLinkageData(i).NodeNums[0]).AirLoopNum &&
10943 16 : DisSysCompCVFData(j).fanType != HVAC::FanType::OnOff) {
10944 22 : SetupOutputVariable(m_state,
10945 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
10946 : Constant::Units::kg_s,
10947 11 : linkReport(i).FLOW,
10948 : OutputProcessor::TimeStepType::System,
10949 : OutputProcessor::StoreType::Average,
10950 11 : AirflowNetworkLinkageData(i).Name);
10951 22 : SetupOutputVariable(m_state,
10952 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
10953 : Constant::Units::kg_s,
10954 11 : linkReport(i).FLOW2,
10955 : OutputProcessor::TimeStepType::System,
10956 : OutputProcessor::StoreType::Average,
10957 11 : AirflowNetworkLinkageData(i).Name);
10958 22 : SetupOutputVariable(m_state,
10959 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
10960 : Constant::Units::m3_s,
10961 11 : linkReport(i).VolFLOW,
10962 : OutputProcessor::TimeStepType::System,
10963 : OutputProcessor::StoreType::Average,
10964 11 : AirflowNetworkLinkageData(i).Name);
10965 22 : SetupOutputVariable(m_state,
10966 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
10967 : Constant::Units::m3_s,
10968 11 : linkReport(i).VolFLOW2,
10969 : OutputProcessor::TimeStepType::System,
10970 : OutputProcessor::StoreType::Average,
10971 11 : AirflowNetworkLinkageData(i).Name);
10972 22 : SetupOutputVariable(m_state,
10973 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
10974 : Constant::Units::Pa,
10975 11 : AirflowNetworkLinkSimu(i).DP,
10976 : OutputProcessor::TimeStepType::System,
10977 : OutputProcessor::StoreType::Average,
10978 11 : AirflowNetworkLinkageData(i).Name);
10979 : }
10980 : }
10981 : }
10982 : }
10983 : }
10984 23 : bool FanModelConstFlag = false;
10985 47 : for (int i = 1; i <= DisSysNumOfCVFs; i++) {
10986 24 : if (DisSysCompCVFData(i).FanModelFlag) {
10987 1 : int fanIndex = Fans::GetFanIndex(m_state, DisSysCompCVFData(i).name); // What is this accomplishing here?
10988 1 : if (DisSysCompCVFData(i).fanType == HVAC::FanType::OnOff && m_state.dataFans->fans(fanIndex)->airPathFlag) {
10989 0 : DisSysCompCVFData(i).fanType = HVAC::FanType::Constant;
10990 0 : supplyFanType = HVAC::FanType::Constant;
10991 0 : FanModelConstFlag = true;
10992 0 : break;
10993 : }
10994 : }
10995 : }
10996 23 : if (FanModelConstFlag) {
10997 0 : for (int i = 1; i <= AirflowNetworkNumOfSurfaces; ++i) {
10998 0 : if (supplyFanType == HVAC::FanType::Constant) {
10999 0 : SetupOutputVariable(m_state,
11000 : "AFN Linkage Node 1 to Node 2 Mass Flow Rate",
11001 : Constant::Units::kg_s,
11002 0 : linkReport(i).FLOW,
11003 : OutputProcessor::TimeStepType::System,
11004 : OutputProcessor::StoreType::Average,
11005 0 : AirflowNetworkLinkageData(i).Name);
11006 0 : SetupOutputVariable(m_state,
11007 : "AFN Linkage Node 2 to Node 1 Mass Flow Rate",
11008 : Constant::Units::kg_s,
11009 0 : linkReport(i).FLOW2,
11010 : OutputProcessor::TimeStepType::System,
11011 : OutputProcessor::StoreType::Average,
11012 0 : AirflowNetworkLinkageData(i).Name);
11013 0 : SetupOutputVariable(m_state,
11014 : "AFN Linkage Node 1 to Node 2 Volume Flow Rate",
11015 : Constant::Units::m3_s,
11016 0 : linkReport(i).VolFLOW,
11017 : OutputProcessor::TimeStepType::System,
11018 : OutputProcessor::StoreType::Average,
11019 0 : AirflowNetworkLinkageData(i).Name);
11020 0 : SetupOutputVariable(m_state,
11021 : "AFN Linkage Node 2 to Node 1 Volume Flow Rate",
11022 : Constant::Units::m3_s,
11023 0 : linkReport(i).VolFLOW2,
11024 : OutputProcessor::TimeStepType::System,
11025 : OutputProcessor::StoreType::Average,
11026 0 : AirflowNetworkLinkageData(i).Name);
11027 0 : SetupOutputVariable(m_state,
11028 : "AFN Linkage Node 1 to Node 2 Pressure Difference",
11029 : Constant::Units::Pa,
11030 0 : AirflowNetworkLinkSimu(i).DP,
11031 : OutputProcessor::TimeStepType::System,
11032 : OutputProcessor::StoreType::Average,
11033 0 : AirflowNetworkLinkageData(i).Name);
11034 : }
11035 : }
11036 : }
11037 :
11038 : // Add AirLoopNum to pressure control object
11039 24 : for (int i = 1; i <= NumOfPressureControllers; ++i) {
11040 5 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11041 4 : if (PressureControllerData(i).ZoneNum == j) {
11042 2 : for (int k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumInletNodes; ++k) {
11043 1 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(k) > 0) {
11044 1 : PressureControllerData(i).AirLoopNum = m_state.dataZoneEquip->ZoneEquipConfig(j).InletNodeAirLoopNum(k);
11045 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlRelief) {
11046 2 : PressureControllerData(i).OANodeNum =
11047 1 : m_state.dataAirSystemsData->PrimaryAirSystems(PressureControllerData(i).AirLoopNum).OAMixOAInNodeNum;
11048 2 : for (n = 1; n <= NumOfReliefFans; ++n) {
11049 1 : if (DisSysCompReliefAirData(n).OutletNode == PressureControllerData(i).OANodeNum) {
11050 1 : DisSysCompReliefAirData(n).PressCtrlNum = i;
11051 : }
11052 : }
11053 : }
11054 1 : if (PressureControllerData(i).ControlTypeSet == PressureCtrlExhaust) {
11055 0 : PressureControllerData(i).OANodeNum =
11056 0 : m_state.dataZoneEquip->ZoneEquipConfig(PressureControllerData(i).ZoneNum).ExhaustNode(1);
11057 0 : for (n = 1; n <= AirflowNetworkNumOfExhFan; ++n) {
11058 0 : if (MultizoneCompExhaustFanData(n).EPlusZoneNum == PressureControllerData(i).ZoneNum) {
11059 0 : MultizoneCompExhaustFanData(n).PressCtrlNum = i;
11060 : }
11061 : }
11062 : }
11063 : }
11064 : }
11065 : }
11066 : }
11067 : }
11068 :
11069 : // Check number of fans specified in an AirLoop #6748
11070 : int BranchNum;
11071 : int NumOfFans;
11072 23 : std::string FanNames;
11073 46 : for (BranchNum = 1; BranchNum <= m_state.dataAirSystemsData->PrimaryAirSystems(1).NumBranches; ++BranchNum) {
11074 23 : NumOfFans = 0;
11075 23 : FanNames = "";
11076 87 : for (int CompNum = 1; CompNum <= m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).TotalComponents; ++CompNum) {
11077 115 : if (Util::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf, "Fan:ConstantVolume") ||
11078 115 : Util::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf, "Fan:OnOff") ||
11079 115 : Util::SameString(m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).TypeOf, "Fan:VariableVolume")) {
11080 14 : NumOfFans++;
11081 14 : if (NumOfFans > 1) {
11082 0 : FanNames += m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).Name;
11083 0 : break;
11084 : } else {
11085 14 : FanNames += m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Comp(CompNum).Name + ",";
11086 : }
11087 : }
11088 : }
11089 23 : if (NumOfFans > 1) break;
11090 : }
11091 23 : if (NumOfFans > 1) {
11092 0 : ShowSevereError(m_state,
11093 0 : format(RoutineName) + "An AirLoop branch, " + m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Name +
11094 0 : ", has two or more fans: " + FanNames);
11095 0 : ShowContinueError(m_state,
11096 : "The AirflowNetwork model allows a single supply fan in an AirLoop only. Please make changes in the input "
11097 : "file accordingly.");
11098 0 : ErrorsFound = true;
11099 : }
11100 :
11101 23 : if (ErrorsFound) {
11102 0 : ShowFatalError(m_state, format("{}Program terminates for preceding reason(s).", RoutineName));
11103 : }
11104 23 : }
11105 :
11106 23 : void Solver::validate_fan_flowrate()
11107 : {
11108 :
11109 : // Catch a fan flow rate from EPlus input file and add a flag for VAV terminal damper
11110 1053 : for (int i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
11111 1030 : switch (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum) {
11112 24 : case iComponentTypeNum::CVF: { // 'CVF'
11113 24 : int typeNum = AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).TypeNum;
11114 24 : if (DisSysCompCVFData(typeNum).fanType == HVAC::FanType::VAV) {
11115 1 : DisSysCompCVFData(typeNum).MaxAirMassFlowRate =
11116 1 : m_state.dataFans->fans(DisSysCompCVFData(typeNum).FanIndex)->maxAirFlowRate * m_state.dataEnvrn->StdRhoAir;
11117 : }
11118 24 : } break;
11119 42 : case iComponentTypeNum::FAN:
11120 : case iComponentTypeNum::SOP:
11121 : case iComponentTypeNum::TMU:
11122 42 : break;
11123 964 : default:
11124 964 : break;
11125 : }
11126 : }
11127 23 : }
11128 :
11129 541114 : void Solver::validate_exhaust_fan_input()
11130 : {
11131 :
11132 : // SUBROUTINE INFORMATION:
11133 : // AUTHOR Lixing Gu
11134 : // DATE WRITTEN Dec. 2006
11135 : // MODIFIED na
11136 : // RE-ENGINEERED na
11137 :
11138 : // PURPOSE OF THIS SUBROUTINE:
11139 : // This subroutine validate zone exhaust fan and associated surface
11140 :
11141 : // SUBROUTINE PARAMETER DEFINITIONS:
11142 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::validate_exhaust_fan_input: "); // include trailing blank space
11143 :
11144 : // Validate supply and return connections
11145 541114 : if (ValidateExhaustFanInputOneTimeFlag) {
11146 35 : bool ErrorsFound = false;
11147 35 : std::string const CurrentModuleObject = "AirflowNetwork:MultiZone:Component:ZoneExhaustFan";
11148 35 : if (std::any_of(m_state.dataZoneEquip->ZoneEquipConfig.begin(),
11149 35 : m_state.dataZoneEquip->ZoneEquipConfig.end(),
11150 52 : [](DataZoneEquipment::EquipConfiguration const &e) { return e.IsControlled; })) {
11151 26 : AirflowNetworkZoneExhaustFan.dimension(m_state.dataGlobal->NumOfZones, false);
11152 : }
11153 : // Ensure the number of exhaust fan defined in the AirflowNetwork model matches the number of Zone Exhaust Fan objects
11154 35 : if (NumOfExhaustFans != AirflowNetworkNumOfExhFan) {
11155 0 : ShowSevereError(
11156 : m_state,
11157 0 : format("{}The number of {} is not equal to the number of Fan:ZoneExhaust fans defined in ZoneHVAC:EquipmentConnections",
11158 : RoutineName,
11159 : CurrentModuleObject));
11160 0 : ShowContinueError(m_state, format("The number of {} is {}", CurrentModuleObject, AirflowNetworkNumOfExhFan));
11161 0 : ShowContinueError(m_state,
11162 0 : format("The number of Zone exhaust fans defined in ZoneHVAC:EquipmentConnections is {}", NumOfExhaustFans));
11163 0 : ErrorsFound = true;
11164 : }
11165 :
11166 49 : for (int i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
11167 : // Get zone number
11168 66 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11169 52 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) continue;
11170 39 : for (int k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumExhaustNodes; ++k) {
11171 15 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).ExhaustNode(k) == MultizoneCompExhaustFanData(i).InletNode) {
11172 14 : MultizoneCompExhaustFanData(i).EPlusZoneNum = j;
11173 14 : break;
11174 : }
11175 : }
11176 : }
11177 14 : if (MultizoneCompExhaustFanData(i).EPlusZoneNum == 0) {
11178 0 : ShowSevereError(m_state,
11179 0 : format("{}Zone name in {} = {} does not match the zone name in ZoneHVAC:EquipmentConnections",
11180 : RoutineName,
11181 : CurrentModuleObject,
11182 0 : MultizoneCompExhaustFanData(i).name));
11183 0 : ErrorsFound = true;
11184 : }
11185 : // Ensure a surface using zone exhaust fan to expose to the same zone
11186 14 : bool found = false;
11187 : int j;
11188 220 : for (j = 1; j <= AirflowNetworkNumOfSurfaces; ++j) {
11189 220 : if (Util::SameString(MultizoneSurfaceData(j).OpeningName, MultizoneCompExhaustFanData(i).name)) {
11190 14 : found = true;
11191 14 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).ExtBoundCond != ExternalEnvironment &&
11192 0 : !(m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt &&
11193 0 : m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).ExtWind)) {
11194 0 : ShowSevereError(m_state,
11195 0 : format("{}The surface using {} is not an exterior surface: {}",
11196 : RoutineName,
11197 : CurrentModuleObject,
11198 0 : MultizoneSurfaceData(j).SurfName));
11199 0 : ErrorsFound = true;
11200 : }
11201 14 : break;
11202 : }
11203 : }
11204 14 : if (!found) {
11205 0 : ShowSevereError(m_state, CurrentModuleObject + " = " + MultizoneCompExhaustFanData(i).name + " is defined and never used.");
11206 0 : ErrorsFound = true;
11207 : } else {
11208 14 : if (MultizoneCompExhaustFanData(i).EPlusZoneNum != m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Zone) {
11209 0 : ShowSevereError(m_state,
11210 0 : format("{}Zone name in {} = {} does not match the zone name",
11211 : RoutineName,
11212 : CurrentModuleObject,
11213 0 : MultizoneCompExhaustFanData(i).name));
11214 0 : ShowContinueError(m_state, "the surface is exposed to " + m_state.dataSurface->Surface(MultizoneSurfaceData(j).SurfNum).Name);
11215 0 : ErrorsFound = true;
11216 : } else {
11217 14 : AirflowNetworkZoneExhaustFan(MultizoneCompExhaustFanData(i).EPlusZoneNum) = true;
11218 : }
11219 : }
11220 : }
11221 :
11222 : // Ensure all zone exhaust fans are defined
11223 150 : for (int j = 1; j <= m_state.dataGlobal->NumOfZones; ++j) {
11224 115 : if (!m_state.dataZoneEquip->ZoneEquipConfig(j).IsControlled) continue;
11225 127 : for (int EquipTypeNum = 1; EquipTypeNum <= m_state.dataZoneEquip->ZoneEquipList(j).NumOfEquipTypes; ++EquipTypeNum) {
11226 73 : if (m_state.dataZoneEquip->ZoneEquipList(j).EquipType(EquipTypeNum) == DataZoneEquipment::ZoneEquipType::ExhaustFan) {
11227 14 : bool found = false;
11228 31 : for (int k = 1; k <= m_state.dataZoneEquip->ZoneEquipConfig(j).NumExhaustNodes; ++k) {
11229 34 : for (int i = 1; i <= AirflowNetworkNumOfExhFan; ++i) {
11230 17 : if (m_state.dataZoneEquip->ZoneEquipConfig(j).ExhaustNode(k) == MultizoneCompExhaustFanData(i).InletNode) {
11231 14 : MultizoneCompExhaustFanData(i).EPlusZoneNum = j;
11232 14 : found = true;
11233 : }
11234 : }
11235 17 : if (!found) {
11236 0 : ShowSevereError(m_state, format("{}Fan:ZoneExhaust is not defined in {}", RoutineName, CurrentModuleObject));
11237 0 : ShowContinueError(m_state,
11238 0 : "Zone Air Exhaust Node in ZoneHVAC:EquipmentConnections =" +
11239 0 : m_state.dataLoopNodes->NodeID(m_state.dataZoneEquip->ZoneEquipConfig(j).ExhaustNode(k)));
11240 0 : ErrorsFound = true;
11241 : }
11242 : }
11243 : }
11244 : }
11245 : }
11246 :
11247 35 : ValidateExhaustFanInputOneTimeFlag = false;
11248 35 : if (ErrorsFound) {
11249 0 : ShowFatalError(m_state, format("{}Program terminates for preceding reason(s).", RoutineName));
11250 : }
11251 35 : } // End if OneTimeFlag_FindFirstLastPtr
11252 541114 : }
11253 :
11254 82088 : void Solver::hybrid_ventilation_control()
11255 : {
11256 :
11257 : // SUBROUTINE INFORMATION:
11258 : // AUTHOR Lixing Gu
11259 : // DATE WRITTEN Dec. 2006
11260 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone hybrid ventilation managers
11261 :
11262 : // PURPOSE OF THIS SUBROUTINE:
11263 : // This subroutine performs hybrid ventilation control
11264 :
11265 : // SUBROUTINE PARAMETER DEFINITIONS:
11266 82088 : int constexpr IndividualCtrlType(0); // Individual window or door control
11267 82088 : int constexpr GlobalCtrlType(1); // Global window or door control
11268 : static constexpr std::string_view RoutineName("AirflowNetwork::Solver::hybrid_ventilation_control: "); // include trailing blank space
11269 :
11270 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11271 : int SysAvailNum; // Hybrid ventilation control number
11272 : int ControlledZoneNum; // Controlled zone number
11273 : int ANSurfaceNum; // AirflowNetwork Surface Number
11274 : int SurfNum; // Surface number
11275 : int ControlType; // Hybrid ventilation control type: 0 individual; 1 global
11276 :
11277 1772248 : for (auto &e : MultizoneSurfaceData) {
11278 1690160 : e.HybridVentClose = false;
11279 1690160 : e.HybridCtrlGlobal = false;
11280 1690160 : e.HybridCtrlMaster = false;
11281 1690160 : e.WindModifier = 1.0;
11282 82088 : }
11283 82088 : ControlType = IndividualCtrlType;
11284 :
11285 180929 : for (SysAvailNum = 1; SysAvailNum <= m_state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
11286 98841 : auto &hybridVentMgr = m_state.dataAvail->HybridVentData(SysAvailNum);
11287 98841 : int AirLoopNum = hybridVentMgr.AirLoopNum;
11288 98841 : ventCtrlStatus = hybridVentMgr.ctrlStatus;
11289 98841 : if (hybridVentMgr.ANCtrlStatus > 0) {
11290 43233 : ControlType = static_cast<int>(GetCurrentScheduleValue(m_state, hybridVentMgr.ANCtrlStatus));
11291 : }
11292 98841 : bool Found = false; // Logical to indicate whether a master surface is found or not
11293 98841 : int ActualZoneNum = 0;
11294 494205 : for (ControlledZoneNum = 1; ControlledZoneNum <= m_state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
11295 395364 : if (!m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).IsControlled) continue;
11296 : // Ensure all the zones served by this AirLoopHVAC to be controlled by the hybrid ventilation
11297 363552 : for (int zoneInNode = 1; zoneInNode <= m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
11298 296523 : if (AirLoopNum > 0) {
11299 246246 : if (AirLoopNum == m_state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode)) {
11300 229494 : ActualZoneNum = ControlledZoneNum;
11301 229494 : break;
11302 : }
11303 : } else {
11304 50277 : if (hybridVentMgr.ControlledZoneNum == ControlledZoneNum) {
11305 16759 : ActualZoneNum = hybridVentMgr.ControlledZoneNum;
11306 : }
11307 : }
11308 : }
11309 296523 : if (ActualZoneNum > 0) {
11310 6053634 : for (ANSurfaceNum = 1; ANSurfaceNum <= AirflowNetworkNumOfSurfaces; ++ANSurfaceNum) {
11311 5773875 : SurfNum = MultizoneSurfaceData(ANSurfaceNum).SurfNum;
11312 5773875 : auto const &surf = m_state.dataSurface->Surface(SurfNum);
11313 :
11314 5773875 : if (surf.Zone == ActualZoneNum) {
11315 1711874 : if (ventCtrlStatus == Avail::VentCtrlStatus::Close) {
11316 877270 : MultizoneSurfaceData(ANSurfaceNum).HybridVentClose = true;
11317 : } else {
11318 834604 : if (hybridVentMgr.WindModifier >= 0) {
11319 157744 : MultizoneSurfaceData(ANSurfaceNum).WindModifier = hybridVentMgr.WindModifier;
11320 : }
11321 834604 : if (ControlType == GlobalCtrlType) {
11322 240254 : MultizoneSurfaceData(ANSurfaceNum).HybridCtrlGlobal = true;
11323 240254 : if (hybridVentMgr.Master == ActualZoneNum) {
11324 202524 : if ((surf.OriginalClass == SurfaceClass::Window || surf.OriginalClass == SurfaceClass::Door ||
11325 131460 : surf.OriginalClass == SurfaceClass::GlassDoor) &&
11326 71064 : surf.ExtBoundCond == ExternalEnvironment) {
11327 27408 : MultizoneSurfaceData(ANSurfaceNum).HybridCtrlMaster = true;
11328 27408 : Found = true;
11329 : }
11330 : }
11331 : }
11332 : }
11333 : }
11334 : }
11335 : }
11336 : }
11337 98841 : if (ControlType == GlobalCtrlType && !Found && !m_state.dataGlobal->WarmupFlag && ventCtrlStatus != Avail::VentCtrlStatus::Close) {
11338 0 : ++HybridGlobalErrCount;
11339 0 : if (HybridGlobalErrCount < 2) {
11340 0 : ShowWarningError(m_state,
11341 0 : format("{}The hybrid ventilation control schedule value indicates global control in the controlled zone = {}",
11342 : RoutineName,
11343 0 : m_state.dataHeatBal->Zone(hybridVentMgr.Master).Name));
11344 0 : ShowContinueError(m_state,
11345 : "The exterior surface containing an opening component in the controlled zone is not found. No global control "
11346 : "will not be modeled.");
11347 0 : ShowContinueError(m_state, "The individual control is assumed.");
11348 0 : ShowContinueErrorTimeStamp(m_state, "");
11349 : } else {
11350 0 : ShowRecurringWarningErrorAtEnd(
11351 : m_state,
11352 0 : format("{}The hybrid ventilation control requires a global control. The individual control continues...", RoutineName),
11353 0 : HybridGlobalErrIndex,
11354 0 : double(ControlType),
11355 0 : double(ControlType));
11356 : }
11357 : }
11358 : }
11359 82088 : }
11360 :
11361 1 : void Solver::single_sided_Cps(std::vector<std::vector<Real64>> &valsByFacade, int numWindDir)
11362 : {
11363 : // SUBROUTINE INFORMATION:
11364 : // AUTHOR Sam Brunswick
11365 : // DATE WRITTEN September 2013
11366 : // MODIFIED Revised by J. DeGraw, May 2017, to use tables
11367 : // RE-ENGINEERED n/a
11368 :
11369 : // PURPOSE OF THIS SUBROUTINE:
11370 : // Modify the wind pressure coefficients for single sided ventilation.
11371 :
11372 : // Using/Aliasing
11373 : using namespace DataEnvironment;
11374 :
11375 : // Locals
11376 : int windDirNum;
11377 :
11378 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11379 : int AFNZnNum; // counters
11380 : int SrfNum;
11381 : int ExtOpenNum;
11382 : int ZnNum;
11383 : int DetOpenNum; // row index of surface in MultizoneCompDetOpeningData
11384 : int SimOpenNum; // row index of surface in MultizoneCompSimOpeningData
11385 : int MZDZoneNum; // row index of surface zone in MultizoneZoneData
11386 : Real64 X1;
11387 : Real64 Y1;
11388 : Real64 X2;
11389 : Real64 Y2;
11390 : Real64 ZoneAng1;
11391 : Real64 ZoneAng2;
11392 : Real64 ZoneAngDiff;
11393 1 : Array1D<Real64> ZoneAng; // Azimuth angle of the exterior wall of the zone
11394 1 : Array1D<Real64> PiFormula; // Formula for the mean pressure difference
11395 1 : Array1D<Real64> SigmaFormula; // Formula for the fluctuating pressure difference
11396 1 : Array1D<Real64> Sprime; // The dimensionless ratio of the window separation to the building width
11397 1 : Array1D<Real64> CPV1; // Wind pressure coefficient for the first opening in the zone
11398 1 : Array1D<Real64> CPV2; // Wind pressure coefficient for the second opening in the zone
11399 1 : Array1D_int NumofExtSurfInZone; // List of the number of exterior openings in each zone
11400 :
11401 : struct AFNExtSurfacesProp // External opening information
11402 : {
11403 : // Members
11404 : int SurfNum; // row index of the external opening in the Surface array
11405 : std::string SurfName; // Surface name
11406 : int MSDNum; // row index of the external opening in the MultizoneSurfaceData array
11407 : int ZoneNum; // EnergyPlus zone number
11408 : int MZDZoneNum; // row index of the zone in the MultizoneZoneData array
11409 : int ExtNodeNum; // External node number; = row index in MultizoneExternalNodeData array +
11410 : // AirflowNetworkNumOfZones
11411 : std::string ZoneName; // EnergyPlus zone name
11412 : int facadeNum;
11413 : int curve; // wind pressure coefficient curve index
11414 : iComponentTypeNum CompTypeNum; // Opening type (detailed, simple, etc.)
11415 : Real64 NodeHeight; // Elevation of the opening node
11416 : Real64 OpeningArea; // Opening area (=Height*Width)
11417 : Real64 Height; // Opening height = MultizoneSurfaceData()%Height
11418 : Real64 Width; // Opening width = MultizoneSurfaceData()%Width
11419 : Real64 DischCoeff; // Opening discharge coefficient
11420 :
11421 : // Default Constructor
11422 1 : AFNExtSurfacesProp()
11423 3 : : SurfNum(0), MSDNum(0), ZoneNum(0), MZDZoneNum(0), ExtNodeNum(0), facadeNum(0), curve(0), CompTypeNum(iComponentTypeNum::Invalid),
11424 1 : NodeHeight(0.0), OpeningArea(0.0), Height(0.0), Width(0.0), DischCoeff(0.0)
11425 : {
11426 1 : }
11427 : };
11428 :
11429 : // Object Data
11430 1 : Array1D<AFNExtSurfacesProp> AFNExtSurfaces; // Surface numbers of all exterior openings
11431 : // Count the total number of exterior simple and detailed openings and the number in each zone
11432 : // Verify that each zone with "ADVANCED" single sided wind pressure coefficients has exactly two openings.
11433 : // If it doesn't have two openings, change "ADVANCED" to "STANDARD"
11434 1 : NumofExtSurfInZone.dimension(AirflowNetworkNumOfZones, 0);
11435 5 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
11436 4 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
11437 45 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11438 42 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond ==
11439 : ExternalEnvironment) { // check if outdoor boundary condition
11440 42 : MZDZoneNum = Util::FindItemInList(m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName,
11441 42 : MultizoneZoneData,
11442 : &MultizoneZoneProp::ZoneName);
11443 42 : if (MZDZoneNum == AFNZnNum) {
11444 : // This is terrible, should not do it this way
11445 9 : auto afe = elements.find(MultizoneSurfaceData(SrfNum).OpeningName);
11446 9 : if (afe != elements.end()) {
11447 9 : auto type = afe->second->type();
11448 9 : if (type == ComponentType::DOP) {
11449 6 : ++AFNNumOfExtOpenings;
11450 6 : ++NumofExtSurfInZone(AFNZnNum);
11451 3 : } else if (type == ComponentType::SOP) {
11452 0 : ++AFNNumOfExtOpenings;
11453 0 : ++NumofExtSurfInZone(AFNZnNum);
11454 : }
11455 : }
11456 9 : }
11457 : }
11458 : }
11459 3 : if (NumofExtSurfInZone(AFNZnNum) == 0) {
11460 0 : ShowWarningError(m_state,
11461 0 : "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName +
11462 : " has single side wind pressure coefficient type \"ADVANCED\", but has no exterior "
11463 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or AirflowNetwork:MultiZone:Component:SimpleOpening "
11464 : "objects.");
11465 0 : ShowContinueError(m_state,
11466 : "Zones must have exactly two exterior openings in order for the \"ADVANCED\" single sided wind pressure "
11467 : "coefficient model to be used.");
11468 0 : ShowContinueError(m_state,
11469 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11470 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11471 3 : } else if (NumofExtSurfInZone(AFNZnNum) == 1) {
11472 0 : ShowWarningError(m_state, "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName);
11473 0 : ShowContinueError(m_state,
11474 : "has single side wind pressure coefficient type \"ADVANCED\", but has only one exterior "
11475 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or "
11476 : "AirflowNetwork:MultiZone:Component:SimpleOpening objects.");
11477 0 : ShowContinueError(m_state,
11478 : "Zones must have exactly two openings in order for the \"ADVANCED\" single side wind pressure coefficient "
11479 : "model to be used.");
11480 0 : ShowContinueError(m_state,
11481 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11482 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11483 3 : } else if (NumofExtSurfInZone(AFNZnNum) > 2) {
11484 0 : ShowWarningError(m_state,
11485 0 : format("AirflowNetwork:Multizone:Zone = {} has single side wind pressure coefficient type "
11486 : "\"ADVANCED\", but has {} exterior "
11487 : "AirflowNetwork:MultiZone:Component:DetailedOpening and/or "
11488 : "AirflowNetwork:MultiZone:Component:SimpleOpening objects.",
11489 0 : MultizoneZoneData(AFNZnNum).ZoneName,
11490 : NumofExtSurfInZone(AFNZnNum)));
11491 0 : ShowContinueError(m_state,
11492 : "Zones must have exactly two openings in order for the \"ADVANCED\" single side wind pressure coefficient "
11493 : "model to be used.");
11494 0 : ShowContinueError(m_state,
11495 : "The wind pressure coefficient model for this zone will be set to \"STANDARD\" and simulation continues.");
11496 0 : MultizoneZoneData(AFNZnNum).SingleSidedCpType = "STANDARD";
11497 : }
11498 : }
11499 : }
11500 1 : if (AFNNumOfExtOpenings == 0) return;
11501 : // Recount the number of single sided zones
11502 1 : AirflowNetworkNumOfSingleSideZones = 0;
11503 5 : for (AFNZnNum = 1; AFNZnNum <= AirflowNetworkNumOfZones; ++AFNZnNum) {
11504 4 : if (MultizoneZoneData(AFNZnNum).SingleSidedCpType == "ADVANCED") {
11505 3 : ++AirflowNetworkNumOfSingleSideZones;
11506 : }
11507 : }
11508 1 : if (AirflowNetworkNumOfSingleSideZones == 0) return; // Bail if no zones call for the advanced single sided model.
11509 : // Recount the number of detailed and simple exterior openings in zones with "ADVANCED" single sided wind pressure coefficients
11510 1 : AFNNumOfExtOpenings = 0;
11511 15 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11512 14 : MZDZoneNum = Util::FindItemInList(
11513 14 : m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11514 14 : if (MultizoneZoneData(MZDZoneNum).SingleSidedCpType == "ADVANCED") {
11515 9 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond ==
11516 : ExternalEnvironment) { // check if outdoor boundary condition
11517 : // This is terrible, should not do it this way
11518 9 : auto afe = elements.find(MultizoneSurfaceData(SrfNum).OpeningName);
11519 9 : if (afe != elements.end()) {
11520 9 : auto type = afe->second->type();
11521 9 : if (type == ComponentType::DOP) {
11522 6 : ++AFNNumOfExtOpenings;
11523 3 : } else if (type == ComponentType::SOP) {
11524 0 : ++AFNNumOfExtOpenings;
11525 : }
11526 : }
11527 9 : }
11528 : }
11529 : }
11530 1 : AFNExtSurfaces.allocate(AFNNumOfExtOpenings);
11531 : // Create array of properties for all the exterior single sided openings
11532 1 : ExtOpenNum = 1;
11533 15 : for (SrfNum = 1; SrfNum <= AirflowNetworkNumOfSurfaces; ++SrfNum) {
11534 14 : if (m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ExtBoundCond == ExternalEnvironment) {
11535 14 : if (AirflowNetworkNumOfDetOpenings > 0) {
11536 14 : DetOpenNum = Util::FindItemInList(
11537 14 : MultizoneSurfaceData(SrfNum).OpeningName, MultizoneCompDetOpeningData, &AirflowNetwork::DetailedOpening::name);
11538 14 : MZDZoneNum = Util::FindItemInList(
11539 14 : m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11540 14 : if (MultizoneZoneData(MZDZoneNum).SingleSidedCpType == "ADVANCED") {
11541 9 : if (DetOpenNum > 0) {
11542 6 : AFNExtSurfaces(ExtOpenNum).MSDNum = SrfNum;
11543 6 : AFNExtSurfaces(ExtOpenNum).SurfNum = MultizoneSurfaceData(SrfNum).SurfNum;
11544 6 : AFNExtSurfaces(ExtOpenNum).NodeHeight = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.z;
11545 6 : AFNExtSurfaces(ExtOpenNum).SurfName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Name;
11546 6 : AFNExtSurfaces(ExtOpenNum).ZoneNum = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Zone;
11547 6 : AFNExtSurfaces(ExtOpenNum).ZoneName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName;
11548 12 : AFNExtSurfaces(ExtOpenNum).MZDZoneNum =
11549 6 : Util::FindItemInList(AFNExtSurfaces(ExtOpenNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11550 6 : AFNExtSurfaces(ExtOpenNum).CompTypeNum = iComponentTypeNum::DOP;
11551 6 : AFNExtSurfaces(ExtOpenNum).Height = MultizoneSurfaceData(SrfNum).Height;
11552 6 : AFNExtSurfaces(ExtOpenNum).Width = MultizoneSurfaceData(SrfNum).Width;
11553 12 : AFNExtSurfaces(ExtOpenNum).OpeningArea =
11554 6 : MultizoneSurfaceData(SrfNum).Width * MultizoneSurfaceData(SrfNum).Height * MultizoneSurfaceData(SrfNum).OpenFactor;
11555 6 : AFNExtSurfaces(ExtOpenNum).ExtNodeNum = MultizoneSurfaceData(ExtOpenNum).NodeNums[1];
11556 12 : AFNExtSurfaces(ExtOpenNum).facadeNum =
11557 6 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum;
11558 12 : AFNExtSurfaces(ExtOpenNum).curve =
11559 6 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).curve;
11560 6 : AFNExtSurfaces(ExtOpenNum).DischCoeff = MultizoneCompDetOpeningData(DetOpenNum).DischCoeff2;
11561 6 : ++ExtOpenNum;
11562 : }
11563 : }
11564 0 : } else if (AirflowNetworkNumOfSimOpenings > 0) {
11565 0 : SimOpenNum = Util::FindItemInList(
11566 0 : MultizoneSurfaceData(SrfNum).OpeningName, MultizoneCompSimpleOpeningData, &AirflowNetwork::SimpleOpening::name);
11567 0 : if (SimOpenNum > 0) {
11568 0 : AFNExtSurfaces(ExtOpenNum).MSDNum = SrfNum;
11569 0 : AFNExtSurfaces(ExtOpenNum).SurfNum = MultizoneSurfaceData(SrfNum).SurfNum;
11570 0 : AFNExtSurfaces(ExtOpenNum).SurfName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Name;
11571 0 : AFNExtSurfaces(ExtOpenNum).ZoneNum = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).Zone;
11572 0 : AFNExtSurfaces(ExtOpenNum).ZoneName = m_state.dataSurface->Surface(MultizoneSurfaceData(SrfNum).SurfNum).ZoneName;
11573 0 : AFNExtSurfaces(ExtOpenNum).MZDZoneNum =
11574 0 : Util::FindItemInList(AFNExtSurfaces(ExtOpenNum).ZoneName, MultizoneZoneData, &MultizoneZoneProp::ZoneName);
11575 0 : AFNExtSurfaces(ExtOpenNum).CompTypeNum = iComponentTypeNum::SOP;
11576 0 : AFNExtSurfaces(ExtOpenNum).Height = MultizoneSurfaceData(SrfNum).Height;
11577 0 : AFNExtSurfaces(ExtOpenNum).Width = MultizoneSurfaceData(SrfNum).Width;
11578 0 : AFNExtSurfaces(ExtOpenNum).OpeningArea =
11579 0 : MultizoneSurfaceData(SrfNum).Width * MultizoneSurfaceData(SrfNum).Height * MultizoneSurfaceData(SrfNum).OpenFactor;
11580 0 : AFNExtSurfaces(ExtOpenNum).ExtNodeNum = MultizoneSurfaceData(ExtOpenNum).NodeNums[1];
11581 0 : AFNExtSurfaces(ExtOpenNum).curve =
11582 0 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).curve;
11583 0 : AFNExtSurfaces(ExtOpenNum).DischCoeff = MultizoneCompSimpleOpeningData(SimOpenNum).DischCoeff;
11584 0 : ++ExtOpenNum;
11585 : }
11586 : }
11587 : }
11588 : }
11589 : // Calculate the azimuth and the coordinates of the centroid of each opening.
11590 : // Calculate Sprime and DeltaCp for each zone.
11591 1 : PiFormula.allocate(numWindDir);
11592 1 : SigmaFormula.allocate(numWindDir);
11593 1 : DeltaCp.allocate(AirflowNetworkNumOfZones);
11594 1 : EPDeltaCP.allocate(AirflowNetworkNumOfZones);
11595 1 : Sprime.allocate(AirflowNetworkNumOfZones);
11596 1 : ZoneAng.allocate(AirflowNetworkNumOfZones);
11597 5 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11598 4 : DeltaCp(ZnNum).WindDir.allocate(numWindDir);
11599 4 : EPDeltaCP(ZnNum).WindDir.allocate(numWindDir);
11600 148 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11601 144 : DeltaCp(ZnNum).WindDir(windDirNum) = 0.0;
11602 144 : EPDeltaCP(ZnNum).WindDir(windDirNum) = 0.0;
11603 : }
11604 : }
11605 1 : Sprime = 0.0;
11606 1 : ZoneAng = 0.0;
11607 5 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11608 4 : if (MultizoneZoneData(ZnNum).SingleSidedCpType == "ADVANCED") {
11609 3 : OpenNuminZone = 1;
11610 15 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11611 14 : if (OpenNuminZone > 2) break; // Tuned
11612 12 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11613 6 : if (OpenNuminZone == 1) {
11614 3 : X1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.x;
11615 3 : Y1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.y;
11616 3 : ZoneAng1 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Azimuth;
11617 3 : ++OpenNuminZone;
11618 3 : } else if (OpenNuminZone == 2) {
11619 3 : X2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.x;
11620 3 : Y2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Centroid.y;
11621 3 : ZoneAng2 = m_state.dataSurface->Surface(AFNExtSurfaces(ExtOpenNum).SurfNum).Azimuth;
11622 3 : ++OpenNuminZone;
11623 : }
11624 : }
11625 : }
11626 3 : ZoneAngDiff = ZoneAng1 - ZoneAng2;
11627 3 : if (ZoneAngDiff > 0.01) {
11628 0 : ShowWarningError(m_state,
11629 0 : "AirflowNetwork:Multizone:Zone = " + MultizoneZoneData(AFNZnNum).ZoneName +
11630 : " has single side wind pressure coefficient type \"ADVANCED\", but has openings which are not coplanar.");
11631 0 : ShowContinueError(m_state, "The openings should be coplanar for the model to be valid. Simulation Continues.");
11632 : }
11633 3 : ZoneAng(ZnNum) = ZoneAng1;
11634 3 : Sprime(ZnNum) = std::sqrt(pow_2(X1 - X2) + pow_2(Y1 - Y2)) / MultizoneZoneData(ZnNum).BuildWidth;
11635 : // Calculate DeltaCp for each wind direction for each zone
11636 111 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11637 108 : m_state.dataEnvrn->WindDir = (windDirNum - 1) * 10.0;
11638 108 : Real64 WindAng = (windDirNum - 1) * 10.0;
11639 108 : IncAng = std::abs(WindAng - ZoneAng(ZnNum));
11640 108 : if (std::abs(IncAng) > 180.0) IncAng -= 360.0;
11641 108 : if (Util::SameString(simulation_control.WPCCntr, "SurfaceAverageCalculation")) {
11642 108 : if (std::abs(IncAng) <= 67.5) {
11643 39 : PiFormula(windDirNum) = 0.44 * sign(std::sin(2.67 * std::abs(IncAng) * Constant::Pi / 180.0), IncAng);
11644 69 : } else if (std::abs(IncAng) <= 180.0) {
11645 69 : PiFormula(windDirNum) = -0.69 * sign(std::sin((288 - 1.6 * std::abs(IncAng)) * Constant::Pi / 180.0), IncAng);
11646 : }
11647 108 : SigmaFormula(windDirNum) = 0.423 - 0.00163 * std::abs(IncAng);
11648 108 : DeltaCp(ZnNum).WindDir(windDirNum) =
11649 108 : (0.02 + (0.346 * std::abs(PiFormula(windDirNum)) + 0.084 * SigmaFormula(windDirNum)) * Sprime(ZnNum));
11650 : }
11651 : }
11652 : }
11653 : }
11654 :
11655 : // Calculate the single sided Cp arrays from DeltaCp for each single sided opening
11656 1 : CPV1.allocate(numWindDir); // These two arrays should probably be removed
11657 1 : CPV2.allocate(numWindDir);
11658 1 : CPV1 = 0.0;
11659 1 : CPV2 = 0.0;
11660 1 : SrfNum = 6;
11661 5 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11662 4 : if (MultizoneZoneData(ZnNum).SingleSidedCpType == "ADVANCED") {
11663 3 : OpenNuminZone = 1;
11664 15 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11665 14 : if (OpenNuminZone > 2) break; // Tuned
11666 12 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11667 6 : Real64 const VelRatio_2(std::pow(10.0 / AFNExtSurfaces(ExtOpenNum).NodeHeight, 2.0 * m_state.dataEnvrn->SiteWindExp));
11668 6 : Real64 const AFNEExtSurface_fac(0.5 * (1.0 / pow_2(AFNExtSurfaces(ExtOpenNum).DischCoeff)));
11669 6 : if (OpenNuminZone == 1) {
11670 3 : std::vector<Real64> cpvalues(numWindDir);
11671 111 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11672 108 : Real64 unmodifiedValue = valsByFacade[AFNExtSurfaces(ExtOpenNum).facadeNum - 1][windDirNum - 1] +
11673 108 : AFNEExtSurface_fac * DeltaCp(ZnNum).WindDir(windDirNum);
11674 108 : cpvalues[windDirNum - 1] = CPV1(windDirNum) = VelRatio_2 * unmodifiedValue;
11675 : }
11676 3 : valsByFacade.push_back(cpvalues);
11677 3 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum = SrfNum;
11678 3 : ++OpenNuminZone;
11679 3 : ++SrfNum;
11680 6 : } else if (OpenNuminZone == 2) {
11681 3 : std::vector<Real64> cpvalues(numWindDir);
11682 111 : for (windDirNum = 1; windDirNum <= numWindDir; ++windDirNum) {
11683 108 : Real64 unmodifiedValue = valsByFacade[AFNExtSurfaces(ExtOpenNum).facadeNum - 1][windDirNum - 1] -
11684 108 : AFNEExtSurface_fac * DeltaCp(ZnNum).WindDir(windDirNum);
11685 108 : cpvalues[windDirNum - 1] = CPV2(windDirNum) = VelRatio_2 * unmodifiedValue;
11686 108 : EPDeltaCP(ZnNum).WindDir(windDirNum) = std::abs(CPV2(windDirNum) - CPV1(windDirNum));
11687 : }
11688 3 : valsByFacade.push_back(cpvalues);
11689 3 : MultizoneExternalNodeData(AFNExtSurfaces(ExtOpenNum).ExtNodeNum - AirflowNetworkNumOfZones).facadeNum = SrfNum;
11690 3 : ++OpenNuminZone;
11691 3 : ++SrfNum;
11692 3 : }
11693 : }
11694 : }
11695 : }
11696 : }
11697 : // Rewrite the CPVNum for all nodes that correspond with a simple or detailed opening
11698 : // Does this loop really do anything?
11699 5 : for (ZnNum = 1; ZnNum <= AirflowNetworkNumOfZones; ++ZnNum) {
11700 4 : OpenNuminZone = 1;
11701 28 : for (ExtOpenNum = 1; ExtOpenNum <= AFNNumOfExtOpenings; ++ExtOpenNum) {
11702 24 : if (AFNExtSurfaces(ExtOpenNum).MZDZoneNum == ZnNum) {
11703 6 : if (OpenNuminZone == 1) {
11704 3 : ++OpenNuminZone;
11705 3 : } else if (OpenNuminZone == 2) {
11706 3 : ++OpenNuminZone;
11707 : }
11708 : }
11709 : }
11710 : }
11711 1 : }
11712 :
11713 2974681 : Real64 Solver::zone_OA_change_rate(int const ZoneNum) // hybrid ventilation system controlled zone number
11714 : {
11715 :
11716 : // SUBROUTINE INFORMATION:
11717 : // AUTHOR Lixing Gu
11718 : // DATE WRITTEN May. 2007
11719 :
11720 : // PURPOSE OF THIS SUBROUTINE:
11721 : // This function outputs air change per hour in a given zone
11722 :
11723 2974681 : auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys;
11724 2974681 : auto &thisZoneHB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
11725 :
11726 2974681 : Real64 CpAir = PsyCpAirFnW(thisZoneHB.airHumRat);
11727 2974681 : Real64 RhoAir = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.airHumRat);
11728 2974681 : Real64 InfilVolume = ((exchangeData(ZoneNum).SumMCp + exchangeData(ZoneNum).SumMVCp) / CpAir / RhoAir) * TimeStepSys * Constant::SecInHour;
11729 2974681 : Real64 ACH = InfilVolume / (TimeStepSys * m_state.dataHeatBal->Zone(ZoneNum).Volume);
11730 :
11731 2974681 : return ACH;
11732 : }
11733 :
11734 333 : int Solver::get_airloop_number(int const NodeNumber) // Get air loop number for each distribution node and linkage
11735 : {
11736 : // SUBROUTINE INFORMATION:
11737 : // AUTHOR Lixing Gu
11738 : // DATE WRITTEN Feb. 2018
11739 :
11740 : // PURPOSE OF THIS SUBROUTINE:
11741 : // This function outputs an AirLoopNum based on node number
11742 :
11743 : // Using/Aliasing
11744 : using BranchNodeConnections::GetChildrenData;
11745 : using BranchNodeConnections::GetNumChildren;
11746 : using BranchNodeConnections::IsParentObject;
11747 333 : auto &NumPrimaryAirSys = m_state.dataHVACGlobal->NumPrimaryAirSys;
11748 : using SingleDuct::GetHVACSingleDuctSysIndex;
11749 :
11750 : // Return value
11751 333 : int AirLoopNumber = 0;
11752 :
11753 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11754 : int BranchNum;
11755 : int NumOfNodes;
11756 : int NodeNum;
11757 : int OutNum;
11758 : int SupAirPath;
11759 : int SupAirPathOutNodeNum;
11760 : int CtrlZoneNum;
11761 : int ZoneInNum;
11762 : int ZoneOutNum;
11763 : int AirLoopNum;
11764 333 : int TUNum = 0;
11765 333 : int TermNum = 0;
11766 : bool LocalError;
11767 : int NumOfComp;
11768 : int NumOfSubComp;
11769 : bool ErrorsFound;
11770 : int NumOfSubSubComp;
11771 :
11772 447 : for (AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
11773 : // Check OAMixer OA inlet node
11774 349 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).OAMixOAInNodeNum) {
11775 13 : return AirLoopNum;
11776 : }
11777 : // Check branch
11778 550 : for (BranchNum = 1; BranchNum <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
11779 336 : NumOfNodes = m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalNodes;
11780 1456 : for (NodeNum = 1; NodeNum <= NumOfNodes; ++NodeNum) {
11781 1210 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).NodeNum(NodeNum)) {
11782 90 : return AirLoopNum;
11783 : }
11784 : }
11785 939 : for (NumOfComp = 1; NumOfComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
11786 : ++NumOfComp) {
11787 725 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NodeNumIn) {
11788 0 : return AirLoopNum;
11789 : }
11790 725 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NodeNumOut) {
11791 0 : return AirLoopNum;
11792 : }
11793 725 : if (m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NumSubComps == 0) {
11794 725 : DataLoopNode::ConnectionObjectType TypeOfComp = static_cast<DataLoopNode::ConnectionObjectType>(EnergyPlus::getEnumValue(
11795 : BranchNodeConnections::ConnectionObjectTypeNamesUC,
11796 725 : m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).TypeOf));
11797 : std::string const &NameOfComp =
11798 725 : m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).Name;
11799 725 : if (IsParentObject(m_state, TypeOfComp, NameOfComp)) {
11800 :
11801 417 : int NumChildren = GetNumChildren(m_state, TypeOfComp, NameOfComp);
11802 417 : EPVector<DataLoopNode::ConnectionObjectType> SubCompTypes;
11803 417 : Array1D_string SubCompNames;
11804 417 : Array1D_string InletNodeNames;
11805 417 : Array1D_int InletNodeNumbers;
11806 417 : Array1D_string OutletNodeNames;
11807 417 : Array1D_int OutletNodeNumbers;
11808 :
11809 417 : SubCompTypes.allocate(NumChildren);
11810 417 : SubCompNames.allocate(NumChildren);
11811 417 : InletNodeNames.allocate(NumChildren);
11812 417 : InletNodeNumbers.allocate(NumChildren);
11813 417 : OutletNodeNames.allocate(NumChildren);
11814 417 : OutletNodeNumbers.allocate(NumChildren);
11815 :
11816 417 : GetChildrenData(m_state,
11817 : TypeOfComp,
11818 : NameOfComp,
11819 : NumChildren,
11820 : SubCompTypes,
11821 : SubCompNames,
11822 : InletNodeNames,
11823 : InletNodeNumbers,
11824 : OutletNodeNames,
11825 : OutletNodeNumbers,
11826 : ErrorsFound);
11827 :
11828 1016 : for (NumOfSubComp = 1; NumOfSubComp <= NumChildren; ++NumOfSubComp) {
11829 629 : if (NodeNumber == InletNodeNumbers(NumOfSubComp)) {
11830 1 : SubCompTypes.deallocate();
11831 1 : SubCompNames.deallocate();
11832 1 : InletNodeNames.deallocate();
11833 1 : InletNodeNumbers.deallocate();
11834 1 : OutletNodeNames.deallocate();
11835 1 : OutletNodeNumbers.deallocate();
11836 1 : return AirLoopNum;
11837 : }
11838 628 : if (NodeNumber == OutletNodeNumbers(NumOfSubComp)) {
11839 29 : SubCompTypes.deallocate();
11840 29 : SubCompNames.deallocate();
11841 29 : InletNodeNames.deallocate();
11842 29 : InletNodeNumbers.deallocate();
11843 29 : OutletNodeNames.deallocate();
11844 29 : OutletNodeNumbers.deallocate();
11845 29 : return AirLoopNum;
11846 : }
11847 : }
11848 954 : for (NumOfSubComp = 1; NumOfSubComp <= NumChildren; ++NumOfSubComp) {
11849 569 : DataLoopNode::ConnectionObjectType TypeOfSubComp = SubCompTypes(NumOfSubComp);
11850 569 : std::string NameOfSubComp = SubCompNames(NumOfSubComp);
11851 569 : if (IsParentObject(m_state, TypeOfSubComp, NameOfSubComp)) {
11852 :
11853 13 : int NumGrandChildren = GetNumChildren(m_state, TypeOfSubComp, NameOfSubComp);
11854 13 : EPVector<DataLoopNode::ConnectionObjectType> SubSubCompTypes;
11855 13 : Array1D_string SubSubCompNames;
11856 13 : Array1D_string SubSubInletNodeNames;
11857 13 : Array1D_int SubSubInletNodeNumbers;
11858 13 : Array1D_string SubSubOutletNodeNames;
11859 13 : Array1D_int SubSubOutletNodeNumbers;
11860 :
11861 13 : SubSubCompTypes.allocate(NumGrandChildren);
11862 13 : SubSubCompNames.allocate(NumGrandChildren);
11863 13 : SubSubInletNodeNames.allocate(NumGrandChildren);
11864 13 : SubSubInletNodeNumbers.allocate(NumGrandChildren);
11865 13 : SubSubOutletNodeNames.allocate(NumGrandChildren);
11866 13 : SubSubOutletNodeNumbers.allocate(NumGrandChildren);
11867 :
11868 13 : GetChildrenData(m_state,
11869 : TypeOfSubComp,
11870 : NameOfSubComp,
11871 : NumGrandChildren,
11872 : SubSubCompTypes,
11873 : SubSubCompNames,
11874 : SubSubInletNodeNames,
11875 : SubSubInletNodeNumbers,
11876 : SubSubOutletNodeNames,
11877 : SubSubOutletNodeNumbers,
11878 : ErrorsFound);
11879 47 : for (int SubSubCompNum = 1; SubSubCompNum <= NumGrandChildren; ++SubSubCompNum) {
11880 36 : if (NodeNumber == SubSubInletNodeNumbers(SubSubCompNum)) {
11881 0 : SubSubCompTypes.deallocate();
11882 0 : SubSubCompNames.deallocate();
11883 0 : SubSubInletNodeNames.deallocate();
11884 0 : SubSubInletNodeNumbers.deallocate();
11885 0 : SubSubOutletNodeNames.deallocate();
11886 0 : SubSubOutletNodeNumbers.deallocate();
11887 0 : SubCompTypes.deallocate();
11888 0 : SubCompNames.deallocate();
11889 0 : InletNodeNames.deallocate();
11890 0 : InletNodeNumbers.deallocate();
11891 0 : OutletNodeNames.deallocate();
11892 0 : OutletNodeNumbers.deallocate();
11893 0 : return AirLoopNum;
11894 : }
11895 36 : if (NodeNumber == SubSubOutletNodeNumbers(SubSubCompNum)) {
11896 2 : SubSubCompTypes.deallocate();
11897 2 : SubSubCompNames.deallocate();
11898 2 : SubSubInletNodeNames.deallocate();
11899 2 : SubSubInletNodeNumbers.deallocate();
11900 2 : SubSubOutletNodeNames.deallocate();
11901 2 : SubSubOutletNodeNumbers.deallocate();
11902 2 : SubCompTypes.deallocate();
11903 2 : SubCompNames.deallocate();
11904 2 : InletNodeNames.deallocate();
11905 2 : InletNodeNumbers.deallocate();
11906 2 : OutletNodeNames.deallocate();
11907 2 : OutletNodeNumbers.deallocate();
11908 2 : return AirLoopNum;
11909 : }
11910 : }
11911 11 : SubSubCompTypes.deallocate();
11912 11 : SubSubCompNames.deallocate();
11913 11 : SubSubInletNodeNames.deallocate();
11914 11 : SubSubInletNodeNumbers.deallocate();
11915 11 : SubSubOutletNodeNames.deallocate();
11916 11 : SubSubOutletNodeNumbers.deallocate();
11917 23 : }
11918 569 : }
11919 :
11920 385 : SubCompTypes.deallocate();
11921 385 : SubCompNames.deallocate();
11922 385 : InletNodeNames.deallocate();
11923 385 : InletNodeNumbers.deallocate();
11924 385 : OutletNodeNames.deallocate();
11925 385 : OutletNodeNumbers.deallocate();
11926 577 : }
11927 : } else {
11928 0 : for (NumOfSubComp = 1;
11929 0 : NumOfSubComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(NumOfComp).NumSubComps;
11930 : ++NumOfSubComp) {
11931 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
11932 0 : .Branch(BranchNum)
11933 0 : .Comp(NumOfComp)
11934 0 : .SubComp(NumOfSubComp)
11935 0 : .NodeNumIn) {
11936 0 : return AirLoopNum;
11937 : }
11938 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
11939 0 : .Branch(BranchNum)
11940 0 : .Comp(NumOfComp)
11941 0 : .SubComp(NumOfSubComp)
11942 0 : .NodeNumOut) {
11943 0 : return AirLoopNum;
11944 : }
11945 0 : for (NumOfSubSubComp = 1; NumOfSubSubComp <= m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
11946 0 : .Branch(BranchNum)
11947 0 : .Comp(NumOfComp)
11948 0 : .SubComp(NumOfSubComp)
11949 0 : .NumSubSubComps;
11950 : ++NumOfSubSubComp) {
11951 0 : if (NodeNumber == m_state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum)
11952 0 : .Branch(BranchNum)
11953 0 : .Comp(NumOfComp)
11954 0 : .SubComp(NumOfSubComp)
11955 0 : .SubSubComp(NumOfSubSubComp)
11956 0 : .NodeNumIn) {
11957 0 : return AirLoopNum;
11958 : }
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 : .NodeNumOut) {
11965 0 : return AirLoopNum;
11966 : }
11967 : }
11968 : }
11969 : }
11970 : }
11971 : }
11972 :
11973 : // Check connection between supply and demand
11974 328 : for (OutNum = 1; OutNum <= m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumSupplyNodes; ++OutNum) {
11975 : // AirLoop supply outlet node
11976 214 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopSupplyNodeNum(OutNum) == NodeNumber) {
11977 0 : return AirLoopNum;
11978 : }
11979 214 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(OutNum) == NodeNumber) {
11980 24 : return AirLoopNum;
11981 : }
11982 : // supply path
11983 353 : for (SupAirPath = 1; SupAirPath <= m_state.dataZoneEquip->NumSupplyAirPaths; ++SupAirPath) {
11984 215 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).InletNodeNum ==
11985 215 : m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(OutNum)) {
11986 553 : for (SupAirPathOutNodeNum = 1; SupAirPathOutNodeNum <= m_state.dataZoneEquip->SupplyAirPath(SupAirPath).NumOutletNodes;
11987 : ++SupAirPathOutNodeNum) {
11988 415 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).OutletNode(SupAirPathOutNodeNum) == NodeNumber) {
11989 49 : return AirLoopNum;
11990 : }
11991 972 : for (TUNum = 1; TUNum <= DisSysNumOfTermUnits; ++TUNum) {
11992 609 : if (Util::SameString(DisSysCompTermUnitData(TUNum).EPlusType, "AirTerminal:SingleDuct:VAV:Reheat")) {
11993 87 : LocalError = false;
11994 174 : GetHVACSingleDuctSysIndex(m_state,
11995 87 : DisSysCompTermUnitData(TUNum).name,
11996 : TermNum,
11997 : LocalError,
11998 : "AirflowNetwork:Distribution:Component:TerminalUnit",
11999 87 : DisSysCompTermUnitData(TUNum).DamperInletNode,
12000 87 : DisSysCompTermUnitData(TUNum).DamperOutletNode);
12001 87 : if (m_state.dataZoneEquip->SupplyAirPath(SupAirPath).OutletNode(SupAirPathOutNodeNum) ==
12002 87 : DisSysCompTermUnitData(TUNum).DamperInletNode) {
12003 30 : if (DisSysCompTermUnitData(TUNum).DamperOutletNode == NodeNumber) {
12004 3 : DisSysCompTermUnitData(TUNum).AirLoopNum = AirLoopNum;
12005 3 : return AirLoopNum;
12006 : }
12007 : }
12008 84 : if (LocalError) {
12009 : }
12010 : }
12011 : }
12012 : }
12013 : }
12014 : }
12015 : // return path
12016 138 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopReturnNodeNum(OutNum) == NodeNumber) {
12017 0 : return AirLoopNum;
12018 : }
12019 138 : if (m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipReturnNodeNum(OutNum) == NodeNumber) {
12020 24 : return AirLoopNum;
12021 : }
12022 250 : for (int retPathNum = 1; retPathNum <= m_state.dataZoneEquip->NumReturnAirPaths; ++retPathNum) {
12023 136 : if (m_state.dataZoneEquip->ReturnAirPath(retPathNum).OutletNodeNum ==
12024 136 : m_state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipReturnNodeNum(1)) {
12025 114 : if (m_state.dataZoneEquip->ReturnAirPath(retPathNum).OutletNodeNum == NodeNumber) {
12026 0 : return AirLoopNum;
12027 : }
12028 : }
12029 : }
12030 : // Supply inlet node
12031 :
12032 : // Terminal damper node
12033 : }
12034 : }
12035 :
12036 178 : for (CtrlZoneNum = 1; CtrlZoneNum <= m_state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
12037 178 : if (!m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
12038 308 : for (ZoneInNum = 1; ZoneInNum <= m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumInletNodes; ++ZoneInNum) {
12039 181 : if (m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNode(ZoneInNum) == NodeNumber) {
12040 49 : return m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNodeAirLoopNum(ZoneInNum);
12041 : }
12042 : }
12043 205 : for (ZoneOutNum = 1; ZoneOutNum <= m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumReturnNodes; ++ZoneOutNum) {
12044 127 : if (m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ReturnNode(ZoneOutNum) == NodeNumber) {
12045 49 : return m_state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ReturnNodeAirLoopNum(ZoneOutNum);
12046 : }
12047 : }
12048 : }
12049 :
12050 0 : return AirLoopNumber;
12051 : }
12052 :
12053 1 : void Solver::SizeDucts()
12054 : {
12055 1 : Real64 constexpr EPS(0.001);
12056 1 : int constexpr MaxIte(500);
12057 1 : Real64 constexpr MinVelocity(0.5); // minimum airflow velocity (m/s)
12058 1 : Real64 constexpr MaxVelocity(20.0); // maximum airflow velocity (m/s)
12059 :
12060 1 : int NodeLoopSupply = 0;
12061 1 : int NodeLoopReturn = 0;
12062 1 : int NodeSplitter = 0;
12063 1 : int NodeMixer = 0;
12064 1 : int NodeZoneIntlet = 0;
12065 1 : int NodeZoneReturn = 0;
12066 : int AFNNodeNum;
12067 : int AFNLinkNum;
12068 : int AFNLinkNum1;
12069 1 : Real64 SumLength = 0.0;
12070 1 : Real64 DynamicLoss = 0.0;
12071 1 : Real64 MaxRough = 0.0;
12072 : bool DuctSizingSTFlag;
12073 : bool DuctSizingSBFlag;
12074 : bool DuctSizingRTFlag;
12075 : bool DuctSizingRBFlag;
12076 1 : Real64 hydraulicDiameter = 0.0;
12077 1 : Real64 SupplyTrunkD = 0.0;
12078 1 : Real64 SupplyTrunkArea = 0.0;
12079 1 : Real64 SupplyBranchD = 0.0;
12080 1 : Real64 SupplyBranchArea = 0.0;
12081 1 : Real64 ReturnTrunkD = 0.0;
12082 1 : Real64 ReturnTrunkArea = 0.0;
12083 1 : Real64 ReturnBranchD = 0.0;
12084 1 : Real64 ReturnBranchArea = 0.0;
12085 1 : Real64 MdotBranch = 0.0;
12086 1 : int SolFla = 0;
12087 :
12088 1 : int NumOfCtrlZones = 0;
12089 4 : for (int ZoneNum = 1; ZoneNum <= m_state.dataGlobal->NumOfZones; ++ZoneNum) {
12090 3 : if (!m_state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) continue;
12091 1 : NumOfCtrlZones++;
12092 1 : for (int EquipTypeNum = 1; EquipTypeNum <= m_state.dataZoneEquip->ZoneEquipList(ZoneNum).NumOfEquipTypes; ++EquipTypeNum) {
12093 1 : if (m_state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipType(EquipTypeNum) == DataZoneEquipment::ZoneEquipType::AirDistributionUnit) {
12094 1 : int AirDistUnitNum = m_state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipIndex(EquipTypeNum);
12095 1 : MdotBranch = m_state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).MassFlowRateTU;
12096 1 : break;
12097 : }
12098 : }
12099 : }
12100 1 : if (NumOfCtrlZones != 1) {
12101 0 : ShowWarningError(m_state, "AirflowNetwork Duct Sizing: The current restriction is limited to a single controlled zone only");
12102 0 : ShowContinueError(m_state, format("The number of controlled zone is {}", NumOfCtrlZones));
12103 0 : ShowContinueError(m_state, "..Duct sizing is not performed");
12104 0 : simulation_control.autosize_ducts = false;
12105 0 : simulation_control.iWPCCnt = iWPCCntr::Input;
12106 0 : simulation_control.allow_unsupported_zone_equipment = false;
12107 : }
12108 1 : Real64 factor = simulation_control.ductSizing.factor;
12109 :
12110 1 : NodeLoopSupply = m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipSupplyNodeNum(1);
12111 1 : NodeLoopReturn = m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipReturnNodeNum(1);
12112 23 : for (AFNNodeNum = 1; AFNNodeNum <= AirflowNetworkNumOfNodes; AFNNodeNum++) {
12113 22 : if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::SPL) {
12114 1 : NodeSplitter = AFNNodeNum;
12115 21 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::MIX) {
12116 1 : NodeMixer = AFNNodeNum;
12117 20 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipSupplyNodeNum(1)) {
12118 1 : NodeLoopSupply = AFNNodeNum;
12119 19 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusNodeNum == m_state.dataAirLoop->AirToZoneNodeInfo(1).ZoneEquipReturnNodeNum(1)) {
12120 1 : NodeLoopReturn = AFNNodeNum;
12121 18 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::ZIN) {
12122 1 : NodeZoneIntlet = AFNNodeNum;
12123 17 : } else if (AirflowNetworkNodeData(AFNNodeNum).EPlusTypeNum == iEPlusNodeType::ZOU) {
12124 1 : NodeZoneReturn = AFNNodeNum;
12125 : }
12126 : }
12127 :
12128 : // find trunk ducts
12129 1 : DuctSizingSTFlag = false;
12130 1 : DuctSizingSBFlag = false;
12131 1 : int CompNum = 0;
12132 1 : int TypeNum = 0;
12133 :
12134 25 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12135 24 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12136 24 : iComponentTypeNum CompTypeNum = AirflowNetworkCompData(CompNum).CompTypeNum;
12137 24 : SumLength = 0.0;
12138 24 : DynamicLoss = 0.0;
12139 24 : MaxRough = 0.0;
12140 : // supply duct trunk
12141 24 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeLoopSupply) {
12142 1 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeSplitter) {
12143 : // A single trunk duct
12144 1 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12145 1 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12146 1 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12147 1 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12148 1 : SumLength = disSysCompDuct.L;
12149 1 : MaxRough = disSysCompDuct.roughness;
12150 1 : DynamicLoss = disSysCompDuct.TurDynCoef;
12151 1 : DuctSizingSTFlag = true;
12152 : }
12153 : } else {
12154 0 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1];
12155 : int CompNum1;
12156 : iComponentTypeNum CompTypeNum1;
12157 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12158 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12159 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12160 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12161 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12162 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12163 0 : SumLength += disSysCompDuct.L;
12164 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12165 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12166 : // NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12167 0 : DuctSizingSBFlag = true;
12168 : }
12169 0 : while (NodeNum1 != NodeSplitter) {
12170 0 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12171 0 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) continue;
12172 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12173 0 : continue;
12174 0 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
12175 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12176 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12177 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12178 0 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::SupplyTrunk;
12179 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12180 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12181 0 : SumLength += disSysCompDuct.L;
12182 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12183 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12184 0 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1];
12185 0 : DuctSizingSTFlag = true;
12186 0 : break;
12187 : }
12188 : }
12189 : }
12190 : }
12191 : }
12192 1 : if (DuctSizingSTFlag) {
12193 1 : Real64 Velocity = 0.0;
12194 1 : Real64 flowrate = DisSysCompCVFData(1).FlowRate / m_state.dataEnvrn->StdRhoAir;
12195 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12196 0 : SupplyTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12197 0 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * Constant::Pi;
12198 : } else {
12199 1 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12200 1 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12201 1 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12202 1 : Real64 const deltaP = simulation_control.ductSizing.supply_trunk_pressure_loss;
12203 1 : Real64 const MassFlowRate = DisSysCompCVFData(1).FlowRate;
12204 90 : auto f = [&thisState, deltaP, MassFlowRate, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12205 90 : return DuctDResidual(thisState, D, deltaP, MassFlowRate, SumLength, DynamicLoss, MaxRough);
12206 1 : };
12207 1 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12208 1 : if (SolFla == -1) {
12209 0 : if (!m_state.dataGlobal->WarmupFlag) {
12210 0 : if (ErrCountDuct == 0) {
12211 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12212 0 : ShowWarningError(m_state,
12213 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Supply Duct Trunk size.");
12214 0 : ShowContinueErrorTimeStamp(m_state, format("Supply Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12215 : } else {
12216 0 : ++ErrCountDuct;
12217 0 : ShowRecurringWarningErrorAtEnd(
12218 : m_state,
12219 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Trunk "
12220 : "size. Supply Trunk is calculated using velocity at 5m/s. Simulation continues...",
12221 0 : ErrIndexDuct,
12222 : hydraulicDiameter,
12223 : hydraulicDiameter);
12224 : }
12225 : }
12226 1 : } else if (SolFla == -2) {
12227 0 : ShowFatalError(
12228 : m_state,
12229 : "Duct Autosizing for Supply Trunk calculation failed: iteration limits exceeded. Supply Trunk is calculated "
12230 : "using velocity at 5m/s.");
12231 : }
12232 1 : if (SolFla < 0) {
12233 0 : SupplyTrunkD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12234 : } else {
12235 1 : SupplyTrunkD = hydraulicDiameter * factor;
12236 : }
12237 1 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * Constant::Pi;
12238 1 : Velocity = flowrate / SupplyTrunkArea;
12239 : }
12240 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12241 0 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12242 0 : SupplyTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12243 0 : SupplyTrunkArea = SupplyTrunkD * SupplyTrunkD / 4.0 * Constant::Pi;
12244 0 : ShowWarningError(
12245 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Supply Trunk size");
12246 0 : ShowContinueError(
12247 : m_state,
12248 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12249 0 : simulation_control.ductSizing.max_velocity,
12250 : Velocity));
12251 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Supply Trunk Diameter");
12252 : }
12253 : }
12254 : }
12255 : }
12256 : // supply duct branch
12257 24 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeZoneIntlet) {
12258 1 : SumLength = 0.0;
12259 1 : DynamicLoss = 0.0;
12260 1 : MaxRough = 0.0;
12261 1 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeSplitter) {
12262 : // A single branch duct
12263 0 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12264 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyTrunk;
12265 0 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12266 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12267 0 : SumLength = disSysCompDuct.L;
12268 0 : MaxRough = disSysCompDuct.roughness;
12269 0 : DynamicLoss = disSysCompDuct.TurDynCoef;
12270 0 : DuctSizingSTFlag = true;
12271 : }
12272 : } else {
12273 1 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12274 : int CompNum1;
12275 : iComponentTypeNum CompTypeNum1;
12276 1 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12277 1 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12278 1 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12279 1 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::SupplyBranch;
12280 1 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12281 1 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12282 1 : SumLength += disSysCompDuct.L;
12283 1 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12284 1 : DynamicLoss += disSysCompDuct.TurDynCoef;
12285 1 : DuctSizingSBFlag = true;
12286 : }
12287 3 : while (NodeNum1 != NodeSplitter) {
12288 18 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12289 18 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) continue;
12290 2 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12291 0 : continue;
12292 2 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
12293 2 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12294 2 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12295 2 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12296 2 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::SupplyBranch;
12297 2 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12298 2 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12299 2 : SumLength += disSysCompDuct.L;
12300 2 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12301 2 : DynamicLoss += disSysCompDuct.TurDynCoef;
12302 2 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0];
12303 2 : DuctSizingSBFlag = true;
12304 2 : break;
12305 : }
12306 : }
12307 : }
12308 : }
12309 : }
12310 1 : if (DuctSizingSBFlag) {
12311 1 : SolFla = 0;
12312 : Real64 Velocity;
12313 1 : Real64 flowrate = MdotBranch / m_state.dataEnvrn->StdRhoAir;
12314 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12315 0 : SupplyBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12316 0 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * Constant::Pi;
12317 : } else {
12318 1 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12319 1 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12320 1 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12321 1 : Real64 const deltaP = simulation_control.ductSizing.supply_branch_pressure_loss;
12322 65 : auto f = [&thisState, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12323 65 : return DuctDResidual(thisState, D, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough);
12324 1 : };
12325 1 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12326 1 : if (SolFla == -1) {
12327 0 : if (!m_state.dataGlobal->WarmupFlag) {
12328 0 : if (ErrCountDuct == 0) {
12329 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12330 0 : ShowWarningError(m_state,
12331 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Supply Duct Branch size.");
12332 0 : ShowContinueErrorTimeStamp(m_state, format("Supply Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12333 : } else {
12334 0 : ++ErrCountDuct;
12335 0 : ShowRecurringWarningErrorAtEnd(
12336 : m_state,
12337 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Branch "
12338 : "size. Supply Branch is calculated using velocity at 5m/s. Simulation continues...",
12339 0 : ErrIndexDuct,
12340 : hydraulicDiameter,
12341 : hydraulicDiameter);
12342 : }
12343 : }
12344 1 : } else if (SolFla == -2) {
12345 0 : ShowFatalError(
12346 : m_state,
12347 : "Duct Autosizing for Supply Branch calculation failed: iteration limits exceeded. Supply Branch is calculated "
12348 : "using velocity at 5m/s.");
12349 : }
12350 1 : if (SolFla < 0) {
12351 0 : SupplyBranchD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12352 : } else {
12353 1 : SupplyBranchD = hydraulicDiameter * factor;
12354 : }
12355 1 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * Constant::Pi;
12356 1 : Velocity = flowrate / SupplyBranchArea;
12357 : }
12358 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12359 0 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12360 0 : SupplyBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12361 0 : SupplyBranchArea = SupplyBranchD * SupplyBranchD / 4.0 * Constant::Pi;
12362 0 : ShowWarningError(
12363 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Supply Branch size");
12364 0 : ShowContinueError(
12365 : m_state,
12366 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12367 0 : simulation_control.ductSizing.max_velocity,
12368 : Velocity));
12369 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Supply Branch Diameter");
12370 : }
12371 : }
12372 : }
12373 : }
12374 :
12375 24 : DuctSizingRTFlag = false;
12376 24 : DuctSizingRBFlag = false;
12377 :
12378 : // return duct trunk
12379 24 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeLoopReturn) {
12380 1 : SumLength = 0.0;
12381 1 : DynamicLoss = 0.0;
12382 1 : MaxRough = 0.0;
12383 1 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeMixer) {
12384 : // A single branch duct
12385 1 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12386 1 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnTrunk;
12387 1 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12388 1 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12389 1 : SumLength = disSysCompDuct.L;
12390 1 : MaxRough = disSysCompDuct.roughness;
12391 1 : DynamicLoss = disSysCompDuct.TurDynCoef;
12392 1 : DuctSizingRTFlag = true;
12393 : }
12394 : } else {
12395 0 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0];
12396 : int CompNum1;
12397 : iComponentTypeNum CompTypeNum1;
12398 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12399 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12400 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12401 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnTrunk;
12402 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12403 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12404 0 : SumLength += disSysCompDuct.L;
12405 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12406 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12407 0 : DuctSizingRTFlag = true;
12408 : }
12409 0 : while (NodeNum1 != NodeMixer) {
12410 0 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12411 0 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) continue;
12412 0 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12413 0 : continue;
12414 0 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
12415 0 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12416 0 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12417 0 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12418 0 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::ReturnTrunk;
12419 0 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12420 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12421 0 : SumLength += disSysCompDuct.L;
12422 0 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12423 0 : DynamicLoss += disSysCompDuct.TurDynCoef;
12424 0 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0];
12425 0 : DuctSizingRTFlag = true;
12426 0 : break;
12427 : }
12428 : }
12429 : }
12430 : }
12431 : }
12432 1 : if (DuctSizingRTFlag) {
12433 1 : SolFla = 0;
12434 : Real64 Velocity;
12435 1 : Real64 flowrate = DisSysCompCVFData(1).FlowRate / m_state.dataEnvrn->StdRhoAir;
12436 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12437 0 : ReturnTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12438 0 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * Constant::Pi;
12439 : } else {
12440 1 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12441 1 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12442 1 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12443 1 : Real64 const deltaP = simulation_control.ductSizing.return_trunk_pressure_loss;
12444 1 : Real64 const massFlowRate = DisSysCompCVFData(1).FlowRate;
12445 145 : auto f = [&thisState, deltaP, massFlowRate, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12446 145 : return DuctDResidual(thisState, D, deltaP, massFlowRate, SumLength, DynamicLoss, MaxRough);
12447 1 : };
12448 1 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12449 1 : if (SolFla == -1) {
12450 0 : if (!m_state.dataGlobal->WarmupFlag) {
12451 0 : if (ErrCountDuct == 0) {
12452 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12453 0 : ShowWarningError(m_state,
12454 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Return Duct Trunk size.");
12455 0 : ShowContinueErrorTimeStamp(m_state, format("Return Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12456 : } else {
12457 0 : ++ErrCountDuct;
12458 0 : ShowRecurringWarningErrorAtEnd(
12459 : m_state,
12460 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Return Duct Trunk "
12461 : "size. Supply Branch is calculated using velocity at 5m/s. Simulation continues...",
12462 0 : ErrIndexDuct,
12463 : hydraulicDiameter,
12464 : hydraulicDiameter);
12465 : }
12466 : }
12467 1 : } else if (SolFla == -2) {
12468 0 : ShowFatalError(
12469 : m_state,
12470 : "Duct Autosizing for Return Trunk calculation failed: iteration limits exceeded. Return Trunk is calculated "
12471 : "using velocity at 5m/s.");
12472 : }
12473 1 : if (SolFla < 0) {
12474 0 : ReturnTrunkD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12475 : } else {
12476 1 : ReturnTrunkD = hydraulicDiameter * factor;
12477 : }
12478 1 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * Constant::Pi;
12479 1 : Velocity = flowrate / SupplyBranchArea;
12480 : }
12481 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12482 0 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12483 0 : ReturnTrunkD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12484 0 : ReturnTrunkArea = ReturnTrunkD * ReturnTrunkD / 4.0 * Constant::Pi;
12485 0 : ShowWarningError(
12486 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Return Trunk size");
12487 0 : ShowContinueError(
12488 : m_state,
12489 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12490 0 : simulation_control.ductSizing.max_velocity,
12491 : Velocity));
12492 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Return Trunk Diameter");
12493 : }
12494 : }
12495 : }
12496 : }
12497 :
12498 : // return duct branch
12499 24 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[0] == NodeZoneReturn) {
12500 1 : SumLength = 0.0;
12501 1 : DynamicLoss = 0.0;
12502 1 : MaxRough = 0.0;
12503 1 : if (AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1] == NodeMixer) {
12504 : // A single trunk duct
12505 0 : if (CompTypeNum == iComponentTypeNum::DWC && AirflowNetworkLinkageData(AFNLinkNum).ZoneNum > 0) {
12506 0 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnBranch;
12507 0 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12508 0 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12509 0 : SumLength = disSysCompDuct.L;
12510 0 : MaxRough = disSysCompDuct.roughness;
12511 0 : DynamicLoss = disSysCompDuct.TurDynCoef;
12512 0 : DuctSizingRBFlag = true;
12513 : }
12514 : } else {
12515 1 : int NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum).NodeNums[1];
12516 : int CompNum1;
12517 : iComponentTypeNum CompTypeNum1;
12518 1 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12519 1 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12520 1 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12521 1 : AirflowNetworkLinkageData(AFNLinkNum).ductLineType = DuctLineType::ReturnBranch;
12522 1 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12523 1 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12524 1 : SumLength += disSysCompDuct.L;
12525 1 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12526 1 : DynamicLoss += disSysCompDuct.TurDynCoef;
12527 1 : DuctSizingRBFlag = true;
12528 : }
12529 2 : while (NodeNum1 != NodeMixer) {
12530 14 : for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
12531 14 : if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) continue;
12532 1 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(AFNLinkNum1).CompNum).CompTypeNum != iComponentTypeNum::DWC)
12533 0 : continue;
12534 1 : if (NodeNum1 == AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
12535 1 : CompNum1 = AirflowNetworkLinkageData(AFNLinkNum1).CompNum;
12536 1 : CompTypeNum1 = AirflowNetworkCompData(CompNum1).CompTypeNum;
12537 1 : if (CompTypeNum1 == iComponentTypeNum::DWC) {
12538 1 : AirflowNetworkLinkageData(AFNLinkNum1).ductLineType = DuctLineType::ReturnBranch;
12539 1 : TypeNum = AirflowNetworkCompData(CompNum1).TypeNum;
12540 1 : auto const &disSysCompDuct = DisSysCompDuctData(TypeNum);
12541 1 : SumLength += disSysCompDuct.L;
12542 1 : MaxRough = max(MaxRough, disSysCompDuct.roughness);
12543 1 : DynamicLoss += disSysCompDuct.TurDynCoef;
12544 1 : NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1];
12545 1 : DuctSizingRBFlag = true;
12546 1 : break;
12547 : }
12548 : }
12549 : }
12550 : }
12551 : }
12552 1 : if (DuctSizingRBFlag) {
12553 1 : SolFla = 0;
12554 : Real64 Velocity;
12555 1 : Real64 flowrate = MdotBranch / m_state.dataEnvrn->StdRhoAir;
12556 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::MaxVelocity) {
12557 0 : ReturnBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12558 0 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * Constant::Pi;
12559 : } else {
12560 1 : Real64 MaxDiameter = sqrt(4.0 * flowrate / MinVelocity / Constant::Pi);
12561 1 : Real64 MinDiameter = sqrt(4.0 * flowrate / MaxVelocity / Constant::Pi);
12562 1 : auto &thisState = m_state; // can't use m_state directly in the capture list, just create a reference
12563 1 : Real64 const deltaP = simulation_control.ductSizing.return_branch_pressure_loss;
12564 196 : auto f = [&thisState, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough](Real64 const D) {
12565 196 : return DuctDResidual(thisState, D, deltaP, MdotBranch, SumLength, DynamicLoss, MaxRough);
12566 1 : };
12567 1 : General::SolveRoot(m_state, EPS, MaxIte, SolFla, hydraulicDiameter, f, MinDiameter, MaxDiameter);
12568 1 : if (SolFla == -1) {
12569 0 : if (!m_state.dataGlobal->WarmupFlag) {
12570 0 : if (ErrCountDuct == 0) {
12571 0 : ++ErrCountDuct; // TODO: Why is the error count shared among all heat pump units?
12572 0 : ShowWarningError(m_state,
12573 : "AirflowNetwork Duct Autosizing: Iteration limit exceeded calculating Return Duct Branch size.");
12574 0 : ShowContinueErrorTimeStamp(m_state, format("Return Duct Hydronic Diameter={:.2R}", hydraulicDiameter));
12575 : } else {
12576 0 : ++ErrCountDuct;
12577 0 : ShowRecurringWarningErrorAtEnd(
12578 : m_state,
12579 : "AirflowNetwork Duct Autosizing: Iteration limit warning exceeding Supply Duct Branch "
12580 : "size. Return Branch is calculated using velocity at 5m/s. Simulation continues...",
12581 0 : ErrIndexDuct,
12582 : hydraulicDiameter,
12583 : hydraulicDiameter);
12584 : }
12585 : }
12586 1 : } else if (SolFla == -2) {
12587 0 : ShowFatalError(
12588 : m_state,
12589 : "Duct Autosizing for Return Branch calculation failed: iteration limits exceeded. Return Branch is calculated "
12590 : "using velocity at 5m/s.");
12591 : }
12592 1 : if (SolFla < 0) {
12593 0 : ReturnBranchD = sqrt(4.0 * flowrate / 5.0 / Constant::Pi) * factor;
12594 : } else {
12595 1 : ReturnBranchD = hydraulicDiameter * factor;
12596 : }
12597 1 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * Constant::Pi;
12598 1 : Velocity = flowrate / ReturnBranchArea;
12599 : }
12600 1 : if (simulation_control.ductSizing.method == DuctSizingMethod::VelocityAndLoss) {
12601 0 : if (Velocity > simulation_control.ductSizing.max_velocity) {
12602 0 : ReturnBranchD = sqrt(4.0 * flowrate / simulation_control.ductSizing.max_velocity / Constant::Pi);
12603 0 : ReturnBranchArea = ReturnBranchD * ReturnBranchD / 4.0 * Constant::Pi;
12604 0 : ShowWarningError(
12605 : m_state, "AirflowNetwork Duct Sizing: Duct Sizing Method = PressureLossWithMaximumVelocity for Return Branch size");
12606 0 : ShowContinueError(
12607 : m_state,
12608 0 : format("The Maximum Airflow Velocity at {:.1R} is less than calculated velosity at {:.1R} using PressureLoss",
12609 0 : simulation_control.ductSizing.max_velocity,
12610 : Velocity));
12611 0 : ShowContinueError(m_state, "..The Maximum Airflow Velocity is used to calculate Return Branch Diameter");
12612 : }
12613 : }
12614 : }
12615 : }
12616 : }
12617 : // Assign autosize values in Duct element
12618 25 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12619 24 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12620 24 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12621 24 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12622 24 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyTrunk) {
12623 1 : disSysCompDuct.hydraulicDiameter = SupplyTrunkD;
12624 1 : disSysCompDuct.A = SupplyTrunkArea;
12625 1 : disSysCompDuct.RelRough = disSysCompDuct.roughness / SupplyTrunkD; // e/D: relative roughness
12626 1 : disSysCompDuct.RelL = disSysCompDuct.L / SupplyTrunkD; // L/D: relative length
12627 1 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12628 1 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12629 23 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyBranch) {
12630 3 : disSysCompDuct.hydraulicDiameter = SupplyBranchD;
12631 3 : disSysCompDuct.A = SupplyBranchArea;
12632 3 : disSysCompDuct.RelRough = disSysCompDuct.roughness / SupplyBranchD; // e/D: relative roughness
12633 3 : disSysCompDuct.RelL = disSysCompDuct.L / SupplyBranchD; // L/D: relative length
12634 3 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12635 3 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12636 20 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnTrunk) {
12637 1 : disSysCompDuct.hydraulicDiameter = ReturnTrunkD;
12638 1 : disSysCompDuct.A = ReturnTrunkArea;
12639 1 : disSysCompDuct.RelRough = disSysCompDuct.roughness / ReturnTrunkD; // e/D: relative roughness
12640 1 : disSysCompDuct.RelL = disSysCompDuct.L / ReturnTrunkD; // L/D: relative length
12641 1 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12642 1 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12643 19 : } else if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnBranch) {
12644 2 : disSysCompDuct.hydraulicDiameter = ReturnBranchD;
12645 2 : disSysCompDuct.A = ReturnBranchArea;
12646 2 : disSysCompDuct.RelRough = disSysCompDuct.roughness / ReturnBranchD; // e/D: relative roughness
12647 2 : disSysCompDuct.RelL = disSysCompDuct.L / ReturnBranchD; // L/D: relative length
12648 2 : disSysCompDuct.A1 = 1.14 - 0.868589 * std::log(disSysCompDuct.RelRough); // 1.14 - 0.868589*ln(e/D)
12649 2 : disSysCompDuct.g = disSysCompDuct.A1; // 1/sqrt(Darcy friction factor)
12650 : }
12651 : }
12652 :
12653 : // Print data in eio
12654 1 : print(m_state.files.eio,
12655 : "! <AirflowNetwork Model:Duct Autosizing>, Linkage Name, Duct Type, Duct Name, Duct Hydraunic Diameter, Duct Cross Section Area\n");
12656 :
12657 : // Assign autosize values in Duct element
12658 25 : for (AFNLinkNum = 1; AFNLinkNum <= AirflowNetworkNumOfLinks; AFNLinkNum++) {
12659 24 : CompNum = AirflowNetworkLinkageData(AFNLinkNum).CompNum;
12660 24 : TypeNum = AirflowNetworkCompData(CompNum).TypeNum;
12661 24 : auto &disSysCompDuct = DisSysCompDuctData(TypeNum);
12662 24 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyTrunk) {
12663 1 : print(m_state.files.eio,
12664 : "AirflowNetwork Model:Duct Autosizing, {}, Supply Trunk, {}, ",
12665 1 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12666 1 : disSysCompDuct.name);
12667 1 : print(m_state.files.eio, "{:.4R},{:.4R}\n", SupplyTrunkD, SupplyTrunkArea);
12668 : }
12669 24 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::SupplyBranch) {
12670 3 : print(m_state.files.eio,
12671 : "AirflowNetwork Model:Duct Autosizing, {}, Supply Branch, {}, ",
12672 3 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12673 3 : disSysCompDuct.name);
12674 3 : print(m_state.files.eio, "{:.4R},{:.4R}\n", SupplyBranchD, SupplyBranchArea);
12675 : }
12676 24 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnTrunk) {
12677 1 : print(m_state.files.eio,
12678 : "AirflowNetwork Model:Duct Autosizing, {}, Return Trunk, {}, ",
12679 1 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12680 1 : disSysCompDuct.name);
12681 1 : print(m_state.files.eio, "{:.4R},{:.4R}\n", ReturnTrunkD, ReturnTrunkArea);
12682 : }
12683 24 : if (AirflowNetworkLinkageData(AFNLinkNum).ductLineType == DuctLineType::ReturnBranch) {
12684 2 : print(m_state.files.eio,
12685 : "AirflowNetwork Model:Duct Autosizing, {}, Return Branch, {}, ",
12686 2 : AirflowNetworkLinkageData(AFNLinkNum).Name,
12687 2 : disSysCompDuct.name);
12688 2 : print(m_state.files.eio, "{:.4R},{:.4R}\n", ReturnBranchD, ReturnBranchArea);
12689 : }
12690 : }
12691 1 : }
12692 :
12693 496 : Real64 Solver::CalcDuctDiameter(Real64 hydraulicDiameter, Real64 DeltaP, Real64 MassFlowrate, Real64 TotalL, Real64 TotalLossCoe, Real64 MaxRough)
12694 : {
12695 496 : Real64 CalcDeltaP = 0.0;
12696 :
12697 : Real64 A;
12698 : Real64 A0;
12699 : Real64 A1;
12700 : Real64 A2;
12701 : Real64 B;
12702 : Real64 D;
12703 : Real64 S2;
12704 : Real64 CDM;
12705 : Real64 FL; // friction factor for laminar flow.
12706 : Real64 FT; // friction factor for turbulent flow.
12707 : Real64 FTT;
12708 : Real64 RE; // Reynolds number.
12709 : Real64 ed;
12710 : Real64 ld;
12711 : Real64 g;
12712 : Real64 AA1;
12713 : Real64 velocity;
12714 496 : Real64 constexpr LamDynCoef(64.0);
12715 496 : Real64 constexpr LamFriCoef(0.001);
12716 496 : Real64 constexpr EPS(0.001);
12717 496 : Real64 constexpr C(0.868589);
12718 :
12719 : //// Initial guess with 5 m/s
12720 496 : Real64 flowrate = MassFlowrate / m_state.dataEnvrn->StdRhoAir;
12721 :
12722 496 : ed = MaxRough / hydraulicDiameter;
12723 496 : ld = TotalL / hydraulicDiameter;
12724 496 : g = 1.14 - 0.868589 * std::log(ed);
12725 496 : AA1 = g;
12726 496 : A = hydraulicDiameter * hydraulicDiameter / 4.0 * Constant::Pi;
12727 496 : Real64 viscosity{AirflowNetwork::AIRDYNAMICVISCOSITY_CONSTEXPR(20)};
12728 496 : velocity = flowrate / A;
12729 :
12730 : if (LamFriCoef >= 0.001) {
12731 496 : A2 = LamFriCoef / (2.0 * m_state.dataEnvrn->StdRhoAir * A * A);
12732 496 : A1 = (viscosity * LamDynCoef * ld) / (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter);
12733 496 : A0 = -DeltaP;
12734 496 : CDM = std::sqrt(A1 * A1 - 4.0 * A2 * A0);
12735 496 : FL = (CDM - A1) / (2.0 * A2);
12736 496 : CDM = 1.0 / CDM;
12737 : } else {
12738 : CDM = (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter) / (viscosity * LamDynCoef * ld);
12739 : FL = CDM * DeltaP;
12740 : }
12741 :
12742 : // CDM = (2.0 * m_state.dataEnvrn->StdRhoAir * A * hydraulicDiameter) / (viscosity * LamDynCoef * ld);
12743 : // FL = CDM * DeltaP;
12744 :
12745 496 : RE = FL * hydraulicDiameter / (viscosity * A);
12746 496 : S2 = std::sqrt(2.0 * m_state.dataEnvrn->StdRhoAir * DeltaP) * A;
12747 496 : FTT = S2 / std::sqrt(ld / pow_2(g) + TotalLossCoe);
12748 : while (true) {
12749 975 : FT = FTT;
12750 975 : B = (9.3 * viscosity * A) / (FT * MaxRough);
12751 975 : D = 1.0 + g * B;
12752 975 : g -= (g - AA1 + C * std::log(D)) / (1.0 + C * B / D);
12753 975 : FTT = S2 / std::sqrt(ld / pow_2(g) + TotalLossCoe);
12754 975 : if (std::abs(FTT - FT) / FTT < EPS) break;
12755 : }
12756 496 : FT = FTT;
12757 :
12758 496 : Real64 f = 1.0 / (g * g);
12759 :
12760 : // CalcDeltaP = ((FT * TotalL) / hydraulicDiameter + TotalLossCoe) * (m_state.dataEnvrn->StdRhoAir * velocity * velocity / 2.0);
12761 496 : CalcDeltaP = ((f * TotalL) / hydraulicDiameter + TotalLossCoe) * (m_state.dataEnvrn->StdRhoAir * velocity * velocity / 2.0);
12762 :
12763 496 : return CalcDeltaP;
12764 : }
12765 :
12766 496 : Real64 DuctDResidual(EnergyPlusData &state,
12767 : Real64 D, // duct diameter
12768 : Real64 DeltaP,
12769 : Real64 MassFlowrate,
12770 : Real64 TotalL,
12771 : Real64 TotalLossCoe,
12772 : Real64 MaxRough)
12773 : {
12774 496 : Real64 CalcDeltaP = state.afn->CalcDuctDiameter(D, DeltaP, MassFlowrate, TotalL, TotalLossCoe, MaxRough);
12775 496 : return (CalcDeltaP - DeltaP) / DeltaP;
12776 : }
12777 :
12778 5192 : void OccupantVentilationControlProp::calc(EnergyPlusData &state,
12779 : int const ZoneNum,
12780 : Real64 const TimeOpenDuration,
12781 : Real64 const TimeCloseDuration,
12782 : int &OpeningStatus,
12783 : int &OpeningProbStatus,
12784 : int &ClosingProbStatus)
12785 : {
12786 :
12787 : Real64 Tcomfort; // Thermal comfort temperature
12788 : Real64 ComfortBand; // Thermal comfort band
12789 : Real64 Toperative; // Operative temperature
12790 : Real64 OutDryBulb; // Outdoor dry-bulb temperature
12791 :
12792 5192 : auto &Zone(state.dataHeatBal->Zone);
12793 :
12794 5192 : if (TimeOpenDuration > 0) {
12795 1832 : if (TimeOpenDuration >= MinOpeningTime) {
12796 1622 : OpeningStatus = OpenStatus::FreeOperation; // free operation
12797 : } else {
12798 210 : OpeningStatus = OpenStatus::MinCheckForceOpen; // forced to open
12799 : }
12800 : }
12801 5192 : if (TimeCloseDuration > 0) {
12802 3360 : if (TimeCloseDuration >= MinClosingTime) {
12803 3124 : OpeningStatus = OpenStatus::FreeOperation; // free operation
12804 : } else {
12805 236 : OpeningStatus = OpenStatus::MinCheckForceClose; // forced to close
12806 : }
12807 : }
12808 :
12809 5192 : if (MinTimeControlOnly) return;
12810 :
12811 5192 : if (Zone(ZoneNum).LinkedOutAirNode > 0) {
12812 0 : OutDryBulb = Zone(ZoneNum).OutDryBulbTemp;
12813 : } else {
12814 5192 : OutDryBulb = OutDryBulbTempAt(state, Zone(ZoneNum).Centroid.z);
12815 : }
12816 :
12817 5192 : if (OutDryBulb < ComfortBouPoint) {
12818 2616 : Tcomfort = CurveValue(state, ComfortLowTempCurveNum, OutDryBulb);
12819 : } else {
12820 2576 : Tcomfort = CurveValue(state, ComfortHighTempCurveNum, OutDryBulb);
12821 : }
12822 5192 : ComfortBand = -0.0028 * (100 - MaxPPD) * (100 - MaxPPD) + 0.3419 * (100 - MaxPPD) - 6.6275;
12823 5192 : Toperative = 0.5 * (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT +
12824 5192 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MRT);
12825 :
12826 5192 : if (Toperative > (Tcomfort + ComfortBand)) {
12827 770 : if (opening_probability(state, ZoneNum, TimeCloseDuration)) {
12828 16 : OpeningProbStatus = ProbabilityCheck::ForceChange;
12829 : ; // forced to open
12830 : } else {
12831 754 : OpeningProbStatus = ProbabilityCheck::KeepStatus; // Keep previous status
12832 : }
12833 : } else {
12834 4422 : OpeningProbStatus = ProbabilityCheck::NoAction; // free operation
12835 : }
12836 :
12837 5192 : if (Toperative < (Tcomfort - ComfortBand)) {
12838 2872 : if (closing_probability(state, TimeOpenDuration)) {
12839 82 : ClosingProbStatus = ProbabilityCheck::ForceChange; // forced to close
12840 : } else {
12841 2790 : ClosingProbStatus = ProbabilityCheck::KeepStatus; // Keep previous status
12842 : }
12843 : } else {
12844 2320 : ClosingProbStatus = ProbabilityCheck::NoAction; // free operation
12845 : }
12846 : }
12847 :
12848 : bool
12849 770 : OccupantVentilationControlProp::opening_probability(EnergyPlusData &state,
12850 : int const ZoneNum,
12851 : Real64 const TimeCloseDuration) // function to perform calculations of opening probability
12852 : {
12853 : Real64 SchValue;
12854 : Real64 RandomValue;
12855 770 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
12856 :
12857 770 : if (TimeCloseDuration < MinClosingTime) {
12858 754 : return false;
12859 : }
12860 16 : if (OccupancyCheck) {
12861 16 : if (state.dataHeatBal->ZoneIntGain(ZoneNum).NOFOCC <= 0.0) {
12862 0 : return false;
12863 : }
12864 : }
12865 :
12866 16 : switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
12867 0 : case HVAC::ThermostatType::SingleHeating:
12868 0 : if (thisZoneHB.MAT <= state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum)) {
12869 0 : return false;
12870 : }
12871 0 : break;
12872 0 : case HVAC::ThermostatType::SingleCooling:
12873 0 : if (thisZoneHB.MAT >= state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum)) {
12874 0 : return false;
12875 : }
12876 0 : break;
12877 0 : case HVAC::ThermostatType::SingleHeatCool:
12878 0 : return false;
12879 0 : case HVAC::ThermostatType::DualSetPointWithDeadBand:
12880 0 : if (thisZoneHB.MAT < state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum) ||
12881 0 : thisZoneHB.MAT > state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum)) {
12882 0 : return false;
12883 : }
12884 0 : break;
12885 16 : default:
12886 16 : break;
12887 : }
12888 :
12889 16 : if (OpeningProbSchNum == 0) {
12890 16 : return true;
12891 : } else {
12892 0 : SchValue = GetCurrentScheduleValue(state, OpeningProbSchNum);
12893 0 : RandomValue = Real64(rand()) / RAND_MAX;
12894 0 : if (SchValue > RandomValue) {
12895 0 : return true;
12896 : } else {
12897 0 : return false;
12898 : }
12899 : }
12900 : }
12901 :
12902 2872 : bool OccupantVentilationControlProp::closing_probability(EnergyPlusData &state,
12903 : Real64 const TimeOpenDuration) // function to perform calculations of closing probability
12904 : {
12905 : Real64 SchValue;
12906 : Real64 RandomValue;
12907 :
12908 2872 : if (TimeOpenDuration < MinOpeningTime) {
12909 2790 : return false;
12910 : }
12911 82 : if (ClosingProbSchNum == 0) {
12912 82 : return true;
12913 : } else {
12914 0 : SchValue = GetCurrentScheduleValue(state, ClosingProbSchNum);
12915 0 : RandomValue = Real64(rand()) / RAND_MAX;
12916 0 : if (SchValue > RandomValue) {
12917 0 : return true;
12918 : } else {
12919 0 : return false;
12920 : }
12921 : }
12922 : }
12923 :
12924 35 : void Solver::allocate()
12925 : {
12926 :
12927 : // SUBROUTINE INFORMATION:
12928 : // AUTHOR Lixing Gu
12929 : // DATE WRITTEN Aug. 2003
12930 : // MODIFIED na
12931 : // RE-ENGINEERED na
12932 :
12933 : // PURPOSE OF THIS SUBROUTINE:
12934 : // This subroutine allocates dynamic arrays for AirflowNetworkSolver.
12935 :
12936 : // METHODOLOGY EMPLOYED:
12937 : // na
12938 :
12939 : // REFERENCES:
12940 : // na
12941 :
12942 : // USE STATEMENTS:
12943 : // na
12944 :
12945 : // Locals
12946 : // SUBROUTINE ARGUMENT DEFINITIONS:
12947 : // na
12948 :
12949 : // SUBROUTINE PARAMETER DEFINITIONS:
12950 : // na
12951 :
12952 : // INTERFACE BLOCK SPECIFICATIONS
12953 : // na
12954 :
12955 : // DERIVED TYPE DEFINITIONS
12956 : // na
12957 :
12958 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12959 : int i;
12960 : iComponentTypeNum j;
12961 : int n;
12962 :
12963 : // Formats
12964 :
12965 : // Assume a network to simulate multizone airflow is a subset of the network to simulate air distribution system.
12966 : // Network array size is allocated based on the network of air distribution system.
12967 : // If multizone airflow is simulated only, the array size is allocated based on the multizone network.
12968 :
12969 35 : auto &NetworkNumOfLinks = ActualNumOfLinks;
12970 35 : auto &NetworkNumOfNodes = ActualNumOfNodes;
12971 :
12972 35 : NetworkNumOfLinks = AirflowNetworkNumOfLinks;
12973 35 : NetworkNumOfNodes = AirflowNetworkNumOfNodes;
12974 :
12975 35 : AFECTL.allocate(NetworkNumOfLinks);
12976 35 : AFLOW2.allocate(NetworkNumOfLinks);
12977 35 : AFLOW.allocate(NetworkNumOfLinks);
12978 35 : PW.allocate(NetworkNumOfLinks);
12979 35 : PS.allocate(NetworkNumOfLinks);
12980 :
12981 : // TZ.allocate(NetworkNumOfNodes);
12982 : // WZ.allocate(NetworkNumOfNodes);
12983 35 : PZ.allocate(NetworkNumOfNodes);
12984 : // RHOZ.allocate(NetworkNumOfNodes);
12985 : // SQRTDZ.allocate(NetworkNumOfNodes);
12986 : // VISCZ.allocate(NetworkNumOfNodes);
12987 35 : SUMAF.allocate(NetworkNumOfNodes);
12988 :
12989 950 : for (int it = 0; it <= NetworkNumOfNodes + 1; ++it)
12990 915 : node_states.emplace_back(properties.density(101325.0, 20.0, 0.0));
12991 :
12992 35 : ID.allocate(NetworkNumOfNodes);
12993 35 : IK.allocate(NetworkNumOfNodes + 1);
12994 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
12995 35 : newIK.allocate(NetworkNumOfNodes + 1);
12996 : #endif
12997 35 : AD.allocate(NetworkNumOfNodes);
12998 35 : SUMF.allocate(NetworkNumOfNodes);
12999 :
13000 35 : n = 0;
13001 1234 : for (i = 1; i <= AirflowNetworkNumOfLinks; ++i) {
13002 1199 : j = AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum;
13003 1199 : if (j == iComponentTypeNum::DOP) {
13004 70 : ++n;
13005 : }
13006 : }
13007 :
13008 35 : dos.allocate(AirflowNetworkNumOfLinks, n);
13009 :
13010 35 : PB = 101325.0;
13011 : // LIST = 5
13012 : // LIST = 0;
13013 :
13014 880 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13015 845 : ID(n) = n;
13016 : }
13017 1234 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13018 1199 : AFECTL(i) = 1.0;
13019 1199 : AFLOW(i) = 0.0;
13020 1199 : AFLOW2(i) = 0.0;
13021 : }
13022 :
13023 880 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13024 : // TZ(i) = AirflowNetworkNodeSimu(i).TZ;
13025 : // WZ(i) = AirflowNetworkNodeSimu(i).WZ;
13026 845 : PZ(i) = AirflowNetworkNodeSimu(i).PZ;
13027 845 : node_states[i].temperature = AirflowNetworkNodeSimu(i).TZ;
13028 845 : node_states[i].humidity_ratio = AirflowNetworkNodeSimu(i).WZ;
13029 : // properties[i].pressure = AirflowNetworkNodeSimu(i).PZ;
13030 : }
13031 :
13032 : // Assign linkage values
13033 1234 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13034 1199 : PW(i) = 0.0;
13035 : }
13036 : // Write an ouput file used for AIRNET input
13037 : /*
13038 : if (LIST >= 5) {
13039 : Unit11 = GetNewUnitNumber();
13040 : ObjexxFCL::gio::open(Unit11, DataStringGlobals::eplusADSFileName);
13041 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13042 : ObjexxFCL::gio::write(Unit11, Format_901) << i << state.afn->AirflowNetworkNodeData(i).NodeTypeNum <<
13043 : state.afn->AirflowNetworkNodeData(i).NodeHeight << TZ(i)
13044 : << PZ(i);
13045 : }
13046 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13047 : for (i = 1; i <= AirflowNetworkNumOfComps; ++i) {
13048 : j = state.afn->AirflowNetworkCompData(i).TypeNum;
13049 : {
13050 : auto const SELECT_CASE_var(state.afn->AirflowNetworkCompData(i).CompTypeNum);
13051 : if (SELECT_CASE_var == CompTypeNum_PLR) { //'PLR' Power law component
13052 : // WRITE(Unit11,902)
13053 : state.afn->AirflowNetworkCompData(i)%CompNum,1,DisSysCompLeakData(j)%FlowCoef, &
13054 : // DisSysCompLeakData(j)%FlowCoef,DisSysCompLeakData(j)%FlowCoef,DisSysCompLeakData(j)%FlowExpo
13055 : } else if (SELECT_CASE_var == CompTypeNum_SCR) { //'SCR' Surface crack component
13056 : ObjexxFCL::gio::write(Unit11, Format_902) << state.afn->AirflowNetworkCompData(i).CompNum << 1 <<
13057 : MultizoneSurfaceCrackData(j).FlowCoef
13058 : << MultizoneSurfaceCrackData(j).FlowCoef << MultizoneSurfaceCrackData(j).FlowCoef
13059 : << MultizoneSurfaceCrackData(j).FlowExpo;
13060 : } else if (SELECT_CASE_var == CompTypeNum_DWC) { //'DWC' Duct component
13061 : // WRITE(Unit11,902)
13062 : state.afn->AirflowNetworkCompData(i)%CompNum,2,DisSysCompDuctData(j)%L,DisSysCompDuctData(j)%D, &
13063 : // DisSysCompDuctData(j)%A,DisSysCompDuctData(j)%Rough
13064 : // WRITE(Unit11,903) DisSysCompDuctData(i)%TurDynCoef,DisSysCompDuctData(j)%LamFriCoef, &
13065 : // DisSysCompDuctData(j)%LamFriCoef,DisSysCompDuctData(j)%InitLamCoef
13066 : // CASE (CompTypeNum_CVF) ! 'CVF' Constant volume fan component
13067 : // WRITE(Unit11,904) state.afn->AirflowNetworkCompData(i)%CompNum,4,DisSysCompCVFData(j)%FlowRate
13068 : } else if (SELECT_CASE_var == CompTypeNum_EXF) { // 'EXF' Zone exhaust fan
13069 : ObjexxFCL::gio::write(Unit11, Format_904) << state.afn->AirflowNetworkCompData(i).CompNum << 4 <<
13070 : MultizoneCompExhaustFanData(j).FlowRate; } else {
13071 : }
13072 : }
13073 : }
13074 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13075 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13076 : gio::write(Unit11, Format_910) << i << state.afn->AirflowNetworkLinkageData(i).NodeNums[0] <<
13077 : state.afn->AirflowNetworkLinkageData(i).NodeHeights[0]
13078 : << state.afn->AirflowNetworkLinkageData(i).NodeNums[1] <<
13079 : state.afn->AirflowNetworkLinkageData(i).NodeHeights[1]
13080 : << state.afn->AirflowNetworkLinkageData(i).CompNum << 0 << 0;
13081 : }
13082 : ObjexxFCL::gio::write(Unit11, Format_900) << 0;
13083 : }
13084 : */
13085 35 : setsky();
13086 :
13087 : // SETSKY figures out the IK stuff -- which is why E+ doesn't allocate AU until here
13088 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13089 : // ! only printing to screen, can be commented
13090 : // print*, "SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS is defined"
13091 : // write(*,'(2(a,i8))') "AllocateAirflowNetworkData: after SETSKY, allocating AU. NetworkNumOfNodes=", &
13092 : // NetworkNumOfNodes, " IK(NetworkNumOfNodes+1)= NNZE=", IK(NetworkNumOfNodes+1)
13093 : // print*, " NetworkNumOfLinks=", NetworkNumOfLinks
13094 : // allocate same size as others -- this will be maximum !noel
13095 35 : newAU.allocate(IK(NetworkNumOfNodes + 1));
13096 : #endif
13097 :
13098 : // noel, GNU says the AU is indexed above its upper bound
13099 : // ALLOCATE(AU(IK(NetworkNumOfNodes+1)-1))
13100 35 : AU.allocate(IK(NetworkNumOfNodes + 1));
13101 35 : }
13102 :
13103 582976 : void Solver::initialize_calculation()
13104 : {
13105 :
13106 : // SUBROUTINE INFORMATION:
13107 : // AUTHOR Lixing Gu
13108 : // DATE WRITTEN Aug. 2003
13109 : // MODIFIED na
13110 : // RE-ENGINEERED na
13111 :
13112 : // PURPOSE OF THIS SUBROUTINE:
13113 : // This subroutine initializes variables for AirflowNetworkSolver.
13114 :
13115 : // METHODOLOGY EMPLOYED:
13116 : // na
13117 :
13118 : // REFERENCES:
13119 : // na
13120 :
13121 : // USE STATEMENTS:
13122 : // na
13123 :
13124 : // Locals
13125 : // SUBROUTINE ARGUMENT DEFINITIONS:
13126 : // na
13127 :
13128 : // SUBROUTINE PARAMETER DEFINITIONS:
13129 : // na
13130 :
13131 : // INTERFACE BLOCK SPECIFICATIONS
13132 : // na
13133 :
13134 : // DERIVED TYPE DEFINITIONS
13135 : // na
13136 :
13137 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13138 :
13139 12600089 : for (int i = 1; i <= ActualNumOfNodes; ++i) {
13140 12017113 : ID(i) = i;
13141 : }
13142 17413843 : for (int i = 1; i <= ActualNumOfLinks; ++i) {
13143 16830867 : AFECTL(i) = 1.0;
13144 16830867 : AFLOW(i) = 0.0;
13145 16830867 : AFLOW2(i) = 0.0;
13146 : }
13147 :
13148 12600089 : for (int i = 1; i <= ActualNumOfNodes; ++i) {
13149 : // TZ(i) = AirflowNetworkNodeSimu(i).TZ;
13150 : // WZ(i) = AirflowNetworkNodeSimu(i).WZ;
13151 12017113 : PZ(i) = AirflowNetworkNodeSimu(i).PZ;
13152 12017113 : node_states[i].temperature = AirflowNetworkNodeSimu(i).TZ;
13153 12017113 : node_states[i].humidity_ratio = AirflowNetworkNodeSimu(i).WZ;
13154 : // properties[i].pressure = AirflowNetworkNodeSimu(i).PZ;
13155 : }
13156 582976 : }
13157 :
13158 35 : void Solver::setsky()
13159 : {
13160 : // SUBROUTINE INFORMATION:
13161 : // AUTHOR George Walton
13162 : // DATE WRITTEN 1998
13163 : // MODIFIED Feb. 2006 (L. Gu) to meet requirements of AirflowNetwork
13164 : // RE-ENGINEERED na
13165 :
13166 : // PURPOSE OF THIS SUBROUTINE:
13167 : // This subroutine sets up the "IK" array describing the sparse matrix [A] in skyline
13168 : // form by using the location matrix.
13169 :
13170 : // METHODOLOGY EMPLOYED:
13171 : // na
13172 :
13173 : // REFERENCES:
13174 : // AIRNET
13175 :
13176 : // USE STATEMENTS:
13177 : // na
13178 :
13179 : // Locals
13180 : // SUBROUTINE ARGUMENT DEFINITIONS:
13181 : // na
13182 :
13183 : // SUBROUTINE PARAMETER DEFINITIONS:
13184 : // na
13185 :
13186 : // INTERFACE BLOCK SPECIFICATIONS
13187 : // na
13188 :
13189 : // DERIVED TYPE DEFINITIONS
13190 : // na
13191 :
13192 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13193 : // IK(K) - pointer to the top of column/row "K".
13194 : int i;
13195 : int j;
13196 : int k;
13197 : int L;
13198 : int M;
13199 : int N1;
13200 : int N2;
13201 :
13202 : // Initialize "IK".
13203 915 : for (i = 1; i <= ActualNumOfNodes + 1; ++i) {
13204 880 : IK(i) = 0;
13205 : }
13206 : // Determine column heights.
13207 1234 : for (M = 1; M <= ActualNumOfLinks; ++M) {
13208 1199 : j = AirflowNetworkLinkageData(M).NodeNums[1];
13209 1199 : if (j == 0) continue;
13210 1199 : L = ID(j);
13211 1199 : i = AirflowNetworkLinkageData(M).NodeNums[0];
13212 1199 : k = ID(i);
13213 1199 : N1 = std::abs(L - k);
13214 1199 : N2 = max(k, L);
13215 1199 : IK(N2) = max(IK(N2), N1);
13216 : }
13217 : // Convert heights to column addresses.
13218 35 : j = IK(1);
13219 35 : IK(1) = 1;
13220 880 : for (k = 1; k <= ActualNumOfNodes; ++k) {
13221 845 : i = IK(k + 1);
13222 845 : IK(k + 1) = IK(k) + j;
13223 845 : j = i;
13224 : }
13225 35 : }
13226 :
13227 577221 : void Solver::airmov()
13228 : {
13229 : // SUBROUTINE INFORMATION:
13230 : // AUTHOR George Walton
13231 : // DATE WRITTEN Extracted from AIRNETf
13232 : // MODIFIED Lixing Gu, 2/1/04
13233 : // Revised the subroutine to meet E+ needs
13234 : // MODIFIED Lixing Gu, 6/8/05
13235 : // RE-ENGINEERED na
13236 :
13237 : // PURPOSE OF THIS SUBROUTINE:
13238 : // This subroutine is a driver for AIRNET to calculate nodal pressures and linkage airflows
13239 :
13240 : // METHODOLOGY EMPLOYED:
13241 : // na
13242 :
13243 : // REFERENCES:
13244 : // na
13245 :
13246 : // USE STATEMENTS:
13247 :
13248 : // Locals
13249 : // SUBROUTINE ARGUMENT DEFINITIONS:
13250 : // na
13251 :
13252 : // SUBROUTINE PARAMETER DEFINITIONS:
13253 : // na
13254 :
13255 : // INTERFACE BLOCK SPECIFICATIONS
13256 : // na
13257 :
13258 : // DERIVED TYPE DEFINITIONS
13259 : // na
13260 :
13261 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13262 : int i;
13263 : int m;
13264 : int n;
13265 : int ITER;
13266 :
13267 : // Formats
13268 :
13269 : // static ObjexxFCL::gio::Fmt Format_900("(,/,11X,'i n m DP',12x,'F1',12X,'F2')");
13270 : // static ObjexxFCL::gio::Fmt Format_901("(1X,A6,3I5,3F14.6)");
13271 : // static ObjexxFCL::gio::Fmt Format_902("(,/,11X,'n P',12x,'sumF')");
13272 : // static ObjexxFCL::gio::Fmt Format_903("(1X,A6,I5,3F14.6)");
13273 : // static ObjexxFCL::gio::Fmt Format_907("(,/,' CPU seconds for ',A,F12.3)");
13274 :
13275 577221 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13276 577221 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13277 :
13278 : // Initialize pressure for pressure control and for Initialization Type = LinearInitializationMethod
13279 577221 : if ((simulation_control.InitFlag == 0) || (PressureSetFlag > 0 && AirflowNetworkFanActivated)) {
13280 1590756 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13281 1548894 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) PZ(n) = 0.0;
13282 : }
13283 : }
13284 : // Compute zone air properties.
13285 12381399 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13286 23608356 : node_states[n].density =
13287 11804178 : properties.density(m_state.dataEnvrn->StdBaroPress + PZ(n), node_states[n].temperature, node_states[n].humidity_ratio);
13288 : // RHOZ(n) = PsyRhoAirFnPbTdbW(StdBaroPress + PZ(n), TZ(n), WZ(n));
13289 11804178 : if (AirflowNetworkNodeData(n).ExtNodeNum > 0) {
13290 7507864 : node_states[n].density =
13291 3753932 : properties.density(m_state.dataEnvrn->StdBaroPress + PZ(n), m_state.dataEnvrn->OutDryBulbTemp, m_state.dataEnvrn->OutHumRat);
13292 3753932 : node_states[n].temperature = m_state.dataEnvrn->OutDryBulbTemp;
13293 3753932 : node_states[n].humidity_ratio = m_state.dataEnvrn->OutHumRat;
13294 : }
13295 11804178 : node_states[n].sqrt_density = std::sqrt(node_states[n].density);
13296 11804178 : node_states[n].viscosity = 1.71432e-5 + 4.828e-8 * node_states[n].temperature;
13297 : // if (LIST >= 2) ObjexxFCL::gio::write(outputFile, Format_903) << "D,V:" << n << properties[n].density << properties[n].viscosity;
13298 : }
13299 : // Compute stack pressures.
13300 17062788 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13301 16485567 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13302 16485567 : m = AirflowNetworkLinkageData(i).NodeNums[1];
13303 16485567 : if (AFLOW(i) > 0.0) {
13304 0 : PS(i) = 9.80 * (node_states[n].density * (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13305 0 : m_state.afn->AirflowNetworkLinkageData(i).NodeHeights[1] * (node_states[m].density - node_states[n].density));
13306 16485567 : } else if (AFLOW(i) < 0.0) {
13307 0 : PS(i) = 9.80 * (node_states[m].density * (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13308 0 : AirflowNetworkLinkageData(i).NodeHeights[0] * (node_states[m].density - node_states[n].density));
13309 : } else {
13310 32971134 : PS(i) = 4.90 * ((node_states[n].density + node_states[m].density) *
13311 16485567 : (AirflowNetworkNodeData(n).NodeHeight - AirflowNetworkNodeData(m).NodeHeight) +
13312 16485567 : (AirflowNetworkLinkageData(i).NodeHeights[0] + AirflowNetworkLinkageData(i).NodeHeights[1]) *
13313 16485567 : (node_states[m].density - node_states[n].density));
13314 : }
13315 : }
13316 :
13317 : // Calculate pressure field in a large opening
13318 577221 : dos.pstack(m_state, node_states, PZ);
13319 577221 : solvzp(ITER);
13320 :
13321 : // Report element flows and zone pressures.
13322 12381399 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13323 11804178 : SUMAF(n) = 0.0;
13324 : }
13325 : // if (LIST >= 1) ObjexxFCL::gio::write(outputFile, Format_900);
13326 17062788 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13327 16485567 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13328 16485567 : m = AirflowNetworkLinkageData(i).NodeNums[1];
13329 : // if (LIST >= 1) {
13330 : // gio::write(outputFile, Format_901) << "Flow: " << i << n << m << AirflowNetworkLinkSimu(i).DP << AFLOW(i) << AFLOW2(i);
13331 : //}
13332 16485567 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
13333 7332 : SUMAF(n) = SUMAF(n) - AFLOW(i);
13334 7332 : SUMAF(m) += AFLOW(i);
13335 : } else {
13336 16478235 : SUMAF(n) = SUMAF(n) - AFLOW(i) - AFLOW2(i);
13337 16478235 : SUMAF(m) += AFLOW(i) + AFLOW2(i);
13338 : }
13339 : }
13340 : // for (n = 1; n <= NetworkNumOfNodes; ++n) {
13341 : // if (LIST >= 1) gio::write(outputFile, Format_903) << "Room: " << n << PZ(n) << SUMAF(n) << properties[n].temperature;
13342 : //}
13343 :
13344 17062788 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13345 16485567 : if (AFLOW2(i) != 0.0) {
13346 : }
13347 16485567 : if (AFLOW(i) > 0.0) {
13348 12414341 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i);
13349 12414341 : AirflowNetworkLinkSimu(i).FLOW2 = 0.0;
13350 : } else {
13351 4071226 : AirflowNetworkLinkSimu(i).FLOW = 0.0;
13352 4071226 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i);
13353 : }
13354 16485567 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::HOP) {
13355 7332 : if (AFLOW(i) > 0.0) {
13356 767 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i) + AFLOW2(i);
13357 767 : AirflowNetworkLinkSimu(i).FLOW2 = AFLOW2(i);
13358 : } else {
13359 6565 : AirflowNetworkLinkSimu(i).FLOW = AFLOW2(i);
13360 6565 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i) + AFLOW2(i);
13361 : }
13362 : }
13363 16485567 : if (AirflowNetworkLinkageData(i).DetOpenNum > 0) {
13364 742174 : if (AFLOW2(i) != 0.0) {
13365 185350 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i) + AFLOW2(i);
13366 185350 : AirflowNetworkLinkSimu(i).FLOW2 = AFLOW2(i);
13367 : }
13368 : }
13369 16485567 : if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SOP && AFLOW2(i) != 0.0) {
13370 5028 : if (AFLOW(i) >= 0.0) {
13371 3374 : AirflowNetworkLinkSimu(i).FLOW = AFLOW(i);
13372 3374 : AirflowNetworkLinkSimu(i).FLOW2 = std::abs(AFLOW2(i));
13373 : } else {
13374 1654 : AirflowNetworkLinkSimu(i).FLOW = std::abs(AFLOW2(i));
13375 1654 : AirflowNetworkLinkSimu(i).FLOW2 = -AFLOW(i);
13376 : }
13377 : }
13378 : }
13379 :
13380 12381399 : for (i = 1; i <= NetworkNumOfNodes; ++i) {
13381 11804178 : AirflowNetworkNodeSimu(i).PZ = PZ(i);
13382 : }
13383 577221 : }
13384 :
13385 577221 : void Solver::solvzp(int &ITER) // number of iterations
13386 : {
13387 :
13388 : // SUBROUTINE INFORMATION:
13389 : // AUTHOR George Walton
13390 : // DATE WRITTEN Extracted from AIRNET
13391 : // MODIFIED Lixing Gu, 2/1/04
13392 : // Revised the subroutine to meet E+ needs
13393 : // MODIFIED Lixing Gu, 6/8/05
13394 : // RE-ENGINEERED na
13395 :
13396 : // PURPOSE OF THIS SUBROUTINE:
13397 : // This subroutine solves zone pressures by modified Newton-Raphson iteration
13398 :
13399 : // METHODOLOGY EMPLOYED:
13400 : // na
13401 :
13402 : // REFERENCES:
13403 : // na
13404 :
13405 577221 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13406 577221 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13407 :
13408 : // Argument array dimensioning (these used to be arguments, need to also test newAU and newIK)
13409 577221 : EP_SIZE_CHECK(IK, NetworkNumOfNodes + 1);
13410 577221 : EP_SIZE_CHECK(AD, NetworkNumOfNodes);
13411 577221 : EP_SIZE_CHECK(AU, IK(NetworkNumOfNodes + 1));
13412 :
13413 : // Locals
13414 : // SUBROUTINE ARGUMENT DEFINITIONS:
13415 : // noel GNU says AU is being indexed beyound bounds
13416 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
13417 :
13418 : // SUBROUTINE PARAMETER DEFINITIONS:
13419 :
13420 : // INTERFACE BLOCK SPECIFICATIONS
13421 : // na
13422 :
13423 : // DERIVED TYPE DEFINITIONS
13424 : // na
13425 :
13426 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13427 :
13428 : // NNZE - number of nonzero entries in the "AU" array.
13429 : // LFLAG - if = 1, use laminar relationship (initialization).
13430 : // I - element number.
13431 : // N - number of node/zone 1.
13432 : // M - number of node/zone 2.
13433 : // F - flows through the element (kg/s).
13434 : // DF - partial derivatives: DF/DP.
13435 : // NF - number of flows, 1 or 2.
13436 : // SUMF - sum of flows into node/zone.
13437 : // CCF - current pressure correction (Pa).
13438 : // PCF - previous pressure correction (Pa).
13439 : // CEF - convergence enhancement factor.
13440 : int n;
13441 : int NNZE;
13442 : int NSYM;
13443 : bool LFLAG;
13444 : int CONVG;
13445 : int ACCEL;
13446 577221 : Array1D<Real64> PCF(NetworkNumOfNodes);
13447 577221 : Array1D<Real64> CEF(NetworkNumOfNodes);
13448 : Real64 C;
13449 : Real64 SSUMF;
13450 : Real64 SSUMAF;
13451 : Real64 ACC0;
13452 : Real64 ACC1;
13453 577221 : Array1D<Real64> CCF(NetworkNumOfNodes);
13454 :
13455 : // auto &outputFile = std::cout;
13456 :
13457 577221 : ACC1 = 0.0;
13458 577221 : ACCEL = 0;
13459 577221 : NSYM = 0;
13460 577221 : NNZE = IK(NetworkNumOfNodes + 1) - 1;
13461 : // if (LIST >= 2) print(outputFile, "Initialization{:16}{:16}{:16}\n", NetworkNumOfNodes, NetworkNumOfLinks, NNZE);
13462 577221 : ITER = 0;
13463 :
13464 12381399 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13465 11804178 : PCF(n) = 0.0;
13466 11804178 : CEF(n) = 0.0;
13467 : }
13468 :
13469 577221 : if (simulation_control.InitFlag != 1) {
13470 : // Initialize node/zone pressure values by assuming only linear relationship between
13471 : // airflows and pressure drops.
13472 0 : LFLAG = true;
13473 0 : filjac(NNZE, LFLAG);
13474 0 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13475 0 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) PZ(n) = SUMF(n);
13476 : }
13477 : // Data dump.
13478 : // if (LIST >= 3) {
13479 : // DUMPVD("AD:", AD, NetworkNumOfNodes, outputFile);
13480 : // DUMPVD("AU:", AU, NNZE, outputFile);
13481 : // DUMPVR("AF:", SUMF, NetworkNumOfNodes, outputFile);
13482 : // }
13483 : // Solve linear system for approximate PZ.
13484 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13485 0 : facsky(newAU, AD, newAU, newIK, NetworkNumOfNodes, NSYM); // noel
13486 0 : slvsky(newAU, AD, newAU, PZ, newIK, NetworkNumOfNodes, NSYM); // noel
13487 : #else
13488 : facsky(AU, AD, AU, IK, NetworkNumOfNodes, NSYM);
13489 : slvsky(AU, AD, AU, PZ, IK, NetworkNumOfNodes, NSYM);
13490 : #endif
13491 : // if (LIST >= 2) DUMPVD("PZ:", PZ, NetworkNumOfNodes, outputFile);
13492 : }
13493 : // Solve nonlinear airflow network equations by modified Newton's method.
13494 6990895 : while (ITER < simulation_control.maximum_iterations) {
13495 6990895 : LFLAG = false;
13496 6990895 : ++ITER;
13497 : // if (LIST >= 2) {
13498 : // print(outputFile, "Begin iteration {}\n", ITER);
13499 : // }
13500 : // Set up the Jacobian matrix.
13501 6990895 : filjac(NNZE, LFLAG);
13502 : // Data dump.
13503 : // if (LIST >= 3) {
13504 : // DUMPVR("SUMF:", SUMF, NetworkNumOfNodes, outputFile);
13505 : // DUMPVR("SUMAF:", SUMAF, NetworkNumOfNodes, outputFile);
13506 : // }
13507 : // Check convergence.
13508 6990895 : CONVG = 1;
13509 6990895 : SSUMF = 0.0;
13510 6990895 : SSUMAF = 0.0;
13511 178482905 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13512 171492010 : SSUMF += std::abs(SUMF(n));
13513 171492010 : SSUMAF += SUMAF(n);
13514 171492010 : if (CONVG == 1) {
13515 63665290 : if (std::abs(SUMF(n)) <= simulation_control.absolute_convergence_tolerance) continue;
13516 8319201 : if (std::abs(SUMF(n) / SUMAF(n)) > simulation_control.relative_convergence_tolerance) CONVG = 0;
13517 : }
13518 : }
13519 6990895 : ACC0 = ACC1;
13520 6990895 : if (SSUMAF > 0.0) ACC1 = SSUMF / SSUMAF;
13521 6990895 : if (CONVG == 1 && ITER > 1) return;
13522 6413674 : if (ITER >= simulation_control.maximum_iterations) break;
13523 : // Data dump.
13524 : // if (LIST >= 3) {
13525 : // DUMPVD("AD:", AD, NetworkNumOfNodes, outputFile);
13526 : // DUMPVD("AU:", AU, NNZE, outputFile);
13527 : // }
13528 : // Solve AA * CCF = SUMF.
13529 166101506 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13530 159687832 : CCF(n) = SUMF(n);
13531 : }
13532 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13533 6413674 : facsky(newAU, AD, newAU, newIK, NetworkNumOfNodes, NSYM); // noel
13534 6413674 : slvsky(newAU, AD, newAU, CCF, newIK, NetworkNumOfNodes, NSYM); // noel
13535 : #else
13536 : facsky(AU, AD, AU, IK, NetworkNumOfNodes, NSYM);
13537 : slvsky(AU, AD, AU, CCF, IK, NetworkNumOfNodes, NSYM);
13538 : #endif
13539 : // Revise PZ (Steffensen iteration on the N-R correction factors to handle oscillating corrections).
13540 6413674 : if (ACCEL == 1) {
13541 1824816 : ACCEL = 0;
13542 : } else {
13543 4588858 : if (ITER > 2 && ACC1 > 0.5 * ACC0) ACCEL = 1;
13544 : }
13545 166101506 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13546 159687832 : if (AirflowNetworkNodeData(n).NodeTypeNum == 1) continue;
13547 116374027 : CEF(n) = 1.0;
13548 116374027 : if (ACCEL == 1) {
13549 37128491 : C = CCF(n) / PCF(n);
13550 37128491 : if (C < simulation_control.convergence_acceleration_limit) CEF(n) = 1.0 / (1.0 - C);
13551 37128491 : C = CCF(n) * CEF(n);
13552 : } else {
13553 : // IF (CCF(N) .EQ. 0.0d0) CCF(N)=TINY(CCF(N)) ! 1.0E-40
13554 79245536 : if (CCF(n) == 0.0) CCF(n) = Constant::rTinyValue; // 1.0E-40 (Epsilon)
13555 79245536 : PCF(n) = CCF(n);
13556 79245536 : C = CCF(n);
13557 : }
13558 116374027 : if (std::abs(C) > simulation_control.MaxPressure) {
13559 0 : CEF(n) *= simulation_control.MaxPressure / std::abs(C);
13560 0 : PZ(n) -= CCF(n) * CEF(n);
13561 : } else {
13562 116374027 : PZ(n) -= C;
13563 : }
13564 : }
13565 : // Data revision dump.
13566 : // if (LIST >= 2) {
13567 : // for (n = 1; n <= NetworkNumOfNodes; ++n) {
13568 : // if (state.afn->AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13569 : // print(outputFile, "Rev: {:5}{:3}{:14.6E} {:8.4F}{:24.14F}", n, SUMF(n), CCF(n), CEF(n), PZ(n));
13570 : // }
13571 : // }
13572 : // }
13573 : }
13574 :
13575 : // Error termination.
13576 0 : ShowSevereError(m_state, "Too many iterations (SOLVZP) in Airflow Network simulation");
13577 0 : ++ExtLargeOpeningErrCount;
13578 0 : if (ExtLargeOpeningErrCount < 2) {
13579 0 : ShowWarningError(m_state,
13580 : "AirflowNetwork: SOLVER, Changing values for initialization flag, Relative airflow convergence, Absolute airflow "
13581 : "convergence, Convergence acceleration limit or Maximum Iteration Number may solve the problem.");
13582 0 : ShowContinueErrorTimeStamp(m_state, "");
13583 0 : ShowContinueError(m_state,
13584 0 : "..Iterations=" + std::to_string(ITER) + ", Max allowed=" + std::to_string(simulation_control.maximum_iterations));
13585 0 : ShowFatalError(m_state, "AirflowNetwork: SOLVER, The previous error causes termination.");
13586 : } else {
13587 0 : ShowRecurringWarningErrorAtEnd(
13588 0 : m_state, "AirFlowNetwork: Too many iterations (SOLVZP) in AirflowNetwork simulation continues.", ExtLargeOpeningErrIndex);
13589 : }
13590 1731663 : }
13591 :
13592 6990895 : void Solver::filjac(int const NNZE, // number of nonzero entries in the "AU" array.
13593 : bool const LFLAG // if = 1, use laminar relationship (initialization).
13594 : )
13595 : {
13596 :
13597 : // SUBROUTINE INFORMATION:
13598 : // AUTHOR George Walton
13599 : // DATE WRITTEN Extracted from AIRNET
13600 : // MODIFIED Lixing Gu, 2/1/04
13601 : // Revised the subroutine to meet E+ needs
13602 : // MODIFIED Lixing Gu, 6/8/05
13603 : // RE-ENGINEERED na
13604 :
13605 : // PURPOSE OF THIS SUBROUTINE:
13606 : // This subroutine creates matrices for solution of flows
13607 :
13608 : // METHODOLOGY EMPLOYED:
13609 : // na
13610 :
13611 : // REFERENCES:
13612 : // na
13613 :
13614 : // USE STATEMENTS:
13615 : // na
13616 :
13617 : // Locals
13618 : // SUBROUTINE ARGUMENT DEFINITIONS:
13619 :
13620 : // SUBROUTINE PARAMETER DEFINITIONS:
13621 : // na
13622 :
13623 : // INTERFACE BLOCK SPECIFICATIONS
13624 : // na
13625 :
13626 : // DERIVED TYPE DEFINITIONS
13627 : // na
13628 :
13629 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13630 :
13631 : // I - component number.
13632 : // N - number of node/zone 1.
13633 : // M - number of node/zone 2.
13634 : // F - flows through the element (kg/s).
13635 : // DF - partial derivatives: DF/DP.
13636 : // NF - number of flows, 1 or 2.
13637 : int i;
13638 : int j;
13639 : int n;
13640 : int FLAG;
13641 : int NF;
13642 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13643 : int LHK; // noel
13644 : int JHK;
13645 : int JHK1;
13646 : int newsum;
13647 : int newh;
13648 : int ispan;
13649 : int thisIK;
13650 : bool allZero; // noel
13651 : #endif
13652 6990895 : Array1D<Real64> X(4);
13653 : Real64 DP;
13654 6990895 : std::array<Real64, 2> F{{0.0, 0.0}};
13655 6990895 : std::array<Real64, 2> DF{{0.0, 0.0}};
13656 :
13657 6990895 : auto &NetworkNumOfLinks = ActualNumOfLinks;
13658 6990895 : auto &NetworkNumOfNodes = ActualNumOfNodes;
13659 :
13660 178482905 : for (n = 1; n <= NetworkNumOfNodes; ++n) {
13661 171492010 : SUMF(n) = 0.0;
13662 171492010 : SUMAF(n) = 0.0;
13663 171492010 : if (AirflowNetworkNodeData(n).NodeTypeNum == 1) {
13664 47067737 : AD(n) = 1.0;
13665 : } else {
13666 124424273 : AD(n) = 0.0;
13667 : }
13668 : }
13669 996093551 : for (n = 1; n <= NNZE; ++n) {
13670 989102656 : AU(n) = 0.0;
13671 : }
13672 : // Loop(s) to calculate control, etc.
13673 : // Set up the Jacobian matrix.
13674 240912554 : for (i = 1; i <= NetworkNumOfLinks; ++i) {
13675 233921659 : if (AirflowNetworkLinkageData(i).element == nullptr) {
13676 0 : continue;
13677 : }
13678 233921659 : n = AirflowNetworkLinkageData(i).NodeNums[0];
13679 233921659 : int m = AirflowNetworkLinkageData(i).NodeNums[1];
13680 : //!!! Check array of DP. DpL is used for multizone air flow calculation only
13681 : //!!! and is not for forced air calculation
13682 233921659 : if (i > NumOfLinksMultiZone) {
13683 134500909 : DP = PZ(n) - PZ(m) + PS(i) + PW(i);
13684 : } else {
13685 99420750 : DP = PZ(n) - PZ(m) + dos.DpL(i, 1) + PW(i);
13686 : }
13687 233921659 : Real64 multiplier = 1.0;
13688 233921659 : Real64 control = AirflowNetworkLinkageData(i).control;
13689 : // if (LIST >= 4) ObjexxFCL::gio::write(outputFile, Format_901) << "PS:" << i << n << M << PS(i) << PW(i) << AirflowNetworkLinkSimu(i).DP;
13690 233921659 : j = AirflowNetworkLinkageData(i).CompNum;
13691 :
13692 233921659 : NF = AirflowNetworkLinkageData(i).element->calculate(m_state, LFLAG, DP, i, multiplier, control, node_states[n], node_states[m], F, DF);
13693 233921659 : if (AirflowNetworkLinkageData(i).element->type() == ComponentType::CPD && DP != 0.0) {
13694 1700668 : DP = DisSysCompCPDData(AirflowNetworkCompData(j).TypeNum).DP;
13695 : }
13696 :
13697 233921659 : AirflowNetworkLinkSimu(i).DP = DP;
13698 233921659 : AFLOW(i) = F[0];
13699 233921659 : AFLOW2(i) = 0.0;
13700 233921659 : if (AirflowNetworkCompData(j).CompTypeNum == iComponentTypeNum::DOP) {
13701 6750179 : AFLOW2(i) = F[1];
13702 : }
13703 : // if (LIST >= 3) ObjexxFCL::gio::write(outputFile, Format_901) << " NRi:" << i << n << M << AirflowNetworkLinkSimu(i).DP << F[0] <<
13704 : // DF[0];
13705 233921659 : FLAG = 1;
13706 233921659 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13707 232912472 : ++FLAG;
13708 232912472 : X(1) = DF[0];
13709 232912472 : X(2) = -DF[0];
13710 232912472 : SUMF(n) += F[0];
13711 232912472 : SUMAF(n) += std::abs(F[0]);
13712 : }
13713 233921659 : if (AirflowNetworkNodeData(m).NodeTypeNum == 0) {
13714 160627409 : FLAG += 2;
13715 160627409 : X(4) = DF[0];
13716 160627409 : X(3) = -DF[0];
13717 160627409 : SUMF(m) -= F[0];
13718 160627409 : SUMAF(m) += std::abs(F[0]);
13719 : }
13720 233921659 : if (FLAG != 1) filsky(X, AirflowNetworkLinkageData(i).NodeNums, IK, AU, AD, FLAG);
13721 233921659 : if (NF == 1) continue;
13722 32754 : AFLOW2(i) = F[1];
13723 : // if (LIST >= 3) ObjexxFCL::gio::write(outputFile, Format_901) << " NRj:" << i << n << m << AirflowNetworkLinkSimu(i).DP << F[1] <<
13724 : // DF[1];
13725 32754 : FLAG = 1;
13726 32754 : if (AirflowNetworkNodeData(n).NodeTypeNum == 0) {
13727 32754 : ++FLAG;
13728 32754 : X(1) = DF[1];
13729 32754 : X(2) = -DF[1];
13730 32754 : SUMF(n) += F[1];
13731 32754 : SUMAF(n) += std::abs(F[1]);
13732 : }
13733 32754 : if (AirflowNetworkNodeData(m).NodeTypeNum == 0) {
13734 32754 : FLAG += 2;
13735 32754 : X(4) = DF[1];
13736 32754 : X(3) = -DF[1];
13737 32754 : SUMF(m) -= F[1];
13738 32754 : SUMAF(m) += std::abs(F[1]);
13739 : }
13740 32754 : if (FLAG != 1) filsky(X, AirflowNetworkLinkageData(i).NodeNums, IK, AU, AD, FLAG);
13741 : }
13742 :
13743 : #ifdef SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS
13744 :
13745 : // After the matrix values have been set, we can look at them and see if any columns are filled with zeros.
13746 : // If they are, let's remove them from the matrix -- but only for the purposes of doing the solve.
13747 : // They way I do this is building a separate IK array (newIK) that simply changes the column heights.
13748 : // So the affected SOLVEs would use this newIK and nothing else changes.
13749 185473800 : for (n = 1; n <= NetworkNumOfNodes + 1; ++n) {
13750 178482905 : newIK(n) = IK(n);
13751 : // print*, " NetworkNumOfNodes n=", n, " IK(n)=", IK(n)
13752 : }
13753 :
13754 6990895 : newsum = IK(2) - IK(1); // always 0?
13755 :
13756 6990895 : JHK = 1;
13757 171492010 : for (n = 2; n <= NetworkNumOfNodes; ++n) {
13758 164501115 : JHK1 = IK(n + 1); // starts at IK(3)-IK(2)
13759 164501115 : LHK = JHK1 - JHK;
13760 164501115 : if (LHK <= 0) {
13761 8051209 : newIK(n + 1) = newIK(n);
13762 8051209 : continue;
13763 : }
13764 : // write(*,'(4(a,i8))') "n=", n, " ik=", ik(n), " JHK=", JHK, " LHK=", LHK
13765 :
13766 : // is the entire column zero? noel
13767 156449906 : allZero = true;
13768 436769718 : for (i = 0; i <= LHK - 1; ++i) {
13769 386385692 : if (AU(JHK + i) != 0.0) {
13770 106065880 : allZero = false;
13771 106065880 : break;
13772 : }
13773 : }
13774 :
13775 156449906 : newh = LHK;
13776 156449906 : if (allZero) {
13777 : // print*, "allzero n=", n
13778 50384026 : newh = 0;
13779 : } else {
13780 : // DO i=0,LHK-1
13781 : // write(*, '(2(a,i8),a, f15.3)') " n=", n, " i=", i, " AU(JHK+i)=", AU(JHK+i)
13782 : // enddo
13783 : }
13784 156449906 : newIK(n + 1) = newIK(n) + newh;
13785 156449906 : newsum += newh;
13786 :
13787 : // do i = LHK-1,0, -1
13788 : // write(*, '(2(a,i8),a, f15.3)') " n=", n, " i=", i, " AU(JHK+i)=", AU(JHK+i)
13789 : // enddo
13790 156449906 : JHK = JHK1;
13791 : }
13792 :
13793 : // this is just a print to screen, is not necessary
13794 : // if (firstTime) then
13795 : // write(*, '(2(a,i8))') " After SKYLINE_MATRIX_REMOVE_ZERO_COLUMNS: newsum=", newsum, " oldsum=", IK(NetworkNumOfNodes+1)
13796 : // firstTime=.FALSE.
13797 : // endif
13798 :
13799 : // Now fill newAU from AU, using newIK
13800 171492010 : for (n = 2; n <= NetworkNumOfNodes; ++n) {
13801 164501115 : thisIK = newIK(n);
13802 164501115 : ispan = newIK(n + 1) - thisIK;
13803 :
13804 164501115 : if (ispan <= 0) continue;
13805 814848724 : for (i = 0; i <= ispan - 1; ++i) {
13806 708782844 : newAU(thisIK + i) = AU(IK(n) + i);
13807 : }
13808 : }
13809 : #endif
13810 6990895 : }
13811 :
13812 6413674 : void Solver::facsky(Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
13813 : Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
13814 : Array1D<Real64> &AL, // the lower triangle of [A] before and after factoring
13815 : const Array1D_int &IK, // pointer to the top of column/row "K"
13816 : int const NEQ, // number of equations
13817 : int const NSYM // symmetry: 0 = symmetric matrix, 1 = non-symmetric
13818 : )
13819 : {
13820 :
13821 : // SUBROUTINE INFORMATION:
13822 : // AUTHOR George Walton
13823 : // DATE WRITTEN Extracted from AIRNET
13824 : // MODIFIED Lixing Gu, 2/1/04
13825 : // Revised the subroutine to meet E+ needs
13826 : // MODIFIED Lixing Gu, 6/8/05
13827 : // RE-ENGINEERED This subroutine is revised from FACSKY developed by George Walton, NIST
13828 :
13829 : // PURPOSE OF THIS SUBROUTINE:
13830 : // This subroutine performs L-U factorization of a skyline ordered matrix, [A]
13831 : // The algorithm has been restructured for clarity.
13832 : // Note dependence on compiler for optimizing the inner do loops.
13833 :
13834 : // METHODOLOGY EMPLOYED:
13835 : // L-U factorization of a skyline ordered matrix, [A], used for
13836 : // solution of simultaneous linear algebraic equations [A] * X = B.
13837 : // No pivoting! No scaling! No warnings!!!
13838 : // Related routines: SLVSKY, SETSKY, FILSKY.
13839 :
13840 : // REFERENCES:
13841 : // Algorithm is described in "The Finite Element Method Displayed",
13842 : // by G. Dhatt and G. Touzot, John Wiley & Sons, New York, 1984.
13843 :
13844 : // USE STATEMENTS:
13845 : // na
13846 :
13847 : // Argument array dimensioning
13848 6413674 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
13849 6413674 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
13850 6413674 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
13851 6413674 : EP_SIZE_CHECK(AL, IK(ActualNumOfNodes + 1) - 1);
13852 :
13853 : // Locals
13854 : // SUBROUTINE ARGUMENT DEFINITIONS:
13855 : // noel, GNU says the AU is indexed above its upper bound
13856 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
13857 :
13858 : // SUBROUTINE PARAMETER DEFINITIONS:
13859 : // na
13860 :
13861 : // INTERFACE BLOCK SPECIFICATIONS
13862 : // na
13863 :
13864 : // DERIVED TYPE DEFINITIONS
13865 : // na
13866 :
13867 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13868 : int JHK;
13869 : int LHK1;
13870 : int IMIN;
13871 : int IMIN1;
13872 : int JHJ;
13873 : int JHJ1;
13874 : int IC;
13875 : int i;
13876 : int j;
13877 : int k;
13878 : Real64 T1;
13879 : Real64 T2;
13880 : Real64 SDOT;
13881 : Real64 SUMD;
13882 :
13883 6413674 : AD(1) = 1.0 / AD(1);
13884 6413674 : JHK = 1;
13885 159687832 : for (k = 2; k <= NEQ; ++k) {
13886 153274158 : SUMD = 0.0;
13887 153274158 : int JHK1 = IK(k + 1);
13888 153274158 : int LHK = JHK1 - JHK;
13889 153274158 : if (LHK > 0) {
13890 99286193 : LHK1 = LHK - 1;
13891 99286193 : IMIN = k - LHK1;
13892 99286193 : IMIN1 = IMIN - 1;
13893 99286193 : if (NSYM == 1) AL(JHK) *= AD(IMIN1);
13894 99286193 : if (LHK1 != 0) {
13895 54103262 : JHJ = IK(IMIN);
13896 54103262 : if (NSYM == 0) {
13897 619388763 : for (j = 1; j <= LHK1; ++j) {
13898 565285501 : JHJ1 = IK(IMIN + j);
13899 565285501 : IC = min(j, JHJ1 - JHJ);
13900 565285501 : if (IC > 0) {
13901 338038265 : SDOT = 0.0;
13902 2137340847 : for (i = 0; i <= IC - 1; ++i) {
13903 1799302582 : SDOT += AU(JHJ1 - IC + i) * AU(JHK + j - IC + i);
13904 : }
13905 338038265 : AU(JHK + j) -= SDOT;
13906 : }
13907 565285501 : JHJ = JHJ1;
13908 : }
13909 : } else {
13910 0 : for (j = 1; j <= LHK1; ++j) {
13911 0 : JHJ1 = IK(IMIN + j);
13912 0 : IC = min(j, JHJ1 - JHJ);
13913 0 : SDOT = 0.0;
13914 0 : if (IC > 0) {
13915 0 : for (i = 0; i <= IC - 1; ++i) {
13916 0 : SDOT += AL(JHJ1 - IC + i) * AU(JHK + j - IC + i);
13917 : }
13918 0 : AU(JHK + j) -= SDOT;
13919 0 : SDOT = 0.0;
13920 0 : for (i = 0; i <= IC - 1; ++i) {
13921 0 : SDOT += AU(JHJ1 - IC + i) * AL(JHK + j - IC + i);
13922 : }
13923 : }
13924 0 : AL(JHK + j) = (AL(JHK + j) - SDOT) * AD(IMIN1 + j);
13925 0 : JHJ = JHJ1;
13926 : }
13927 : }
13928 : }
13929 99286193 : if (NSYM == 0) {
13930 763857887 : for (i = 0; i <= LHK1; ++i) {
13931 664571694 : T1 = AU(JHK + i);
13932 664571694 : T2 = T1 * AD(IMIN1 + i);
13933 664571694 : AU(JHK + i) = T2;
13934 664571694 : SUMD += T1 * T2;
13935 : }
13936 : } else {
13937 0 : for (i = 0; i <= LHK1; ++i) {
13938 0 : SUMD += AU(JHK + i) * AL(JHK + i);
13939 : }
13940 : }
13941 : }
13942 153274158 : if (AD(k) - SUMD == 0.0) {
13943 0 : ShowSevereError(m_state, "AirflowNetworkSolver: L-U factorization in Subroutine FACSKY.");
13944 0 : ShowContinueError(
13945 : m_state,
13946 0 : "The denominator used in L-U factorizationis equal to 0.0 at node = " + m_state.afn->AirflowNetworkNodeData(k).Name + '.');
13947 0 : ShowContinueError(
13948 : m_state, "One possible cause is that this node may not be connected directly, or indirectly via airflow network connections ");
13949 0 : ShowContinueError(
13950 : m_state, "(e.g., AirflowNetwork:Multizone:SurfaceCrack, AirflowNetwork:Multizone:Component:SimpleOpening, etc.), to an external");
13951 0 : ShowContinueError(m_state, "node (AirflowNetwork:MultiZone:Surface).");
13952 0 : ShowContinueError(m_state,
13953 : "Please send your input file and weather file to EnergyPlus support/development team for further investigation.");
13954 0 : ShowFatalError(m_state, "Preceding condition causes termination.");
13955 : }
13956 153274158 : AD(k) = 1.0 / (AD(k) - SUMD);
13957 153274158 : JHK = JHK1;
13958 : }
13959 6413674 : }
13960 :
13961 6413674 : void Solver::slvsky(const Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
13962 : const Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
13963 : const Array1D<Real64> &AL, // the lower triangle of [A] before and after factoring
13964 : Array1D<Real64> &B, // "B" vector (input); "X" vector (output).
13965 : const Array1D_int &IK, // pointer to the top of column/row "K"
13966 : int const NEQ, // number of equations
13967 : int const NSYM // symmetry: 0 = symmetric matrix, 1 = non-symmetric
13968 : )
13969 : {
13970 :
13971 : // SUBROUTINE INFORMATION:
13972 : // AUTHOR George Walton
13973 : // DATE WRITTEN Extracted from AIRNET
13974 : // MODIFIED Lixing Gu, 2/1/04
13975 : // Revised the subroutine to meet E+ needs
13976 : // MODIFIED Lixing Gu, 6/8/05
13977 : // RE-ENGINEERED This subroutine is revised from CLVSKY developed by George Walton, NIST
13978 :
13979 : // PURPOSE OF THIS SUBROUTINE:
13980 : // This subroutine solves simultaneous linear algebraic equations [A] * X = B
13981 : // using L-U factored skyline form of [A] from "FACSKY"
13982 :
13983 : // METHODOLOGY EMPLOYED:
13984 : // na
13985 :
13986 : // REFERENCES:
13987 : // na
13988 :
13989 : // USE STATEMENTS:
13990 : // na
13991 :
13992 : // Argument array dimensioning
13993 6413674 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
13994 6413674 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
13995 6413674 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
13996 6413674 : EP_SIZE_CHECK(AL, IK(ActualNumOfNodes + 1) - 1);
13997 6413674 : EP_SIZE_CHECK(B, ActualNumOfNodes);
13998 :
13999 : // Locals
14000 : // SUBROUTINE ARGUMENT DEFINITIONS:
14001 : // noel, GNU says the AU is indexed above its upper bound
14002 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
14003 :
14004 : // SUBROUTINE PARAMETER DEFINITIONS:
14005 : // na
14006 :
14007 : // INTERFACE BLOCK SPECIFICATIONS
14008 : // na
14009 :
14010 : // DERIVED TYPE DEFINITIONS
14011 : // na
14012 :
14013 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14014 :
14015 : int i;
14016 : int JHK;
14017 : int JHK1;
14018 : int k;
14019 : Real64 SDOT;
14020 : Real64 T1;
14021 :
14022 6413674 : JHK = 1;
14023 159687832 : for (k = 2; k <= NEQ; ++k) {
14024 153274158 : JHK1 = IK(k + 1);
14025 153274158 : int LHK = JHK1 - JHK;
14026 153274158 : if (LHK <= 0) continue;
14027 99286193 : SDOT = 0.0;
14028 99286193 : if (NSYM == 0) {
14029 763857887 : for (i = 0; i <= LHK - 1; ++i) {
14030 664571694 : SDOT += AU(JHK + i) * B(k - LHK + i);
14031 : }
14032 : } else {
14033 0 : for (i = 0; i <= LHK - 1; ++i) {
14034 0 : SDOT += AL(JHK + i) * B(k - LHK + i);
14035 : }
14036 : }
14037 99286193 : B(k) -= SDOT;
14038 99286193 : JHK = JHK1;
14039 : }
14040 6413674 : if (NSYM == 0) {
14041 166101506 : for (k = 1; k <= NEQ; ++k) {
14042 159687832 : B(k) *= AD(k);
14043 : }
14044 : }
14045 6413674 : k = NEQ + 1;
14046 6413674 : JHK1 = IK(k);
14047 159687832 : while (k != 1) {
14048 159687832 : --k;
14049 159687832 : if (NSYM == 1) B(k) *= AD(k);
14050 159687832 : if (k == 1) break;
14051 : // IF(K.EQ.1) RETURN
14052 153274158 : JHK = IK(k);
14053 153274158 : T1 = B(k);
14054 817845852 : for (i = 0; i <= JHK1 - JHK - 1; ++i) {
14055 664571694 : B(k - JHK1 + JHK + i) -= AU(JHK + i) * T1;
14056 : }
14057 153274158 : JHK1 = JHK;
14058 : }
14059 6413674 : }
14060 :
14061 233954413 : void Solver::filsky(const Array1D<Real64> &X, // element array (row-wise sequence)
14062 : std::array<int, 2> const LM, // location matrix
14063 : const Array1D_int &IK, // pointer to the top of column/row "K"
14064 : Array1D<Real64> &AU, // the upper triangle of [A] before and after factoring
14065 : Array1D<Real64> &AD, // the main diagonal of [A] before and after factoring
14066 : int const FLAG // mode of operation
14067 : )
14068 : {
14069 :
14070 : // SUBROUTINE INFORMATION:
14071 : // AUTHOR George Walton
14072 : // DATE WRITTEN Extracted from AIRNET
14073 : // MODIFIED Lixing Gu, 2/1/04
14074 : // Revised the subroutine to meet E+ needs
14075 : // MODIFIED Lixing Gu, 6/8/05
14076 : // RE-ENGINEERED This subroutine is revised from FILSKY developed by George Walton, NIST
14077 :
14078 : // PURPOSE OF THIS SUBROUTINE:
14079 : // This subroutine adds element array "X" to the sparse skyline matrix [A]
14080 :
14081 : // Argument array dimensioning
14082 233954413 : EP_SIZE_CHECK(X, 4);
14083 233954413 : EP_SIZE_CHECK(IK, ActualNumOfNodes + 1);
14084 233954413 : EP_SIZE_CHECK(AU, IK(ActualNumOfNodes + 1));
14085 233954413 : EP_SIZE_CHECK(AD, ActualNumOfNodes);
14086 :
14087 : // SUBROUTINE ARGUMENT DEFINITIONS:
14088 : // noel, GNU says the AU is indexed above its upper bound
14089 : // REAL(r64), INTENT(INOUT) :: AU(IK(NetworkNumOfNodes+1)-1) ! the upper triangle of [A] before and after factoring
14090 :
14091 : // K = row number, L = column number.
14092 233954413 : if (FLAG > 1) {
14093 233954413 : int k = LM[0];
14094 233954413 : int L = LM[1];
14095 233954413 : if (FLAG == 4) {
14096 159650976 : AD(k) += X(1);
14097 159650976 : if (k < L) {
14098 131236660 : int j = IK(L + 1) - L + k;
14099 131236660 : AU(j) += X(2);
14100 : } else {
14101 28414316 : int j = IK(k + 1) - k + L;
14102 28414316 : AU(j) += X(3);
14103 : }
14104 159650976 : AD(L) += X(4);
14105 74303437 : } else if (FLAG == 3) {
14106 1009187 : AD(L) += X(4);
14107 73294250 : } else if (FLAG == 2) {
14108 73294250 : AD(k) += X(1);
14109 : }
14110 : }
14111 233954413 : }
14112 :
14113 : } // namespace AirflowNetwork
14114 :
14115 : } // namespace EnergyPlus
|