Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cmath>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 : #include <ObjexxFCL/Fmath.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <EnergyPlus/Autosizing/SystemAirFlowSizing.hh>
57 : #include <EnergyPlus/BranchNodeConnections.hh>
58 : #include <EnergyPlus/CurveManager.hh>
59 : #include <EnergyPlus/Data/EnergyPlusData.hh>
60 : #include <EnergyPlus/DataEnvironment.hh>
61 : #include <EnergyPlus/DataHVACGlobals.hh>
62 : #include <EnergyPlus/DataHeatBalance.hh>
63 : #include <EnergyPlus/DataLoopNode.hh>
64 : #include <EnergyPlus/DataSizing.hh>
65 : #include <EnergyPlus/DataZoneControls.hh>
66 : #include <EnergyPlus/DataZoneEquipment.hh>
67 : #include <EnergyPlus/Fans.hh>
68 : #include <EnergyPlus/General.hh>
69 : #include <EnergyPlus/GeneralRoutines.hh>
70 : #include <EnergyPlus/GlobalNames.hh>
71 : #include <EnergyPlus/HVACFan.hh>
72 : #include <EnergyPlus/HVACStandAloneERV.hh>
73 : #include <EnergyPlus/HeatRecovery.hh>
74 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
75 : #include <EnergyPlus/MixedAir.hh>
76 : #include <EnergyPlus/NodeInputManager.hh>
77 : #include <EnergyPlus/OutAirNodeManager.hh>
78 : #include <EnergyPlus/OutputProcessor.hh>
79 : #include <EnergyPlus/ScheduleManager.hh>
80 : #include <EnergyPlus/UtilityRoutines.hh>
81 :
82 : namespace EnergyPlus::HVACStandAloneERV {
83 :
84 : // Module containing the routines dealing with stand alone energy recovery ventilators (ERVs)
85 :
86 : // MODULE INFORMATION:
87 : // AUTHOR Richard Raustad, FSEC
88 : // DATE WRITTEN June 2003
89 : // MODIFIED na
90 : // RE-ENGINEERED na
91 :
92 : // PURPOSE OF THIS MODULE:
93 : // To encapsulate the data and algorithms needed to simulate stand alone
94 : // energy recovery ventilators that condition outdoor ventilation air and
95 : // supply that air directly to a zone.
96 :
97 : // METHODOLOGY EMPLOYED:
98 : // These units are modeled as a collection of components: air-to-air generic heat exchanger,
99 : // supply air fan, exhaust air fan and an optional controller to avoid overheating
100 : // of the supply air (economizer or free cooling operation).
101 :
102 : // REFERENCES: none
103 :
104 : // OTHER NOTES: none
105 :
106 : // USE STATEMENTS:
107 : // Use statements for data only modules
108 : // Using/Aliasing
109 : using namespace DataLoopNode;
110 : using namespace DataHVACGlobals;
111 : using Fans::GetFanVolFlow;
112 : using ScheduleManager::GetCurrentScheduleValue;
113 : using ScheduleManager::GetScheduleIndex;
114 :
115 758119 : void SimStandAloneERV(EnergyPlusData &state,
116 : std::string_view CompName, // name of the Stand Alone ERV unit
117 : int const ZoneNum, // number of zone being served unused1208
118 : bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
119 : Real64 &SensLoadMet, // net sensible load supplied by the ERV unit to the zone (W)
120 : Real64 &LatLoadMet, // net latent load supplied by ERV unit to the zone (kg/s),
121 : int &CompIndex // pointer to correct component
122 : )
123 : {
124 :
125 : // SUBROUTINE INFORMATION:
126 : // AUTHOR Richard Raustad, FSEC
127 : // DATE WRITTEN June 2003
128 : // MODIFIED Don Shirey, Aug 2009 (LatLoadMet)
129 : // RE-ENGINEERED na
130 :
131 : // PURPOSE OF THIS SUBROUTINE:
132 : // Manages the simulation of a Stand Alone ERV unit. Called from SimZoneEquipment
133 :
134 : // Using/Aliasing
135 :
136 : // Locals
137 : // SUBROUTINE ARGUMENT DEFINITIONS:
138 : // ZoneNum not used at this time, future modifications may require zone information
139 : // dehumid = negative
140 :
141 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
142 : int StandAloneERVNum; // index of Stand Alone ERV unit being simulated
143 :
144 : // First time SimStandAloneERV is called, get the input for all Stand Alone ERV units
145 758119 : if (state.dataHVACStandAloneERV->GetERVInputFlag) {
146 5 : GetStandAloneERV(state);
147 5 : state.dataHVACStandAloneERV->GetERVInputFlag = false;
148 : }
149 :
150 : // Find the correct Stand Alone ERV unit index
151 758119 : if (CompIndex == 0) {
152 107 : StandAloneERVNum = UtilityRoutines::FindItem(CompName, state.dataHVACStandAloneERV->StandAloneERV);
153 107 : if (StandAloneERVNum == 0) {
154 0 : ShowFatalError(state, "SimStandAloneERV: Unit not found=" + std::string{CompName});
155 : }
156 107 : CompIndex = StandAloneERVNum;
157 : } else {
158 758012 : StandAloneERVNum = CompIndex;
159 758012 : if (StandAloneERVNum > state.dataHVACStandAloneERV->NumStandAloneERVs || StandAloneERVNum < 1) {
160 0 : ShowFatalError(state,
161 0 : format("SimStandAloneERV: Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
162 : StandAloneERVNum,
163 0 : state.dataHVACStandAloneERV->NumStandAloneERVs,
164 0 : CompName));
165 : }
166 758012 : if (state.dataHVACStandAloneERV->CheckEquipName(StandAloneERVNum)) {
167 107 : if (CompName != state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name) {
168 0 : ShowFatalError(state,
169 0 : format("SimStandAloneERV: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
170 : StandAloneERVNum,
171 : CompName,
172 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name));
173 : }
174 107 : state.dataHVACStandAloneERV->CheckEquipName(StandAloneERVNum) = false;
175 : }
176 : }
177 :
178 : // Initialize the Stand Alone ERV unit
179 758119 : InitStandAloneERV(state, StandAloneERVNum, ZoneNum, FirstHVACIteration);
180 :
181 758119 : CalcStandAloneERV(state, StandAloneERVNum, FirstHVACIteration, SensLoadMet, LatLoadMet);
182 :
183 758119 : ReportStandAloneERV(state, StandAloneERVNum);
184 758119 : }
185 :
186 5 : void GetStandAloneERV(EnergyPlusData &state)
187 : {
188 :
189 : // SUBROUTINE INFORMATION:
190 : // AUTHOR Richard Raustad
191 : // DATE WRITTEN June 2003
192 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
193 : // RE-ENGINEERED na
194 :
195 : // PURPOSE OF THIS SUBROUTINE:
196 : // Obtains input data for Stand Alone ERV units and stores it in the Stand Alone ERV data structure
197 :
198 : // METHODOLOGY EMPLOYED:
199 : // Uses "Get" routines to read in data.
200 :
201 : // Using/Aliasing
202 : using BranchNodeConnections::SetUpCompSets;
203 : using DataSizing::AutoSize;
204 : using Fans::GetFanAvailSchPtr;
205 : using Fans::GetFanDesignVolumeFlowRate;
206 : using Fans::GetFanIndex;
207 : using Fans::GetFanOutletNode;
208 : using Fans::GetFanType;
209 :
210 : using NodeInputManager::GetOnlySingleNode;
211 5 : auto &GetGenericSupplyAirFlowRate(HeatRecovery::GetSupplyAirFlowRate);
212 : using HeatRecovery::GetHeatExchangerObjectTypeNum;
213 5 : auto &GetHXSupplyInletNode(HeatRecovery::GetSupplyInletNode);
214 5 : auto &GetHXSecondaryInletNode(HeatRecovery::GetSecondaryInletNode);
215 : using Curve::GetCurveIndex;
216 : using OutAirNodeManager::CheckOutAirNodeNumber;
217 :
218 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
219 : int StandAloneERVIndex; // loop index
220 : int StandAloneERVNum; // current Stand Alone ERV number
221 10 : Array1D_string Alphas; // Alpha items for object
222 10 : Array1D<Real64> Numbers; // Numeric items for object
223 10 : Array1D_string cAlphaFields;
224 10 : Array1D_string cNumericFields;
225 10 : Array1D_bool lAlphaBlanks;
226 10 : Array1D_bool lNumericBlanks;
227 10 : std::string CompSetSupplyFanInlet;
228 10 : std::string CompSetSupplyFanOutlet;
229 10 : std::string CompSetExhaustFanInlet;
230 10 : std::string CompSetExhaustFanOutlet;
231 10 : std::string CurrentModuleObject; // Object type for getting and error messages
232 : int SAFanTypeNum; // Integer equivalent to fan type
233 : int EAFanTypeNum; // Integer equivalent to fan type
234 : int NumArg;
235 : int NumAlphas; // Number of Alphas for each GetObjectItem call
236 : int NumNumbers; // Number of Numbers for each GetObjectItem call
237 : int MaxAlphas; // Max between the two objects gotten here
238 : int MaxNumbers; // Max between the two objects gotten here
239 : int IOStatus; // Used in GetObjectItem
240 5 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
241 : int NumERVCtrlrs; // total number of CONTROLLER:STAND ALONE ERV objects
242 : int ERVControllerNum; // index to ERV controller
243 : int WhichERV; // used in controller GetInput
244 : Real64 AirFlowRate; // used to find zone with humidistat
245 : int NodeNumber; // used to find zone with humidistat
246 : int HStatZoneNum; // used to find zone with humidistat
247 : int NumHstatZone; // index to humidity controlled zones
248 5 : bool ZoneNodeFound(false); // used to find zone with humidistat
249 5 : bool HStatFound(false); // used to find zone with humidistat
250 : bool errFlag; // Error flag used in mining calls
251 : Real64 SAFanVolFlowRate; // supply air fan volumetric flow rate [m3/s]
252 : Real64 EAFanVolFlowRate; // exhaust air fan volumetric flow rate [m3/s]
253 : Real64 HXSupAirFlowRate; // HX supply air flow rate [m3/s]
254 : Real64 HighRHOARatio; // local variable for HighRHOAFlowRatio
255 : bool ZoneInletNodeFound; // used for warning when zone node not listed in equipment connections
256 : bool ZoneExhaustNodeFound; // used for warning when zone node not listed in equipment connections
257 : int ZoneInletCZN; // used for warning when zone node not listed in equipment connections
258 : int ZoneExhaustCZN; // used for warning when zone node not listed in equipment connections
259 :
260 5 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "ZoneHVAC:EnergyRecoveryVentilator", NumArg, NumAlphas, NumNumbers);
261 5 : MaxAlphas = NumAlphas;
262 5 : MaxNumbers = NumNumbers;
263 10 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
264 5 : state, "ZoneHVAC:EnergyRecoveryVentilator:Controller", NumArg, NumAlphas, NumNumbers);
265 5 : MaxAlphas = max(MaxAlphas, NumAlphas);
266 5 : MaxNumbers = max(MaxNumbers, NumNumbers);
267 :
268 5 : Alphas.allocate(MaxAlphas);
269 5 : Numbers.dimension(MaxNumbers, 0.0);
270 5 : cAlphaFields.allocate(MaxAlphas);
271 5 : cNumericFields.allocate(MaxNumbers);
272 5 : lNumericBlanks.dimension(MaxNumbers, false);
273 5 : lAlphaBlanks.dimension(MaxAlphas, false);
274 :
275 5 : state.dataHVACStandAloneERV->GetERVInputFlag = false;
276 :
277 : // find the number of each type of Stand Alone ERV unit
278 5 : CurrentModuleObject = "ZoneHVAC:EnergyRecoveryVentilator";
279 :
280 5 : state.dataHVACStandAloneERV->NumStandAloneERVs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
281 :
282 : // allocate the data structures
283 5 : state.dataHVACStandAloneERV->StandAloneERV.allocate(state.dataHVACStandAloneERV->NumStandAloneERVs);
284 5 : state.dataHVACStandAloneERV->HeatExchangerUniqueNames.reserve(static_cast<unsigned>(state.dataHVACStandAloneERV->NumStandAloneERVs));
285 5 : state.dataHVACStandAloneERV->SupplyAirFanUniqueNames.reserve(static_cast<unsigned>(state.dataHVACStandAloneERV->NumStandAloneERVs));
286 5 : state.dataHVACStandAloneERV->ExhaustAirFanUniqueNames.reserve(static_cast<unsigned>(state.dataHVACStandAloneERV->NumStandAloneERVs));
287 5 : state.dataHVACStandAloneERV->ControllerUniqueNames.reserve(static_cast<unsigned>(state.dataHVACStandAloneERV->NumStandAloneERVs));
288 5 : state.dataHVACStandAloneERV->CheckEquipName.dimension(state.dataHVACStandAloneERV->NumStandAloneERVs, true);
289 :
290 : // loop over Stand Alone ERV units; get and load the input data
291 112 : for (StandAloneERVIndex = 1; StandAloneERVIndex <= state.dataHVACStandAloneERV->NumStandAloneERVs; ++StandAloneERVIndex) {
292 :
293 107 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
294 : CurrentModuleObject,
295 : StandAloneERVIndex,
296 : Alphas,
297 : NumAlphas,
298 : Numbers,
299 : NumNumbers,
300 : IOStatus,
301 : lNumericBlanks,
302 : lAlphaBlanks,
303 : cAlphaFields,
304 : cNumericFields);
305 107 : StandAloneERVNum = StandAloneERVIndex; // separate variables in case other objects read by this module at some point later
306 107 : UtilityRoutines::IsNameEmpty(state, Alphas(1), CurrentModuleObject, ErrorsFound);
307 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name = Alphas(1);
308 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).UnitType = CurrentModuleObject;
309 :
310 107 : if (lAlphaBlanks(2)) {
311 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
312 : } else {
313 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SchedPtr =
314 107 : GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
315 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SchedPtr == 0) {
316 0 : ShowSevereError(state,
317 0 : CurrentModuleObject + ", \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\" " +
318 0 : cAlphaFields(2) + " not found = " + Alphas(2));
319 0 : ErrorsFound = true;
320 : }
321 : }
322 :
323 321 : GlobalNames::IntraObjUniquenessCheck(
324 321 : state, Alphas(3), CurrentModuleObject, cAlphaFields(3), state.dataHVACStandAloneERV->HeatExchangerUniqueNames, ErrorsFound);
325 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerName = Alphas(3);
326 107 : errFlag = false;
327 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerTypeNum =
328 107 : GetHeatExchangerObjectTypeNum(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerName, errFlag);
329 107 : if (errFlag) {
330 0 : ShowContinueError(
331 0 : state, "... occurs in " + CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
332 0 : ErrorsFound = true;
333 : }
334 :
335 107 : errFlag = false;
336 107 : HXSupAirFlowRate =
337 107 : GetGenericSupplyAirFlowRate(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerName, errFlag);
338 107 : if (errFlag) {
339 0 : ShowContinueError(
340 0 : state, "... occurs in " + CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
341 0 : ErrorsFound = true;
342 : }
343 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignHXVolFlowRate = HXSupAirFlowRate;
344 :
345 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName = Alphas(4);
346 321 : GlobalNames::IntraObjUniquenessCheck(
347 321 : state, Alphas(4), CurrentModuleObject, cAlphaFields(4), state.dataHVACStandAloneERV->SupplyAirFanUniqueNames, ErrorsFound);
348 :
349 107 : errFlag = false;
350 107 : if (HVACFan::checkIfFanNameIsAFanSystem(state,
351 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum)
352 : .SupplyAirFanName)) { // no object type in input, so check if Fan:SystemModel
353 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanType_Num = DataHVACGlobals::FanType_SystemModelObject;
354 6 : state.dataHVACFan->fanObjs.emplace_back(
355 6 : new HVACFan::FanSystem(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName)); // call constructor
356 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanIndex =
357 3 : HVACFan::getFanObjectVectorIndex(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName);
358 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanSchPtr =
359 3 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanIndex]->availSchedIndex;
360 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate =
361 3 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanIndex]->designAirVolFlowRate;
362 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirOutletNode =
363 3 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanIndex]->outletNodeNum;
364 : } else {
365 208 : GetFanType(state,
366 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName,
367 : SAFanTypeNum,
368 : errFlag,
369 : CurrentModuleObject,
370 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name);
371 104 : if (errFlag) {
372 0 : ErrorsFound = true;
373 : }
374 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanType_Num = SAFanTypeNum;
375 :
376 104 : errFlag = false;
377 208 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanSchPtr = GetFanAvailSchPtr(
378 208 : state, cFanTypes(SAFanTypeNum), state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName, errFlag);
379 104 : if (errFlag) {
380 0 : ShowContinueError(
381 0 : state, "... occurs in " + CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
382 0 : ErrorsFound = true;
383 : }
384 :
385 312 : GetFanIndex(state,
386 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName,
387 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanIndex,
388 : errFlag,
389 208 : CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
390 :
391 : // Set the SA Design Fan Volume Flow Rate
392 : // get from fan module
393 104 : errFlag = false;
394 312 : SAFanVolFlowRate = GetFanDesignVolumeFlowRate(
395 208 : state, cFanTypes(SAFanTypeNum), state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName, errFlag);
396 104 : if (errFlag) {
397 0 : ShowContinueError(state,
398 0 : "... occurs in " + CurrentModuleObject + " =" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name);
399 0 : ErrorsFound = true;
400 : }
401 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate = SAFanVolFlowRate;
402 104 : errFlag = false;
403 208 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirOutletNode = GetFanOutletNode(
404 208 : state, cFanTypes(SAFanTypeNum), state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName, errFlag);
405 : }
406 :
407 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName = Alphas(5);
408 321 : GlobalNames::IntraObjUniquenessCheck(
409 321 : state, Alphas(5), CurrentModuleObject, cAlphaFields(5), state.dataHVACStandAloneERV->ExhaustAirFanUniqueNames, ErrorsFound);
410 107 : errFlag = false;
411 107 : if (HVACFan::checkIfFanNameIsAFanSystem(state,
412 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum)
413 : .ExhaustAirFanName)) { // no object type in input, so check if Fan:SystemModel
414 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanType_Num = DataHVACGlobals::FanType_SystemModelObject;
415 6 : state.dataHVACFan->fanObjs.emplace_back(
416 6 : new HVACFan::FanSystem(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName)); // call constructor
417 :
418 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanIndex =
419 3 : HVACFan::getFanObjectVectorIndex(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName);
420 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanSchPtr =
421 3 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanIndex]->availSchedIndex;
422 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanVolFlowRate =
423 3 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanIndex]->designAirVolFlowRate;
424 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirOutletNode =
425 3 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanIndex]->outletNodeNum;
426 :
427 : } else {
428 208 : GetFanType(state,
429 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName,
430 : EAFanTypeNum,
431 : errFlag,
432 : CurrentModuleObject,
433 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name);
434 104 : if (!errFlag) {
435 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanType_Num = EAFanTypeNum;
436 : // error for fan availability schedule?
437 208 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanSchPtr = GetFanAvailSchPtr(
438 208 : state, cFanTypes(EAFanTypeNum), state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName, errFlag);
439 312 : GetFanIndex(state,
440 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName,
441 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanIndex,
442 : errFlag,
443 208 : CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
444 : } else {
445 0 : ErrorsFound = true;
446 : }
447 :
448 : // Set the EA Design Fan Volume Flow Rate
449 : // get from fan module
450 104 : errFlag = false;
451 312 : EAFanVolFlowRate = GetFanDesignVolumeFlowRate(
452 208 : state, cFanTypes(EAFanTypeNum), state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName, errFlag);
453 104 : if (errFlag) {
454 0 : ShowContinueError(state,
455 0 : "... occurs in " + CurrentModuleObject + " =" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name);
456 0 : ErrorsFound = true;
457 : }
458 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanVolFlowRate = EAFanVolFlowRate;
459 :
460 208 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirOutletNode = GetFanOutletNode(
461 208 : state, cFanTypes(EAFanTypeNum), state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName, errFlag);
462 104 : if (errFlag) {
463 0 : ShowContinueError(state,
464 0 : "... occurs in " + CurrentModuleObject + " =" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name);
465 0 : ErrorsFound = true;
466 : }
467 : }
468 :
469 107 : errFlag = false;
470 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirInletNode =
471 107 : GetHXSupplyInletNode(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerName, errFlag);
472 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirInletNode =
473 107 : GetHXSecondaryInletNode(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerName, errFlag);
474 107 : if (errFlag) {
475 0 : ShowContinueError(state,
476 0 : "... occurs in " + CurrentModuleObject + " =" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name);
477 0 : ErrorsFound = true;
478 : }
479 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirInletNode =
480 214 : GetOnlySingleNode(state,
481 107 : state.dataLoopNodes->NodeID(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirInletNode),
482 : ErrorsFound,
483 : DataLoopNode::ConnectionObjectType::ZoneHVACEnergyRecoveryVentilator,
484 107 : Alphas(1),
485 : DataLoopNode::NodeFluidType::Air,
486 : DataLoopNode::ConnectionType::Inlet,
487 : NodeInputManager::CompFluidStream::Primary,
488 107 : ObjectIsParent);
489 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirOutletNode =
490 214 : GetOnlySingleNode(state,
491 107 : state.dataLoopNodes->NodeID(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirOutletNode),
492 : ErrorsFound,
493 : DataLoopNode::ConnectionObjectType::ZoneHVACEnergyRecoveryVentilator,
494 107 : Alphas(1),
495 : DataLoopNode::NodeFluidType::Air,
496 : DataLoopNode::ConnectionType::Outlet,
497 : NodeInputManager::CompFluidStream::Primary,
498 107 : ObjectIsParent);
499 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirInletNode =
500 214 : GetOnlySingleNode(state,
501 107 : state.dataLoopNodes->NodeID(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirInletNode),
502 : ErrorsFound,
503 : DataLoopNode::ConnectionObjectType::ZoneHVACEnergyRecoveryVentilator,
504 107 : Alphas(1),
505 : DataLoopNode::NodeFluidType::Air,
506 : DataLoopNode::ConnectionType::Inlet,
507 : NodeInputManager::CompFluidStream::Secondary,
508 107 : ObjectIsParent);
509 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirOutletNode =
510 214 : GetOnlySingleNode(state,
511 107 : state.dataLoopNodes->NodeID(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirOutletNode),
512 : ErrorsFound,
513 : DataLoopNode::ConnectionObjectType::ZoneHVACEnergyRecoveryVentilator,
514 107 : Alphas(1),
515 : DataLoopNode::NodeFluidType::Air,
516 : DataLoopNode::ConnectionType::ReliefAir,
517 : NodeInputManager::CompFluidStream::Secondary,
518 107 : ObjectIsParent);
519 :
520 : // Check that supply air inlet node is an OA node
521 107 : if (!CheckOutAirNodeNumber(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirInletNode)) {
522 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
523 0 : ShowContinueError(state,
524 0 : " Node name of supply air inlet node not valid Outdoor Air Node = " +
525 0 : state.dataLoopNodes->NodeID(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirInletNode));
526 0 : ShowContinueError(state, "...does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
527 0 : ErrorsFound = true;
528 : }
529 :
530 : // Check to make sure inlet and exhaust nodes are listed in a ZoneHVAC:EquipmentConnections object
531 107 : ZoneInletNodeFound = false;
532 107 : ZoneExhaustNodeFound = false;
533 7851 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
534 7744 : if (!ZoneInletNodeFound) {
535 10783 : for (NodeNumber = 1; NodeNumber <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++NodeNumber) {
536 13976 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(NodeNumber) ==
537 6988 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirOutletNode) {
538 107 : ZoneInletNodeFound = true;
539 107 : ZoneInletCZN = ControlledZoneNum;
540 107 : break; // found zone inlet node
541 : }
542 : }
543 : }
544 7744 : if (!ZoneExhaustNodeFound) {
545 7245 : for (NodeNumber = 1; NodeNumber <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumExhaustNodes; ++NodeNumber) {
546 6900 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(NodeNumber) ==
547 3450 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirInletNode) {
548 107 : ZoneExhaustNodeFound = true;
549 107 : ZoneExhaustCZN = ControlledZoneNum;
550 107 : break; // found zone exhaust node
551 : }
552 : }
553 : }
554 : }
555 107 : if (!ZoneInletNodeFound) {
556 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
557 0 : ShowContinueError(state, "... Node name of supply air outlet node does not appear in a ZoneHVAC:EquipmentConnections object.");
558 0 : ShowContinueError(state,
559 0 : "... Supply air outlet node = " +
560 0 : state.dataLoopNodes->NodeID(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirOutletNode));
561 0 : ErrorsFound = true;
562 : }
563 107 : if (!ZoneExhaustNodeFound) {
564 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
565 0 : ShowContinueError(state, "... Node name of exhaust air inlet node does not appear in a ZoneHVAC:EquipmentConnections object.");
566 0 : ShowContinueError(state,
567 0 : "... Exhaust air inlet node = " +
568 0 : state.dataLoopNodes->NodeID(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirInletNode));
569 0 : ErrorsFound = true;
570 : }
571 : // If nodes are found, make sure they are in the same zone
572 107 : if (ZoneInletNodeFound && ZoneExhaustNodeFound) {
573 107 : if (ZoneInletCZN != ZoneExhaustCZN) {
574 0 : ShowSevereError(state,
575 0 : "For " + CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
576 0 : ShowContinueError(state,
577 : "... Node name of supply air outlet node and exhasut air inlet node must appear in the same "
578 : "ZoneHVAC:EquipmentConnections object.");
579 0 : ShowContinueError(state,
580 0 : "... Supply air outlet node = " +
581 0 : state.dataLoopNodes->NodeID(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirOutletNode));
582 0 : ShowContinueError(state,
583 0 : "... ZoneHVAC:EquipmentConnections Zone Name = " + state.dataZoneEquip->ZoneEquipConfig(ZoneInletCZN).ZoneName);
584 0 : ShowContinueError(state,
585 0 : "... Exhaust air inlet node = " +
586 0 : state.dataLoopNodes->NodeID(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirInletNode));
587 0 : ShowContinueError(state,
588 0 : "... ZoneHVAC:EquipmentConnections Zone Name = " + state.dataZoneEquip->ZoneEquipConfig(ZoneExhaustCZN).ZoneName);
589 0 : ErrorsFound = true;
590 : }
591 : }
592 :
593 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerName = Alphas(6);
594 : // If controller name is blank the ERV unit will operate with no controller
595 107 : if (lAlphaBlanks(6)) {
596 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerName = "xxxxx";
597 3 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerNameDefined = false;
598 : } else {
599 : // Verify controller name in Stand Alone ERV object matches name of valid controller object
600 312 : GlobalNames::IntraObjUniquenessCheck(
601 312 : state, Alphas(6), CurrentModuleObject, cAlphaFields(6), state.dataHVACStandAloneERV->ControllerUniqueNames, ErrorsFound);
602 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerNameDefined = true;
603 104 : if (ErrorsFound) {
604 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerNameDefined = false;
605 : }
606 :
607 416 : if (state.dataInputProcessing->inputProcessor->getObjectItemNum(
608 : state,
609 : "ZoneHVAC:EnergyRecoveryVentilator:Controller",
610 312 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerName) <= 0) {
611 0 : ShowSevereError(state,
612 0 : CurrentModuleObject + " controller type ZoneHVAC:EnergyRecoveryVentilator:Controller not found = " + Alphas(6));
613 0 : ErrorsFound = true;
614 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerNameDefined = false;
615 : }
616 : }
617 :
618 107 : if (!lAlphaBlanks(7)) {
619 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).AvailManagerListName = Alphas(7);
620 : }
621 :
622 : // Read supply and exhaust air flow rates
623 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow = Numbers(1);
624 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow = Numbers(2);
625 :
626 : // Read ventilation rate per floor area for autosizing HX and fans
627 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).AirVolFlowPerFloorArea = Numbers(3);
628 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).AirVolFlowPerOccupant = Numbers(4);
629 :
630 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow == AutoSize &&
631 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate != AutoSize) {
632 0 : ShowSevereError(state, CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
633 0 : ShowContinueError(state,
634 0 : "... When autosizing ERV, supply air fan = " + cFanTypes(SAFanTypeNum) + " \"" +
635 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName + "\" must also be autosized.");
636 : }
637 :
638 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow == AutoSize &&
639 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanVolFlowRate != AutoSize) {
640 0 : ShowSevereError(state, CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
641 0 : ShowContinueError(state,
642 0 : "... When autosizing ERV, exhaust air fan = " + cFanTypes(EAFanTypeNum) + " \"" +
643 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName + "\" must also be autosized.");
644 : }
645 :
646 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow == AutoSize && HXSupAirFlowRate != AutoSize) {
647 0 : ShowSevereError(state, CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
648 0 : ShowContinueError(state,
649 0 : "... When autosizing ERV " + cNumericFields(1) + ", nominal supply air flow rate for heat exchanger with name = " +
650 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerName + " must also be autosized.");
651 : }
652 :
653 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow == AutoSize && HXSupAirFlowRate != AutoSize) {
654 0 : ShowSevereError(state, CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
655 0 : ShowContinueError(state,
656 0 : "... When autosizing ERV " + cNumericFields(2) + ", nominal supply air flow rate for heat exchanger with name = " +
657 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerName + " must also be autosized.");
658 : }
659 :
660 : // Compare the ERV SA flow rates to SA fan object.
661 112 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate != AutoSize &&
662 5 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow != AutoSize) {
663 10 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow >
664 5 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate) {
665 0 : ShowWarningError(state,
666 0 : CurrentModuleObject + " = " + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + " has a " +
667 0 : cNumericFields(1) + " > Max Volume Flow Rate defined in the associated fan object, should be <=");
668 0 : ShowContinueError(state,
669 0 : format("... Entered value={:.2R}... Fan [{} \"{}\"] Max Value = {:.2R}",
670 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow,
671 : cFanTypes(SAFanTypeNum),
672 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName,
673 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate));
674 0 : ShowContinueError(state, " The ERV " + cNumericFields(1) + " is reset to the supply air fan flow rate and the simulation continues.");
675 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow =
676 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate;
677 : }
678 : }
679 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow != AutoSize) {
680 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow <= 0.0) {
681 0 : ShowSevereError(state,
682 0 : CurrentModuleObject + " = " + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + " has a " +
683 0 : cNumericFields(1) + " <= 0.0, it must be >0.0");
684 0 : ShowContinueError(state,
685 0 : format("... Entered value={:.2R}", state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow));
686 0 : ErrorsFound = true;
687 : }
688 : } else {
689 0 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).AirVolFlowPerFloorArea == 0.0 &&
690 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).AirVolFlowPerOccupant == 0.0) {
691 0 : ShowSevereError(state, CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
692 0 : ShowContinueError(state,
693 0 : "... Autosizing " + cNumericFields(1) + " requires at least one input for " + cNumericFields(3) + " or " +
694 0 : cNumericFields(4) + '.');
695 0 : ErrorsFound = true;
696 : }
697 : // both inputs must be autosized
698 0 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow != AutoSize) {
699 0 : ShowSevereError(state, CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
700 0 : ShowContinueError(state, "... When autosizing, " + cNumericFields(1) + " and " + cNumericFields(2) + " must both be autosized.");
701 0 : ErrorsFound = true;
702 : }
703 : }
704 :
705 : // Compare the ERV EA flow rates to EA fan object.
706 112 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanVolFlowRate != AutoSize &&
707 5 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow != AutoSize) {
708 10 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow >
709 5 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanVolFlowRate) {
710 0 : ShowWarningError(state,
711 0 : CurrentModuleObject + " = " + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + " has an " +
712 0 : cNumericFields(2) + " > Max Volume Flow Rate defined in the associated fan object, should be <=");
713 0 : ShowContinueError(state,
714 0 : format("... Entered value={:.2R}... Fan [{}:{}] Max Value = {:.2R}",
715 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow,
716 : cFanTypes(EAFanTypeNum),
717 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName,
718 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanVolFlowRate));
719 0 : ShowContinueError(state,
720 0 : " The ERV " + cNumericFields(2) + " is reset to the exhaust air fan flow rate and the simulation continues.");
721 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow =
722 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanVolFlowRate;
723 : }
724 : }
725 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow != AutoSize) {
726 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow <= 0.0) {
727 0 : ShowSevereError(state,
728 0 : CurrentModuleObject + " = " + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + " has an " +
729 0 : cNumericFields(2) + " <= 0.0, it must be >0.0");
730 0 : ShowContinueError(state,
731 0 : format("... Entered value={:.2R}", state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow));
732 0 : ErrorsFound = true;
733 : }
734 : } else {
735 0 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).AirVolFlowPerFloorArea == 0.0 &&
736 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).AirVolFlowPerOccupant == 0.0) {
737 0 : ShowSevereError(state, CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
738 0 : ShowContinueError(state,
739 0 : "... Autosizing " + cNumericFields(2) + " requires at least one input for " + cNumericFields(3) + " or " +
740 0 : cNumericFields(4) + '.');
741 0 : ErrorsFound = true;
742 : }
743 0 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow != AutoSize) {
744 0 : ShowSevereError(state, CurrentModuleObject + " \"" + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\"");
745 0 : ShowContinueError(state, "... When autosizing, " + cNumericFields(1) + " and " + cNumericFields(2) + " must both be autosized.");
746 0 : ErrorsFound = true;
747 : }
748 : }
749 :
750 : // Add supply fan to component sets array
751 107 : CompSetSupplyFanInlet = "UNDEFINED";
752 107 : CompSetSupplyFanOutlet = state.dataLoopNodes->NodeID(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirOutletNode);
753 :
754 : // Add exhaust fan to component sets array
755 107 : CompSetExhaustFanInlet = "UNDEFINED";
756 107 : CompSetExhaustFanOutlet = state.dataLoopNodes->NodeID(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirOutletNode);
757 :
758 : // Add HX to component sets array
759 321 : SetUpCompSets(state,
760 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).UnitType,
761 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name,
762 : "UNDEFINED",
763 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerName,
764 : "UNDEFINED",
765 214 : "UNDEFINED");
766 :
767 : // Add supply fan to component sets array
768 428 : SetUpCompSets(state,
769 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).UnitType,
770 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name,
771 : "UNDEFINED",
772 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName,
773 : CompSetSupplyFanInlet,
774 214 : CompSetSupplyFanOutlet);
775 :
776 : // Add exhaust fan to component sets array
777 428 : SetUpCompSets(state,
778 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).UnitType,
779 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name,
780 : "UNDEFINED",
781 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName,
782 : CompSetExhaustFanInlet,
783 214 : CompSetExhaustFanOutlet);
784 :
785 : // Verify HX name in Stand Alone ERV object matches name of valid HX object
786 428 : if (state.dataInputProcessing->inputProcessor->getObjectItemNum(
787 321 : state, "HeatExchanger:AirToAir:SensibleAndLatent", state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerName) <=
788 : 0) {
789 0 : ShowSevereError(state,
790 0 : CurrentModuleObject + " heat exchanger type HeatExchanger:AirToAir:SensibleAndLatent not found = " +
791 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerName);
792 0 : ErrorsFound = true;
793 : }
794 : // Verify supply air fan name in Stand Alone ERV object matches name of valid fan object
795 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
796 416 : if (state.dataInputProcessing->inputProcessor->getObjectItemNum(
797 312 : state, "Fan:OnOff", state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName) <= 0) {
798 0 : ShowSevereError(state,
799 0 : CurrentModuleObject + " supply fan type Fan:OnOff not found = " +
800 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName);
801 0 : ErrorsFound = true;
802 : }
803 : } else {
804 12 : if (state.dataInputProcessing->inputProcessor->getObjectItemNum(
805 9 : state, "Fan:SystemModel", state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName) <= 0) {
806 0 : ShowSevereError(state,
807 0 : CurrentModuleObject + " supply fan type Fan:SystemModel not found = " +
808 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName);
809 0 : ErrorsFound = true;
810 : }
811 : }
812 :
813 : // Verify exhaust air fan name in Stand Alone ERV object matches name of valid fan object
814 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
815 416 : if (state.dataInputProcessing->inputProcessor->getObjectItemNum(
816 312 : state, "Fan:OnOff", state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName) <= 0) {
817 0 : ShowSevereError(state,
818 0 : CurrentModuleObject + " exhaust fan type Fan:OnOff not found = " +
819 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName);
820 0 : ErrorsFound = true;
821 : }
822 : } else {
823 12 : if (state.dataInputProcessing->inputProcessor->getObjectItemNum(
824 9 : state, "Fan:SystemModel", state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName) <= 0) {
825 0 : ShowSevereError(state,
826 0 : CurrentModuleObject + " exhaust fan type Fan:SystemModel not found = " +
827 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName);
828 0 : ErrorsFound = true;
829 : }
830 : }
831 : }
832 :
833 5 : int OutAirNum = 0;
834 5 : CurrentModuleObject = "ZoneHVAC:EnergyRecoveryVentilator:Controller";
835 5 : NumERVCtrlrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
836 :
837 109 : for (ERVControllerNum = 1; ERVControllerNum <= NumERVCtrlrs; ++ERVControllerNum) {
838 104 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
839 : CurrentModuleObject,
840 : ERVControllerNum,
841 : Alphas,
842 : NumAlphas,
843 : Numbers,
844 : NumNumbers,
845 : IOStatus,
846 : lNumericBlanks,
847 : lAlphaBlanks,
848 : cAlphaFields,
849 : cNumericFields);
850 104 : MixedAir::CheckOAControllerName(state, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
851 104 : ++OutAirNum;
852 104 : auto &thisOAController(state.dataMixedAir->OAController(OutAirNum));
853 :
854 104 : thisOAController.Name = Alphas(1);
855 104 : thisOAController.ControllerType = CurrentModuleObject;
856 104 : thisOAController.ControllerType_Num = MixedAir::MixedAirControllerType::ControllerStandAloneERV;
857 104 : WhichERV = UtilityRoutines::FindItemInList(Alphas(1), state.dataHVACStandAloneERV->StandAloneERV, &StandAloneERVData::ControllerName);
858 104 : if (WhichERV != 0) {
859 104 : AirFlowRate = state.dataHVACStandAloneERV->StandAloneERV(WhichERV).SupplyAirVolFlow;
860 104 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).ControllerIndex = OutAirNum;
861 : } else {
862 0 : ShowSevereError(
863 0 : state, "GetERVController: Could not find ZoneHVAC:EnergyRecoveryVentilator with " + cAlphaFields(1) + " = \"" + Alphas(1) + "\"");
864 0 : ErrorsFound = true;
865 0 : AirFlowRate = -1000.0;
866 : }
867 104 : thisOAController.MaxOA = AirFlowRate;
868 104 : thisOAController.MinOA = AirFlowRate;
869 : // OAController(OutAirNum)%TempLim = Numbers(1)
870 104 : if (lNumericBlanks(1)) {
871 102 : thisOAController.TempLim = BlankNumeric;
872 : } else {
873 2 : thisOAController.TempLim = Numbers(1);
874 : }
875 : // OAController(OutAirNum)%TempLowLim = Numbers(2)
876 104 : if (lNumericBlanks(2)) {
877 102 : thisOAController.TempLowLim = BlankNumeric;
878 : } else {
879 2 : thisOAController.TempLowLim = Numbers(2);
880 : }
881 : // OAController(OutAirNum)%EnthLim = Numbers(3)
882 104 : if (lNumericBlanks(3)) {
883 104 : thisOAController.EnthLim = BlankNumeric;
884 : } else {
885 0 : thisOAController.EnthLim = Numbers(3);
886 : }
887 : // OAController(OutAirNum)%DPTempLim = Numbers(4)
888 104 : if (lNumericBlanks(4)) {
889 102 : thisOAController.DPTempLim = BlankNumeric;
890 : } else {
891 2 : thisOAController.DPTempLim = Numbers(4);
892 : }
893 :
894 104 : if (WhichERV != 0) {
895 104 : NodeNumber = state.dataHVACStandAloneERV->StandAloneERV(WhichERV).SupplyAirInletNode;
896 : } else {
897 0 : NodeNumber = 0;
898 : }
899 104 : thisOAController.OANode = NodeNumber;
900 : // set the inlet node to also equal the OA node because this is a special controller for economizing stand alone ERV
901 : // with the assumption that equipment is bypassed....(moved from module MixedAir)
902 104 : thisOAController.InletNode = NodeNumber;
903 :
904 104 : if (WhichERV != 0) {
905 104 : NodeNumber = state.dataHVACStandAloneERV->StandAloneERV(WhichERV).ExhaustAirInletNode;
906 : } else {
907 0 : NodeNumber = 0;
908 : }
909 104 : thisOAController.RetNode = NodeNumber;
910 :
911 104 : if (!lAlphaBlanks(2)) {
912 1 : thisOAController.EnthalpyCurvePtr = GetCurveIndex(state, Alphas(2));
913 1 : if (GetCurveIndex(state, Alphas(2)) == 0) {
914 0 : ShowSevereError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
915 0 : ShowContinueError(state, "..." + cAlphaFields(2) + " not found:" + Alphas(2));
916 0 : ErrorsFound = true;
917 : } else {
918 : // Verify Curve Object, only legal types are Quadratic and Cubic
919 2 : ErrorsFound |= Curve::CheckCurveDims(state,
920 : thisOAController.EnthalpyCurvePtr, // Curve index
921 : {1}, // Valid dimensions
922 : "GetStandAloneERV: ", // Routine name
923 : CurrentModuleObject, // Object Type
924 : thisOAController.Name, // Object Name
925 2 : cAlphaFields(2)); // Field Name
926 : }
927 : }
928 :
929 : // Changed by AMIT for new implementation of the controller:outside air
930 104 : if (Alphas(3) == "EXHAUSTAIRTEMPERATURELIMIT" && Alphas(4) == "EXHAUSTAIRENTHALPYLIMIT") {
931 0 : thisOAController.Econo = MixedAir::EconoOp::DifferentialDryBulbAndEnthalpy;
932 104 : } else if (Alphas(3) == "EXHAUSTAIRTEMPERATURELIMIT" && Alphas(4) == "NOEXHAUSTAIRENTHALPYLIMIT") {
933 0 : thisOAController.Econo = MixedAir::EconoOp::DifferentialDryBulb;
934 104 : } else if (Alphas(3) == "NOEXHAUSTAIRTEMPERATURELIMIT" && Alphas(4) == "EXHAUSTAIRENTHALPYLIMIT") {
935 0 : thisOAController.Econo = MixedAir::EconoOp::DifferentialEnthalpy;
936 104 : } else if (Alphas(3) == "NOEXHAUSTAIRTEMPERATURELIMIT" && Alphas(4) == "NOEXHAUSTAIRENTHALPYLIMIT") {
937 104 : if ((!lNumericBlanks(1)) || (!lNumericBlanks(3)) || (!lNumericBlanks(4)) || (!lAlphaBlanks(2))) {
938 : // This means that any of the FIXED DRY BULB, FIXED ENTHALPY, FIXED DEW POINT AND DRY BULB OR
939 : // ELECTRONIC ENTHALPY ECONOMIZER STRATEGY is present
940 2 : thisOAController.Econo = MixedAir::EconoOp::FixedDryBulb;
941 : }
942 0 : } else if ((!lAlphaBlanks(3)) && (!lAlphaBlanks(4))) {
943 0 : if ((lNumericBlanks(1)) && (lNumericBlanks(3)) && (lNumericBlanks(4)) && lAlphaBlanks(2)) {
944 0 : ShowWarningError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
945 0 : ShowContinueError(state, "... Invalid " + cAlphaFields(3) + cAlphaFields(4) + " = " + Alphas(3) + Alphas(4));
946 0 : ShowContinueError(state, "... Assumed NO EXHAUST AIR TEMP LIMIT and NO EXHAUST AIR ENTHALPY LIMIT.");
947 0 : thisOAController.Econo = MixedAir::EconoOp::NoEconomizer;
948 : } else {
949 : // This means that any of the FIXED DRY BULB, FIXED ENTHALPY, FIXED DEW POINT AND DRY BULB OR
950 : // ELECTRONIC ENTHALPY ECONOMIZER STRATEGY is present
951 0 : thisOAController.Econo = MixedAir::EconoOp::FixedDryBulb;
952 : }
953 0 : } else if ((lAlphaBlanks(3)) && (!lAlphaBlanks(4))) {
954 0 : if ((lNumericBlanks(1)) && (lNumericBlanks(3)) && (lNumericBlanks(4)) && lAlphaBlanks(2)) {
955 0 : ShowWarningError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
956 0 : ShowContinueError(state, "... Invalid " + cAlphaFields(4) + " = " + Alphas(4));
957 0 : ShowContinueError(state, "... Assumed NO EXHAUST AIR ENTHALPY LIMIT.");
958 0 : thisOAController.Econo = MixedAir::EconoOp::NoEconomizer;
959 : } else {
960 : // This means that any of the FIXED DRY BULB, FIXED ENTHALPY, FIXED DEW POINT AND DRY BULB OR
961 : // ELECTRONIC ENTHALPY ECONOMIZER STRATEGY is present
962 0 : thisOAController.Econo = MixedAir::EconoOp::FixedDryBulb;
963 : }
964 0 : } else if ((!lAlphaBlanks(3)) && (lAlphaBlanks(4))) {
965 0 : if ((lNumericBlanks(1)) && (lNumericBlanks(3)) && (lNumericBlanks(4)) && lAlphaBlanks(2)) {
966 0 : ShowWarningError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
967 0 : ShowContinueError(state, "... Invalid " + cAlphaFields(3) + " = " + Alphas(3));
968 0 : ShowContinueError(state, "... Assumed NO EXHAUST AIR TEMP LIMIT ");
969 0 : thisOAController.Econo = MixedAir::EconoOp::NoEconomizer;
970 : } else {
971 : // This means that any of the FIXED DRY BULB, FIXED ENTHALPY, FIXED DEW POINT AND DRY BULB OR
972 : // ELECTRONIC ENTHALPY ECONOMIZER STRATEGY is present
973 0 : thisOAController.Econo = MixedAir::EconoOp::FixedDryBulb;
974 : }
975 : } else { // NO Economizer
976 0 : thisOAController.Econo = MixedAir::EconoOp::NoEconomizer;
977 : }
978 :
979 104 : thisOAController.FixedMin = false;
980 104 : thisOAController.EconBypass = true;
981 :
982 : // Initialize to one in case high humidity control is NOT used
983 104 : HighRHOARatio = 1.0;
984 : // READ Modify Air Flow Data
985 : // High humidity control option is YES, read in additional data
986 104 : if (UtilityRoutines::SameString(Alphas(6), "Yes")) {
987 :
988 1 : HStatZoneNum = UtilityRoutines::FindItemInList(Alphas(7), state.dataHeatBal->Zone);
989 1 : thisOAController.HumidistatZoneNum = HStatZoneNum;
990 :
991 : // Get the node number for the zone with the humidistat
992 1 : if (HStatZoneNum > 0) {
993 1 : ZoneNodeFound = false;
994 1 : HStatFound = false;
995 1 : if (state.dataZoneEquip->ZoneEquipConfig(HStatZoneNum).IsControlled) {
996 : // Find the controlled zone number for the specified humidistat location
997 1 : thisOAController.NodeNumofHumidistatZone = state.dataZoneEquip->ZoneEquipConfig(HStatZoneNum).ZoneNode;
998 1 : ZoneNodeFound = true;
999 : }
1000 1 : if (!ZoneNodeFound) {
1001 0 : ShowSevereError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
1002 0 : ShowContinueError(state, "... Did not find Air Node (Zone with Humidistat)");
1003 0 : ShowContinueError(state, "... Specified " + cAlphaFields(7) + " = " + Alphas(7));
1004 0 : ShowContinueError(state, "... A ZoneHVAC:EquipmentConnections object must be specified for this zone.");
1005 0 : ErrorsFound = true;
1006 : } else {
1007 1 : for (NumHstatZone = 1; NumHstatZone <= state.dataZoneCtrls->NumHumidityControlZones; ++NumHstatZone) {
1008 1 : if (state.dataZoneCtrls->HumidityControlZone(NumHstatZone).ActualZoneNum != HStatZoneNum) continue;
1009 1 : HStatFound = true;
1010 1 : break;
1011 : }
1012 1 : if (!HStatFound) {
1013 0 : ShowSevereError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
1014 0 : ShowContinueError(state, "... Did not find zone humidistat");
1015 0 : ShowContinueError(state, "... A ZoneControl:Humidistat object must be specified for this zone.");
1016 0 : ErrorsFound = true;
1017 : }
1018 : }
1019 : } else {
1020 0 : ShowSevereError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
1021 0 : ShowContinueError(state, "... Did not find Air Node (Zone with Humidistat)");
1022 0 : ShowContinueError(state, "... A ZoneHVAC:EquipmentConnections object must be specified for this zone.");
1023 0 : ErrorsFound = true;
1024 : }
1025 :
1026 1 : if (Numbers(5) <= 0.0 && NumNumbers > 4) {
1027 :
1028 0 : ShowWarningError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
1029 0 : ShowContinueError(state, "... " + cNumericFields(5) + " must be greater than 0.");
1030 0 : ShowContinueError(state, "... " + cNumericFields(5) + " is reset to 1 and the simulation continues.");
1031 :
1032 0 : HighRHOARatio = 1.0;
1033 :
1034 1 : } else if (NumNumbers > 4) {
1035 :
1036 1 : HighRHOARatio = Numbers(5);
1037 :
1038 : } else {
1039 :
1040 0 : HighRHOARatio = 1.0;
1041 : }
1042 :
1043 1 : if (UtilityRoutines::SameString(Alphas(8), "Yes")) {
1044 1 : thisOAController.ModifyDuringHighOAMoisture = false;
1045 : } else {
1046 0 : thisOAController.ModifyDuringHighOAMoisture = true;
1047 : }
1048 :
1049 103 : } else if (!UtilityRoutines::SameString(Alphas(6), "No") && NumAlphas > 4 && (!lAlphaBlanks(5))) {
1050 0 : ShowWarningError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
1051 0 : ShowContinueError(state, "... Invalid " + cAlphaFields(6) + " = " + Alphas(6));
1052 0 : ShowContinueError(state, "... " + cAlphaFields(6) + " is assumed to be \"No\" and the simulation continues.");
1053 : } // IF(UtilityRoutines::SameString(Alphas(6),'Yes'))THEN
1054 :
1055 104 : thisOAController.HighRHOAFlowRatio = HighRHOARatio;
1056 104 : if (WhichERV != 0) {
1057 104 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).HighRHOAFlowRatio = HighRHOARatio;
1058 : }
1059 :
1060 : // Check for a time of day outside air schedule
1061 104 : thisOAController.EconomizerOASchedPtr = GetScheduleIndex(state, Alphas(5));
1062 :
1063 104 : if (WhichERV != 0) {
1064 104 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).EconomizerOASchedPtr = GetScheduleIndex(state, Alphas(5));
1065 :
1066 : // Compare the ERV SA fan flow rates to modified air flow rate.
1067 105 : if (HighRHOARatio > 1.0 && state.dataHVACStandAloneERV->StandAloneERV(WhichERV).SupplyAirVolFlow != AutoSize &&
1068 1 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).DesignSAFanVolFlowRate != AutoSize) {
1069 2 : if (state.dataHVACStandAloneERV->StandAloneERV(WhichERV).SupplyAirVolFlow * HighRHOARatio >
1070 1 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).DesignSAFanVolFlowRate) {
1071 0 : ShowWarningError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
1072 0 : ShowContinueError(state, format("... A {} was entered as {:.4R}", cNumericFields(5), HighRHOARatio));
1073 0 : ShowContinueError(state,
1074 : "... This flow ratio results in a Supply Air Volume Flow Rate through the ERV which is greater than the "
1075 : "Max Volume specified in the supply air fan object.");
1076 0 : ShowContinueError(state,
1077 0 : "... Associated fan object = " + cFanTypes(SAFanTypeNum) + " \"" +
1078 0 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).SupplyAirFanName + "\"");
1079 0 : ShowContinueError(state,
1080 0 : format("... Modified value = {:.2R}",
1081 0 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).SupplyAirVolFlow * HighRHOARatio));
1082 0 : ShowContinueError(state,
1083 0 : format(" ... Supply Fan Max Volume Flow Rate = {:.2R}",
1084 0 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).DesignSAFanVolFlowRate));
1085 0 : ShowContinueError(state, "... The ERV supply air fan will limit the air flow through the ERV and the simulation continues.");
1086 : }
1087 : }
1088 :
1089 : // Compare the ERV EA fan flow rates to modified air flow rate.
1090 105 : if (HighRHOARatio > 1.0 && state.dataHVACStandAloneERV->StandAloneERV(WhichERV).ExhaustAirVolFlow != AutoSize &&
1091 1 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).DesignEAFanVolFlowRate != AutoSize) {
1092 2 : if (state.dataHVACStandAloneERV->StandAloneERV(WhichERV).ExhaustAirVolFlow * HighRHOARatio >
1093 1 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).DesignEAFanVolFlowRate) {
1094 0 : ShowWarningError(state, "ZoneHVAC:EnergyRecoveryVentilator:Controller \"" + Alphas(1) + "\"");
1095 0 : ShowContinueError(state, format("... A {} was entered as {:.4R}", cNumericFields(5), HighRHOARatio));
1096 0 : ShowContinueError(state,
1097 : "... This flow ratio results in an Exhaust Air Volume Flow Rate through the ERV which is greater than the "
1098 : "Max Volume specified in the exhaust air fan object.");
1099 0 : ShowContinueError(state,
1100 0 : "... Associated fan object = " + cFanTypes(EAFanTypeNum) + " \"" +
1101 0 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).ExhaustAirFanName + "\"");
1102 0 : ShowContinueError(state,
1103 0 : format("... Modified value = {:.2R}",
1104 0 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).ExhaustAirVolFlow * HighRHOARatio));
1105 0 : ShowContinueError(state,
1106 0 : format(" ... Exhaust Fan Max Volume Flow Rate = {:.2R}",
1107 0 : state.dataHVACStandAloneERV->StandAloneERV(WhichERV).DesignEAFanVolFlowRate));
1108 0 : ShowContinueError(state, "... The ERV exhaust air fan will limit the air flow through the ERV and the simulation continues.");
1109 : }
1110 : }
1111 : } // IF(WhichERV /= 0)THEN
1112 : }
1113 :
1114 5 : if (ErrorsFound) {
1115 0 : ShowFatalError(state, "Errors found in getting ZoneHVAC:EnergyRecoveryVentilator input.");
1116 : }
1117 :
1118 : // Setup report variables for the stand alone ERVs
1119 112 : for (StandAloneERVIndex = 1; StandAloneERVIndex <= state.dataHVACStandAloneERV->NumStandAloneERVs; ++StandAloneERVIndex) {
1120 428 : SetupOutputVariable(state,
1121 : "Zone Ventilator Sensible Cooling Rate",
1122 : OutputProcessor::Unit::W,
1123 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).SensCoolingRate,
1124 : OutputProcessor::SOVTimeStepType::System,
1125 : OutputProcessor::SOVStoreType::Average,
1126 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1127 428 : SetupOutputVariable(state,
1128 : "Zone Ventilator Sensible Cooling Energy",
1129 : OutputProcessor::Unit::J,
1130 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).SensCoolingEnergy,
1131 : OutputProcessor::SOVTimeStepType::System,
1132 : OutputProcessor::SOVStoreType::Summed,
1133 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1134 428 : SetupOutputVariable(state,
1135 : "Zone Ventilator Latent Cooling Rate",
1136 : OutputProcessor::Unit::W,
1137 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).LatCoolingRate,
1138 : OutputProcessor::SOVTimeStepType::System,
1139 : OutputProcessor::SOVStoreType::Average,
1140 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1141 428 : SetupOutputVariable(state,
1142 : "Zone Ventilator Latent Cooling Energy",
1143 : OutputProcessor::Unit::J,
1144 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).LatCoolingEnergy,
1145 : OutputProcessor::SOVTimeStepType::System,
1146 : OutputProcessor::SOVStoreType::Summed,
1147 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1148 428 : SetupOutputVariable(state,
1149 : "Zone Ventilator Total Cooling Rate",
1150 : OutputProcessor::Unit::W,
1151 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).TotCoolingRate,
1152 : OutputProcessor::SOVTimeStepType::System,
1153 : OutputProcessor::SOVStoreType::Average,
1154 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1155 428 : SetupOutputVariable(state,
1156 : "Zone Ventilator Total Cooling Energy",
1157 : OutputProcessor::Unit::J,
1158 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).TotCoolingEnergy,
1159 : OutputProcessor::SOVTimeStepType::System,
1160 : OutputProcessor::SOVStoreType::Summed,
1161 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1162 :
1163 428 : SetupOutputVariable(state,
1164 : "Zone Ventilator Sensible Heating Rate",
1165 : OutputProcessor::Unit::W,
1166 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).SensHeatingRate,
1167 : OutputProcessor::SOVTimeStepType::System,
1168 : OutputProcessor::SOVStoreType::Average,
1169 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1170 428 : SetupOutputVariable(state,
1171 : "Zone Ventilator Sensible Heating Energy",
1172 : OutputProcessor::Unit::J,
1173 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).SensHeatingEnergy,
1174 : OutputProcessor::SOVTimeStepType::System,
1175 : OutputProcessor::SOVStoreType::Summed,
1176 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1177 428 : SetupOutputVariable(state,
1178 : "Zone Ventilator Latent Heating Rate",
1179 : OutputProcessor::Unit::W,
1180 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).LatHeatingRate,
1181 : OutputProcessor::SOVTimeStepType::System,
1182 : OutputProcessor::SOVStoreType::Average,
1183 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1184 428 : SetupOutputVariable(state,
1185 : "Zone Ventilator Latent Heating Energy",
1186 : OutputProcessor::Unit::J,
1187 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).LatHeatingEnergy,
1188 : OutputProcessor::SOVTimeStepType::System,
1189 : OutputProcessor::SOVStoreType::Summed,
1190 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1191 428 : SetupOutputVariable(state,
1192 : "Zone Ventilator Total Heating Rate",
1193 : OutputProcessor::Unit::W,
1194 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).TotHeatingRate,
1195 : OutputProcessor::SOVTimeStepType::System,
1196 : OutputProcessor::SOVStoreType::Average,
1197 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1198 428 : SetupOutputVariable(state,
1199 : "Zone Ventilator Total Heating Energy",
1200 : OutputProcessor::Unit::J,
1201 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).TotHeatingEnergy,
1202 : OutputProcessor::SOVTimeStepType::System,
1203 : OutputProcessor::SOVStoreType::Summed,
1204 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1205 :
1206 428 : SetupOutputVariable(state,
1207 : "Zone Ventilator Electricity Rate",
1208 : OutputProcessor::Unit::W,
1209 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).ElecUseRate,
1210 : OutputProcessor::SOVTimeStepType::System,
1211 : OutputProcessor::SOVStoreType::Average,
1212 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1213 428 : SetupOutputVariable(state,
1214 : "Zone Ventilator Electricity Energy",
1215 : OutputProcessor::Unit::J,
1216 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).ElecUseEnergy,
1217 : OutputProcessor::SOVTimeStepType::System,
1218 : OutputProcessor::SOVStoreType::Summed,
1219 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1220 428 : SetupOutputVariable(state,
1221 : "Zone Ventilator Supply Fan Availability Status",
1222 : OutputProcessor::Unit::None,
1223 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).AvailStatus,
1224 : OutputProcessor::SOVTimeStepType::System,
1225 : OutputProcessor::SOVStoreType::Average,
1226 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex).Name);
1227 : }
1228 :
1229 5 : Alphas.deallocate();
1230 5 : Numbers.deallocate();
1231 5 : cAlphaFields.deallocate();
1232 5 : cNumericFields.deallocate();
1233 5 : lNumericBlanks.deallocate();
1234 5 : lAlphaBlanks.deallocate();
1235 5 : }
1236 :
1237 758119 : void InitStandAloneERV(EnergyPlusData &state,
1238 : int const StandAloneERVNum, // number of the current Stand Alone ERV unit being simulated
1239 : int const ZoneNum, // number of zone being served unused1208
1240 : bool const FirstHVACIteration // TRUE if first HVAC iteration
1241 : )
1242 : {
1243 :
1244 : // SUBROUTINE INFORMATION:
1245 : // AUTHOR Richard Raustad, FSEC
1246 : // DATE WRITTEN June 2003
1247 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
1248 : // RE-ENGINEERED na
1249 :
1250 : // PURPOSE OF THIS SUBROUTINE:
1251 : // This subroutine is for initializations of the Stand Alone ERV unit information.
1252 :
1253 : // METHODOLOGY EMPLOYED:
1254 : // Uses the status flags to trigger initializations.
1255 :
1256 : using DataZoneEquipment::CheckZoneEquipmentList;
1257 : using MixedAir::SimOAController;
1258 :
1259 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1260 : int SupInNode; // supply air inlet node number
1261 : int ExhInNode; // exhaust air inlet node number
1262 : int SupInletNode; // supply air inlet node number for Stand Alone ERV 'StandAloneERVNum'
1263 : int Loop; // loop counter
1264 :
1265 758119 : auto &Node(state.dataLoopNodes->Node);
1266 :
1267 : // Do the one time initializations
1268 758119 : if (state.dataHVACStandAloneERV->MyOneTimeFlag) {
1269 :
1270 5 : state.dataHVACStandAloneERV->MyEnvrnFlag.allocate(state.dataHVACStandAloneERV->NumStandAloneERVs);
1271 5 : state.dataHVACStandAloneERV->MySizeFlag_InitStandAloneERV.allocate(state.dataHVACStandAloneERV->NumStandAloneERVs);
1272 5 : state.dataHVACStandAloneERV->MyZoneEqFlag.allocate(state.dataHVACStandAloneERV->NumStandAloneERVs);
1273 5 : state.dataHVACStandAloneERV->MyEnvrnFlag = true;
1274 5 : state.dataHVACStandAloneERV->MySizeFlag_InitStandAloneERV = true;
1275 5 : state.dataHVACStandAloneERV->MyZoneEqFlag = true;
1276 5 : state.dataHVACStandAloneERV->MyOneTimeFlag = false;
1277 : }
1278 :
1279 758119 : if (allocated(state.dataHVACGlobal->ZoneComp)) {
1280 758096 : if (state.dataHVACStandAloneERV->MyZoneEqFlag(StandAloneERVNum)) { // initialize the name of each availability manager list and zone number
1281 214 : state.dataHVACGlobal->ZoneComp(DataZoneEquipment::ZoneEquip::ERVStandAlone).ZoneCompAvailMgrs(StandAloneERVNum).AvailManagerListName =
1282 214 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).AvailManagerListName;
1283 107 : state.dataHVACGlobal->ZoneComp(DataZoneEquipment::ZoneEquip::ERVStandAlone).ZoneCompAvailMgrs(StandAloneERVNum).ZoneNum = ZoneNum;
1284 107 : state.dataHVACStandAloneERV->MyZoneEqFlag(StandAloneERVNum) = false;
1285 : }
1286 758096 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).AvailStatus =
1287 758096 : state.dataHVACGlobal->ZoneComp(DataZoneEquipment::ZoneEquip::ERVStandAlone).ZoneCompAvailMgrs(StandAloneERVNum).AvailStatus;
1288 : }
1289 :
1290 : // need to check all units to see if they are on Zone Equipment List or issue warning
1291 758119 : if (!state.dataHVACStandAloneERV->ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
1292 5 : state.dataHVACStandAloneERV->ZoneEquipmentListChecked = true;
1293 112 : for (Loop = 1; Loop <= state.dataHVACStandAloneERV->NumStandAloneERVs; ++Loop) {
1294 321 : if (CheckZoneEquipmentList(
1295 214 : state, state.dataHVACStandAloneERV->StandAloneERV(Loop).UnitType, state.dataHVACStandAloneERV->StandAloneERV(Loop).Name))
1296 107 : continue;
1297 0 : ShowSevereError(state,
1298 0 : "InitStandAloneERV: Unit=[" + state.dataHVACStandAloneERV->StandAloneERV(Loop).UnitType + ',' +
1299 0 : state.dataHVACStandAloneERV->StandAloneERV(Loop).Name +
1300 : "] is not on any ZoneHVAC:EquipmentList. It will not be simulated.");
1301 : }
1302 : }
1303 :
1304 758119 : if (!state.dataGlobal->SysSizingCalc && state.dataHVACStandAloneERV->MySizeFlag_InitStandAloneERV(StandAloneERVNum)) {
1305 107 : SizeStandAloneERV(state, StandAloneERVNum);
1306 107 : state.dataHVACStandAloneERV->MySizeFlag_InitStandAloneERV(StandAloneERVNum) = false;
1307 : }
1308 :
1309 : // Do the Begin Environment initializations
1310 758119 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHVACStandAloneERV->MyEnvrnFlag(StandAloneERVNum)) {
1311 742 : SupInNode = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirInletNode;
1312 742 : ExhInNode = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirInletNode;
1313 : // set the mass flow rates from the input volume flow rates
1314 742 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).MaxSupAirMassFlow =
1315 742 : state.dataEnvrn->StdRhoAir * state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow;
1316 742 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).MaxExhAirMassFlow =
1317 742 : state.dataEnvrn->StdRhoAir * state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow;
1318 742 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanMassFlowRate =
1319 742 : state.dataEnvrn->StdRhoAir * state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate;
1320 742 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanMassFlowRate =
1321 742 : state.dataEnvrn->StdRhoAir * state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanVolFlowRate;
1322 : // set the node max and min mass flow rates
1323 742 : Node(SupInNode).MassFlowRateMax = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).MaxSupAirMassFlow;
1324 742 : Node(SupInNode).MassFlowRateMin = 0.0;
1325 742 : Node(ExhInNode).MassFlowRateMax = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).MaxExhAirMassFlow;
1326 742 : Node(ExhInNode).MassFlowRateMin = 0.0;
1327 742 : state.dataHVACStandAloneERV->MyEnvrnFlag(StandAloneERVNum) = false;
1328 : // Initialize OA Controller on BeginEnvrnFlag
1329 742 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerNameDefined) {
1330 2178 : SimOAController(state,
1331 726 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerName,
1332 726 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerIndex,
1333 : FirstHVACIteration,
1334 : 0);
1335 : }
1336 : } // end one time inits
1337 :
1338 758119 : if (!state.dataGlobal->BeginEnvrnFlag) {
1339 754349 : state.dataHVACStandAloneERV->MyEnvrnFlag(StandAloneERVNum) = true;
1340 : }
1341 :
1342 : // These initializations are done every iteration
1343 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ElecUseRate = 0.0;
1344 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SensCoolingRate = 0.0;
1345 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).LatCoolingRate = 0.0;
1346 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).TotCoolingRate = 0.0;
1347 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SensHeatingRate = 0.0;
1348 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).LatHeatingRate = 0.0;
1349 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).TotHeatingRate = 0.0;
1350 758119 : SupInletNode = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirInletNode;
1351 758119 : ExhInNode = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirInletNode;
1352 :
1353 : // Set the inlet node mass flow rate
1354 758119 : if (GetCurrentScheduleValue(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SchedPtr) > 0.0) {
1355 :
1356 : // IF optional ControllerName is defined SimOAController ONLY to set economizer and Modifyairflow flags
1357 751714 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerNameDefined) {
1358 : // Initialize a flow rate for controller
1359 563259 : Node(SupInletNode).MassFlowRate = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).MaxSupAirMassFlow;
1360 1689777 : SimOAController(state,
1361 563259 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerName,
1362 563259 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerIndex,
1363 : FirstHVACIteration,
1364 : 0);
1365 : }
1366 :
1367 1503428 : if (GetCurrentScheduleValue(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanSchPtr) > 0 ||
1368 0 : (state.dataHVACGlobal->ZoneCompTurnFansOn && !state.dataHVACGlobal->ZoneCompTurnFansOff)) {
1369 751714 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerNameDefined) {
1370 1126518 : if (state.dataMixedAir->OAController(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerIndex)
1371 563259 : .HighHumCtrlActive) {
1372 202 : Node(SupInletNode).MassFlowRate = min(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanMassFlowRate,
1373 202 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).MaxSupAirMassFlow *
1374 202 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HighRHOAFlowRatio);
1375 : } else {
1376 563057 : Node(SupInletNode).MassFlowRate = min(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanMassFlowRate,
1377 563057 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).MaxSupAirMassFlow);
1378 : }
1379 : } else {
1380 188455 : Node(SupInletNode).MassFlowRate = min(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanMassFlowRate,
1381 188455 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).MaxSupAirMassFlow);
1382 : }
1383 : } else {
1384 0 : Node(SupInletNode).MassFlowRate = 0.0;
1385 : }
1386 751714 : Node(SupInletNode).MassFlowRateMaxAvail = Node(SupInletNode).MassFlowRate;
1387 751714 : Node(SupInletNode).MassFlowRateMinAvail = Node(SupInletNode).MassFlowRate;
1388 :
1389 751714 : if (GetCurrentScheduleValue(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanSchPtr) > 0) {
1390 751714 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerNameDefined) {
1391 1126518 : if (state.dataMixedAir->OAController(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerIndex)
1392 563259 : .HighHumCtrlActive) {
1393 202 : Node(ExhInNode).MassFlowRate = min(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanMassFlowRate,
1394 202 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).MaxExhAirMassFlow *
1395 202 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HighRHOAFlowRatio);
1396 : } else {
1397 563057 : Node(ExhInNode).MassFlowRate = min(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanMassFlowRate,
1398 563057 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).MaxExhAirMassFlow);
1399 : }
1400 : } else {
1401 188455 : Node(ExhInNode).MassFlowRate = min(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanMassFlowRate,
1402 188455 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).MaxExhAirMassFlow);
1403 : }
1404 : } else {
1405 0 : Node(ExhInNode).MassFlowRate = 0.0;
1406 : }
1407 751714 : Node(ExhInNode).MassFlowRateMaxAvail = Node(ExhInNode).MassFlowRate;
1408 751714 : Node(ExhInNode).MassFlowRateMinAvail = Node(ExhInNode).MassFlowRate;
1409 : } else {
1410 6405 : Node(SupInletNode).MassFlowRate = 0.0;
1411 6405 : Node(SupInletNode).MassFlowRateMaxAvail = 0.0;
1412 6405 : Node(SupInletNode).MassFlowRateMinAvail = 0.0;
1413 6405 : Node(ExhInNode).MassFlowRate = 0.0;
1414 6405 : Node(ExhInNode).MassFlowRateMaxAvail = 0.0;
1415 6405 : Node(ExhInNode).MassFlowRateMinAvail = 0.0;
1416 : }
1417 758119 : }
1418 :
1419 107 : void SizeStandAloneERV(EnergyPlusData &state, int const StandAloneERVNum)
1420 : {
1421 :
1422 : // SUBROUTINE INFORMATION:
1423 : // AUTHOR Richard Raustad
1424 : // DATE WRITTEN October 2007
1425 : // MODIFIED August 2013 Daeho Kang, add component sizing table entries
1426 : // RE-ENGINEERED na
1427 :
1428 : // PURPOSE OF THIS SUBROUTINE:
1429 : // This subroutine is for sizing Stand Alone ERV Components for which flow rates have not been
1430 : // specified in the input.
1431 :
1432 : // METHODOLOGY EMPLOYED:
1433 : // Obtains flow rates from the zone or system sizing arrays.
1434 :
1435 : // Using/Aliasing
1436 : using Fans::SetFanData;
1437 : using Fans::SimulateFanComponents;
1438 : using HeatRecovery::SetHeatExchangerData;
1439 : using ScheduleManager::GetScheduleMaxValue;
1440 :
1441 : static constexpr std::string_view RoutineName("SizeStandAloneERV: ");
1442 :
1443 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1444 214 : std::string ZoneName; // Name of zone
1445 : Real64 ZoneMult; // Zone multiplier
1446 : int PeopleNum; // Index to people object
1447 : Real64 NumberOfPeople; // Maximum number of people in zone
1448 : int PeopleSchPtr; // Pointer to people schedule
1449 : Real64 MaxPeopleSch; // maximum people schedule value
1450 : Real64 FloorArea; // Floor area of zone (m2)
1451 : bool IsAutoSize; // Indicator to autosize
1452 : Real64 SupplyAirVolFlowDes; // Autosized supply air flow for reporting
1453 : Real64 SupplyAirVolFlowUser; // Hardsized supply air flow for reporting
1454 : Real64 DesignSAFanVolFlowRateDes; // Autosized supply air fan flow for reporting
1455 : Real64 DesignSAFanVolFlowRateUser; // Hardsized supply air fan flow for reporting
1456 : Real64 ExhaustAirVolFlowDes; // Autosized exhaust air flow for reporting
1457 : Real64 ExhaustAirVolFlowUser; // Hardsized exhaust air flow for reporting
1458 :
1459 107 : IsAutoSize = false;
1460 107 : SupplyAirVolFlowDes = 0.0;
1461 107 : SupplyAirVolFlowUser = 0.0;
1462 107 : DesignSAFanVolFlowRateDes = 0.0;
1463 107 : DesignSAFanVolFlowRateUser = 0.0;
1464 107 : ExhaustAirVolFlowDes = 0.0;
1465 107 : ExhaustAirVolFlowUser = 0.0;
1466 214 : std::string CompType("ZoneHVAC:EnergyRecoveryVentilator");
1467 214 : std::string CompName(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name);
1468 107 : bool PrintFlag = true;
1469 107 : bool ErrorsFound = false;
1470 :
1471 107 : auto &ZoneEqSizing(state.dataSize->ZoneEqSizing);
1472 :
1473 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow == DataSizing::AutoSize) {
1474 0 : IsAutoSize = true;
1475 : }
1476 :
1477 107 : if (state.dataSize->CurZoneEqNum > 0) {
1478 :
1479 : // Sizing objects are not required for stand alone ERV
1480 : // CALL CheckZoneSizing('ZoneHVAC:EnergyRecoveryVentilator',StandAloneERV(StandAloneERVNum)%Name)
1481 107 : ZoneName = state.dataZoneEquip->ZoneEquipConfig(state.dataSize->CurZoneEqNum).ZoneName;
1482 107 : int ZoneNum = state.dataSize->CurZoneEqNum;
1483 107 : ZoneMult = state.dataHeatBal->Zone(ZoneNum).Multiplier * state.dataHeatBal->Zone(ZoneNum).ListMultiplier;
1484 107 : FloorArea = 0.0;
1485 107 : FloorArea = state.dataHeatBal->Zone(ZoneNum).FloorArea;
1486 107 : NumberOfPeople = 0.0;
1487 107 : MaxPeopleSch = 0.0;
1488 6990 : for (PeopleNum = 1; PeopleNum <= state.dataHeatBal->TotPeople; ++PeopleNum) {
1489 6883 : if (ZoneNum != state.dataHeatBal->People(PeopleNum).ZonePtr) continue;
1490 107 : PeopleSchPtr = state.dataHeatBal->People(PeopleNum).NumberOfPeoplePtr;
1491 107 : MaxPeopleSch = GetScheduleMaxValue(state, PeopleSchPtr);
1492 107 : NumberOfPeople = NumberOfPeople + (state.dataHeatBal->People(PeopleNum).NumberOfPeople * MaxPeopleSch);
1493 : }
1494 214 : SupplyAirVolFlowDes = FloorArea * state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).AirVolFlowPerFloorArea +
1495 107 : NumberOfPeople * state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).AirVolFlowPerOccupant;
1496 107 : SupplyAirVolFlowDes = ZoneMult * SupplyAirVolFlowDes;
1497 :
1498 107 : if (SupplyAirVolFlowDes < SmallAirVolFlow) {
1499 107 : SupplyAirVolFlowDes = 0.0;
1500 : }
1501 :
1502 : // Size ERV supply flow rate
1503 107 : Real64 TempSize = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow;
1504 214 : std::string SizingString = "Supply Air Flow Rate [m3/s]";
1505 107 : if (IsAutoSize) {
1506 0 : state.dataSize->DataConstantUsedForSizing = SupplyAirVolFlowDes;
1507 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
1508 0 : TempSize = SupplyAirVolFlowDes;
1509 0 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerNameDefined) {
1510 0 : state.dataMixedAir->OAController(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerIndex).MaxOA =
1511 0 : SupplyAirVolFlowDes * state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HighRHOAFlowRatio;
1512 0 : state.dataMixedAir->OAController(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerIndex).MinOA =
1513 : SupplyAirVolFlowDes;
1514 : }
1515 : } else {
1516 107 : state.dataSize->DataConstantUsedForSizing = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow;
1517 107 : state.dataSize->DataFractionUsedForSizing = 1.0;
1518 : }
1519 107 : if (TempSize > 0.0) {
1520 214 : SystemAirFlowSizer sizerSystemAirFlow;
1521 107 : sizerSystemAirFlow.overrideSizingString(SizingString);
1522 107 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1523 107 : TempSize = sizerSystemAirFlow.size(state, TempSize, ErrorsFound);
1524 : }
1525 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow = TempSize;
1526 : }
1527 :
1528 : // Size ERV exhaust flow rate
1529 107 : state.dataSize->DataFractionUsedForSizing = 1.0;
1530 107 : IsAutoSize = false;
1531 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow == DataSizing::AutoSize) {
1532 0 : IsAutoSize = true;
1533 : }
1534 :
1535 107 : if (state.dataSize->CurZoneEqNum > 0) {
1536 :
1537 107 : ExhaustAirVolFlowDes = SupplyAirVolFlowDes;
1538 :
1539 107 : if (ExhaustAirVolFlowDes < SmallAirVolFlow) {
1540 107 : ExhaustAirVolFlowDes = 0.0;
1541 : }
1542 :
1543 107 : if (ExhaustAirVolFlowDes > state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow) {
1544 0 : ExhaustAirVolFlowDes = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow;
1545 : }
1546 :
1547 214 : std::string SizingString = "Exhaust Air Flow Rate [m3/s]";
1548 107 : Real64 TempSize = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow;
1549 107 : if (IsAutoSize) {
1550 0 : TempSize = ExhaustAirVolFlowDes;
1551 0 : state.dataSize->DataConstantUsedForSizing = ExhaustAirVolFlowDes;
1552 : } else {
1553 107 : state.dataSize->DataConstantUsedForSizing = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow;
1554 : }
1555 107 : state.dataSize->DataFractionUsedForSizing = 1.0;
1556 107 : if (TempSize > 0.0) {
1557 214 : SystemAirFlowSizer sizerSystemAirFlow;
1558 107 : sizerSystemAirFlow.overrideSizingString(SizingString);
1559 107 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1560 107 : TempSize = sizerSystemAirFlow.size(state, TempSize, ErrorsFound);
1561 : }
1562 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirVolFlow = TempSize;
1563 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignEAFanVolFlowRate =
1564 107 : TempSize * state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HighRHOAFlowRatio;
1565 : }
1566 :
1567 : // Set Zone equipment sizing data for autosizing the fans and heat exchanger
1568 214 : ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow *
1569 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HighRHOAFlowRatio;
1570 107 : ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow;
1571 107 : ZoneEqSizing(state.dataSize->CurZoneEqNum).SystemAirFlow = true;
1572 107 : ZoneEqSizing(state.dataSize->CurZoneEqNum).DesignSizeFromParent = true;
1573 :
1574 : // Check supply fan flow rate or set flow rate if autosized in fan object
1575 107 : IsAutoSize = false;
1576 107 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate == DataSizing::AutoSize) {
1577 102 : IsAutoSize = true;
1578 : }
1579 214 : DesignSAFanVolFlowRateDes = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow *
1580 107 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HighRHOAFlowRatio;
1581 107 : if (IsAutoSize) {
1582 102 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate = DesignSAFanVolFlowRateDes;
1583 : } else {
1584 5 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate > 0.0 && DesignSAFanVolFlowRateDes > 0.0) {
1585 5 : DesignSAFanVolFlowRateUser = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).DesignSAFanVolFlowRate;
1586 5 : if (state.dataGlobal->DisplayExtraWarnings) {
1587 0 : if ((std::abs(DesignSAFanVolFlowRateDes - DesignSAFanVolFlowRateUser) / DesignSAFanVolFlowRateUser) >
1588 0 : state.dataSize->AutoVsHardSizingThreshold) {
1589 0 : ShowMessage(state,
1590 0 : "SizeStandAloneERV: Potential issue with equipment sizing for ZoneHVAC:EnergyRecoveryVentilator " +
1591 0 : cFanTypes(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanType_Num) + ' ' +
1592 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName);
1593 0 : ShowContinueError(state, format("User-Specified Supply Fan Maximum Flow Rate of {:.5R} [m3/s]", DesignSAFanVolFlowRateUser));
1594 0 : ShowContinueError(state, format("differs from the ERV Supply Air Flow Rate of {:.5R} [m3/s]", DesignSAFanVolFlowRateDes));
1595 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1596 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1597 : }
1598 : }
1599 : }
1600 : }
1601 :
1602 : // simulate the fan to size using the flow rate specified above
1603 : // (i.e., ZoneEqSizing( CurZoneEqNum ).AirVolFlow = StandAloneERV( StandAloneERVNum ).SupplyAirVolFlow * StandAloneERV( StandAloneERVNum
1604 : // ).HighRHOAFlowRatio;)
1605 107 : if (!(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanType_Num == DataHVACGlobals::FanType_SystemModelObject)) {
1606 312 : SimulateFanComponents(state,
1607 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName,
1608 : true,
1609 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanIndex);
1610 : } else {
1611 9 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanIndex]->simulate(
1612 6 : state, _, state.dataHVACGlobal->ZoneCompTurnFansOn, state.dataHVACGlobal->ZoneCompTurnFansOff, _);
1613 : }
1614 107 : if (!(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanType_Num == DataHVACGlobals::FanType_SystemModelObject)) {
1615 312 : SimulateFanComponents(state,
1616 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName,
1617 : true,
1618 104 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanIndex);
1619 : } else {
1620 9 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanIndex]->simulate(
1621 6 : state, _, state.dataHVACGlobal->ZoneCompTurnFansOn, state.dataHVACGlobal->ZoneCompTurnFansOff, _);
1622 : }
1623 :
1624 : // now reset the ZoneEqSizing variable to NOT use the multiplier for HighRHOAFlowRatio for sizing HXs
1625 107 : ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirVolFlow;
1626 107 : }
1627 :
1628 758119 : void CalcStandAloneERV(EnergyPlusData &state,
1629 : int const StandAloneERVNum, // Unit index in ERV data structure
1630 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
1631 : Real64 &SensLoadMet, // sensible zone load met by unit (W)
1632 : Real64 &LatentMassLoadMet // latent zone load met by unit (kg/s), dehumid = negative
1633 : )
1634 : {
1635 :
1636 : // SUBROUTINE INFORMATION:
1637 : // AUTHOR Richard Raustad, FSEC
1638 : // DATE WRITTEN June 2003
1639 : // MODIFIED Don Shirey, Aug 2009 (LatentMassLoadMet)
1640 : // July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
1641 : // RE-ENGINEERED na
1642 :
1643 : // PURPOSE OF THIS SUBROUTINE:
1644 : // Simulate the components making up the Stand Alone ERV unit.
1645 :
1646 : // METHODOLOGY EMPLOYED:
1647 : // Simulates the unit components sequentially in the air flow direction.
1648 :
1649 : // Using/Aliasing
1650 : using Fans::SimulateFanComponents;
1651 : using HeatRecovery::SimHeatRecovery;
1652 :
1653 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1654 : int SupOutletNode; // unit supply air outlet node
1655 : int ExhaustInletNode; // unit exhaust air inlet node
1656 : int SupInletNode; // unit supply air inlet node
1657 : Real64 AirMassFlow; // total mass flow through supply side of the ERV (supply air outlet node)
1658 : // (so enthalpy routines work without error)
1659 : Real64 TotLoadMet; // total zone load met by unit (W)
1660 : Real64 LatLoadMet; // latent zone load met by unit (W)
1661 : bool HXUnitOn; // flag to operate heat exchanger heat recovery
1662 : bool EconomizerFlag; // economizer signal from OA controller
1663 : bool HighHumCtrlFlag; // high humditiy control signal from OA controller
1664 : Real64 TotalExhaustMassFlow; // total exhaust air mass flow rate in controlled zone
1665 : Real64 TotalSupplyMassFlow; // total supply air mass flow rate in controlled zone
1666 :
1667 758119 : SupInletNode = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirInletNode;
1668 758119 : SupOutletNode = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirOutletNode;
1669 758119 : ExhaustInletNode = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirInletNode;
1670 :
1671 : // Stand alone ERV's HX is ON by default
1672 758119 : HXUnitOn = true;
1673 :
1674 : // Get stand alone ERV's controller economizer and high humidity control status
1675 758119 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerNameDefined) {
1676 567529 : EconomizerFlag = state.dataMixedAir->OAController(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerIndex).EconoActive;
1677 567529 : HighHumCtrlFlag =
1678 567529 : state.dataMixedAir->OAController(state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ControllerIndex).HighHumCtrlActive;
1679 : } else {
1680 190590 : EconomizerFlag = false;
1681 190590 : HighHumCtrlFlag = false;
1682 : }
1683 :
1684 2274357 : SimHeatRecovery(state,
1685 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerName,
1686 : FirstHVACIteration,
1687 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).HeatExchangerIndex,
1688 : ContFanCycCoil,
1689 : _,
1690 : HXUnitOn,
1691 : _,
1692 : _,
1693 : EconomizerFlag,
1694 : HighHumCtrlFlag);
1695 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ElecUseRate = state.dataHVACGlobal->AirToAirHXElecPower;
1696 :
1697 758119 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
1698 3706385 : SimulateFanComponents(state,
1699 741277 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanName,
1700 : FirstHVACIteration,
1701 741277 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanIndex,
1702 : _,
1703 741277 : state.dataHVACGlobal->ZoneCompTurnFansOn,
1704 741277 : state.dataHVACGlobal->ZoneCompTurnFansOff);
1705 741277 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ElecUseRate +=
1706 741277 : Fans::GetFanPower(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanIndex);
1707 : } else {
1708 50526 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanIndex]->simulate(
1709 33684 : state, _, state.dataHVACGlobal->ZoneCompTurnFansOn, state.dataHVACGlobal->ZoneCompTurnFansOff, _);
1710 16842 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ElecUseRate +=
1711 16842 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirFanIndex]->fanPower();
1712 : }
1713 :
1714 758119 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
1715 2223831 : SimulateFanComponents(state,
1716 741277 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanName,
1717 : FirstHVACIteration,
1718 741277 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanIndex); // why no Turn on off flags here?
1719 741277 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ElecUseRate +=
1720 741277 : Fans::GetFanPower(state, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanIndex);
1721 : } else {
1722 50526 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanIndex]->simulate(
1723 33684 : state, _, state.dataHVACGlobal->ZoneCompTurnFansOn, state.dataHVACGlobal->ZoneCompTurnFansOff, _);
1724 16842 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ElecUseRate +=
1725 16842 : state.dataHVACFan->fanObjs[state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirFanIndex]->fanPower();
1726 : }
1727 :
1728 758119 : AirMassFlow = state.dataLoopNodes->Node(SupOutletNode).MassFlowRate;
1729 3032476 : CalcZoneSensibleLatentOutput(AirMassFlow,
1730 758119 : state.dataLoopNodes->Node(SupOutletNode).Temp,
1731 758119 : state.dataLoopNodes->Node(SupOutletNode).HumRat,
1732 758119 : state.dataLoopNodes->Node(ExhaustInletNode).Temp,
1733 758119 : state.dataLoopNodes->Node(ExhaustInletNode).HumRat,
1734 : SensLoadMet,
1735 : LatLoadMet,
1736 : TotLoadMet);
1737 1516238 : LatentMassLoadMet = AirMassFlow * (state.dataLoopNodes->Node(SupOutletNode).HumRat -
1738 758119 : state.dataLoopNodes->Node(ExhaustInletNode).HumRat); // kg/s, dehumidification = negative
1739 :
1740 758119 : if (SensLoadMet < 0.0) {
1741 501937 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SensCoolingRate = std::abs(SensLoadMet);
1742 501937 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SensHeatingRate = 0.0;
1743 : } else {
1744 256182 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SensCoolingRate = 0.0;
1745 256182 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SensHeatingRate = SensLoadMet;
1746 : }
1747 758119 : if (TotLoadMet < 0.0) {
1748 617749 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).TotCoolingRate = std::abs(TotLoadMet);
1749 617749 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).TotHeatingRate = 0.0;
1750 : } else {
1751 140370 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).TotCoolingRate = 0.0;
1752 140370 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).TotHeatingRate = TotLoadMet;
1753 : }
1754 758119 : if (LatLoadMet < 0.0) {
1755 740487 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).LatCoolingRate = std::abs(LatLoadMet);
1756 740487 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).LatHeatingRate = 0.0;
1757 : } else {
1758 17632 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).LatCoolingRate = 0.0;
1759 17632 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).LatHeatingRate = LatLoadMet;
1760 : }
1761 :
1762 : // Provide a one time message when exhaust flow rate is greater than supply flow rate
1763 758119 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).FlowError && !state.dataGlobal->WarmupFlag) {
1764 89765 : TotalExhaustMassFlow = state.dataLoopNodes->Node(ExhaustInletNode).MassFlowRate;
1765 89765 : TotalSupplyMassFlow = state.dataLoopNodes->Node(SupInletNode).MassFlowRate;
1766 89765 : if (TotalExhaustMassFlow > TotalSupplyMassFlow && !state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) {
1767 0 : ShowWarningError(state,
1768 0 : "For " + state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).UnitType + " \"" +
1769 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).Name + "\" there is unbalanced exhaust air flow.");
1770 0 : ShowContinueError(state, format("... The exhaust air mass flow rate = {:.6R}", state.dataLoopNodes->Node(ExhaustInletNode).MassFlowRate));
1771 0 : ShowContinueError(state, format("... The supply air mass flow rate = {:.6R}", state.dataLoopNodes->Node(SupInletNode).MassFlowRate));
1772 0 : ShowContinueErrorTimeStamp(state, "");
1773 0 : ShowContinueError(state, "... Unless there is balancing infiltration / ventilation air flow, this will result in");
1774 0 : ShowContinueError(state, "... load due to induced outside air being neglected in the simulation.");
1775 0 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).FlowError = false;
1776 : }
1777 : }
1778 758119 : }
1779 :
1780 758119 : void ReportStandAloneERV(EnergyPlusData &state, int const StandAloneERVNum) // number of the current Stand Alone ERV being simulated
1781 : {
1782 :
1783 : // SUBROUTINE INFORMATION:
1784 : // AUTHOR Richard Raustad, FSEC
1785 : // DATE WRITTEN June 2003
1786 : // MODIFIED na
1787 : // RE-ENGINEERED na
1788 :
1789 : // PURPOSE OF THIS SUBROUTINE:
1790 : // Fill remaining report variables
1791 :
1792 : // METHODOLOGY EMPLOYED:
1793 : // na
1794 :
1795 : // REFERENCES:
1796 : // na
1797 :
1798 : // USE STATEMENTS:
1799 : // na
1800 :
1801 : // Locals
1802 : // SUBROUTINE ARGUMENT DEFINITIONS:
1803 :
1804 : // SUBROUTINE PARAMETER DEFINITIONS:
1805 : // na
1806 :
1807 : // INTERFACE BLOCK SPECIFICATIONS
1808 : // na
1809 :
1810 : // DERIVED TYPE DEFINITIONS
1811 : // na
1812 :
1813 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1814 : Real64 ReportingConstant;
1815 :
1816 758119 : ReportingConstant = state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
1817 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ElecUseEnergy =
1818 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ElecUseRate * ReportingConstant;
1819 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SensCoolingEnergy =
1820 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SensCoolingRate * ReportingConstant;
1821 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).LatCoolingEnergy =
1822 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).LatCoolingRate * ReportingConstant;
1823 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).TotCoolingEnergy =
1824 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).TotCoolingRate * ReportingConstant;
1825 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SensHeatingEnergy =
1826 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SensHeatingRate * ReportingConstant;
1827 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).LatHeatingEnergy =
1828 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).LatHeatingRate * ReportingConstant;
1829 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).TotHeatingEnergy =
1830 758119 : state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).TotHeatingRate * ReportingConstant;
1831 :
1832 758119 : if (state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).FirstPass) { // reset sizing flags so other zone equipment can size normally
1833 211 : if (!state.dataGlobal->SysSizingCalc) {
1834 214 : DataSizing::resetHVACSizingGlobals(
1835 214 : state, state.dataSize->CurZoneEqNum, 0, state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).FirstPass);
1836 : }
1837 : }
1838 758119 : }
1839 :
1840 : // End of Reporting subroutines for the Module
1841 :
1842 : // Utility subroutines/functions for the HeatingCoil Module
1843 :
1844 0 : Real64 GetSupplyAirFlowRate(EnergyPlusData &state,
1845 : std::string const &ERVType, // must be "ZoneHVAC:EnergyRecoveryVentilator"
1846 : std::string const &ERVCtrlName, // must match a controller name in the ERV data structure
1847 : bool &ErrorsFound // set to true if problem
1848 : )
1849 : {
1850 :
1851 : // FUNCTION INFORMATION:
1852 : // AUTHOR Linda Lawrie
1853 : // DATE WRITTEN October 2006
1854 : // MODIFIED na
1855 : // RE-ENGINEERED na
1856 :
1857 : // PURPOSE OF THIS FUNCTION:
1858 : // This function looks up the ERVCtrlName in the ERV Stand Alone list and returns the
1859 : // Supply Air Flow rate, if found. If incorrect name is given, ErrorsFound is returned as true
1860 : // and supply air flow rate as negative.
1861 :
1862 : // Return value
1863 : Real64 AirFlowRate; // returned supply air flow rate of the ERV unit
1864 :
1865 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1866 : int WhichERV;
1867 :
1868 0 : if (state.dataHVACStandAloneERV->GetERVInputFlag) {
1869 0 : GetStandAloneERV(state);
1870 0 : state.dataHVACStandAloneERV->GetERVInputFlag = false;
1871 : }
1872 :
1873 0 : if (UtilityRoutines::SameString(ERVType, "ZoneHVAC:EnergyRecoveryVentilator")) {
1874 0 : WhichERV = UtilityRoutines::FindItem(ERVCtrlName, state.dataHVACStandAloneERV->StandAloneERV, &StandAloneERVData::ControllerName);
1875 0 : if (WhichERV != 0) {
1876 0 : AirFlowRate = state.dataHVACStandAloneERV->StandAloneERV(WhichERV).SupplyAirVolFlow;
1877 : }
1878 : } else {
1879 0 : WhichERV = 0;
1880 : }
1881 :
1882 0 : if (WhichERV == 0) {
1883 0 : ShowSevereError(state, "Could not find ZoneHVAC:EnergyRecoveryVentilator with Controller Name=\"" + ERVCtrlName + "\"");
1884 0 : ErrorsFound = true;
1885 0 : AirFlowRate = -1000.0;
1886 : }
1887 :
1888 0 : return AirFlowRate;
1889 : }
1890 :
1891 0 : int GetSupplyAirInletNode(EnergyPlusData &state,
1892 : std::string const &ERVType, // must be "ZoneHVAC:EnergyRecoveryVentilator"
1893 : std::string const &ERVCtrlName, // must match a controller name in the ERV data structure
1894 : bool &ErrorsFound // set to true if problem
1895 : )
1896 : {
1897 :
1898 : // FUNCTION INFORMATION:
1899 : // AUTHOR Linda Lawrie
1900 : // DATE WRITTEN October 2006
1901 : // MODIFIED na
1902 : // RE-ENGINEERED na
1903 :
1904 : // PURPOSE OF THIS FUNCTION:
1905 : // This function looks up the ERVCtrlName in the ERV Stand Alone list and returns the
1906 : // Supply Air Inlet Node Number, if found. If incorrect name is given, ErrorsFound is returned as true
1907 : // and Supply Air Inlet Node Number as zero.
1908 :
1909 : // Return value
1910 0 : int AirInletNode(0); // returned air inlet node number of the ERV unit
1911 :
1912 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1913 : int WhichERV;
1914 :
1915 0 : if (state.dataHVACStandAloneERV->GetERVInputFlag) {
1916 0 : GetStandAloneERV(state);
1917 0 : state.dataHVACStandAloneERV->GetERVInputFlag = false;
1918 : }
1919 :
1920 0 : if (UtilityRoutines::SameString(ERVType, "ZoneHVAC:EnergyRecoveryVentilator")) {
1921 0 : WhichERV = UtilityRoutines::FindItem(ERVCtrlName, state.dataHVACStandAloneERV->StandAloneERV, &StandAloneERVData::ControllerName);
1922 0 : if (WhichERV != 0) {
1923 0 : AirInletNode = state.dataHVACStandAloneERV->StandAloneERV(WhichERV).SupplyAirInletNode;
1924 : }
1925 : } else {
1926 0 : WhichERV = 0;
1927 : }
1928 :
1929 0 : if (WhichERV == 0) {
1930 0 : ShowSevereError(state, "Could not find ZoneHVAC:EnergyRecoveryVentilator with Controller Name=\"" + ERVCtrlName + "\"");
1931 0 : ErrorsFound = true;
1932 0 : AirInletNode = 0;
1933 : }
1934 :
1935 0 : return AirInletNode;
1936 : }
1937 :
1938 0 : int GetExhaustAirInletNode(EnergyPlusData &state,
1939 : std::string const &ERVType, // must be "ZoneHVAC:EnergyRecoveryVentilator"
1940 : std::string const &ERVCtrlName, // must match a controller name in the ERV data structure
1941 : bool &ErrorsFound // set to true if problem
1942 : )
1943 : {
1944 :
1945 : // FUNCTION INFORMATION:
1946 : // AUTHOR Linda Lawrie
1947 : // DATE WRITTEN October 2006
1948 : // MODIFIED na
1949 : // RE-ENGINEERED na
1950 :
1951 : // PURPOSE OF THIS FUNCTION:
1952 : // This function looks up the ERVCtrlName in the ERV Stand Alone list and returns the
1953 : // Exhaust Air Inlet Node Number, if found. If incorrect name is given, ErrorsFound is returned as true
1954 : // and Exhaust Air Inlet Node Number as zero.
1955 :
1956 : // Return value
1957 0 : int AirInletNode(0); // returned air inlet node number of the ERV unit
1958 :
1959 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1960 : int WhichERV;
1961 :
1962 0 : if (state.dataHVACStandAloneERV->GetERVInputFlag) {
1963 0 : GetStandAloneERV(state);
1964 0 : state.dataHVACStandAloneERV->GetERVInputFlag = false;
1965 : }
1966 :
1967 0 : if (UtilityRoutines::SameString(ERVType, "ZoneHVAC:EnergyRecoveryVentilator")) {
1968 0 : WhichERV = UtilityRoutines::FindItem(ERVCtrlName, state.dataHVACStandAloneERV->StandAloneERV, &StandAloneERVData::ControllerName);
1969 0 : if (WhichERV != 0) {
1970 0 : AirInletNode = state.dataHVACStandAloneERV->StandAloneERV(WhichERV).ExhaustAirInletNode;
1971 : }
1972 : } else {
1973 0 : WhichERV = 0;
1974 : }
1975 :
1976 0 : if (WhichERV == 0) {
1977 0 : ShowSevereError(state, "Could not find ZoneHVAC:EnergyRecoveryVentilator with Controller Name=\"" + ERVCtrlName + "\"");
1978 0 : ErrorsFound = true;
1979 0 : AirInletNode = 0;
1980 : }
1981 :
1982 0 : return AirInletNode;
1983 : }
1984 :
1985 21438 : int GetStandAloneERVOutAirNode(EnergyPlusData &state, int const StandAloneERVNum)
1986 : {
1987 : // FUNCTION INFORMATION:
1988 : // AUTHOR B Griffith
1989 : // DATE WRITTEN Dec 2006
1990 : // MODIFIED na
1991 : // RE-ENGINEERED na
1992 :
1993 : // PURPOSE OF THIS FUNCTION:
1994 : // lookup function for OA inlet node for ventilation rate reporting
1995 :
1996 : // METHODOLOGY EMPLOYED:
1997 : // <description>
1998 :
1999 : // REFERENCES:
2000 : // na
2001 :
2002 : // USE STATEMENTS:
2003 : // na
2004 :
2005 : // Return value
2006 : int GetStandAloneERVOutAirNode;
2007 :
2008 : // Locals
2009 : // FUNCTION ARGUMENT DEFINITIONS:
2010 :
2011 : // FUNCTION PARAMETER DEFINITIONS:
2012 : // na
2013 :
2014 : // INTERFACE BLOCK SPECIFICATIONS:
2015 : // na
2016 :
2017 : // DERIVED TYPE DEFINITIONS:
2018 : // na
2019 :
2020 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2021 : // na
2022 21438 : if (state.dataHVACStandAloneERV->GetERVInputFlag) {
2023 0 : GetStandAloneERV(state);
2024 0 : state.dataHVACStandAloneERV->GetERVInputFlag = false;
2025 : }
2026 :
2027 21438 : GetStandAloneERVOutAirNode = 0;
2028 21438 : if (StandAloneERVNum > 0 && StandAloneERVNum <= state.dataHVACStandAloneERV->NumStandAloneERVs) {
2029 21438 : GetStandAloneERVOutAirNode = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirInletNode;
2030 : }
2031 :
2032 21438 : return GetStandAloneERVOutAirNode;
2033 : }
2034 :
2035 21438 : int GetStandAloneERVZoneInletAirNode(EnergyPlusData &state, int const StandAloneERVNum)
2036 : {
2037 : // FUNCTION INFORMATION:
2038 : // AUTHOR B Griffith
2039 : // DATE WRITTEN Dec 2006
2040 : // MODIFIED na
2041 : // RE-ENGINEERED na
2042 :
2043 : // PURPOSE OF THIS FUNCTION:
2044 : // lookup function for OA inlet node for ventilation rate reporting
2045 :
2046 : // METHODOLOGY EMPLOYED:
2047 : // <description>
2048 :
2049 : // REFERENCES:
2050 : // na
2051 :
2052 : // USE STATEMENTS:
2053 : // na
2054 :
2055 : // Return value
2056 : int GetStandAloneERVZoneInletAirNode;
2057 :
2058 : // Locals
2059 : // FUNCTION ARGUMENT DEFINITIONS:
2060 :
2061 : // FUNCTION PARAMETER DEFINITIONS:
2062 : // na
2063 :
2064 : // INTERFACE BLOCK SPECIFICATIONS:
2065 : // na
2066 :
2067 : // DERIVED TYPE DEFINITIONS:
2068 : // na
2069 :
2070 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2071 : // na
2072 21438 : if (state.dataHVACStandAloneERV->GetERVInputFlag) {
2073 0 : GetStandAloneERV(state);
2074 0 : state.dataHVACStandAloneERV->GetERVInputFlag = false;
2075 : }
2076 :
2077 21438 : GetStandAloneERVZoneInletAirNode = 0;
2078 21438 : if (StandAloneERVNum > 0 && StandAloneERVNum <= state.dataHVACStandAloneERV->NumStandAloneERVs) {
2079 21438 : GetStandAloneERVZoneInletAirNode = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).SupplyAirOutletNode;
2080 : }
2081 :
2082 21438 : return GetStandAloneERVZoneInletAirNode;
2083 : }
2084 :
2085 21438 : int GetStandAloneERVReturnAirNode(EnergyPlusData &state, int const StandAloneERVNum)
2086 : {
2087 : // FUNCTION INFORMATION:
2088 : // AUTHOR B Griffith
2089 : // DATE WRITTEN Dec 2006
2090 : // MODIFIED na
2091 : // RE-ENGINEERED na
2092 :
2093 : // PURPOSE OF THIS FUNCTION:
2094 : // lookup function for OA inlet node for ventilation rate reporting
2095 :
2096 : // METHODOLOGY EMPLOYED:
2097 : // <description>
2098 :
2099 : // REFERENCES:
2100 : // na
2101 :
2102 : // USE STATEMENTS:
2103 : // na
2104 :
2105 : // Return value
2106 : int GetStandAloneERVReturnAirNode;
2107 :
2108 : // Locals
2109 : // FUNCTION ARGUMENT DEFINITIONS:
2110 :
2111 : // FUNCTION PARAMETER DEFINITIONS:
2112 : // na
2113 :
2114 : // INTERFACE BLOCK SPECIFICATIONS:
2115 : // na
2116 :
2117 : // DERIVED TYPE DEFINITIONS:
2118 : // na
2119 :
2120 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2121 : // na
2122 21438 : if (state.dataHVACStandAloneERV->GetERVInputFlag) {
2123 0 : GetStandAloneERV(state);
2124 0 : state.dataHVACStandAloneERV->GetERVInputFlag = false;
2125 : }
2126 :
2127 21438 : GetStandAloneERVReturnAirNode = 0;
2128 21438 : if (StandAloneERVNum > 0 && StandAloneERVNum <= state.dataHVACStandAloneERV->NumStandAloneERVs) {
2129 21438 : GetStandAloneERVReturnAirNode = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVNum).ExhaustAirInletNode;
2130 : }
2131 :
2132 21438 : return GetStandAloneERVReturnAirNode;
2133 : }
2134 :
2135 16 : bool GetStandAloneERVNodeNumber(EnergyPlusData &state, int const NodeNumber)
2136 : {
2137 : // PURPOSE OF THIS FUNCTION:
2138 : // Check if a node is used by a stand alone ERV
2139 : // and can be excluded from an airflow network.
2140 :
2141 : // Return value
2142 : bool StandSloneERVAFNException;
2143 :
2144 : int StandAloneERVIndex;
2145 :
2146 16 : if (state.dataHVACStandAloneERV->GetERVInputFlag) {
2147 0 : GetStandAloneERV(state);
2148 0 : state.dataHVACStandAloneERV->GetERVInputFlag = false;
2149 : }
2150 :
2151 16 : StandSloneERVAFNException = false;
2152 :
2153 26 : for (StandAloneERVIndex = 1; StandAloneERVIndex <= state.dataHVACStandAloneERV->NumStandAloneERVs; ++StandAloneERVIndex) {
2154 :
2155 26 : auto StandAloneERV = state.dataHVACStandAloneERV->StandAloneERV(StandAloneERVIndex);
2156 16 : bool ErrorsFound{false};
2157 16 : int SupplyFanInletNodeIndex(0);
2158 16 : int SupplyFanOutletNodeIndex(0);
2159 16 : int ExhaustFanInletNodeIndex(0);
2160 16 : int ExhaustFanOutletNodeIndex(0);
2161 : Real64 SupplyFanAirFlow;
2162 : Real64 ExhaustFanAirFlow;
2163 :
2164 : // Get supply air fan inlet and outlet node index and air flow
2165 : // ZoneHVAC:EnergyRecoveryVentilator only accepts Fan:SystemModel or Fan:OnOff
2166 16 : if (StandAloneERV.SupplyAirFanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
2167 : // Fan:SystemModel
2168 0 : SupplyFanInletNodeIndex = state.dataHVACFan->fanObjs[StandAloneERV.SupplyAirFanIndex]->inletNodeNum;
2169 0 : SupplyFanOutletNodeIndex = state.dataHVACFan->fanObjs[StandAloneERV.SupplyAirFanIndex]->outletNodeNum;
2170 0 : SupplyFanAirFlow = state.dataHVACFan->fanObjs[StandAloneERV.SupplyAirFanIndex]->designAirVolFlowRate;
2171 : } else {
2172 : // Fan:OnOff
2173 16 : SupplyFanInletNodeIndex = Fans::GetFanInletNode(state, "Fan:OnOff", StandAloneERV.SupplyAirFanName, ErrorsFound);
2174 16 : SupplyFanOutletNodeIndex = Fans::GetFanOutletNode(state, "Fan:OnOff", StandAloneERV.SupplyAirFanName, ErrorsFound);
2175 16 : GetFanVolFlow(state, StandAloneERV.SupplyAirFanIndex, SupplyFanAirFlow);
2176 16 : if (ErrorsFound) {
2177 0 : ShowWarningError(state, "Could not retrieve fan outlet node for this unit=\"" + StandAloneERV.Name + "\".");
2178 0 : ErrorsFound = true;
2179 : }
2180 : }
2181 : // Get exhaust air fan inlet and outlet node index and air flow
2182 16 : if (StandAloneERV.ExhaustAirFanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
2183 : // Fan:SystemModel
2184 0 : ExhaustFanInletNodeIndex = state.dataHVACFan->fanObjs[StandAloneERV.ExhaustAirFanIndex]->inletNodeNum;
2185 0 : ExhaustFanOutletNodeIndex = state.dataHVACFan->fanObjs[StandAloneERV.ExhaustAirFanIndex]->outletNodeNum;
2186 0 : ExhaustFanAirFlow = state.dataHVACFan->fanObjs[StandAloneERV.ExhaustAirFanIndex]->designAirVolFlowRate;
2187 : } else {
2188 : // Fan:OnOff
2189 16 : ExhaustFanInletNodeIndex = Fans::GetFanInletNode(state, "Fan:OnOff", StandAloneERV.ExhaustAirFanName, ErrorsFound);
2190 16 : ExhaustFanOutletNodeIndex = Fans::GetFanOutletNode(state, "Fan:OnOff", StandAloneERV.ExhaustAirFanName, ErrorsFound);
2191 16 : GetFanVolFlow(state, StandAloneERV.ExhaustAirFanIndex, ExhaustFanAirFlow);
2192 16 : if (ErrorsFound) {
2193 0 : ShowWarningError(state, "Could not retrieve fan outlet node for this unit=\"" + StandAloneERV.Name + "\".");
2194 0 : ErrorsFound = true;
2195 : }
2196 : }
2197 :
2198 : // If a standalone ERV's airflow is unbalanced it shouldn't be model along with an AFN
2199 32 : if (std::abs(SupplyFanAirFlow - ExhaustFanAirFlow) >= 1E-20 ||
2200 16 : std::abs(StandAloneERV.DesignSAFanVolFlowRate - StandAloneERV.DesignEAFanVolFlowRate) >= 1E-20) {
2201 0 : break;
2202 : }
2203 :
2204 : // Supply air fan nodes
2205 16 : if (NodeNumber == SupplyFanInletNodeIndex || NodeNumber == SupplyFanOutletNodeIndex || NodeNumber == ExhaustFanInletNodeIndex ||
2206 : NodeNumber == ExhaustFanOutletNodeIndex) {
2207 4 : StandSloneERVAFNException = true;
2208 4 : break;
2209 : }
2210 :
2211 : // Supply air inlet node
2212 12 : if (NodeNumber == StandAloneERV.SupplyAirInletNode) {
2213 2 : StandSloneERVAFNException = true;
2214 2 : break;
2215 : }
2216 : }
2217 :
2218 16 : return StandSloneERVAFNException;
2219 : }
2220 :
2221 2313 : } // namespace EnergyPlus::HVACStandAloneERV
|