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 <cassert>
50 : #include <cmath>
51 :
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Array.functions.hh>
54 : #include <ObjexxFCL/Fmath.hh>
55 : #include <ObjexxFCL/member.functions.hh>
56 :
57 : // EnergyPlus Headers
58 : #include <EnergyPlus/BranchNodeConnections.hh>
59 : #include <EnergyPlus/Construction.hh>
60 : #include <EnergyPlus/ConvectionCoefficients.hh>
61 : #include <EnergyPlus/Data/EnergyPlusData.hh>
62 : #include <EnergyPlus/DataEnvironment.hh>
63 : #include <EnergyPlus/DataHVACGlobals.hh>
64 : #include <EnergyPlus/DataHeatBalSurface.hh>
65 : #include <EnergyPlus/DataHeatBalance.hh>
66 : #include <EnergyPlus/DataIPShortCuts.hh>
67 : #include <EnergyPlus/DataLoopNode.hh>
68 : #include <EnergyPlus/DataSurfaces.hh>
69 : #include <EnergyPlus/EMSManager.hh>
70 : #include <EnergyPlus/General.hh>
71 : #include <EnergyPlus/GeneralRoutines.hh>
72 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
73 : #include <EnergyPlus/Material.hh>
74 : #include <EnergyPlus/NodeInputManager.hh>
75 : #include <EnergyPlus/OutputProcessor.hh>
76 : #include <EnergyPlus/Psychrometrics.hh>
77 : #include <EnergyPlus/ScheduleManager.hh>
78 : #include <EnergyPlus/TranspiredCollector.hh>
79 : #include <EnergyPlus/UtilityRoutines.hh>
80 :
81 : namespace EnergyPlus {
82 :
83 : namespace TranspiredCollector {
84 :
85 : // Module containing routines and data dealing with the Transpired Collectors
86 :
87 : // MODULE INFORMATION:
88 : // AUTHOR B.T. Griffith
89 : // DATE WRITTEN November 2004
90 : // MODIFIED na
91 : // RE-ENGINEERED na
92 :
93 : // PURPOSE OF THIS MODULE:
94 : // Ecapsulates data and routines for simulating unglazed transpired solar collectors (UTSC)
95 : // as a component on the HVAC air system.
96 :
97 : // METHODOLOGY EMPLOYED:
98 : // Two modes, passive and active. Active is when air is purposely drawn through collector.
99 : // Passive is when air exchanges are driven by Natural Ventilation rather than outside air system
100 :
101 : // REFERENCES:
102 : // Heat Exchange effectiveness relations:
103 : // Kutscher, C.F. 1994. Heat exchange effectiveness and pressure drop for air flow through perforated plates
104 : // with and without crosswind. Journal of Heat Transfer. May 1994, Vol. 116, p. 391.
105 : // American Society of Mechanical Engineers.
106 : // Van Decker, G.W.E., K.G.T. Hollands, and A.P. Brunger. 2001. Heat-exchange relations for unglazed transpired
107 : // solar collectors with circular holes on a square of triangular pitch. Solar Energy. Vol. 71, No. 1. pp 33-45, 2001.
108 : // .
109 :
110 : // OTHER NOTES:
111 : // EnergyPlus implementation is unique and adds new modeling not described in Literature.
112 : // See EngineeringReference for details
113 :
114 : // Using/Aliasing
115 : using DataVectorTypes::Vector;
116 :
117 : int constexpr Layout_Square = 1;
118 : int constexpr Layout_Triangle = 2;
119 : int constexpr Correlation_Kutscher1994 = 1;
120 : int constexpr Correlation_VanDeckerHollandsBrunger2001 = 2;
121 :
122 40675 : void SimTranspiredCollector(EnergyPlusData &state,
123 : std::string_view CompName, // component name
124 : int &CompIndex // component index (to reduce string compares during simulation)
125 : )
126 : {
127 :
128 : // SUBROUTINE INFORMATION:
129 : // AUTHOR B.T. Griffith
130 : // DATE WRITTEN November 2004
131 : // MODIFIED na
132 : // RE-ENGINEERED na
133 :
134 : // PURPOSE OF THIS SUBROUTINE:
135 : // Manage simulation of Transpired Collectors
136 :
137 : // METHODOLOGY EMPLOYED:
138 : // Setup to avoid string comparisons after first call
139 :
140 : // Using/Aliasing
141 : using DataHVACGlobals::TempControlTol;
142 :
143 : using ScheduleManager::GetCurrentScheduleValue;
144 :
145 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
146 :
147 40675 : int UTSCNum(0); // local number index for UTSC
148 :
149 40675 : if (state.dataTranspiredCollector->GetInputFlag) {
150 0 : GetTranspiredCollectorInput(state);
151 0 : state.dataTranspiredCollector->GetInputFlag = false;
152 : }
153 :
154 : // Find the correct transpired collector with the Component name and/or index
155 40675 : if (CompIndex == 0) {
156 9 : UTSCNum = UtilityRoutines::FindItemInList(CompName, state.dataTranspiredCollector->UTSC);
157 9 : if (UTSCNum == 0) {
158 0 : ShowFatalError(state, "Transpired Collector not found=" + std::string{CompName});
159 : }
160 9 : CompIndex = UTSCNum;
161 : } else {
162 40666 : UTSCNum = CompIndex;
163 40666 : if (UTSCNum > state.dataTranspiredCollector->NumUTSC || UTSCNum < 1) {
164 0 : ShowFatalError(state,
165 0 : format("SimTranspiredCollector: Invalid CompIndex passed={}, Number of Transpired Collectors={}, UTSC name={}",
166 : UTSCNum,
167 0 : state.dataTranspiredCollector->NumUTSC,
168 0 : CompName));
169 : }
170 40666 : if (state.dataTranspiredCollector->CheckEquipName(UTSCNum)) {
171 5 : if (CompName != state.dataTranspiredCollector->UTSC(UTSCNum).Name) {
172 0 : ShowFatalError(state,
173 0 : format("SimTranspiredCollector: Invalid CompIndex passed={}, Transpired Collector name={}, stored Transpired "
174 : "Collector Name for that index={}",
175 : UTSCNum,
176 : CompName,
177 0 : state.dataTranspiredCollector->UTSC(UTSCNum).Name));
178 : }
179 5 : state.dataTranspiredCollector->CheckEquipName(UTSCNum) = false;
180 : }
181 : }
182 :
183 40675 : InitTranspiredCollector(state, CompIndex);
184 :
185 : // Control point of deciding if transpired collector is active or not.
186 40675 : auto &UTSC_CI(state.dataTranspiredCollector->UTSC(CompIndex));
187 40675 : auto &InletNode(UTSC_CI.InletNode);
188 40675 : auto &ControlNode(UTSC_CI.ControlNode);
189 40675 : UTSC_CI.IsOn = false;
190 55447 : if ((GetCurrentScheduleValue(state, UTSC_CI.SchedPtr) > 0.0) &&
191 14772 : (UTSC_CI.InletMDot > 0.0)) { // availability Schedule | OA system is setting mass flow
192 9700 : bool ControlLTSet(false);
193 9700 : bool ControlLTSchedule(false);
194 9700 : bool ZoneLTSchedule(false);
195 9700 : assert(equal_dimensions(InletNode, ControlNode));
196 9700 : assert(equal_dimensions(InletNode, UTSC_CI.ZoneNode));
197 31992 : for (int i = InletNode.l(), e = InletNode.u(); i <= e; ++i) {
198 22292 : if (state.dataLoopNodes->Node(InletNode(i)).Temp + TempControlTol < state.dataLoopNodes->Node(ControlNode(i)).TempSetPoint)
199 22292 : ControlLTSet = true;
200 22292 : if (state.dataLoopNodes->Node(InletNode(i)).Temp + TempControlTol < GetCurrentScheduleValue(state, UTSC_CI.FreeHeatSetPointSchedPtr))
201 22292 : ControlLTSchedule = true;
202 44584 : if (state.dataLoopNodes->Node(UTSC_CI.ZoneNode(i)).Temp + TempControlTol <
203 22292 : GetCurrentScheduleValue(state, UTSC_CI.FreeHeatSetPointSchedPtr))
204 6510 : ZoneLTSchedule = true;
205 : }
206 9700 : if (ControlLTSet || (ControlLTSchedule && ZoneLTSchedule))
207 9700 : UTSC_CI.IsOn = true; // heating required | free heating helpful | free heating helpful
208 : }
209 :
210 40675 : if (state.dataTranspiredCollector->UTSC(UTSCNum).IsOn) {
211 9700 : CalcActiveTranspiredCollector(state, UTSCNum);
212 : } else {
213 30975 : CalcPassiveTranspiredCollector(state, UTSCNum);
214 : }
215 :
216 40675 : UpdateTranspiredCollector(state, UTSCNum);
217 40675 : }
218 :
219 1 : void GetTranspiredCollectorInput(EnergyPlusData &state)
220 : {
221 :
222 : // SUBROUTINE INFORMATION:
223 : // AUTHOR B.T. Griffith
224 : // DATE WRITTEN November 2004
225 : // MODIFIED na
226 : // RE-ENGINEERED na
227 :
228 : // PURPOSE OF THIS SUBROUTINE:
229 : // Retrieve user input and set up data structure
230 :
231 : // METHODOLOGY EMPLOYED:
232 : // usual EnergyPlus input
233 : // Extensible UTSC object for underlying heat transfer surfaces and for multisystem
234 :
235 : // Using/Aliasing
236 : using BranchNodeConnections::TestCompSet;
237 : using DataLoopNode::ObjectIsNotParent;
238 : using DataSurfaces::OtherSideCondModeledExt;
239 : using DataSurfaces::SurfaceData;
240 : using NodeInputManager::GetOnlySingleNode;
241 : using ScheduleManager::GetScheduleIndex;
242 :
243 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
244 :
245 2 : Array1D_string Alphas; // Alpha items for extensible
246 : // Solar Collectors:Unglazed Transpired object
247 : int Item; // Item to be "gotten"
248 2 : Array1D<Real64> Numbers(11); // Numeric items for object
249 : int NumAlphas; // Number of Alphas for each GetObjectItem call
250 : int NumNumbers; // Number of Numbers for each GetObjectItem call
251 : int MaxNumAlphas; // argumenet for call to GetObjectDefMaxArgs
252 : int MaxNumNumbers; // argumenet for call to GetObjectDefMaxArgs
253 : int Dummy; // argumenet for call to GetObjectDefMaxArgs
254 : int IOStatus; // Used in GetObjectItem
255 1 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
256 : int Found;
257 : int AlphaOffset; // local temp var
258 2 : std::string Roughness;
259 : int ThisSurf; // do loop counter
260 : Real64 AvgAzimuth; // temp for error checking
261 : Real64 AvgTilt; // temp for error checking
262 : int SurfID; // local surface "pointer"
263 : Real64 TiltRads; // average tilt of collector in radians
264 : Real64 tempHdeltaNPL; // temporary variable for buoyancy length scale
265 1 : int NumUTSCSplitter(0);
266 2 : Array1D_string AlphasSplit; // Alpha items for extensible
267 : // Solar Collectors:Unglazed Transpired object
268 : int ItemSplit; // Item to be "gotten"
269 2 : Array1D<Real64> NumbersSplit(1); // Numeric items for object
270 : int NumAlphasSplit; // Number of Alphas for each GetObjectItem call
271 : int NumNumbersSplit; // Number of Numbers for each GetObjectItem call
272 : int MaxNumAlphasSplit; // argumenet for call to GetObjectDefMaxArgs
273 : int MaxNumNumbersSplit; // argumenet for call to GetObjectDefMaxArgs
274 : int IOStatusSplit; // Used in GetObjectItem
275 : int NumOASys; // do loop counter
276 : int ACountBase; // counter for alhpasSplit
277 2 : Array1D_bool SplitterNameOK; // check for correct association of
278 2 : std::string CurrentModuleObject; // for ease in renaming.
279 2 : std::string CurrentModuleMultiObject; // for ease in renaming.
280 :
281 1 : CurrentModuleObject = "SolarCollector:UnglazedTranspired";
282 1 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Dummy, MaxNumAlphas, MaxNumNumbers);
283 :
284 1 : if (MaxNumNumbers != 11) {
285 0 : ShowSevereError(state,
286 0 : format("GetTranspiredCollectorInput: {} Object Definition indicates not = 11 Number Objects, Number Indicated={}",
287 : CurrentModuleObject,
288 0 : MaxNumNumbers));
289 0 : ErrorsFound = true;
290 : }
291 1 : Alphas.allocate(MaxNumAlphas);
292 1 : Numbers = 0.0;
293 1 : Alphas = "";
294 :
295 1 : state.dataTranspiredCollector->NumUTSC = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
296 1 : CurrentModuleMultiObject = "SolarCollector:UnglazedTranspired:Multisystem";
297 1 : NumUTSCSplitter = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleMultiObject);
298 :
299 1 : state.dataTranspiredCollector->UTSC.allocate(state.dataTranspiredCollector->NumUTSC);
300 1 : state.dataTranspiredCollector->CheckEquipName.dimension(state.dataTranspiredCollector->NumUTSC, true);
301 1 : SplitterNameOK.dimension(NumUTSCSplitter, false);
302 :
303 6 : for (Item = 1; Item <= state.dataTranspiredCollector->NumUTSC; ++Item) {
304 25 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
305 : CurrentModuleObject,
306 : Item,
307 : Alphas,
308 : NumAlphas,
309 : Numbers,
310 : NumNumbers,
311 : IOStatus,
312 5 : state.dataIPShortCut->lNumericFieldBlanks,
313 5 : state.dataIPShortCut->lAlphaFieldBlanks,
314 5 : state.dataIPShortCut->cAlphaFieldNames,
315 5 : state.dataIPShortCut->cNumericFieldNames);
316 :
317 : // first handle alphas
318 5 : state.dataTranspiredCollector->UTSC(Item).Name = Alphas(1);
319 :
320 : // now check for multisystem
321 5 : if (NumUTSCSplitter > 0) {
322 5 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
323 : state, CurrentModuleMultiObject, Dummy, MaxNumAlphasSplit, MaxNumNumbersSplit);
324 :
325 5 : if (MaxNumNumbersSplit != 0) {
326 0 : ShowSevereError(state,
327 0 : format("GetTranspiredCollectorInput: {} Object Definition indicates not = 0 Number Objects, Number Indicated={}",
328 : CurrentModuleMultiObject,
329 0 : MaxNumNumbersSplit));
330 0 : ErrorsFound = true;
331 : }
332 5 : if (!allocated(AlphasSplit)) AlphasSplit.allocate(MaxNumAlphasSplit);
333 5 : NumbersSplit = 0.0;
334 5 : AlphasSplit = "";
335 10 : for (ItemSplit = 1; ItemSplit <= NumUTSCSplitter; ++ItemSplit) {
336 5 : state.dataInputProcessing->inputProcessor->getObjectItem(
337 : state, CurrentModuleMultiObject, ItemSplit, AlphasSplit, NumAlphasSplit, NumbersSplit, NumNumbersSplit, IOStatusSplit);
338 5 : if (!(UtilityRoutines::SameString(AlphasSplit(1), Alphas(1)))) continue;
339 1 : SplitterNameOK(ItemSplit) = true;
340 1 : state.dataTranspiredCollector->UTSC(Item).NumOASysAttached = std::floor(NumAlphasSplit / 4.0);
341 1 : if (mod((NumAlphasSplit), 4) != 1) {
342 0 : ShowSevereError(state,
343 0 : "GetTranspiredCollectorInput: " + CurrentModuleMultiObject +
344 0 : " Object Definition indicates not uniform quadtuples of nodes for " + AlphasSplit(1));
345 0 : ErrorsFound = true;
346 : }
347 1 : state.dataTranspiredCollector->UTSC(Item).InletNode.allocate(state.dataTranspiredCollector->UTSC(Item).NumOASysAttached);
348 1 : state.dataTranspiredCollector->UTSC(Item).InletNode = 0;
349 1 : state.dataTranspiredCollector->UTSC(Item).OutletNode.allocate(state.dataTranspiredCollector->UTSC(Item).NumOASysAttached);
350 1 : state.dataTranspiredCollector->UTSC(Item).OutletNode = 0;
351 1 : state.dataTranspiredCollector->UTSC(Item).ControlNode.allocate(state.dataTranspiredCollector->UTSC(Item).NumOASysAttached);
352 1 : state.dataTranspiredCollector->UTSC(Item).ControlNode = 0;
353 1 : state.dataTranspiredCollector->UTSC(Item).ZoneNode.allocate(state.dataTranspiredCollector->UTSC(Item).NumOASysAttached);
354 1 : state.dataTranspiredCollector->UTSC(Item).ZoneNode = 0;
355 6 : for (NumOASys = 1; NumOASys <= state.dataTranspiredCollector->UTSC(Item).NumOASysAttached; ++NumOASys) {
356 5 : ACountBase = (NumOASys - 1) * 4 + 2;
357 5 : state.dataTranspiredCollector->UTSC(Item).InletNode(NumOASys) =
358 10 : GetOnlySingleNode(state,
359 5 : AlphasSplit(ACountBase),
360 : ErrorsFound,
361 : DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
362 5 : AlphasSplit(1),
363 : DataLoopNode::NodeFluidType::Air,
364 : DataLoopNode::ConnectionType::Inlet,
365 : static_cast<NodeInputManager::CompFluidStream>(NumOASys),
366 5 : ObjectIsNotParent);
367 :
368 5 : state.dataTranspiredCollector->UTSC(Item).OutletNode(NumOASys) =
369 10 : GetOnlySingleNode(state,
370 5 : AlphasSplit(ACountBase + 1),
371 : ErrorsFound,
372 : DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
373 5 : AlphasSplit(1),
374 : DataLoopNode::NodeFluidType::Air,
375 : DataLoopNode::ConnectionType::Outlet,
376 : static_cast<NodeInputManager::CompFluidStream>(NumOASys),
377 5 : ObjectIsNotParent);
378 10 : TestCompSet(state,
379 : CurrentModuleObject,
380 5 : AlphasSplit(1),
381 5 : AlphasSplit(ACountBase),
382 5 : AlphasSplit(ACountBase + 1),
383 : "Transpired Collector Air Nodes"); // appears that test fails by design??
384 5 : state.dataTranspiredCollector->UTSC(Item).ControlNode(NumOASys) =
385 10 : GetOnlySingleNode(state,
386 5 : AlphasSplit(ACountBase + 2),
387 : ErrorsFound,
388 : DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
389 5 : AlphasSplit(1),
390 : DataLoopNode::NodeFluidType::Air,
391 : DataLoopNode::ConnectionType::Sensor,
392 : NodeInputManager::CompFluidStream::Primary,
393 5 : ObjectIsNotParent);
394 :
395 5 : state.dataTranspiredCollector->UTSC(Item).ZoneNode(NumOASys) =
396 10 : GetOnlySingleNode(state,
397 5 : AlphasSplit(ACountBase + 3),
398 : ErrorsFound,
399 : DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
400 5 : AlphasSplit(1),
401 : DataLoopNode::NodeFluidType::Air,
402 : DataLoopNode::ConnectionType::Sensor,
403 : NodeInputManager::CompFluidStream::Primary,
404 5 : ObjectIsNotParent);
405 :
406 : } // Each OA System in a Multisystem
407 : // DEALLOCATE(AlphasSplit)
408 : } // each Multisystem present
409 : } // any UTSC Multisystem present
410 :
411 5 : state.dataTranspiredCollector->UTSC(Item).OSCMName = Alphas(2);
412 5 : Found = UtilityRoutines::FindItemInList(state.dataTranspiredCollector->UTSC(Item).OSCMName, state.dataSurface->OSCM);
413 5 : if (Found == 0) {
414 0 : ShowSevereError(state,
415 0 : state.dataIPShortCut->cAlphaFieldNames(2) + " not found=" + state.dataTranspiredCollector->UTSC(Item).OSCMName +
416 0 : " in " + CurrentModuleObject + " =" + state.dataTranspiredCollector->UTSC(Item).Name);
417 0 : ErrorsFound = true;
418 : }
419 5 : state.dataTranspiredCollector->UTSC(Item).OSCMPtr = Found;
420 5 : if (state.dataIPShortCut->lAlphaFieldBlanks(3)) {
421 0 : state.dataTranspiredCollector->UTSC(Item).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
422 : } else {
423 5 : state.dataTranspiredCollector->UTSC(Item).SchedPtr = GetScheduleIndex(state, Alphas(3));
424 5 : if (state.dataTranspiredCollector->UTSC(Item).SchedPtr == 0) {
425 0 : ShowSevereError(state,
426 0 : state.dataIPShortCut->cAlphaFieldNames(3) + "not found=" + Alphas(3) + " in " + CurrentModuleObject + " =" +
427 0 : state.dataTranspiredCollector->UTSC(Item).Name);
428 0 : ErrorsFound = true;
429 0 : continue;
430 : }
431 : }
432 :
433 : // now if UTSC(Item)%NumOASysAttached still not set, assume no multisystem
434 5 : if (state.dataTranspiredCollector->UTSC(Item).NumOASysAttached == 0) {
435 4 : state.dataTranspiredCollector->UTSC(Item).NumOASysAttached = 1;
436 4 : state.dataTranspiredCollector->UTSC(Item).InletNode.allocate(1);
437 4 : state.dataTranspiredCollector->UTSC(Item).InletNode(1) = 0;
438 4 : state.dataTranspiredCollector->UTSC(Item).OutletNode.allocate(1);
439 4 : state.dataTranspiredCollector->UTSC(Item).OutletNode(1) = 0;
440 4 : state.dataTranspiredCollector->UTSC(Item).ControlNode.allocate(1);
441 4 : state.dataTranspiredCollector->UTSC(Item).ControlNode(1) = 0;
442 4 : state.dataTranspiredCollector->UTSC(Item).ZoneNode.allocate(1);
443 4 : state.dataTranspiredCollector->UTSC(Item).ZoneNode(1) = 0;
444 :
445 4 : state.dataTranspiredCollector->UTSC(Item).InletNode(1) =
446 8 : GetOnlySingleNode(state,
447 4 : Alphas(4),
448 : ErrorsFound,
449 : DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
450 4 : Alphas(1),
451 : DataLoopNode::NodeFluidType::Air,
452 : DataLoopNode::ConnectionType::Inlet,
453 : NodeInputManager::CompFluidStream::Primary,
454 4 : ObjectIsNotParent);
455 4 : state.dataTranspiredCollector->UTSC(Item).OutletNode(1) =
456 8 : GetOnlySingleNode(state,
457 4 : Alphas(5),
458 : ErrorsFound,
459 : DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
460 4 : Alphas(1),
461 : DataLoopNode::NodeFluidType::Air,
462 : DataLoopNode::ConnectionType::Outlet,
463 : NodeInputManager::CompFluidStream::Primary,
464 4 : ObjectIsNotParent);
465 4 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(4), Alphas(5), "Transpired Collector Air Nodes");
466 :
467 4 : state.dataTranspiredCollector->UTSC(Item).ControlNode(1) =
468 8 : GetOnlySingleNode(state,
469 4 : Alphas(6),
470 : ErrorsFound,
471 : DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
472 4 : Alphas(1),
473 : DataLoopNode::NodeFluidType::Air,
474 : DataLoopNode::ConnectionType::Sensor,
475 : NodeInputManager::CompFluidStream::Primary,
476 4 : ObjectIsNotParent);
477 4 : state.dataTranspiredCollector->UTSC(Item).ZoneNode(1) =
478 8 : GetOnlySingleNode(state,
479 4 : Alphas(7),
480 : ErrorsFound,
481 : DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
482 4 : Alphas(1),
483 : DataLoopNode::NodeFluidType::Air,
484 : DataLoopNode::ConnectionType::Sensor,
485 : NodeInputManager::CompFluidStream::Primary,
486 4 : ObjectIsNotParent);
487 : } // no splitter
488 :
489 5 : state.dataTranspiredCollector->UTSC(Item).FreeHeatSetPointSchedPtr = GetScheduleIndex(state, Alphas(8));
490 5 : if (state.dataTranspiredCollector->UTSC(Item).FreeHeatSetPointSchedPtr == 0) {
491 0 : ShowSevereError(state,
492 0 : state.dataIPShortCut->cAlphaFieldNames(8) + " not found=" + Alphas(8) + " in " + CurrentModuleObject + " =" +
493 0 : state.dataTranspiredCollector->UTSC(Item).Name);
494 0 : ErrorsFound = true;
495 0 : continue;
496 : }
497 :
498 5 : if (UtilityRoutines::SameString(Alphas(9), "Triangle")) {
499 5 : state.dataTranspiredCollector->UTSC(Item).Layout = Layout_Triangle;
500 0 : } else if (UtilityRoutines::SameString(Alphas(9), "Square")) {
501 0 : state.dataTranspiredCollector->UTSC(Item).Layout = Layout_Square;
502 : } else {
503 0 : ShowSevereError(state,
504 0 : state.dataIPShortCut->cAlphaFieldNames(9) + " has incorrect entry of " + Alphas(9) + " in " + CurrentModuleObject +
505 0 : " =" + state.dataTranspiredCollector->UTSC(Item).Name);
506 0 : ErrorsFound = true;
507 0 : continue;
508 : }
509 :
510 5 : if (UtilityRoutines::SameString(Alphas(10), "Kutscher1994")) {
511 3 : state.dataTranspiredCollector->UTSC(Item).Correlation = Correlation_Kutscher1994;
512 2 : } else if (UtilityRoutines::SameString(Alphas(10), "VanDeckerHollandsBrunger2001")) {
513 2 : state.dataTranspiredCollector->UTSC(Item).Correlation = Correlation_VanDeckerHollandsBrunger2001;
514 : } else {
515 0 : ShowSevereError(state,
516 0 : state.dataIPShortCut->cAlphaFieldNames(10) + " has incorrect entry of " + Alphas(9) + " in " + CurrentModuleObject +
517 0 : " =" + state.dataTranspiredCollector->UTSC(Item).Name);
518 0 : ErrorsFound = true;
519 0 : continue;
520 : }
521 :
522 5 : Roughness = Alphas(11);
523 : // Select the correct Number for the associated ascii name for the roughness type
524 5 : if (UtilityRoutines::SameString(Roughness, "VeryRough"))
525 0 : state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::VeryRough;
526 5 : if (UtilityRoutines::SameString(Roughness, "Rough"))
527 0 : state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::Rough;
528 5 : if (UtilityRoutines::SameString(Roughness, "MediumRough"))
529 5 : state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::MediumRough;
530 5 : if (UtilityRoutines::SameString(Roughness, "MediumSmooth"))
531 0 : state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::MediumSmooth;
532 5 : if (UtilityRoutines::SameString(Roughness, "Smooth"))
533 0 : state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::Smooth;
534 5 : if (UtilityRoutines::SameString(Roughness, "VerySmooth"))
535 0 : state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::VerySmooth;
536 :
537 : // Was it set?
538 5 : if (state.dataTranspiredCollector->UTSC(Item).CollRoughness == DataSurfaces::SurfaceRoughness::Invalid) {
539 0 : ShowSevereError(state,
540 0 : state.dataIPShortCut->cAlphaFieldNames(11) + " has incorrect entry of " + Alphas(11) + " in " + CurrentModuleObject +
541 0 : " =" + state.dataTranspiredCollector->UTSC(Item).Name);
542 0 : ErrorsFound = true;
543 : }
544 :
545 5 : AlphaOffset = 11;
546 5 : state.dataTranspiredCollector->UTSC(Item).NumSurfs = NumAlphas - AlphaOffset;
547 5 : if (state.dataTranspiredCollector->UTSC(Item).NumSurfs == 0) {
548 0 : ShowSevereError(state,
549 0 : "No underlying surfaces specified in " + CurrentModuleObject + " =" + state.dataTranspiredCollector->UTSC(Item).Name);
550 0 : ErrorsFound = true;
551 0 : continue;
552 : }
553 5 : state.dataTranspiredCollector->UTSC(Item).SurfPtrs.allocate(state.dataTranspiredCollector->UTSC(Item).NumSurfs);
554 5 : state.dataTranspiredCollector->UTSC(Item).SurfPtrs = 0;
555 11 : for (ThisSurf = 1; ThisSurf <= state.dataTranspiredCollector->UTSC(Item).NumSurfs; ++ThisSurf) {
556 6 : Found = UtilityRoutines::FindItemInList(Alphas(ThisSurf + AlphaOffset), state.dataSurface->Surface);
557 6 : if (Found == 0) {
558 0 : ShowSevereError(state,
559 0 : "Surface Name not found=" + Alphas(ThisSurf + AlphaOffset) + " in " + CurrentModuleObject + " =" +
560 0 : state.dataTranspiredCollector->UTSC(Item).Name);
561 0 : ErrorsFound = true;
562 0 : continue;
563 : }
564 : // check that surface is appropriate, Heat transfer, Sun, Wind,
565 6 : if (!state.dataSurface->Surface(Found).HeatTransSurf) {
566 0 : ShowSevereError(state,
567 0 : "Surface " + Alphas(ThisSurf + AlphaOffset) + " not of Heat Transfer type in " + CurrentModuleObject + " =" +
568 0 : state.dataTranspiredCollector->UTSC(Item).Name);
569 0 : ErrorsFound = true;
570 0 : continue;
571 : }
572 6 : if (!state.dataSurface->Surface(Found).ExtSolar) {
573 0 : ShowSevereError(state,
574 0 : "Surface " + Alphas(ThisSurf + AlphaOffset) + " not exposed to sun in " + CurrentModuleObject + " =" +
575 0 : state.dataTranspiredCollector->UTSC(Item).Name);
576 0 : ErrorsFound = true;
577 0 : continue;
578 : }
579 6 : if (!state.dataSurface->Surface(Found).ExtWind) {
580 0 : ShowSevereError(state,
581 0 : "Surface " + Alphas(ThisSurf + AlphaOffset) + " not exposed to wind in " + CurrentModuleObject + " =" +
582 0 : state.dataTranspiredCollector->UTSC(Item).Name);
583 0 : ErrorsFound = true;
584 0 : continue;
585 : }
586 6 : if (state.dataSurface->Surface(Found).ExtBoundCond != OtherSideCondModeledExt) {
587 0 : ShowSevereError(state,
588 0 : "Surface " + Alphas(ThisSurf + AlphaOffset) +
589 0 : " does not have OtherSideConditionsModel for exterior boundary conditions in " + CurrentModuleObject + " =" +
590 0 : state.dataTranspiredCollector->UTSC(Item).Name);
591 0 : ErrorsFound = true;
592 0 : continue;
593 : }
594 : // check surface orientation, warn if upside down
595 6 : if ((state.dataSurface->Surface(Found).Tilt < -95.0) || (state.dataSurface->Surface(Found).Tilt > 95.0)) {
596 0 : ShowWarningError(state, "Suspected input problem with collector surface = " + Alphas(ThisSurf + AlphaOffset));
597 0 : ShowContinueError(
598 0 : state, "Entered in " + state.dataIPShortCut->cCurrentModuleObject + " = " + state.dataTranspiredCollector->UTSC(Item).Name);
599 0 : ShowContinueError(state, "Surface used for solar collector faces down");
600 0 : ShowContinueError(
601 0 : state, format("Surface tilt angle (degrees from ground outward normal) = {:.2R}", state.dataSurface->Surface(Found).Tilt));
602 : }
603 :
604 6 : state.dataTranspiredCollector->UTSC(Item).SurfPtrs(ThisSurf) = Found;
605 : }
606 :
607 5 : if (ErrorsFound) continue; // previous inner do loop may have detected problems that need to be cycle'd again to avoid crash
608 :
609 : // now that we should have all the surfaces, do some preperations and checks.
610 :
611 : // are they all similar tilt and azimuth? Issue warnings so people can do it if they really want
612 5 : Real64 const surfaceArea(sum_sub(state.dataSurface->Surface, &SurfaceData::Area, state.dataTranspiredCollector->UTSC(Item).SurfPtrs));
613 : // AvgAzimuth = sum( Surface( UTSC( Item ).SurfPtrs ).Azimuth * Surface( UTSC( Item ).SurfPtrs ).Area ) / sum( Surface(
614 : // UTSC( Item
615 : //).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below
616 5 : AvgAzimuth =
617 10 : sum_product_sub(
618 10 : state.dataSurface->Surface, &SurfaceData::Azimuth, &SurfaceData::Area, state.dataTranspiredCollector->UTSC(Item).SurfPtrs) /
619 : surfaceArea; // Autodesk:F2C++ Functions handle array subscript usage
620 : // AvgTilt = sum( Surface( UTSC( Item ).SurfPtrs ).Tilt * Surface( UTSC( Item ).SurfPtrs ).Area ) / sum( Surface( UTSC(
621 : // Item
622 : //).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below
623 10 : AvgTilt = sum_product_sub(
624 10 : state.dataSurface->Surface, &SurfaceData::Tilt, &SurfaceData::Area, state.dataTranspiredCollector->UTSC(Item).SurfPtrs) /
625 : surfaceArea; // Autodesk:F2C++ Functions handle array subscript usage
626 11 : for (ThisSurf = 1; ThisSurf <= state.dataTranspiredCollector->UTSC(Item).NumSurfs; ++ThisSurf) {
627 6 : SurfID = state.dataTranspiredCollector->UTSC(Item).SurfPtrs(ThisSurf);
628 6 : if (std::abs(state.dataSurface->Surface(SurfID).Azimuth - AvgAzimuth) > 15.0) {
629 0 : ShowWarningError(state,
630 0 : "Surface " + state.dataSurface->Surface(SurfID).Name +
631 0 : " has Azimuth different from others in the group associated with " + CurrentModuleObject + " =" +
632 0 : state.dataTranspiredCollector->UTSC(Item).Name);
633 : }
634 6 : if (std::abs(state.dataSurface->Surface(SurfID).Tilt - AvgTilt) > 10.0) {
635 0 : ShowWarningError(state,
636 0 : "Surface " + state.dataSurface->Surface(SurfID).Name +
637 0 : " has Tilt different from others in the group associated with " + CurrentModuleObject + " =" +
638 0 : state.dataTranspiredCollector->UTSC(Item).Name);
639 : }
640 :
641 : // test that there are no windows. Now allow windows
642 : // If (Surface(SurfID)%GrossArea > Surface(SurfID)%Area) Then
643 : // Call ShowWarningError(state, 'Surface '//TRIM(Surface(SurfID)%name)//' has a subsurface whose area is not being ' &
644 : // //'subtracted in the group of surfaces associated with '//TRIM(UTSC(Item)%Name))
645 : // endif
646 : }
647 5 : state.dataTranspiredCollector->UTSC(Item).Tilt = AvgTilt;
648 5 : state.dataTranspiredCollector->UTSC(Item).Azimuth = AvgAzimuth;
649 :
650 : // find area weighted centroid.
651 : // UTSC(Item)%Centroid%x = SUM(Surface(UTSC(Item)%SurfPtrs)%Centroid%x*Surface(UTSC(Item)%SurfPtrs)%Area) &
652 : // /SUM(Surface(UTSC(Item)%SurfPtrs)%Area)
653 : // UTSC(Item)%Centroid%y = SUM(Surface(UTSC(Item)%SurfPtrs)%Centroid%y*Surface(UTSC(Item)%SurfPtrs)%Area) &
654 : // /SUM(Surface(UTSC(Item)%SurfPtrs)%Area)
655 : // UTSC( Item ).Centroid.z = sum( Surface( UTSC( Item ).SurfPtrs ).Centroid.z * Surface( UTSC( Item ).SurfPtrs ).Area ) /
656 : // sum( Surface( UTSC( Item ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below
657 15 : state.dataTranspiredCollector->UTSC(Item).Centroid.z = sum_product_sub(state.dataSurface->Surface,
658 : &SurfaceData::Centroid,
659 : &Vector::z,
660 5 : state.dataSurface->Surface,
661 : &SurfaceData::Area,
662 10 : state.dataTranspiredCollector->UTSC(Item).SurfPtrs) /
663 : surfaceArea; // Autodesk:F2C++ Functions handle array subscript usage
664 :
665 : // now handle numbers from input object
666 5 : state.dataTranspiredCollector->UTSC(Item).HoleDia = Numbers(1);
667 5 : state.dataTranspiredCollector->UTSC(Item).Pitch = Numbers(2);
668 5 : state.dataTranspiredCollector->UTSC(Item).LWEmitt = Numbers(3);
669 5 : state.dataTranspiredCollector->UTSC(Item).SolAbsorp = Numbers(4);
670 5 : state.dataTranspiredCollector->UTSC(Item).Height = Numbers(5);
671 5 : state.dataTranspiredCollector->UTSC(Item).PlenGapThick = Numbers(6);
672 5 : if (state.dataTranspiredCollector->UTSC(Item).PlenGapThick <= 0.0) {
673 0 : ShowSevereError(
674 0 : state, "Plenum gap must be greater than Zero in " + CurrentModuleObject + " =" + state.dataTranspiredCollector->UTSC(Item).Name);
675 0 : continue;
676 : }
677 5 : state.dataTranspiredCollector->UTSC(Item).PlenCrossArea = Numbers(7);
678 5 : state.dataTranspiredCollector->UTSC(Item).AreaRatio = Numbers(8);
679 5 : state.dataTranspiredCollector->UTSC(Item).CollectThick = Numbers(9);
680 5 : state.dataTranspiredCollector->UTSC(Item).Cv = Numbers(10);
681 5 : state.dataTranspiredCollector->UTSC(Item).Cd = Numbers(11);
682 :
683 : // Fill out data we now know
684 : // sum areas of HT surface areas
685 : // UTSC( Item ).ProjArea = sum( Surface( UTSC( Item ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced
686 : // by below
687 5 : state.dataTranspiredCollector->UTSC(Item).ProjArea = surfaceArea;
688 5 : if (state.dataTranspiredCollector->UTSC(Item).ProjArea == 0) {
689 0 : ShowSevereError(state,
690 0 : "Gross area of underlying surfaces is zero in " + CurrentModuleObject + " =" +
691 0 : state.dataTranspiredCollector->UTSC(Item).Name);
692 0 : continue;
693 : }
694 5 : state.dataTranspiredCollector->UTSC(Item).ActualArea =
695 5 : state.dataTranspiredCollector->UTSC(Item).ProjArea * state.dataTranspiredCollector->UTSC(Item).AreaRatio;
696 : // need to update this for slots as well as holes
697 5 : switch (state.dataTranspiredCollector->UTSC(Item).Layout) {
698 5 : case Layout_Triangle: { // 'TRIANGLE'
699 5 : state.dataTranspiredCollector->UTSC(Item).Porosity =
700 10 : 0.907 * pow_2(state.dataTranspiredCollector->UTSC(Item).HoleDia /
701 5 : state.dataTranspiredCollector->UTSC(Item).Pitch); // Kutscher equation, Triangle layout
702 5 : } break;
703 0 : case Layout_Square: { // 'SQUARE'
704 0 : state.dataTranspiredCollector->UTSC(Item).Porosity =
705 0 : (DataGlobalConstants::Pi / 4.0) * pow_2(state.dataTranspiredCollector->UTSC(Item).HoleDia) /
706 0 : pow_2(state.dataTranspiredCollector->UTSC(Item).Pitch); // Waterloo equation, square layout
707 0 : } break;
708 0 : default:
709 0 : break;
710 : }
711 5 : TiltRads = std::abs(AvgTilt) * DataGlobalConstants::DegToRadians;
712 5 : tempHdeltaNPL = std::sin(TiltRads) * state.dataTranspiredCollector->UTSC(Item).Height / 4.0;
713 5 : state.dataTranspiredCollector->UTSC(Item).HdeltaNPL = max(tempHdeltaNPL, state.dataTranspiredCollector->UTSC(Item).PlenGapThick);
714 :
715 20 : SetupOutputVariable(state,
716 : "Solar Collector Heat Exchanger Effectiveness",
717 : OutputProcessor::Unit::None,
718 5 : state.dataTranspiredCollector->UTSC(Item).HXeff,
719 : OutputProcessor::SOVTimeStepType::System,
720 : OutputProcessor::SOVStoreType::Average,
721 10 : state.dataTranspiredCollector->UTSC(Item).Name);
722 20 : SetupOutputVariable(state,
723 : "Solar Collector Leaving Air Temperature",
724 : OutputProcessor::Unit::C,
725 5 : state.dataTranspiredCollector->UTSC(Item).TairHX,
726 : OutputProcessor::SOVTimeStepType::System,
727 : OutputProcessor::SOVStoreType::Average,
728 10 : state.dataTranspiredCollector->UTSC(Item).Name);
729 20 : SetupOutputVariable(state,
730 : "Solar Collector Outside Face Suction Velocity",
731 : OutputProcessor::Unit::m_s,
732 5 : state.dataTranspiredCollector->UTSC(Item).Vsuction,
733 : OutputProcessor::SOVTimeStepType::System,
734 : OutputProcessor::SOVStoreType::Average,
735 10 : state.dataTranspiredCollector->UTSC(Item).Name);
736 20 : SetupOutputVariable(state,
737 : "Solar Collector Surface Temperature",
738 : OutputProcessor::Unit::C,
739 5 : state.dataTranspiredCollector->UTSC(Item).Tcoll,
740 : OutputProcessor::SOVTimeStepType::System,
741 : OutputProcessor::SOVStoreType::Average,
742 10 : state.dataTranspiredCollector->UTSC(Item).Name);
743 20 : SetupOutputVariable(state,
744 : "Solar Collector Plenum Air Temperature",
745 : OutputProcessor::Unit::C,
746 5 : state.dataTranspiredCollector->UTSC(Item).Tplen,
747 : OutputProcessor::SOVTimeStepType::System,
748 : OutputProcessor::SOVStoreType::Average,
749 10 : state.dataTranspiredCollector->UTSC(Item).Name);
750 20 : SetupOutputVariable(state,
751 : "Solar Collector Sensible Heating Rate",
752 : OutputProcessor::Unit::W,
753 5 : state.dataTranspiredCollector->UTSC(Item).SensHeatingRate,
754 : OutputProcessor::SOVTimeStepType::System,
755 : OutputProcessor::SOVStoreType::Average,
756 10 : state.dataTranspiredCollector->UTSC(Item).Name);
757 20 : SetupOutputVariable(state,
758 : "Solar Collector Sensible Heating Energy",
759 : OutputProcessor::Unit::J,
760 5 : state.dataTranspiredCollector->UTSC(Item).SensHeatingEnergy,
761 : OutputProcessor::SOVTimeStepType::System,
762 : OutputProcessor::SOVStoreType::Summed,
763 5 : state.dataTranspiredCollector->UTSC(Item).Name,
764 : _,
765 : "SolarAir",
766 : "HeatProduced",
767 : _,
768 5 : "System");
769 :
770 20 : SetupOutputVariable(state,
771 : "Solar Collector Natural Ventilation Air Change Rate",
772 : OutputProcessor::Unit::ach,
773 5 : state.dataTranspiredCollector->UTSC(Item).PassiveACH,
774 : OutputProcessor::SOVTimeStepType::System,
775 : OutputProcessor::SOVStoreType::Average,
776 10 : state.dataTranspiredCollector->UTSC(Item).Name);
777 20 : SetupOutputVariable(state,
778 : "Solar Collector Natural Ventilation Mass Flow Rate",
779 : OutputProcessor::Unit::kg_s,
780 5 : state.dataTranspiredCollector->UTSC(Item).PassiveMdotVent,
781 : OutputProcessor::SOVTimeStepType::System,
782 : OutputProcessor::SOVStoreType::Average,
783 10 : state.dataTranspiredCollector->UTSC(Item).Name);
784 20 : SetupOutputVariable(state,
785 : "Solar Collector Wind Natural Ventilation Mass Flow Rate",
786 : OutputProcessor::Unit::kg_s,
787 5 : state.dataTranspiredCollector->UTSC(Item).PassiveMdotWind,
788 : OutputProcessor::SOVTimeStepType::System,
789 : OutputProcessor::SOVStoreType::Average,
790 10 : state.dataTranspiredCollector->UTSC(Item).Name);
791 20 : SetupOutputVariable(state,
792 : "Solar Collector Buoyancy Natural Ventilation Mass Flow Rate",
793 : OutputProcessor::Unit::kg_s,
794 5 : state.dataTranspiredCollector->UTSC(Item).PassiveMdotTherm,
795 : OutputProcessor::SOVTimeStepType::System,
796 : OutputProcessor::SOVStoreType::Average,
797 10 : state.dataTranspiredCollector->UTSC(Item).Name);
798 20 : SetupOutputVariable(state,
799 : "Solar Collector Incident Solar Radiation",
800 : OutputProcessor::Unit::W_m2,
801 5 : state.dataTranspiredCollector->UTSC(Item).Isc,
802 : OutputProcessor::SOVTimeStepType::System,
803 : OutputProcessor::SOVStoreType::Average,
804 10 : state.dataTranspiredCollector->UTSC(Item).Name);
805 20 : SetupOutputVariable(state,
806 : "Solar Collector System Efficiency",
807 : OutputProcessor::Unit::None,
808 5 : state.dataTranspiredCollector->UTSC(Item).UTSCEfficiency,
809 : OutputProcessor::SOVTimeStepType::System,
810 : OutputProcessor::SOVStoreType::Average,
811 10 : state.dataTranspiredCollector->UTSC(Item).Name);
812 20 : SetupOutputVariable(state,
813 : "Solar Collector Surface Efficiency",
814 : OutputProcessor::Unit::None,
815 5 : state.dataTranspiredCollector->UTSC(Item).UTSCCollEff,
816 : OutputProcessor::SOVTimeStepType::System,
817 : OutputProcessor::SOVStoreType::Average,
818 10 : state.dataTranspiredCollector->UTSC(Item).Name);
819 : }
820 :
821 2 : for (ItemSplit = 1; ItemSplit <= NumUTSCSplitter; ++ItemSplit) {
822 1 : if (!SplitterNameOK(ItemSplit)) {
823 0 : ShowSevereError(state, "Did not find a match, check names for Solar Collectors:Transpired Collector:Multisystem");
824 0 : ErrorsFound = true;
825 : }
826 : }
827 :
828 1 : if (ErrorsFound) {
829 0 : ShowFatalError(state, "GetTranspiredCollectorInput: Errors found in input");
830 : }
831 :
832 1 : Alphas.deallocate();
833 1 : }
834 :
835 40675 : void InitTranspiredCollector(EnergyPlusData &state, int const UTSCNum) // compindex already checked in calling routine
836 : {
837 :
838 : // SUBROUTINE INFORMATION:
839 : // AUTHOR B.T. Griffith
840 : // DATE WRITTEN November 2004
841 : // MODIFIED B. Griffith, May 2009, added EMS setpoint check
842 : // RE-ENGINEERED na
843 :
844 : // Using/Aliasing
845 40675 : auto &DoSetPointTest = state.dataHVACGlobal->DoSetPointTest;
846 40675 : auto &SetPointErrorFlag = state.dataHVACGlobal->SetPointErrorFlag;
847 : using namespace DataLoopNode;
848 : using DataSurfaces::SurfaceData;
849 : using EMSManager::CheckIfNodeSetPointManagedByEMS;
850 :
851 : int UTSCUnitNum;
852 : int ControlNode;
853 : int SplitBranch;
854 : int thisUTSC;
855 : Real64 Tamb;
856 :
857 40675 : if (state.dataTranspiredCollector->MyOneTimeFlag) {
858 : // do various one time setups and pitch adjustments across all UTSC
859 6 : for (thisUTSC = 1; thisUTSC <= state.dataTranspiredCollector->NumUTSC; ++thisUTSC) {
860 5 : if (state.dataTranspiredCollector->UTSC(thisUTSC).Layout == Layout_Triangle) {
861 5 : switch (state.dataTranspiredCollector->UTSC(thisUTSC).Correlation) {
862 3 : case Correlation_Kutscher1994: { // Kutscher1994
863 3 : state.dataTranspiredCollector->UTSC(thisUTSC).Pitch = state.dataTranspiredCollector->UTSC(thisUTSC).Pitch;
864 3 : } break;
865 2 : case Correlation_VanDeckerHollandsBrunger2001: { // VanDeckerHollandsBrunger2001
866 2 : state.dataTranspiredCollector->UTSC(thisUTSC).Pitch /= 1.6;
867 2 : } break;
868 0 : default:
869 0 : break;
870 : }
871 : }
872 5 : if (state.dataTranspiredCollector->UTSC(thisUTSC).Layout == Layout_Square) {
873 0 : switch (state.dataTranspiredCollector->UTSC(thisUTSC).Correlation) {
874 0 : case Correlation_Kutscher1994: { // Kutscher1994
875 0 : state.dataTranspiredCollector->UTSC(thisUTSC).Pitch *= 1.6;
876 0 : } break;
877 0 : case Correlation_VanDeckerHollandsBrunger2001: { // VanDeckerHollandsBrunger2001
878 0 : state.dataTranspiredCollector->UTSC(thisUTSC).Pitch = state.dataTranspiredCollector->UTSC(thisUTSC).Pitch;
879 0 : } break;
880 0 : default:
881 0 : break;
882 : }
883 : }
884 : }
885 :
886 1 : state.dataTranspiredCollector->MyEnvrnFlag.dimension(state.dataTranspiredCollector->NumUTSC, true);
887 1 : state.dataTranspiredCollector->MyOneTimeFlag = false;
888 : } // first time
889 :
890 : // Check that setpoint is active (from test by RJL in HVACEvapComponent)
891 40675 : if (!state.dataGlobal->SysSizingCalc && state.dataTranspiredCollector->MySetPointCheckFlag && DoSetPointTest) {
892 6 : for (UTSCUnitNum = 1; UTSCUnitNum <= state.dataTranspiredCollector->NumUTSC; ++UTSCUnitNum) {
893 14 : for (SplitBranch = 1; SplitBranch <= state.dataTranspiredCollector->UTSC(UTSCUnitNum).NumOASysAttached; ++SplitBranch) {
894 9 : ControlNode = state.dataTranspiredCollector->UTSC(UTSCUnitNum).ControlNode(SplitBranch);
895 9 : if (ControlNode > 0) {
896 9 : if (state.dataLoopNodes->Node(ControlNode).TempSetPoint == SensedNodeFlagValue) {
897 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
898 0 : ShowSevereError(state,
899 0 : "Missing temperature setpoint for UTSC " + state.dataTranspiredCollector->UTSC(UTSCUnitNum).Name);
900 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the unit control node.");
901 0 : SetPointErrorFlag = true;
902 : } else {
903 : // need call to EMS to check node
904 0 : CheckIfNodeSetPointManagedByEMS(
905 : state, ControlNode, EMSManager::SPControlType::TemperatureSetPoint, SetPointErrorFlag);
906 0 : if (SetPointErrorFlag) {
907 0 : ShowSevereError(state,
908 0 : "Missing temperature setpoint for UTSC " + state.dataTranspiredCollector->UTSC(UTSCUnitNum).Name);
909 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the unit control node.");
910 0 : ShowContinueError(state, "Or add EMS Actuator to provide temperature setpoint at this node");
911 : }
912 : }
913 : }
914 : }
915 : }
916 : }
917 1 : state.dataTranspiredCollector->MySetPointCheckFlag = false;
918 : }
919 :
920 40675 : if (state.dataGlobal->BeginEnvrnFlag && state.dataTranspiredCollector->MyEnvrnFlag(UTSCNum)) {
921 30 : state.dataTranspiredCollector->UTSC(UTSCNum).TplenLast = 22.5;
922 30 : state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast = 22.0;
923 :
924 30 : state.dataTranspiredCollector->MyEnvrnFlag(UTSCNum) = false;
925 : }
926 40675 : if (!state.dataGlobal->BeginEnvrnFlag) {
927 40179 : state.dataTranspiredCollector->MyEnvrnFlag(UTSCNum) = true;
928 : }
929 :
930 : // determine average ambient temperature
931 40675 : Real64 sum_area = 0.0;
932 104697 : for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
933 64022 : sum_area += state.dataSurface->Surface(SurfNum).Area;
934 : }
935 40675 : if (!state.dataEnvrn->IsRain) {
936 40675 : Real64 sum_produc_area_drybulb = 0.0;
937 104697 : for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
938 64022 : sum_produc_area_drybulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutDryBulbTemp(SurfNum);
939 : }
940 40675 : Tamb = sum_produc_area_drybulb / sum_area;
941 : } else { // when raining we use wet bulb not drybulb
942 0 : Real64 sum_produc_area_wetbulb = 0.0;
943 0 : for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
944 0 : sum_produc_area_wetbulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutWetBulbTemp(SurfNum);
945 : }
946 0 : Tamb = sum_produc_area_wetbulb / sum_area;
947 : }
948 :
949 : // inits for each iteration
950 : // UTSC( UTSCNum ).InletMDot = sum( Node( UTSC( UTSCNum ).InletNode ).MassFlowRate ); //Autodesk:F2C++ Array subscript usage:
951 : // Replaced by below
952 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot =
953 40675 : sum_sub(state.dataLoopNodes->Node,
954 : &DataLoopNode::NodeData::MassFlowRate,
955 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).InletNode); // Autodesk:F2C++ Functions handle array subscript usage
956 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).IsOn = false; // intialize then turn on if appropriate
957 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).Tplen = state.dataTranspiredCollector->UTSC(UTSCNum).TplenLast;
958 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll = state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast;
959 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).TairHX = Tamb;
960 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).MdotVent = 0.0;
961 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).HXeff = 0.0;
962 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).Isc = 0.0;
963 :
964 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).UTSCEfficiency = 0.0;
965 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).UTSCCollEff = 0.0;
966 40675 : }
967 :
968 9700 : void CalcActiveTranspiredCollector(EnergyPlusData &state, int const UTSCNum)
969 : {
970 :
971 : // SUBROUTINE INFORMATION:
972 : // AUTHOR B.T. Griffith
973 : // DATE WRITTEN November 2004
974 : // MODIFIED na
975 : // RE-ENGINEERED na
976 :
977 : // Using/Aliasing
978 : using ConvectionCoefficients::InitExteriorConvectionCoeff;
979 9700 : auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
980 : using DataSurfaces::SurfaceData;
981 : using Psychrometrics::PsyCpAirFnW;
982 : using Psychrometrics::PsyHFnTdbW;
983 : using Psychrometrics::PsyRhoAirFnPbTdbW;
984 : using namespace DataHeatBalance; // , ONLY: SurfQRadSWOutIncident, Construct, Material
985 :
986 : // SUBROUTINE PARAMETER DEFINITIONS:
987 9700 : Real64 constexpr nu(15.66e-6); // kinematic viscosity (m**2/s) for air at 300 K
988 : // (Mills 1999 Heat Transfer)
989 9700 : Real64 constexpr k(0.0267); // thermal conductivity (W/m K) for air at 300 K
990 : // (Mills 1999 Heat Transfer)
991 9700 : Real64 constexpr Sigma(5.6697e-08); // Stefan-Boltzmann constant
992 :
993 : // following arrays are used to temporarily hold results from multiple underlying surfaces
994 19400 : Array1D<Real64> HSkyARR;
995 19400 : Array1D<Real64> HGroundARR;
996 19400 : Array1D<Real64> HAirARR;
997 19400 : Array1D<Real64> HPlenARR;
998 19400 : Array1D<Real64> LocalWindArr;
999 :
1000 : // working variables
1001 : Real64 RhoAir; // density of air
1002 : Real64 CpAir; // specific heat of air
1003 : Real64 holeArea; // area of perforations, includes corrugation of surface
1004 : Real64 Tamb; // outdoor drybulb
1005 : Real64 A; // projected area of collector, from sum of underlying surfaces
1006 : Real64 Vholes; // mean velocity of air as it passes through collector holes
1007 : Real64 Vsuction; // mean velocity of air as is approaches the collector
1008 : Real64 Vplen; // mean velocity of air inside plenum
1009 : Real64 HcPlen; // surface convection heat transfer coefficient for plenum surfaces
1010 : Real64 D; // hole diameter
1011 : Real64 ReD; // Reynolds number for holes
1012 : Real64 P; // pitch, distance betweeen holes
1013 : Real64 Por; // porosity, area fraction of collector that is open because of holes
1014 : Real64 Mdot; // mass flow rate of suction air
1015 : Real64 QdotSource; // energy flux for source/sink inside collector surface (for hybrid PV UTSC)
1016 : int ThisSurf; // do loop counter
1017 : int NumSurfs; // number of underlying HT surfaces associated with UTSC
1018 : DataSurfaces::SurfaceRoughness Roughness; // parameters for surface roughness, defined in DataHeatBalance
1019 : Real64 SolAbs; // solar absorptivity of collector
1020 : Real64 AbsExt; // thermal emmittance of collector
1021 : Real64 TempExt; // collector temperature
1022 : int SurfPtr; // index of surface in main surface structure
1023 : Real64 HMovInsul; // dummy for call to InitExteriorConvectionCoeff
1024 : Real64 HExt; // dummy for call to InitExteriorConvectionCoeff
1025 : int ConstrNum; // index of construction in main construction structure
1026 : Real64 AbsThermSurf; // thermal emmittance of underlying wall.
1027 : Real64 TsoK; // underlying surface temperature in Kelvin
1028 : Real64 TscollK; // collector temperature in Kelvin (lagged)
1029 : Real64 AreaSum; // sum of contributing surfaces for area-weighted averages.
1030 : Real64 Vwind; // localized, and area-weighted average for wind speed
1031 : Real64 HrSky; // radiation coeff for sky, area-weighted average
1032 : Real64 HrGround; // radiation coeff for ground, area-weighted average
1033 : Real64 HrAtm; // radiation coeff for air (bulk atmosphere), area-weighted average
1034 : Real64 Isc; // Incoming combined solar radiation, area-weighted average
1035 : Real64 HrPlen; // radiation coeff for plenum surfaces, area-weighted average
1036 : Real64 Tso; // temperature of underlying surface, area-weighted average
1037 : Real64 HcWind; // convection coeff for high speed wind situations
1038 : Real64 NuD; // nusselt number for Reynolds based on hole
1039 : Real64 U; // overall heat exchanger coefficient
1040 : Real64 HXeff; // effectiveness for heat exchanger
1041 : Real64 t; // collector thickness
1042 : Real64 ReS; // Reynolds number based on suction velocity and pitch
1043 : Real64 ReW; // Reynolds number based on Wind and pitch
1044 : Real64 ReB; // Reynolds number based on hole velocity and pitch
1045 : Real64 ReH; // Reynolds number based on hole velocity and diameter
1046 : Real64 Tscoll; // temperature of collector
1047 : Real64 TaHX; // leaving air temperature from heat exchanger (entering plenum)
1048 : Real64 Taplen; // Air temperature in plen and outlet node.
1049 : Real64 SensHeatingRate; // Rate at which the system is heating outdoor air
1050 : Real64 AlessHoles; // Area for Kutscher's relation
1051 :
1052 : // Active UTSC calculation
1053 : // first do common things for both correlations
1054 9700 : Real64 sum_area = 0.0;
1055 22548 : for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
1056 12848 : sum_area += state.dataSurface->Surface(SurfNum).Area;
1057 : }
1058 9700 : if (!state.dataEnvrn->IsRain) {
1059 9700 : Real64 sum_produc_area_drybulb = 0.0;
1060 22548 : for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
1061 12848 : sum_produc_area_drybulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutDryBulbTemp(SurfNum);
1062 : }
1063 9700 : Tamb = sum_produc_area_drybulb / sum_area;
1064 : } else { // when raining we use wet bulb not drybulb
1065 0 : Real64 sum_produc_area_wetbulb = 0.0;
1066 0 : for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
1067 0 : sum_produc_area_wetbulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutWetBulbTemp(SurfNum);
1068 : }
1069 0 : Tamb = sum_produc_area_wetbulb / sum_area;
1070 : }
1071 :
1072 9700 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, Tamb, state.dataEnvrn->OutHumRat);
1073 :
1074 9700 : CpAir = PsyCpAirFnW(state.dataEnvrn->OutHumRat);
1075 :
1076 9700 : holeArea = state.dataTranspiredCollector->UTSC(UTSCNum).ActualArea * state.dataTranspiredCollector->UTSC(UTSCNum).Porosity;
1077 :
1078 9700 : A = state.dataTranspiredCollector->UTSC(UTSCNum).ProjArea;
1079 :
1080 9700 : Vholes = state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot / RhoAir / holeArea;
1081 :
1082 9700 : Vplen = state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot / RhoAir / state.dataTranspiredCollector->UTSC(UTSCNum).PlenCrossArea;
1083 :
1084 9700 : Vsuction = state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot / RhoAir / A;
1085 :
1086 9700 : if ((Vsuction < 0.001) || (Vsuction > 0.08)) { // warn that collector is not sized well
1087 0 : if (state.dataTranspiredCollector->UTSC(UTSCNum).VsucErrIndex == 0) {
1088 0 : ShowWarningMessage(state,
1089 0 : "Solar Collector:Unglazed Transpired=\"" + state.dataTranspiredCollector->UTSC(UTSCNum).Name +
1090 : "\", Suction velocity is outside of range for a good design");
1091 0 : ShowContinueErrorTimeStamp(state, format("Suction velocity ={:.4R}", Vsuction));
1092 0 : if (Vsuction < 0.003) {
1093 0 : ShowContinueError(state, "Velocity is low -- suggest decreasing area of transpired collector");
1094 : }
1095 0 : if (Vsuction > 0.08) {
1096 0 : ShowContinueError(state, "Velocity is high -- suggest increasing area of transpired collector");
1097 : }
1098 0 : ShowContinueError(state, "Occasional suction velocity messages are not unexpected when simulating actual conditions");
1099 : }
1100 0 : ShowRecurringWarningErrorAtEnd(state,
1101 0 : "Solar Collector:Unglazed Transpired=\"" + state.dataTranspiredCollector->UTSC(UTSCNum).Name +
1102 : "\", Suction velocity is outside of range",
1103 0 : state.dataTranspiredCollector->UTSC(UTSCNum).VsucErrIndex,
1104 : Vsuction,
1105 : Vsuction,
1106 : _,
1107 : "[m/s]",
1108 : "[m/s]");
1109 : }
1110 :
1111 9700 : HcPlen = 5.62 + 3.92 * Vplen;
1112 :
1113 9700 : D = state.dataTranspiredCollector->UTSC(UTSCNum).HoleDia;
1114 :
1115 9700 : ReD = Vholes * D / nu;
1116 :
1117 9700 : P = state.dataTranspiredCollector->UTSC(UTSCNum).Pitch;
1118 :
1119 9700 : Por = state.dataTranspiredCollector->UTSC(UTSCNum).Porosity;
1120 :
1121 9700 : Mdot = state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot;
1122 :
1123 9700 : QdotSource = state.dataTranspiredCollector->UTSC(UTSCNum).QdotSource; // for hybrid PV transpired collectors
1124 :
1125 : // loop through underlying surfaces and collect needed data
1126 : // now collect average values for things associated with the underlying surface(s)
1127 9700 : NumSurfs = state.dataTranspiredCollector->UTSC(UTSCNum).NumSurfs;
1128 9700 : HSkyARR.dimension(NumSurfs, 0.0);
1129 9700 : HGroundARR.dimension(NumSurfs, 0.0);
1130 9700 : HAirARR.dimension(NumSurfs, 0.0);
1131 9700 : LocalWindArr.dimension(NumSurfs, 0.0);
1132 : // ALLOCATE(IscARR(NumSurfs))
1133 : // IscARR = 0.0
1134 9700 : HPlenARR.dimension(NumSurfs, 0.0);
1135 : // ALLOCATE(TsoARR(NumSurfs))
1136 : // TsoARR = 0.0
1137 :
1138 9700 : Roughness = state.dataTranspiredCollector->UTSC(UTSCNum).CollRoughness;
1139 9700 : SolAbs = state.dataTranspiredCollector->UTSC(UTSCNum).SolAbsorp;
1140 9700 : AbsExt = state.dataTranspiredCollector->UTSC(UTSCNum).LWEmitt;
1141 9700 : TempExt = state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast;
1142 22548 : for (ThisSurf = 1; ThisSurf <= NumSurfs; ++ThisSurf) {
1143 12848 : SurfPtr = state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs(ThisSurf);
1144 : // Initializations for this surface
1145 12848 : HMovInsul = 0.0;
1146 12848 : HExt = 0.0;
1147 12848 : LocalWindArr(ThisSurf) = state.dataSurface->SurfOutWindSpeed(SurfPtr);
1148 12848 : InitExteriorConvectionCoeff(
1149 12848 : state, SurfPtr, HMovInsul, Roughness, AbsExt, TempExt, HExt, HSkyARR(ThisSurf), HGroundARR(ThisSurf), HAirARR(ThisSurf));
1150 12848 : ConstrNum = state.dataSurface->Surface(SurfPtr).Construction;
1151 12848 : AbsThermSurf = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpThermal;
1152 12848 : TsoK = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfPtr) + DataGlobalConstants::KelvinConv;
1153 12848 : TscollK = state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast + DataGlobalConstants::KelvinConv;
1154 12848 : HPlenARR(ThisSurf) = Sigma * AbsExt * AbsThermSurf * (pow_4(TscollK) - pow_4(TsoK)) / (TscollK - TsoK);
1155 : }
1156 : // AreaSum = sum( Surface( UTSC( UTSCNum ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below
1157 : auto Area(
1158 9700 : array_sub(state.dataSurface->Surface,
1159 : &SurfaceData::Area,
1160 9700 : state.dataTranspiredCollector->UTSC(UTSCNum)
1161 29100 : .SurfPtrs)); // Autodesk:F2C++ Copy of subscripted Area array for use below: This makes a copy so review wrt performance
1162 9700 : AreaSum = sum(Area);
1163 : // now figure area-weighted averages from underlying surfaces.
1164 : // Vwind = sum( LocalWindArr * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array subscript usage:
1165 : // Replaced by below
1166 9700 : Vwind = sum(LocalWindArr * Area) / AreaSum;
1167 9700 : LocalWindArr.deallocate();
1168 : // HrSky = sum( HSkyARR * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array subscript usage: Replaced
1169 : // by below
1170 9700 : HrSky = sum(HSkyARR * Area) / AreaSum;
1171 9700 : HSkyARR.deallocate();
1172 : // HrGround = sum( HGroundARR * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array subscript usage:
1173 : // Replaced by below
1174 9700 : HrGround = sum(HGroundARR * Area) / AreaSum;
1175 9700 : HGroundARR.deallocate();
1176 : // HrAtm = sum( HAirARR * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array subscript usage: Replaced
1177 : // by below
1178 9700 : HrAtm = sum(HAirARR * Area) / AreaSum;
1179 9700 : HAirARR.deallocate();
1180 : // HrPlen = sum( HPlenARR * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array subscript usage:
1181 : // Replaced by below
1182 9700 : HrPlen = sum(HPlenARR * Area) / AreaSum;
1183 9700 : HPlenARR.deallocate();
1184 :
1185 : // Isc = sum( SurfQRadSWOutIncident( UTSC( UTSCNum ).SurfPtrs ) * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum;
1186 : ////Autodesk:F2C++ Array subscript usage: Replaced by below
1187 19400 : Isc = sum_product_sub(state.dataHeatBal->SurfQRadSWOutIncident,
1188 9700 : state.dataSurface->Surface,
1189 : &SurfaceData::Area,
1190 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) /
1191 : AreaSum; // Autodesk:F2C++ Functions handle array subscript usage
1192 : // Tso = sum( TH( UTSC( UTSCNum ).SurfPtrs, 1, 1 ) * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array
1193 : // subscript usage: Replaced by below
1194 19400 : Tso = sum_product_sub(state.dataHeatBalSurf->SurfOutsideTempHist(1),
1195 9700 : state.dataSurface->Surface,
1196 : &SurfaceData::Area,
1197 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) /
1198 : AreaSum; // Autodesk:F2C++ Functions handle array subscript usage
1199 :
1200 9700 : if (Vwind > 5.0) {
1201 0 : HcWind = 5.62 + 3.9 * (Vwind - 5.0); // McAdams forced convection correlation
1202 : } else {
1203 9700 : HcWind = 0.0;
1204 : }
1205 :
1206 9700 : if (state.dataEnvrn->IsRain) HcWind = 1000.0;
1207 :
1208 9700 : HXeff = 0.0; // init
1209 :
1210 9700 : switch (state.dataTranspiredCollector->UTSC(UTSCNum).Correlation) {
1211 6424 : case Correlation_Kutscher1994: { // Kutscher1994
1212 6424 : AlessHoles = A - holeArea;
1213 :
1214 6424 : NuD = 2.75 * ((std::pow(P / D, -1.2) * std::pow(ReD, 0.43)) + (0.011 * Por * ReD * std::pow(Vwind / Vsuction, 0.48)));
1215 6424 : U = k * NuD / D;
1216 6424 : HXeff = 1.0 - std::exp(-1.0 * ((U * AlessHoles) / (Mdot * CpAir)));
1217 6424 : } break;
1218 3276 : case Correlation_VanDeckerHollandsBrunger2001: { // VanDeckerHollandsBrunger2001
1219 3276 : t = state.dataTranspiredCollector->UTSC(UTSCNum).CollectThick;
1220 3276 : ReS = Vsuction * P / nu;
1221 3276 : ReW = Vwind * P / nu;
1222 3276 : ReB = Vholes * P / nu;
1223 3276 : ReH = (Vsuction * D) / (nu * Por);
1224 3276 : if (ReD > 0.0) {
1225 3276 : if (ReW > 0.0) {
1226 9828 : HXeff = (1.0 - std::pow(1.0 + ReS * max(1.733 * std::pow(ReW, -0.5), 0.02136), -1.0)) *
1227 6552 : (1.0 - std::pow(1.0 + 0.2273 * std::sqrt(ReB), -1.0)) * std::exp(-0.01895 * (P / D) - (20.62 / ReH) * (t / D));
1228 : } else {
1229 0 : HXeff = (1.0 - std::pow(1.0 + ReS * 0.02136, -1.0)) * (1.0 - std::pow(1.0 + 0.2273 * std::sqrt(ReB), -1.0)) *
1230 0 : std::exp(-0.01895 * (P / D) - (20.62 / ReH) * (t / D));
1231 : }
1232 : } else {
1233 0 : HXeff = 0.0;
1234 : }
1235 3276 : } break;
1236 0 : default:
1237 0 : break;
1238 : }
1239 :
1240 : // now calculate collector temperature
1241 :
1242 29100 : Tscoll = (Isc * SolAbs + HrAtm * Tamb + HrSky * state.dataEnvrn->SkyTemp + HrGround * Tamb + HrPlen * Tso + HcWind * Tamb +
1243 19400 : (Mdot * CpAir / A) * Tamb - (Mdot * CpAir / A) * (1.0 - HXeff) * Tamb + QdotSource) /
1244 9700 : (HrAtm + HrSky + HrGround + HrPlen + HcWind + (Mdot * CpAir / A) * HXeff);
1245 :
1246 : // Heat exchanger leaving temperature
1247 9700 : TaHX = HXeff * Tscoll + (1.0 - HXeff) * Tamb;
1248 :
1249 : // now calculate plenum air temperature
1250 :
1251 9700 : Taplen = (Mdot * CpAir * TaHX + HcPlen * A * Tso) / (Mdot * CpAir + HcPlen * A);
1252 :
1253 : // calculate Sensible Heating Rate
1254 9700 : if (Taplen > Tamb) {
1255 1714 : SensHeatingRate = Mdot * CpAir * (Taplen - Tamb);
1256 : } else {
1257 7986 : SensHeatingRate = 0.0;
1258 : }
1259 :
1260 : // now fill results into derived types
1261 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).Isc = Isc;
1262 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).HXeff = HXeff;
1263 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).Tplen = Taplen;
1264 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll = Tscoll;
1265 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).HrPlen = HrPlen;
1266 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).HcPlen = HcPlen;
1267 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).TairHX = TaHX;
1268 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot = Mdot;
1269 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).InletTempDB = Tamb;
1270 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).Vsuction = Vsuction;
1271 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).PlenumVelocity = Vplen;
1272 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).SupOutTemp = Taplen;
1273 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).SupOutHumRat = state.dataEnvrn->OutHumRat; // stays the same with sensible heating
1274 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).SupOutEnth =
1275 9700 : PsyHFnTdbW(state.dataTranspiredCollector->UTSC(UTSCNum).SupOutTemp, state.dataTranspiredCollector->UTSC(UTSCNum).SupOutHumRat);
1276 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).SupOutMassFlow = Mdot;
1277 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).SensHeatingRate = SensHeatingRate;
1278 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).SensHeatingEnergy = SensHeatingRate * TimeStepSys * DataGlobalConstants::SecInHour;
1279 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).PassiveACH = 0.0;
1280 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotVent = 0.0;
1281 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotWind = 0.0;
1282 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotTherm = 0.0;
1283 9700 : if (Isc > 10.0) {
1284 0 : state.dataTranspiredCollector->UTSC(UTSCNum).UTSCEfficiency = SensHeatingRate / (Isc * A);
1285 0 : if (TaHX > Tamb) {
1286 0 : state.dataTranspiredCollector->UTSC(UTSCNum).UTSCCollEff = Mdot * CpAir * (TaHX - Tamb) / (Isc * A);
1287 : } else {
1288 0 : state.dataTranspiredCollector->UTSC(UTSCNum).UTSCCollEff = 0.0;
1289 : }
1290 : } else {
1291 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).UTSCEfficiency = 0.0;
1292 9700 : state.dataTranspiredCollector->UTSC(UTSCNum).UTSCCollEff = 0.0;
1293 : }
1294 9700 : }
1295 :
1296 30975 : void CalcPassiveTranspiredCollector(EnergyPlusData &state, int const UTSCNum)
1297 : {
1298 :
1299 : // SUBROUTINE INFORMATION:
1300 : // AUTHOR B.T. Griffith
1301 : // DATE WRITTEN November 2004
1302 : // MODIFIED na
1303 : // RE-ENGINEERED na
1304 :
1305 : // PURPOSE OF THIS SUBROUTINE:
1306 : // model the effect of the a ventilated baffle covering the outside of a heat transfer surface.
1307 :
1308 : // METHODOLOGY EMPLOYED:
1309 : // All the work is done in a subroutine .
1310 :
1311 : // REFERENCES:
1312 : // Nat. Vent. equations from ASHRAE HoF 2001 Chapt. 26
1313 :
1314 : // Using/Aliasing
1315 : using DataSurfaces::SurfaceData;
1316 : using Psychrometrics::PsyHFnTdbW;
1317 : using Psychrometrics::PsyRhoAirFnPbTdbW;
1318 : using Psychrometrics::PsyWFnTdbTwbPb;
1319 :
1320 : // local working variables
1321 : Real64 AspRat; // Aspect Ratio of gap
1322 : Real64 TmpTscoll;
1323 : Real64 TmpTaPlen;
1324 : Real64 RhoAir;
1325 : Real64 holeArea;
1326 : Real64 Tamb;
1327 : Real64 HrPlen;
1328 : Real64 HcPlen;
1329 : Real64 Isc;
1330 : Real64 MdotVent;
1331 : Real64 VdotWind;
1332 : Real64 VdotThermal;
1333 : Real64 Twbamb;
1334 : Real64 OutHumRatAmb;
1335 :
1336 : // Tamb = sum( Surface( UTSC( UTSCNum ).SurfPtrs ).OutDryBulbTemp * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / sum( Surface(
1337 : // UTSC( UTSCNum ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below
1338 30975 : Real64 sum_area = 0.0;
1339 30975 : Real64 sum_produc_area_drybulb = 0.0;
1340 30975 : Real64 sum_produc_area_wetbulb = 0.0;
1341 82149 : for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
1342 51174 : sum_area += state.dataSurface->Surface(SurfNum).Area;
1343 51174 : sum_produc_area_wetbulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutWetBulbTemp(SurfNum);
1344 51174 : sum_produc_area_drybulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutDryBulbTemp(SurfNum);
1345 : }
1346 30975 : Tamb = sum_produc_area_drybulb / sum_area;
1347 30975 : Twbamb = sum_produc_area_wetbulb / sum_area;
1348 :
1349 30975 : OutHumRatAmb = PsyWFnTdbTwbPb(state, Tamb, Twbamb, state.dataEnvrn->OutBaroPress);
1350 :
1351 30975 : RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, Tamb, OutHumRatAmb);
1352 30975 : holeArea = state.dataTranspiredCollector->UTSC(UTSCNum).ActualArea * state.dataTranspiredCollector->UTSC(UTSCNum).Porosity;
1353 :
1354 30975 : AspRat = state.dataTranspiredCollector->UTSC(UTSCNum).Height / state.dataTranspiredCollector->UTSC(UTSCNum).PlenGapThick;
1355 30975 : TmpTscoll = state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast;
1356 30975 : TmpTaPlen = state.dataTranspiredCollector->UTSC(UTSCNum).TplenLast;
1357 :
1358 : // all the work is done in this routine located in GeneralRoutines.cc
1359 :
1360 340725 : CalcPassiveExteriorBaffleGap(state,
1361 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs,
1362 : holeArea,
1363 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).Cv,
1364 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).Cd,
1365 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).HdeltaNPL,
1366 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).SolAbsorp,
1367 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).LWEmitt,
1368 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).Tilt,
1369 : AspRat,
1370 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).PlenGapThick,
1371 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).CollRoughness,
1372 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).QdotSource,
1373 : TmpTscoll,
1374 : TmpTaPlen,
1375 : HcPlen,
1376 : HrPlen,
1377 : Isc,
1378 : MdotVent,
1379 : VdotWind,
1380 : VdotThermal);
1381 :
1382 : // now fill results into derived types
1383 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).Isc = Isc;
1384 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).Tplen = TmpTaPlen;
1385 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll = TmpTscoll;
1386 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).HrPlen = HrPlen;
1387 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).HcPlen = HcPlen;
1388 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).TairHX = Tamb;
1389 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot = 0.0;
1390 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).InletTempDB = Tamb;
1391 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).Vsuction = 0.0;
1392 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).PlenumVelocity = 0.0;
1393 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).SupOutTemp = TmpTaPlen;
1394 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).SupOutHumRat = OutHumRatAmb;
1395 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).SupOutEnth = PsyHFnTdbW(TmpTaPlen, OutHumRatAmb);
1396 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).SupOutMassFlow = 0.0;
1397 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).SensHeatingRate = 0.0;
1398 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).SensHeatingEnergy = 0.0;
1399 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).PassiveACH =
1400 61950 : (MdotVent / RhoAir) *
1401 61950 : (1.0 / (state.dataTranspiredCollector->UTSC(UTSCNum).ProjArea * state.dataTranspiredCollector->UTSC(UTSCNum).PlenGapThick)) *
1402 : DataGlobalConstants::SecInHour;
1403 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotVent = MdotVent;
1404 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotWind = VdotWind * RhoAir;
1405 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotTherm = VdotThermal * RhoAir;
1406 30975 : state.dataTranspiredCollector->UTSC(UTSCNum).UTSCEfficiency = 0.0;
1407 30975 : }
1408 :
1409 40675 : void UpdateTranspiredCollector(EnergyPlusData &state, int const UTSCNum)
1410 : {
1411 :
1412 : // SUBROUTINE INFORMATION:
1413 : // AUTHOR B.T. Griffith
1414 : // DATE WRITTEN November 2004
1415 : // MODIFIED na
1416 : // RE-ENGINEERED na
1417 :
1418 : int OutletNode;
1419 : int InletNode;
1420 : int thisOSCM;
1421 : int thisOASys;
1422 :
1423 : // update "last" values in Derived type
1424 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).TplenLast = state.dataTranspiredCollector->UTSC(UTSCNum).Tplen;
1425 40675 : state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast = state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll;
1426 :
1427 : // Set the outlet air nodes of the UTSC
1428 :
1429 40675 : if (state.dataTranspiredCollector->UTSC(UTSCNum).IsOn) { // Active
1430 9700 : if (state.dataTranspiredCollector->UTSC(UTSCNum).NumOASysAttached == 1) {
1431 6552 : OutletNode = state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode(1);
1432 6552 : InletNode = state.dataTranspiredCollector->UTSC(UTSCNum).InletNode(1);
1433 6552 : state.dataLoopNodes->Node(OutletNode).MassFlowRate = state.dataTranspiredCollector->UTSC(UTSCNum).SupOutMassFlow;
1434 6552 : state.dataLoopNodes->Node(OutletNode).Temp = state.dataTranspiredCollector->UTSC(UTSCNum).SupOutTemp;
1435 6552 : state.dataLoopNodes->Node(OutletNode).HumRat = state.dataTranspiredCollector->UTSC(UTSCNum).SupOutHumRat;
1436 6552 : state.dataLoopNodes->Node(OutletNode).Enthalpy = state.dataTranspiredCollector->UTSC(UTSCNum).SupOutEnth;
1437 3148 : } else if (state.dataTranspiredCollector->UTSC(UTSCNum).NumOASysAttached > 1) {
1438 18888 : for (thisOASys = 1; thisOASys <= state.dataTranspiredCollector->UTSC(UTSCNum).NumOASysAttached; ++thisOASys) {
1439 15740 : state.dataLoopNodes->Node(state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode(thisOASys)).MassFlowRate =
1440 15740 : state.dataLoopNodes->Node(state.dataTranspiredCollector->UTSC(UTSCNum).InletNode(thisOASys))
1441 15740 : .MassFlowRate; // system gets what it asked for at inlet
1442 15740 : state.dataLoopNodes->Node(state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode(thisOASys)).Temp =
1443 15740 : state.dataTranspiredCollector->UTSC(UTSCNum).SupOutTemp;
1444 15740 : state.dataLoopNodes->Node(state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode(thisOASys)).HumRat =
1445 15740 : state.dataTranspiredCollector->UTSC(UTSCNum).SupOutHumRat;
1446 15740 : state.dataLoopNodes->Node(state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode(thisOASys)).Enthalpy =
1447 15740 : state.dataTranspiredCollector->UTSC(UTSCNum).SupOutEnth;
1448 : }
1449 : }
1450 : } else { // Passive and/or bypassed Note Array assignments in following
1451 : // Autodesk:F2C++ Array subscript usage: Replaced by below
1452 : // Node( UTSC( UTSCNum ).OutletNode ).MassFlowRate = Node( UTSC( UTSCNum ).InletNode ).MassFlowRate;
1453 : // Node( UTSC( UTSCNum ).OutletNode ).Temp = Node( UTSC( UTSCNum ).InletNode ).Temp;
1454 : // Node( UTSC( UTSCNum ).OutletNode ).HumRat = Node( UTSC( UTSCNum ).InletNode ).HumRat;
1455 : // Node( UTSC( UTSCNum ).OutletNode ).Enthalpy = Node( UTSC( UTSCNum ).InletNode ).Enthalpy;
1456 30975 : auto const &OutletNode(state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode);
1457 30975 : auto const &InletNode(state.dataTranspiredCollector->UTSC(UTSCNum).InletNode);
1458 30975 : assert(OutletNode.size() == InletNode.size());
1459 142746 : for (int io = OutletNode.l(), ii = InletNode.l(), eo = OutletNode.u(); io <= eo; ++io, ++ii) {
1460 111771 : auto &outNode(state.dataLoopNodes->Node(OutletNode(io)));
1461 111771 : auto const &inNode(state.dataLoopNodes->Node(InletNode(ii)));
1462 111771 : outNode.MassFlowRate = inNode.MassFlowRate;
1463 111771 : outNode.Temp = inNode.Temp;
1464 111771 : outNode.HumRat = inNode.HumRat;
1465 111771 : outNode.Enthalpy = inNode.Enthalpy;
1466 : }
1467 : }
1468 :
1469 : // update the OtherSideConditionsModel coefficients.
1470 40675 : thisOSCM = state.dataTranspiredCollector->UTSC(UTSCNum).OSCMPtr;
1471 :
1472 40675 : state.dataSurface->OSCM(thisOSCM).TConv = state.dataTranspiredCollector->UTSC(UTSCNum).Tplen;
1473 40675 : state.dataSurface->OSCM(thisOSCM).HConv = state.dataTranspiredCollector->UTSC(UTSCNum).HcPlen;
1474 40675 : state.dataSurface->OSCM(thisOSCM).TRad = state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll;
1475 40675 : state.dataSurface->OSCM(thisOSCM).HRad = state.dataTranspiredCollector->UTSC(UTSCNum).HrPlen;
1476 40675 : }
1477 :
1478 8208 : void SetUTSCQdotSource(EnergyPlusData &state,
1479 : int const UTSCNum,
1480 : Real64 const QSource // source term in Watts
1481 : )
1482 : {
1483 :
1484 : // SUBROUTINE INFORMATION:
1485 : // AUTHOR B. Griffith
1486 : // DATE WRITTEN November 2004
1487 : // MODIFIED na
1488 : // RE-ENGINEERED na
1489 :
1490 : // PURPOSE OF THIS SUBROUTINE:
1491 : // object oriented "Set" routine for updating sink term without exposing variables
1492 :
1493 : // METHODOLOGY EMPLOYED:
1494 : // update derived type with new data , turn power into W/m2
1495 :
1496 8208 : state.dataTranspiredCollector->UTSC(UTSCNum).QdotSource = QSource / state.dataTranspiredCollector->UTSC(UTSCNum).ProjArea;
1497 8208 : }
1498 :
1499 1 : void GetTranspiredCollectorIndex(EnergyPlusData &state, int const SurfacePtr, int &UTSCIndex)
1500 : {
1501 :
1502 : // SUBROUTINE INFORMATION:
1503 : // AUTHOR B. Griffith
1504 : // DATE WRITTEN November 2004
1505 : // MODIFIED na
1506 : // RE-ENGINEERED na
1507 :
1508 : // PURPOSE OF THIS SUBROUTINE:
1509 : // object oriented "Get" routine for establishing correct integer index from outside this module
1510 :
1511 : // METHODOLOGY EMPLOYED:
1512 : // mine Surface derived type for correct index/number of surface
1513 : // mine UTSC derived type that has the surface.
1514 :
1515 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1516 : int UTSCNum; // temporary
1517 : int ThisSurf; // temporary
1518 : int thisUTSC;
1519 : bool Found;
1520 :
1521 1 : if (state.dataTranspiredCollector->GetInputFlag) {
1522 1 : GetTranspiredCollectorInput(state);
1523 1 : state.dataTranspiredCollector->GetInputFlag = false;
1524 : }
1525 :
1526 1 : if (SurfacePtr == 0) {
1527 0 : ShowFatalError(state,
1528 0 : "Invalid surface passed to GetTranspiredCollectorIndex, Surface name = " + state.dataSurface->Surface(SurfacePtr).Name);
1529 : }
1530 :
1531 1 : UTSCNum = 0;
1532 1 : Found = false;
1533 6 : for (thisUTSC = 1; thisUTSC <= state.dataTranspiredCollector->NumUTSC; ++thisUTSC) {
1534 11 : for (ThisSurf = 1; ThisSurf <= state.dataTranspiredCollector->UTSC(thisUTSC).NumSurfs; ++ThisSurf) {
1535 6 : if (SurfacePtr == state.dataTranspiredCollector->UTSC(thisUTSC).SurfPtrs(ThisSurf)) {
1536 1 : Found = true;
1537 1 : UTSCNum = thisUTSC;
1538 : }
1539 : }
1540 : }
1541 :
1542 1 : if (!Found) {
1543 0 : ShowFatalError(state,
1544 0 : "Did not find surface in UTSC description in GetTranspiredCollectorIndex, Surface name = " +
1545 0 : state.dataSurface->Surface(SurfacePtr).Name);
1546 : } else {
1547 :
1548 1 : UTSCIndex = UTSCNum;
1549 : }
1550 1 : }
1551 :
1552 0 : void GetUTSCTsColl(EnergyPlusData &state, int const UTSCNum, Real64 &TsColl)
1553 : {
1554 :
1555 : // SUBROUTINE INFORMATION:
1556 : // AUTHOR <author>
1557 : // DATE WRITTEN <date_written>
1558 : // MODIFIED na
1559 : // RE-ENGINEERED na
1560 :
1561 : // PURPOSE OF THIS SUBROUTINE:
1562 : // object oriented "Get" routine for collector surface temperature
1563 :
1564 : // METHODOLOGY EMPLOYED:
1565 : // access derived type
1566 :
1567 0 : TsColl = state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll;
1568 0 : }
1569 :
1570 0 : int GetAirInletNodeNum(EnergyPlusData &state, std::string const &UTSCName, bool &ErrorsFound)
1571 : {
1572 : // FUNCTION INFORMATION:
1573 : // AUTHOR Lixing Gu
1574 : // DATE WRITTEN May 2019
1575 : // MODIFIED na
1576 : // RE-ENGINEERED na
1577 :
1578 : // PURPOSE OF THIS FUNCTION:
1579 : // This function looks up the given UTSC and returns the air inlet node number.
1580 : // If incorrect UTSC name is given, ErrorsFound is returned as true and node number as zero.
1581 :
1582 : // Return value
1583 : int NodeNum; // node number returned
1584 :
1585 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1586 : int WhichUTSC;
1587 :
1588 0 : if (state.dataTranspiredCollector->GetInputFlag) {
1589 0 : GetTranspiredCollectorInput(state);
1590 0 : state.dataTranspiredCollector->GetInputFlag = false;
1591 : }
1592 :
1593 0 : WhichUTSC = UtilityRoutines::FindItemInList(UTSCName, state.dataTranspiredCollector->UTSC);
1594 0 : if (WhichUTSC != 0) {
1595 0 : NodeNum = state.dataTranspiredCollector->UTSC(WhichUTSC).InletNode(1);
1596 : } else {
1597 0 : ShowSevereError(state, "GetAirInletNodeNum: Could not find TranspiredCollector = \"" + UTSCName + "\"");
1598 0 : ErrorsFound = true;
1599 0 : NodeNum = 0;
1600 : }
1601 :
1602 0 : return NodeNum;
1603 : }
1604 :
1605 0 : int GetAirOutletNodeNum(EnergyPlusData &state, std::string const &UTSCName, bool &ErrorsFound)
1606 : {
1607 : // FUNCTION INFORMATION:
1608 : // AUTHOR Lixing Gu
1609 : // DATE WRITTEN May 2019
1610 : // MODIFIED na
1611 : // RE-ENGINEERED na
1612 :
1613 : // PURPOSE OF THIS FUNCTION:
1614 : // This function looks up the given UTSC and returns the air outlet node number.
1615 : // If incorrect UTSC name is given, ErrorsFound is returned as true and node number as zero.
1616 :
1617 : // Return value
1618 : int NodeNum; // node number returned
1619 :
1620 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1621 : int WhichUTSC;
1622 :
1623 0 : if (state.dataTranspiredCollector->GetInputFlag) {
1624 0 : GetTranspiredCollectorInput(state);
1625 0 : state.dataTranspiredCollector->GetInputFlag = false;
1626 : }
1627 :
1628 0 : WhichUTSC = UtilityRoutines::FindItemInList(UTSCName, state.dataTranspiredCollector->UTSC);
1629 0 : if (WhichUTSC != 0) {
1630 0 : NodeNum = state.dataTranspiredCollector->UTSC(WhichUTSC).OutletNode(1);
1631 : } else {
1632 0 : ShowSevereError(state, "GetAirOutletNodeNum: Could not find TranspiredCollector = \"" + UTSCName + "\"");
1633 0 : ErrorsFound = true;
1634 0 : NodeNum = 0;
1635 : }
1636 :
1637 0 : return NodeNum;
1638 : }
1639 :
1640 : } // namespace TranspiredCollector
1641 :
1642 2313 : } // namespace EnergyPlus
|