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 <algorithm>
50 : #include <cmath>
51 : #include <string>
52 :
53 : // ObjexxFCL Headers
54 : #include <ObjexxFCL/Array.functions.hh>
55 : #include <ObjexxFCL/Array1S.hh>
56 : #include <ObjexxFCL/ArrayS.functions.hh>
57 : #include <ObjexxFCL/Fmath.hh>
58 : #include <ObjexxFCL/string.functions.hh>
59 :
60 : // EnergyPlus Headers
61 : #include <EnergyPlus/BITF.hh>
62 : #include <EnergyPlus/Construction.hh>
63 : #include <EnergyPlus/CurveManager.hh>
64 : #include <EnergyPlus/Data/EnergyPlusData.hh>
65 : #include <EnergyPlus/DataBSDFWindow.hh>
66 : #include <EnergyPlus/DataComplexFenestration.hh>
67 : #include <EnergyPlus/DataContaminantBalance.hh>
68 : #include <EnergyPlus/DataHVACGlobals.hh>
69 : #include <EnergyPlus/DataHeatBalFanSys.hh>
70 : #include <EnergyPlus/DataHeatBalSurface.hh>
71 : #include <EnergyPlus/DataHeatBalance.hh>
72 : #include <EnergyPlus/DataIPShortCuts.hh>
73 : #include <EnergyPlus/DataReportingFlags.hh>
74 : #include <EnergyPlus/DataStringGlobals.hh>
75 : #include <EnergyPlus/DataSurfaces.hh>
76 : #include <EnergyPlus/DataSystemVariables.hh>
77 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
78 : #include <EnergyPlus/DaylightingDevices.hh>
79 : #include <EnergyPlus/DaylightingManager.hh>
80 : #include <EnergyPlus/DisplayRoutines.hh>
81 : #include <EnergyPlus/EMSManager.hh>
82 : #include <EnergyPlus/EconomicTariff.hh>
83 : #include <EnergyPlus/FileSystem.hh>
84 : #include <EnergyPlus/General.hh>
85 : #include <EnergyPlus/GlobalNames.hh>
86 : #include <EnergyPlus/HVACSizingSimulationManager.hh>
87 : #include <EnergyPlus/HVACSystemRootFindingAlgorithm.hh>
88 : #include <EnergyPlus/HeatBalanceIntRadExchange.hh>
89 : #include <EnergyPlus/HeatBalanceManager.hh>
90 : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
91 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
92 : #include <EnergyPlus/InternalHeatGains.hh>
93 : #include <EnergyPlus/MatrixDataManager.hh>
94 : #include <EnergyPlus/NodeInputManager.hh>
95 : #include <EnergyPlus/OutAirNodeManager.hh>
96 : #include <EnergyPlus/OutputProcessor.hh>
97 : #include <EnergyPlus/OutputReportTabular.hh>
98 : #include <EnergyPlus/PhaseChangeModeling/HysteresisModel.hh>
99 : #include <EnergyPlus/PluginManager.hh>
100 : #include <EnergyPlus/ScheduleManager.hh>
101 : #include <EnergyPlus/SolarShading.hh>
102 : #include <EnergyPlus/StringUtilities.hh>
103 : #include <EnergyPlus/SurfaceGeometry.hh>
104 : #include <EnergyPlus/SurfaceOctree.hh>
105 : #include <EnergyPlus/TARCOGGassesParams.hh>
106 : #include <EnergyPlus/TARCOGParams.hh>
107 : #include <EnergyPlus/UtilityRoutines.hh>
108 : #include <EnergyPlus/WindowComplexManager.hh>
109 : #include <EnergyPlus/WindowEquivalentLayer.hh>
110 : #include <EnergyPlus/WindowManager.hh>
111 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
112 :
113 : namespace EnergyPlus {
114 :
115 : namespace HeatBalanceManager {
116 :
117 : // Module containing the heat balance simulation routines
118 : // calculation (initialization) routines
119 :
120 : // MODULE INFORMATION:
121 : // AUTHOR Richard J. Liesen
122 : // DATE WRITTEN February 1998
123 : // MODIFIED November 1998, FW
124 : // MODIFIED April 1999, LKL
125 : // MODIFIED Dec 2006 DJS of PSU for ecoroof
126 : // Added Dec 2008 TH for thermochromic windows:
127 : // new subroutine CreateTCConstructions called by GetHeatBalanceInput
128 : // RE-ENGINEERED na
129 :
130 : // PURPOSE OF THIS MODULE:
131 : // To encapsulate the data and algorithms required to
132 : // manage the heat balance simulation on the building.
133 :
134 : // METHODOLOGY EMPLOYED:
135 :
136 : // REFERENCES:
137 : // The heat balance method is outlined in the "Tarp Algorithms Manual"
138 : // The methods are also summarized in many BSO Theses and papers.
139 :
140 : // OTHER NOTES:
141 : // This module was created from IBLAST subroutines
142 :
143 : // USE STATEMENTS:
144 : // Use statements for data only modules
145 : // Using/Aliasing
146 : using namespace DataComplexFenestration;
147 : using namespace DataEnvironment;
148 : using namespace DataHeatBalance;
149 : using namespace DataHeatBalSurface;
150 : using namespace DataRoomAirModel;
151 : using DataSurfaces::FrameDividerProperties;
152 : using ScheduleManager::GetCurrentScheduleValue;
153 : using ScheduleManager::GetScheduleIndex;
154 : using WindowComplexManager::CalculateBasisLength;
155 : using WindowManager::W5LsqFit;
156 :
157 771 : Array1D_string const PassFail(2, {"Fail", "Pass"});
158 :
159 2568313 : void ManageHeatBalance(EnergyPlusData &state)
160 : {
161 :
162 : // SUBROUTINE INFORMATION:
163 : // AUTHOR Rick Strand
164 : // DATE WRITTEN January 1997
165 : // MODIFIED February 1998 Richard Liesen
166 : // RE-ENGINEERED na
167 :
168 : // PURPOSE OF THIS SUBROUTINE:
169 : // This subroutine manages the heat balance method of calculating
170 : // building thermal loads. It is called from the SimulationManager
171 : // at the time step level. This driver manages the calls to all of
172 : // the other modules, drivers, and simulation algorithms.
173 :
174 : // METHODOLOGY EMPLOYED:
175 : // The order of this routine was taken from HeatBalanceModule with routine
176 : // and Data Structuring
177 :
178 : // REFERENCES:
179 : // Legacy code from (I)BLAST, subroutine SIMZGD.
180 :
181 : // Using/Aliasing
182 : using namespace HeatBalanceSurfaceManager;
183 : using EMSManager::ManageEMS;
184 : using EMSManager::UpdateEMSTrendVariables;
185 :
186 : // Locals
187 : // SUBROUTINE ARGUMENT DEFINITIONS:
188 : // na
189 :
190 : // SUBROUTINE PARAMETER DEFINITIONS:
191 : // na
192 :
193 : // INTERFACE BLOCK SPECIFICATIONS:
194 : // na
195 :
196 : // DERIVED TYPE DEFINITIONS:
197 : // na
198 :
199 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
200 :
201 : // Get the heat balance input at the beginning of the simulation only
202 2568313 : if (state.dataHeatBalMgr->ManageHeatBalanceGetInputFlag) {
203 771 : GetHeatBalanceInput(state); // Obtains heat balance related parameters from input file
204 771 : if (state.dataGlobal->DoingSizing) state.dataHeatBal->doSpaceHeatBalance = state.dataHeatBal->doSpaceHeatBalanceSizing;
205 771 : HeatBalanceIntRadExchange::InitSolarViewFactors(state);
206 :
207 : // Surface octree setup
208 : // The surface octree holds live references to surfaces so it must be updated
209 : // if in the future surfaces are altered after this point
210 771 : if (state.dataSurface->TotSurfaces >= DaylightingManager::octreeCrossover) { // Octree can be active
211 86 : if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Daylighting:Controls") > 0) { // Daylighting is active
212 15 : state.dataHeatBalMgr->surfaceOctree.init(state.dataSurface->Surface); // Set up surface octree
213 : }
214 : }
215 :
216 44533 : for (auto &surface : state.dataSurface->Surface)
217 43762 : surface.set_computed_geometry(); // Set up extra surface geometry info for PierceSurface
218 :
219 771 : state.dataHeatBalMgr->ManageHeatBalanceGetInputFlag = false;
220 : }
221 :
222 : bool anyRan;
223 :
224 2568313 : ManageEMS(state,
225 : EMSManager::EMSCallFrom::BeginZoneTimestepBeforeInitHeatBalance,
226 : anyRan,
227 5136626 : ObjexxFCL::Optional_int_const()); // EMS calling point
228 :
229 : // These Inits will still have to be looked at as the routines are re-engineered further
230 :
231 2568313 : InitHeatBalance(state); // Initialize all heat balance related parameters
232 2568313 : ManageEMS(
233 5136626 : state, EMSManager::EMSCallFrom::BeginZoneTimestepAfterInitHeatBalance, anyRan, ObjexxFCL::Optional_int_const()); // EMS calling point
234 :
235 : // Solve the zone heat balance by first calling the Surface Heat Balance Manager
236 : // and then the Air Heat Balance Manager is called by the Surface Heat Balance
237 : // Manager. The order of execution is still important and the zone cannot
238 : // go through any record keeping before the HVAC system has run because there
239 : // may be a radiant system in the building which will require iteration between
240 : // the HVAC system (called from the Air Heat Balance) and the zone (simulated
241 : // in the Surface Heat Balance Manager). In the future, this may be improved.
242 2568313 : ManageSurfaceHeatBalance(state);
243 2568314 : ManageEMS(state, EMSManager::EMSCallFrom::EndZoneTimestepBeforeZoneReporting, anyRan, ObjexxFCL::Optional_int_const()); // EMS calling point
244 2568312 : RecKeepHeatBalance(state); // Do any heat balance related record keeping
245 :
246 : // This call has been moved to the FanSystemModule and does effect the output file
247 : // You do get a shift in the Air Handling System Summary for the building electric loads
248 : // IF ((.NOT.WarmupFlag).AND.(DayOfSim.GT.0)) CALL RCKEEP ! Do fan system accounting (to be moved later)
249 :
250 2568312 : ReportHeatBalance(state); // Manage heat balance reporting until the new reporting is in place
251 :
252 2568312 : ManageEMS(state, EMSManager::EMSCallFrom::EndZoneTimestepAfterZoneReporting, anyRan, ObjexxFCL::Optional_int_const()); // EMS calling point
253 :
254 2568312 : UpdateEMSTrendVariables(state);
255 2568312 : EnergyPlus::PluginManagement::PluginManager::updatePluginValues(state);
256 :
257 2568312 : if (state.dataGlobal->WarmupFlag && state.dataGlobal->EndDayFlag) {
258 :
259 16403 : CheckWarmupConvergence(state);
260 16403 : if (!state.dataGlobal->WarmupFlag) {
261 2529 : state.dataGlobal->DayOfSim = 0; // Reset DayOfSim if Warmup converged
262 2529 : state.dataGlobal->DayOfSimChr = "0";
263 :
264 2529 : ManageEMS(state, EMSManager::EMSCallFrom::BeginNewEnvironmentAfterWarmUp, anyRan, ObjexxFCL::Optional_int_const()); // calling point
265 : }
266 : }
267 :
268 2568312 : if (!state.dataGlobal->WarmupFlag && state.dataGlobal->EndDayFlag && state.dataGlobal->DayOfSim == 1 && !state.dataGlobal->DoingSizing) {
269 1645 : ReportWarmupConvergence(state);
270 : }
271 2568312 : }
272 :
273 : // Get Input Section of the Module
274 : //******************************************************************************
275 :
276 771 : void GetHeatBalanceInput(EnergyPlusData &state)
277 : {
278 :
279 : // SUBROUTINE INFORMATION:
280 : // AUTHOR Rick Strand
281 : // DATE WRITTEN September 1997
282 : // MODIFIED February 1998 Richard Liesen
283 : // November 1998 FW
284 : // RE-ENGINEERED na
285 :
286 : // PURPOSE OF THIS SUBROUTINE:
287 : // This subroutine is the main driver for initializations within the
288 : // heat balance.
289 :
290 : // METHODOLOGY EMPLOYED:
291 : // na
292 :
293 : // REFERENCES:
294 : // na
295 :
296 : // Using/Aliasing
297 : using InternalHeatGains::ManageInternalHeatGains;
298 :
299 : // Locals
300 : // SUBROUTINE ARGUMENT DEFINITIONS:
301 : // na
302 :
303 : // SUBROUTINE PARAMETER DEFINITIONS:
304 : // na
305 :
306 : // INTERFACE BLOCK SPECIFICATIONS:
307 : // na
308 :
309 : // DERIVED TYPE DEFINITIONS:
310 : // na
311 :
312 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
313 771 : bool ErrorsFound(false); // If errors detected in input
314 : bool ValidSimulationWithNoZones;
315 :
316 771 : GetProjectControlData(state, ErrorsFound);
317 :
318 771 : GetSiteAtmosphereData(state, ErrorsFound);
319 :
320 771 : GetWindowGlassSpectralData(state, ErrorsFound);
321 :
322 771 : GetMaterialData(state, ErrorsFound); // Read materials from input file/transfer from legacy data structure
323 :
324 771 : GetFrameAndDividerData(state, ErrorsFound);
325 :
326 771 : GetConstructData(state, ErrorsFound); // Read constructs from input file/transfer from legacy data structure
327 :
328 771 : GetBuildingData(state, ErrorsFound); // Read building data from input file
329 :
330 771 : GetIncidentSolarMultiplier(state, ErrorsFound);
331 :
332 : // Added SV 6/26/2013 to load scheduled surface gains
333 771 : GetScheduledSurfaceGains(state, ErrorsFound);
334 :
335 771 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
336 1 : print(state.files.eio, "{}\n", "! <Representative Surface Assignment>,Surface Name,Representative Surface Name");
337 580 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
338 579 : auto &RepSurfNum = state.dataSurface->Surface(SurfNum).RepresentativeCalcSurfNum;
339 579 : if (SurfNum != RepSurfNum) {
340 393 : print(state.files.eio,
341 : " Representative Surface Assignment,{},{}\n",
342 131 : state.dataSurface->Surface(SurfNum).Name,
343 262 : state.dataSurface->Surface(RepSurfNum).Name);
344 : }
345 : }
346 : }
347 :
348 : // Added TH 1/9/2009 to create thermochromic window constructions
349 771 : CreateTCConstructions(state, ErrorsFound);
350 :
351 771 : if (state.dataSurface->TotSurfaces > 0 && state.dataGlobal->NumOfZones == 0) {
352 1 : ValidSimulationWithNoZones = CheckValidSimulationObjects(state);
353 1 : if (!ValidSimulationWithNoZones) {
354 0 : ShowSevereError(state, "GetHeatBalanceInput: There are surfaces in input but no zones found. Invalid simulation.");
355 0 : ErrorsFound = true;
356 : }
357 : }
358 :
359 771 : CheckUsedConstructions(state, ErrorsFound);
360 :
361 771 : if (ErrorsFound) {
362 0 : ShowFatalError(state, "Errors found in Building Input, Program Stopped");
363 : }
364 :
365 : // following is done to "get internal heat gains" input so that lights are gotten before
366 : // daylighting input
367 771 : ManageInternalHeatGains(state, true);
368 :
369 : // following is done so that people are gotten before for thermal comfort calculations
370 : // Setup Kiva instances
371 771 : if (state.dataHeatBal->AnyKiva) {
372 9 : state.dataSurfaceGeometry->kivaManager.setupKivaInstances(state);
373 : }
374 771 : }
375 :
376 771 : void CheckUsedConstructions(EnergyPlusData &state, bool &ErrorsFound)
377 : {
378 :
379 : // SUBROUTINE INFORMATION:
380 : // AUTHOR Linda Lawrie
381 : // DATE WRITTEN August 2011
382 : // MODIFIED na
383 : // RE-ENGINEERED na
384 :
385 : // PURPOSE OF THIS SUBROUTINE:
386 : // Counts or details unused constructions.
387 :
388 : // Using/Aliasing
389 :
390 : // SUBROUTINE PARAMETER DEFINITIONS:
391 771 : int constexpr NumConstrObjects(6);
392 : Array1D_string const ConstrObjects(NumConstrObjects,
393 : {"Pipe:Indoor",
394 : "Pipe:Outdoor",
395 : "Pipe:Underground",
396 : "GroundHeatExchanger:Surface",
397 : "DaylightingDevice:Tubular",
398 1542 : "EnergyManagementSystem:ConstructionIndexVariable"});
399 :
400 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
401 : int Unused;
402 : int Loop;
403 : int NumObjects;
404 : int NumAlphas;
405 : int NumNumbers;
406 : int Status;
407 : int CNum;
408 : int ONum;
409 : bool InErrFlag; // Preserve (no current use) the input status of ErrorsFound
410 :
411 771 : InErrFlag = ErrorsFound;
412 :
413 : // Needs to account for Pipe:HeatTransfer/indoor, etc constructions.
414 5397 : for (ONum = 1; ONum <= NumConstrObjects; ++ONum) {
415 4626 : NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ConstrObjects(ONum));
416 4652 : for (Loop = 1; Loop <= NumObjects; ++Loop) {
417 104 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
418 26 : ConstrObjects(ONum),
419 : Loop,
420 26 : state.dataIPShortCut->cAlphaArgs,
421 : NumAlphas,
422 26 : state.dataIPShortCut->rNumericArgs,
423 : NumNumbers,
424 : Status);
425 26 : if (ONum == 5) {
426 2 : CNum = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(4), state.dataConstruction->Construct);
427 : } else {
428 24 : CNum = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(2), state.dataConstruction->Construct);
429 : }
430 26 : if (CNum == 0) continue;
431 26 : state.dataConstruction->Construct(CNum).IsUsed = true;
432 26 : if (ONum == 4 || ONum == 6) {
433 : // GroundHeatExchanger:Surface or EnergyManagementSystem:ConstructionIndexVariable
434 : // Include all EMS constructions since they can potentially be used by a CTF surface
435 20 : if (!state.dataConstruction->Construct(CNum).TypeIsWindow) {
436 1 : state.dataConstruction->Construct(CNum).IsUsedCTF = true;
437 : }
438 : }
439 : }
440 : }
441 1542 : Unused = state.dataHeatBal->TotConstructs - std::count_if(state.dataConstruction->Construct.begin(),
442 771 : state.dataConstruction->Construct.end(),
443 5868 : [](Construction::ConstructionProps const &e) { return e.IsUsed; });
444 771 : if (Unused > 0) {
445 27 : if (!state.dataGlobal->DisplayExtraWarnings) {
446 27 : ShowWarningError(state, format("CheckUsedConstructions: There are {} nominally unused constructions in input.", Unused));
447 27 : ShowContinueError(state, "For explicit details on each unused construction, use Output:Diagnostics,DisplayExtraWarnings;");
448 : } else {
449 0 : ShowWarningError(state, format("CheckUsedConstructions: There are {} nominally unused constructions in input.", Unused));
450 0 : ShowContinueError(state, "Each Unused construction is shown.");
451 0 : for (Loop = 1; Loop <= state.dataHeatBal->TotConstructs; ++Loop) {
452 0 : if (state.dataConstruction->Construct(Loop).IsUsed) continue;
453 0 : ShowMessage(state, "Construction=" + state.dataConstruction->Construct(Loop).Name);
454 : }
455 : }
456 : }
457 771 : }
458 :
459 1 : bool CheckValidSimulationObjects(EnergyPlusData &state)
460 : {
461 :
462 : // FUNCTION INFORMATION:
463 : // AUTHOR Linda Lawrie
464 : // DATE WRITTEN July 2008
465 : // MODIFIED na
466 : // RE-ENGINEERED na
467 :
468 : // PURPOSE OF THIS FUNCTION:
469 : // If an input file presents with surfaces but no zones, there are certain objects
470 : // that must be present for the simulation to be valid. This check was necessitated by
471 : // an input file that was entirely detached shading surfaces but no zones (and nothing else).
472 : // Other objects include Solar Collectors, PV arrays.
473 :
474 : // METHODOLOGY EMPLOYED:
475 : // Check for specific objects that must be present for such a simulation to be valid.
476 :
477 : // Return value
478 : bool ValidSimulation; // True is other objects appear to make this a valid simulation.
479 :
480 1 : ValidSimulation = false;
481 1 : if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "SolarCollector:FlatPlate:Water") > 0) {
482 1 : ValidSimulation = true;
483 0 : } else if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Generator:Photovoltaic") > 0) {
484 0 : ValidSimulation = true;
485 0 : } else if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Generator:InternalCombustionEngine") > 0) {
486 0 : ValidSimulation = true;
487 0 : } else if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Generator:CombustionTurbine") > 0) {
488 0 : ValidSimulation = true;
489 0 : } else if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Generator:FuelCell") > 0) {
490 0 : ValidSimulation = true;
491 0 : } else if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Generator:MicroCHP") > 0) {
492 0 : ValidSimulation = true;
493 0 : } else if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Generator:MicroTurbine") > 0) {
494 0 : ValidSimulation = true;
495 0 : } else if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Generator:WindTurbine") > 0) {
496 0 : ValidSimulation = true;
497 : }
498 :
499 1 : return ValidSimulation;
500 : }
501 :
502 771 : void SetPreConstructionInputParameters(EnergyPlusData &state)
503 : {
504 : // SUBROUTINE INFORMATION:
505 : // AUTHOR Edwin Lee
506 : // DATE WRITTEN October 2014
507 : // MODIFIED na
508 : // RE-ENGINEERED na
509 :
510 : // PURPOSE OF THIS SUBROUTINE:
511 : // This subroutine sets parameters that need to be established before any heat balance inputs are read
512 :
513 : int NumAlpha;
514 : int NumNumber;
515 : int IOStat;
516 :
517 : // Get all the construction objects to determine the max layers and use this as the value for DataHeatBalance::MaxSolidWinLayers
518 : // The variable MaxSolidWinLayers is initialized to zero to immediately catch any issues with timing of this routine
519 :
520 : // start by setting this to 5; it will satisfy the regular window constructions (Construction) and the Window5 files
521 : // (Construction:WindowDataFile)
522 771 : state.dataHeatBal->MaxSolidWinLayers = 7;
523 :
524 : // Construction:ComplexFenestrationState have a limit of 10 layers, so set it up to 10 if they are present
525 771 : if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction:ComplexFenestrationState") > 0) {
526 10 : state.dataHeatBal->MaxSolidWinLayers = max(state.dataHeatBal->MaxSolidWinLayers, 10);
527 : }
528 :
529 : // then process the rest of the relevant constructions
530 1542 : std::string constructName("Construction:WindowEquivalentLayer");
531 771 : int numConstructions(state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, constructName));
532 774 : for (int constructionNum = 1; constructionNum <= numConstructions; ++constructionNum) {
533 21 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
534 : constructName,
535 : constructionNum,
536 3 : state.dataIPShortCut->cAlphaArgs,
537 : NumAlpha,
538 3 : state.dataIPShortCut->rNumericArgs,
539 : NumNumber,
540 : IOStat,
541 3 : state.dataIPShortCut->lNumericFieldBlanks,
542 3 : state.dataIPShortCut->lAlphaFieldBlanks,
543 3 : state.dataIPShortCut->cAlphaFieldNames,
544 3 : state.dataIPShortCut->cNumericFieldNames);
545 3 : int numLayersInThisConstruct(NumAlpha - 1);
546 3 : state.dataHeatBal->MaxSolidWinLayers = max(state.dataHeatBal->MaxSolidWinLayers, numLayersInThisConstruct);
547 : }
548 :
549 : // construction types being ignored as they are opaque: Construction:CfactorUndergroundWall, Construction:FfactorGroundFloor,
550 771 : }
551 :
552 771 : void GetProjectControlData(EnergyPlusData &state, bool &ErrorsFound) // Set to true if errors detected during getting data
553 : {
554 :
555 : // SUBROUTINE INFORMATION:
556 : // AUTHOR Linda Lawrie
557 : // DATE WRITTEN October 2004
558 : // MODIFIED na
559 : // RE-ENGINEERED na
560 :
561 : // PURPOSE OF THIS SUBROUTINE:
562 : // This subroutine gets the project control data before the rest of the building data (such as
563 : // materials) is obtained.
564 :
565 : // METHODOLOGY EMPLOYED:
566 : // na
567 :
568 : // REFERENCES:
569 : // This routine gets the following objects:
570 : // BUILDING
571 : // INSIDE CONVECTION ALGORITHM
572 : // OUTSIDE CONVECTION ALGORITHM
573 : // SOLUTION ALGORITHM
574 : // ASHRAE Handbook of Fundamentals, Chap 16, for the setting of Site Atmospheric defaults based
575 : // on terrain.
576 : // ZoneAirHeatBalanceAlgorithm, Added by L. Gu, 12/09
577 : // ZoneAirContaminantBalance, Added by L. Gu, 06/10
578 :
579 : // Using/Aliasing
580 771 : auto &HVACSystemRootFinding = state.dataRootFinder->HVACSystemRootFinding;
581 :
582 : // Locals
583 : // SUBROUTINE ARGUMENT DEFINITIONS:
584 :
585 : // SUBROUTINE PARAMETER DEFINITIONS:
586 771 : constexpr const char *RoutineName("GetProjectControlData: ");
587 :
588 : // INTERFACE BLOCK SPECIFICATIONS:
589 : // na
590 :
591 : // DERIVED TYPE DEFINITIONS:
592 : // na
593 :
594 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
595 1542 : Array1D_string AlphaName(4);
596 1542 : Array1D<Real64> BuildingNumbers(5);
597 : int NumAlpha;
598 : int NumNumber;
599 : int IOStat;
600 : int NumObjects;
601 : std::string::size_type TMP;
602 :
603 : // Assign the values to the building data
604 :
605 771 : state.dataHeatBalMgr->CurrentModuleObject = "Building";
606 771 : NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
607 :
608 771 : if (NumObjects > 0) {
609 4626 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
610 771 : state.dataHeatBalMgr->CurrentModuleObject,
611 : 1,
612 : AlphaName,
613 : NumAlpha,
614 : BuildingNumbers,
615 : NumNumber,
616 : IOStat,
617 771 : state.dataIPShortCut->lNumericFieldBlanks,
618 771 : state.dataIPShortCut->lAlphaFieldBlanks,
619 771 : state.dataIPShortCut->cAlphaFieldNames,
620 771 : state.dataIPShortCut->cNumericFieldNames);
621 : // Building Name (remove certain characters)
622 771 : state.dataHeatBal->BuildingName = AlphaName(1);
623 771 : TMP = index(state.dataHeatBal->BuildingName, char(1));
624 771 : while (TMP != std::string::npos) {
625 0 : state.dataHeatBal->BuildingName[TMP] = ',';
626 0 : TMP = index(state.dataHeatBal->BuildingName, char(1));
627 : }
628 771 : TMP = index(state.dataHeatBal->BuildingName, char(2));
629 771 : while (TMP != std::string::npos) {
630 0 : state.dataHeatBal->BuildingName[TMP] = '!';
631 0 : TMP = index(state.dataHeatBal->BuildingName, char(2));
632 : }
633 771 : TMP = index(state.dataHeatBal->BuildingName, char(3));
634 771 : while (TMP != std::string::npos) {
635 0 : state.dataHeatBal->BuildingName[TMP] = '\\';
636 0 : TMP = index(state.dataHeatBal->BuildingName, char(3));
637 : }
638 : // Building Azimuth (no validation)
639 771 : state.dataHeatBal->BuildingAzimuth = mod(BuildingNumbers(1), 360.0);
640 : // Terrain
641 771 : if (AlphaName(2) == "COUNTRY" || AlphaName(2) == "1") {
642 10 : state.dataEnvrn->SiteWindExp = 0.14;
643 10 : state.dataEnvrn->SiteWindBLHeight = 270.0;
644 10 : AlphaName(2) = "Country";
645 761 : } else if (AlphaName(2) == "SUBURBS" || AlphaName(2) == "2" || AlphaName(2) == "SUBURB") {
646 437 : state.dataEnvrn->SiteWindExp = 0.22;
647 437 : state.dataEnvrn->SiteWindBLHeight = 370.0;
648 437 : AlphaName(2) = "Suburbs";
649 324 : } else if (AlphaName(2) == "CITY" || AlphaName(2) == "3") {
650 322 : state.dataEnvrn->SiteWindExp = 0.33;
651 322 : state.dataEnvrn->SiteWindBLHeight = 460.0;
652 322 : AlphaName(2) = "City";
653 2 : } else if (AlphaName(2) == "OCEAN") {
654 0 : state.dataEnvrn->SiteWindExp = 0.10;
655 0 : state.dataEnvrn->SiteWindBLHeight = 210.0;
656 0 : AlphaName(2) = "Ocean";
657 2 : } else if (AlphaName(2) == "URBAN") {
658 2 : state.dataEnvrn->SiteWindExp = 0.22;
659 2 : state.dataEnvrn->SiteWindBLHeight = 370.0;
660 2 : AlphaName(2) = "Urban";
661 : } else {
662 0 : ShowSevereError(state,
663 0 : std::string{RoutineName} + state.dataHeatBalMgr->CurrentModuleObject + ": " +
664 0 : state.dataIPShortCut->cAlphaFieldNames(2) + " invalid=" + AlphaName(2));
665 0 : state.dataEnvrn->SiteWindExp = 0.14;
666 0 : state.dataEnvrn->SiteWindBLHeight = 270.0;
667 0 : AlphaName(2) = AlphaName(2) + "-invalid";
668 0 : ErrorsFound = true;
669 : }
670 : // Loads Convergence Tolerance Value
671 771 : state.dataHeatBal->LoadsConvergTol = BuildingNumbers(2);
672 771 : if (state.dataHeatBal->LoadsConvergTol <= 0.0) {
673 0 : ShowSevereError(state,
674 0 : format("{}{}: {} value invalid, [{:.3R}]",
675 : RoutineName,
676 0 : state.dataHeatBalMgr->CurrentModuleObject,
677 0 : state.dataIPShortCut->cNumericFieldNames(2),
678 0 : state.dataHeatBal->LoadsConvergTol));
679 0 : ErrorsFound = true;
680 : }
681 : // Temperature Convergence Tolerance Value
682 771 : state.dataHeatBal->TempConvergTol = BuildingNumbers(3);
683 771 : if (state.dataHeatBal->TempConvergTol <= 0.0) {
684 0 : ShowSevereError(state,
685 0 : format("{}{}: {} value invalid, [{:.3R}]",
686 : RoutineName,
687 0 : state.dataHeatBalMgr->CurrentModuleObject,
688 0 : state.dataIPShortCut->cNumericFieldNames(3),
689 0 : state.dataHeatBal->TempConvergTol));
690 0 : ErrorsFound = true;
691 : }
692 : // Solar Distribution
693 771 : if (has_prefix(AlphaName(3), "MIN") || AlphaName(3) == "-1" || state.dataSysVars->lMinimalShadowing) {
694 102 : state.dataHeatBal->SolarDistribution = DataHeatBalance::Shadowing::Minimal;
695 102 : AlphaName(3) = "MinimalShadowing";
696 102 : state.dataSurface->CalcSolRefl = false;
697 669 : } else if (AlphaName(3) == "FULLEXTERIOR" || AlphaName(3) == "0") {
698 226 : state.dataHeatBal->SolarDistribution = DataHeatBalance::Shadowing::FullExterior;
699 226 : AlphaName(3) = "FullExterior";
700 226 : state.dataSurface->CalcSolRefl = false;
701 443 : } else if (AlphaName(3) == "FULLINTERIORANDEXTERIOR" || AlphaName(3) == "1") {
702 434 : state.dataHeatBal->SolarDistribution = DataHeatBalance::Shadowing::FullInteriorExterior;
703 434 : AlphaName(3) = "FullInteriorAndExterior";
704 434 : state.dataSurface->CalcSolRefl = false;
705 9 : } else if (AlphaName(3) == "FULLEXTERIORWITHREFLECTIONS") {
706 3 : state.dataHeatBal->SolarDistribution = DataHeatBalance::Shadowing::FullExterior;
707 3 : AlphaName(3) = "FullExteriorWithReflectionsFromExteriorSurfaces";
708 3 : state.dataSurface->CalcSolRefl = true;
709 6 : } else if (AlphaName(3) == "FULLINTERIORANDEXTERIORWITHREFLECTIONS") {
710 6 : state.dataHeatBal->SolarDistribution = DataHeatBalance::Shadowing::FullInteriorExterior;
711 6 : AlphaName(3) = "FullInteriorAndExteriorWithReflectionsFromExteriorSurfaces";
712 6 : state.dataSurface->CalcSolRefl = true;
713 : } else {
714 0 : ShowSevereError(state,
715 0 : std::string{RoutineName} + state.dataHeatBalMgr->CurrentModuleObject + ": " +
716 0 : state.dataIPShortCut->cAlphaFieldNames(3) + " invalid=" + AlphaName(3));
717 0 : ErrorsFound = true;
718 0 : AlphaName(3) = AlphaName(3) + "-invalid";
719 : }
720 : // Maximum Number of Warmup Days
721 771 : if (!state.dataIPShortCut->lNumericFieldBlanks(4)) {
722 754 : state.dataHeatBal->MaxNumberOfWarmupDays = BuildingNumbers(4);
723 754 : if (state.dataHeatBal->MaxNumberOfWarmupDays <= 0) {
724 0 : ShowSevereError(state,
725 0 : format("{}{}: {} invalid, [{}], {} will be used",
726 : RoutineName,
727 0 : state.dataHeatBalMgr->CurrentModuleObject,
728 0 : state.dataIPShortCut->cNumericFieldNames(4),
729 0 : state.dataHeatBal->MaxNumberOfWarmupDays,
730 0 : DefaultMaxNumberOfWarmupDays));
731 0 : state.dataHeatBal->MaxNumberOfWarmupDays = DefaultMaxNumberOfWarmupDays;
732 : }
733 : } else {
734 17 : state.dataHeatBal->MaxNumberOfWarmupDays = DefaultMaxNumberOfWarmupDays;
735 : }
736 : // Minimum Number of Warmup Days
737 771 : if (!state.dataIPShortCut->lNumericFieldBlanks(5)) {
738 766 : state.dataHeatBal->MinNumberOfWarmupDays = BuildingNumbers(5);
739 766 : if (state.dataHeatBal->MinNumberOfWarmupDays <= 0) {
740 0 : ShowWarningError(state,
741 0 : format("{}{}: {} invalid, [{}], {} will be used",
742 : RoutineName,
743 0 : state.dataHeatBalMgr->CurrentModuleObject,
744 0 : state.dataIPShortCut->cNumericFieldNames(5),
745 0 : state.dataHeatBal->MinNumberOfWarmupDays,
746 0 : DefaultMinNumberOfWarmupDays));
747 0 : state.dataHeatBal->MinNumberOfWarmupDays = DefaultMinNumberOfWarmupDays;
748 : }
749 : } else {
750 5 : state.dataHeatBal->MinNumberOfWarmupDays = DefaultMinNumberOfWarmupDays;
751 : }
752 771 : if (state.dataHeatBal->MinNumberOfWarmupDays > state.dataHeatBal->MaxNumberOfWarmupDays) {
753 0 : ShowWarningError(state,
754 0 : format("{}{}: {} [{}] is greater than {} [{}], {} will be used.",
755 : RoutineName,
756 0 : state.dataHeatBalMgr->CurrentModuleObject,
757 0 : state.dataIPShortCut->cNumericFieldNames(5),
758 0 : state.dataHeatBal->MinNumberOfWarmupDays,
759 0 : state.dataIPShortCut->cNumericFieldNames(4),
760 0 : state.dataHeatBal->MaxNumberOfWarmupDays,
761 0 : state.dataHeatBal->MinNumberOfWarmupDays));
762 0 : state.dataHeatBal->MaxNumberOfWarmupDays = state.dataHeatBal->MinNumberOfWarmupDays;
763 : }
764 :
765 : } else {
766 0 : ShowSevereError(state, format("{} A {} Object must be entered.", RoutineName, state.dataHeatBalMgr->CurrentModuleObject));
767 0 : ErrorsFound = true;
768 0 : state.dataHeatBal->BuildingName = "NOT ENTERED";
769 0 : AlphaName(2) = "NOT ENTERED";
770 0 : AlphaName(3) = "NOT ENTERED";
771 0 : state.dataHeatBal->MaxNumberOfWarmupDays = DefaultMaxNumberOfWarmupDays;
772 0 : state.dataHeatBal->MinNumberOfWarmupDays = DefaultMinNumberOfWarmupDays;
773 : }
774 :
775 771 : constexpr const char *Format_720(" Building Information,{},{:.3R},{},{:.5R},{:.5R},{},{},{}\n");
776 771 : constexpr const char *Format_721("! <Building Information>, Building Name,North Axis {{deg}},Terrain, Loads Convergence Tolerance "
777 : "Value,Temperature Convergence Tolerance Value, Solar Distribution,Maximum Number of Warmup Days,Minimum "
778 : "Number of Warmup Days\n");
779 : // Write Building Information to the initialization output file
780 771 : print(state.files.eio, Format_721);
781 5397 : print(state.files.eio,
782 : Format_720,
783 771 : state.dataHeatBal->BuildingName,
784 771 : state.dataHeatBal->BuildingAzimuth,
785 : AlphaName(2),
786 771 : state.dataHeatBal->LoadsConvergTol,
787 771 : state.dataHeatBal->TempConvergTol,
788 : AlphaName(3),
789 771 : state.dataHeatBal->MaxNumberOfWarmupDays,
790 1542 : state.dataHeatBal->MinNumberOfWarmupDays);
791 : // Above should be validated...
792 :
793 771 : state.dataHeatBalMgr->CurrentModuleObject = "SurfaceConvectionAlgorithm:Inside";
794 771 : NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
795 771 : if (NumObjects > 0) {
796 4320 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
797 720 : state.dataHeatBalMgr->CurrentModuleObject,
798 : 1,
799 : AlphaName,
800 : NumAlpha,
801 : BuildingNumbers,
802 : NumNumber,
803 : IOStat,
804 720 : state.dataIPShortCut->lNumericFieldBlanks,
805 720 : state.dataIPShortCut->lAlphaFieldBlanks,
806 720 : state.dataIPShortCut->cAlphaFieldNames,
807 720 : state.dataIPShortCut->cNumericFieldNames);
808 :
809 : {
810 1440 : auto const SELECT_CASE_var(AlphaName(1));
811 :
812 720 : if (SELECT_CASE_var == "SIMPLE") {
813 185 : state.dataHeatBal->DefaultInsideConvectionAlgo = ConvectionConstants::HcInt_ASHRAESimple;
814 185 : AlphaName(1) = "Simple";
815 :
816 535 : } else if ((SELECT_CASE_var == "TARP")) {
817 529 : state.dataHeatBal->DefaultInsideConvectionAlgo = ConvectionConstants::HcInt_ASHRAETARP;
818 529 : AlphaName(1) = "TARP";
819 :
820 6 : } else if (SELECT_CASE_var == "CEILINGDIFFUSER") {
821 3 : state.dataHeatBal->DefaultInsideConvectionAlgo = ConvectionConstants::HcInt_CeilingDiffuser;
822 3 : AlphaName(1) = "CeilingDiffuser";
823 :
824 3 : } else if (SELECT_CASE_var == "TROMBEWALL") {
825 0 : state.dataHeatBal->DefaultInsideConvectionAlgo = ConvectionConstants::HcInt_TrombeWall;
826 0 : ShowSevereError(state,
827 : "GetInsideConvectionAlgorithm: TrombeWall has been used as a global definition. This is a zone oriented value. "
828 : "Will be illegal in the future.");
829 0 : AlphaName(1) = "TrombeWall";
830 :
831 3 : } else if (SELECT_CASE_var == "ADAPTIVECONVECTIONALGORITHM") {
832 3 : state.dataHeatBal->DefaultInsideConvectionAlgo = ConvectionConstants::HcInt_AdaptiveConvectionAlgorithm;
833 3 : AlphaName(1) = "AdaptiveConvectionAlgorithm";
834 :
835 0 : } else if (SELECT_CASE_var == "ASTMC1340") {
836 0 : state.dataHeatBal->DefaultInsideConvectionAlgo = ConvectionConstants::HcInt_ASTMC1340;
837 0 : AlphaName(1) = "ASTMC1340";
838 :
839 : } else {
840 0 : ShowWarningError(state,
841 0 : "GetInsideConvectionAlgorithm: Invalid value for " + state.dataHeatBalMgr->CurrentModuleObject +
842 0 : ", defaulting to TARP, invalid value=" + AlphaName(1));
843 0 : state.dataHeatBal->DefaultInsideConvectionAlgo = ConvectionConstants::HcInt_ASHRAETARP;
844 0 : AlphaName(1) = "TARP";
845 : }
846 : }
847 : } else {
848 : // default value, if not specified
849 51 : state.dataHeatBal->DefaultInsideConvectionAlgo = ConvectionConstants::HcInt_ASHRAETARP;
850 51 : AlphaName(1) = "TARP";
851 : }
852 771 : constexpr const char *Format_722("! <Inside Convection Algorithm>, Algorithm {{Simple | TARP | CeilingDiffuser | "
853 : "AdaptiveConvectionAlgorithm}}\nInside Convection Algorithm,{}\n");
854 771 : print(state.files.eio, Format_722, AlphaName(1));
855 :
856 : // Get only the first (if more were input)
857 771 : state.dataHeatBalMgr->CurrentModuleObject = "SurfaceConvectionAlgorithm:Outside";
858 771 : NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
859 771 : if (NumObjects > 0) {
860 4308 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
861 : "SurfaceConvectionAlgorithm:Outside",
862 : 1,
863 : AlphaName,
864 : NumAlpha,
865 : BuildingNumbers,
866 : NumNumber,
867 : IOStat,
868 718 : state.dataIPShortCut->lNumericFieldBlanks,
869 718 : state.dataIPShortCut->lAlphaFieldBlanks,
870 718 : state.dataIPShortCut->cAlphaFieldNames,
871 1436 : state.dataIPShortCut->cNumericFieldNames);
872 : {
873 1436 : auto const SELECT_CASE_var(AlphaName(1));
874 :
875 718 : if ((SELECT_CASE_var == "SIMPLECOMBINED")) {
876 194 : state.dataHeatBal->DefaultOutsideConvectionAlgo = ConvectionConstants::HcExt_ASHRAESimple;
877 194 : AlphaName(1) = "SimpleCombined";
878 :
879 524 : } else if ((SELECT_CASE_var == "TARP")) {
880 36 : state.dataHeatBal->DefaultOutsideConvectionAlgo = ConvectionConstants::HcExt_ASHRAETARP;
881 36 : AlphaName(1) = "TARP";
882 :
883 488 : } else if (SELECT_CASE_var == "MOWITT") {
884 0 : state.dataHeatBal->DefaultOutsideConvectionAlgo = ConvectionConstants::HcExt_MoWiTTHcOutside;
885 0 : AlphaName(1) = "MoWitt";
886 :
887 488 : } else if ((SELECT_CASE_var == "DOE-2")) {
888 485 : state.dataHeatBal->DefaultOutsideConvectionAlgo = ConvectionConstants::HcExt_DOE2HcOutside;
889 485 : AlphaName(1) = "DOE-2";
890 :
891 3 : } else if (SELECT_CASE_var == "ADAPTIVECONVECTIONALGORITHM") {
892 3 : state.dataHeatBal->DefaultOutsideConvectionAlgo = ConvectionConstants::HcExt_AdaptiveConvectionAlgorithm;
893 3 : AlphaName(1) = "AdaptiveConvectionAlgorithm";
894 :
895 : } else {
896 0 : ShowWarningError(state,
897 0 : "GetOutsideConvectionAlgorithm: Invalid value for " + state.dataHeatBalMgr->CurrentModuleObject +
898 0 : ", defaulting to DOE-2, invalid value=" + AlphaName(1));
899 0 : state.dataHeatBal->DefaultOutsideConvectionAlgo = ConvectionConstants::HcExt_DOE2HcOutside;
900 0 : AlphaName(1) = "DOE-2";
901 : }
902 : }
903 : } else {
904 : // default value, if not specified
905 53 : state.dataHeatBal->DefaultOutsideConvectionAlgo = ConvectionConstants::HcExt_DOE2HcOutside;
906 53 : AlphaName(1) = "DOE-2";
907 : }
908 :
909 771 : constexpr const char *Format_723("! <Outside Convection Algorithm>, Algorithm {{SimpleCombined | TARP | MoWitt | DOE-2 | "
910 : "AdaptiveConvectionAlgorithm}}\nOutside Convection Algorithm,{}\n");
911 771 : print(state.files.eio, Format_723, AlphaName(1));
912 :
913 771 : state.dataHeatBalMgr->CurrentModuleObject = "HeatBalanceAlgorithm";
914 771 : NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
915 771 : if (NumObjects > 0) {
916 4194 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
917 699 : state.dataHeatBalMgr->CurrentModuleObject,
918 : 1,
919 : AlphaName,
920 : NumAlpha,
921 : BuildingNumbers,
922 : NumNumber,
923 : IOStat,
924 699 : state.dataIPShortCut->lNumericFieldBlanks,
925 699 : state.dataIPShortCut->lAlphaFieldBlanks,
926 699 : state.dataIPShortCut->cAlphaFieldNames,
927 699 : state.dataIPShortCut->cNumericFieldNames);
928 : {
929 1398 : auto const SELECT_CASE_var(AlphaName(1));
930 : // The default is CTF
931 699 : if (SELECT_CASE_var == "CONDUCTIONTRANSFERFUNCTION") {
932 686 : state.dataHeatBal->OverallHeatTransferSolutionAlgo = DataSurfaces::HeatTransferModel::CTF;
933 686 : state.dataHeatBal->AnyCTF = true;
934 :
935 13 : } else if (SELECT_CASE_var == "MOISTUREPENETRATIONDEPTHCONDUCTIONTRANSFERFUNCTION") {
936 1 : state.dataHeatBal->OverallHeatTransferSolutionAlgo = DataSurfaces::HeatTransferModel::EMPD;
937 1 : state.dataHeatBal->AnyEMPD = true;
938 1 : state.dataHeatBal->AllCTF = false;
939 12 : } else if (SELECT_CASE_var == "CONDUCTIONFINITEDIFFERENCE") {
940 10 : state.dataHeatBal->OverallHeatTransferSolutionAlgo = DataSurfaces::HeatTransferModel::CondFD;
941 10 : state.dataHeatBal->AnyCondFD = true;
942 10 : state.dataHeatBal->AllCTF = false;
943 10 : if (state.dataGlobal->NumOfTimeStepInHour < 20) {
944 0 : ShowSevereError(
945 : state,
946 0 : format("GetSolutionAlgorithm: {} {} is Conduction Finite Difference but Number of TimeSteps in Hour < 20, Value is {}.",
947 0 : state.dataHeatBalMgr->CurrentModuleObject,
948 0 : state.dataIPShortCut->cAlphaFieldNames(1),
949 0 : state.dataGlobal->NumOfTimeStepInHour));
950 0 : ShowContinueError(state,
951 : "...Suggested minimum number of time steps in hour for Conduction Finite Difference solutions is 20. "
952 : "Errors or inaccurate calculations may occur.");
953 : }
954 :
955 2 : } else if (SELECT_CASE_var == "COMBINEDHEATANDMOISTUREFINITEELEMENT") {
956 2 : state.dataHeatBal->OverallHeatTransferSolutionAlgo = DataSurfaces::HeatTransferModel::HAMT;
957 2 : state.dataHeatBal->AnyHAMT = true;
958 2 : state.dataHeatBal->AllCTF = false;
959 2 : if (state.dataGlobal->NumOfTimeStepInHour < 20) {
960 0 : ShowSevereError(state,
961 0 : format("GetSolutionAlgorithm: {} {} is Combined Heat and Moisture Finite Element but Number of TimeSteps in "
962 : "Hour < 20, Value is {}.",
963 0 : state.dataHeatBalMgr->CurrentModuleObject,
964 0 : state.dataIPShortCut->cAlphaFieldNames(1),
965 0 : state.dataGlobal->NumOfTimeStepInHour));
966 0 : ShowContinueError(state,
967 : "...Suggested minimum number of time steps in hour for Combined Heat and Moisture Finite Element solutions "
968 : "is 20. Errors or inaccurate calculations may occur.");
969 0 : ShowContinueError(state,
970 : "...If the simulation crashes, look at material properties (esp porosity), use timestep=60, or less layers "
971 : "in your constructions.");
972 : }
973 :
974 : } else {
975 0 : state.dataHeatBal->OverallHeatTransferSolutionAlgo = DataSurfaces::HeatTransferModel::CTF;
976 0 : state.dataHeatBal->AnyCTF = true;
977 : }
978 : }
979 :
980 699 : if (NumNumber > 0) {
981 88 : state.dataHeatBalSurf->MaxSurfaceTempLimit = BuildingNumbers(1);
982 88 : state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal = state.dataHeatBalSurf->MaxSurfaceTempLimit * 2.5;
983 88 : if (state.dataHeatBalSurf->MaxSurfaceTempLimit < MinSurfaceTempLimit) {
984 88 : } else if (state.dataHeatBalSurf->MaxSurfaceTempLimit < 0.0) {
985 0 : state.dataHeatBalSurf->MaxSurfaceTempLimit = DefaultSurfaceTempLimit;
986 0 : state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal = state.dataHeatBalSurf->MaxSurfaceTempLimit * 2.5;
987 : }
988 : }
989 :
990 699 : if (!state.dataIPShortCut->lNumericFieldBlanks(2)) {
991 0 : state.dataHeatBal->LowHConvLimit = BuildingNumbers(2);
992 : }
993 699 : if (!state.dataIPShortCut->lNumericFieldBlanks(3)) {
994 0 : state.dataHeatBal->HighHConvLimit = BuildingNumbers(3);
995 : }
996 :
997 : } else {
998 72 : state.dataHeatBal->OverallHeatTransferSolutionAlgo = DataSurfaces::HeatTransferModel::CTF;
999 72 : state.dataHeatBal->AnyCTF = true;
1000 72 : state.dataHeatBalSurf->MaxSurfaceTempLimit = DefaultSurfaceTempLimit;
1001 72 : state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal = state.dataHeatBalSurf->MaxSurfaceTempLimit * 2.5;
1002 : }
1003 :
1004 : // algorithm input checks now deferred until surface properties are read in,
1005 : // moved to SurfaceGeometry.cc routine GetSurfaceHeatTransferAlgorithmOverrides
1006 :
1007 771 : constexpr const char *Format_724("! <Sky Radiance Distribution>, Value {{Anisotropic}}\nSky Radiance Distribution,Anisotropic\n");
1008 771 : print(state.files.eio, Format_724);
1009 :
1010 771 : state.dataHeatBalMgr->CurrentModuleObject = "Compliance:Building";
1011 771 : NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
1012 :
1013 771 : if (NumObjects > 0) {
1014 30 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1015 5 : state.dataHeatBalMgr->CurrentModuleObject,
1016 : 1,
1017 : AlphaName,
1018 : NumAlpha,
1019 : BuildingNumbers,
1020 : NumNumber,
1021 : IOStat,
1022 5 : state.dataIPShortCut->lNumericFieldBlanks,
1023 5 : state.dataIPShortCut->lAlphaFieldBlanks,
1024 5 : state.dataIPShortCut->cAlphaFieldNames,
1025 5 : state.dataIPShortCut->cNumericFieldNames);
1026 : // Building Rotation for Appendix G
1027 5 : state.dataHeatBal->BuildingRotationAppendixG = mod(BuildingNumbers(1), 360.0);
1028 : }
1029 :
1030 : // A new object is added by L. Gu, 12/09
1031 771 : state.dataHeatBalMgr->CurrentModuleObject = "ZoneAirHeatBalanceAlgorithm";
1032 771 : NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
1033 771 : if (NumObjects > 0) {
1034 426 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1035 71 : state.dataHeatBalMgr->CurrentModuleObject,
1036 : 1,
1037 : AlphaName,
1038 : NumAlpha,
1039 : BuildingNumbers,
1040 : NumNumber,
1041 : IOStat,
1042 71 : state.dataIPShortCut->lNumericFieldBlanks,
1043 71 : state.dataIPShortCut->lAlphaFieldBlanks,
1044 71 : state.dataIPShortCut->cAlphaFieldNames,
1045 71 : state.dataIPShortCut->cNumericFieldNames);
1046 71 : if (NumAlpha > 0) {
1047 : {
1048 142 : auto const SELECT_CASE_var(AlphaName(1));
1049 71 : if (SELECT_CASE_var == "THIRDORDERBACKWARDDIFFERENCE") {
1050 1 : state.dataHeatBal->ZoneAirSolutionAlgo = DataHeatBalance::SolutionAlgo::ThirdOrder;
1051 1 : AlphaName(1) = "ThirdOrderBackwardDifference";
1052 70 : } else if (SELECT_CASE_var == "ANALYTICALSOLUTION") {
1053 68 : state.dataHeatBal->ZoneAirSolutionAlgo = DataHeatBalance::SolutionAlgo::AnalyticalSolution;
1054 68 : AlphaName(1) = "AnalyticalSolution";
1055 2 : } else if (SELECT_CASE_var == "EULERMETHOD") {
1056 2 : state.dataHeatBal->ZoneAirSolutionAlgo = DataHeatBalance::SolutionAlgo::EulerMethod;
1057 2 : AlphaName(1) = "EulerMethod";
1058 : } else {
1059 0 : state.dataHeatBal->ZoneAirSolutionAlgo = DataHeatBalance::SolutionAlgo::ThirdOrder;
1060 0 : AlphaName(1) = "ThirdOrderBackwardDifference";
1061 0 : ShowWarningError(state,
1062 0 : state.dataHeatBalMgr->CurrentModuleObject + ": Invalid input of " +
1063 0 : state.dataIPShortCut->cAlphaFieldNames(1) + ". The default choice is assigned = " + AlphaName(1));
1064 0 : ShowContinueError(state, "Valid choices are: ThirdOrderBackwardDifference, AnalyticalSolution, or EulerMethod.");
1065 : }
1066 : }
1067 : }
1068 71 : if (!state.dataIPShortCut->lAlphaFieldBlanks(2)) {
1069 1 : state.dataHeatBal->doSpaceHeatBalanceSizing = static_cast<bool>(getYesNoValue(AlphaName(2)));
1070 : }
1071 71 : if (!state.dataIPShortCut->lAlphaFieldBlanks(3)) {
1072 1 : state.dataHeatBal->doSpaceHeatBalanceSimulation = static_cast<bool>(getYesNoValue(AlphaName(3)));
1073 : }
1074 : } else {
1075 700 : state.dataHeatBal->ZoneAirSolutionAlgo = DataHeatBalance::SolutionAlgo::ThirdOrder;
1076 700 : AlphaName(1) = "ThirdOrderBackwardDifference";
1077 : }
1078 771 : if (state.dataHeatBal->OverrideZoneAirSolutionAlgo) {
1079 1 : state.dataHeatBal->ZoneAirSolutionAlgo = DataHeatBalance::SolutionAlgo::EulerMethod;
1080 1 : AlphaName(1) = "EulerMethod";
1081 : }
1082 :
1083 : // Write Solution Algorithm to the initialization output file for User Verification
1084 771 : constexpr const char *Format_726("! <Zone Air Solution Algorithm>, Algorithm {{ThirdOrderBackwardDifference | AnalyticalSolution | "
1085 : "EulerMethod}}, Space Heat Balance Sizing, Space Heat Balance Simulation\n");
1086 771 : print(state.files.eio, Format_726);
1087 771 : constexpr const char *Format_727(" Zone Air Solution Algorithm, {}, {}, {}\n");
1088 1542 : print(state.files.eio,
1089 : Format_727,
1090 : AlphaName(1),
1091 1542 : state.dataHeatBal->doSpaceHeatBalanceSizing ? "Yes" : "No",
1092 2313 : state.dataHeatBal->doSpaceHeatBalanceSimulation ? "Yes" : "No");
1093 :
1094 : // A new object is added by L. Gu, 06/10
1095 771 : state.dataHeatBalMgr->CurrentModuleObject = "ZoneAirContaminantBalance";
1096 771 : NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
1097 771 : if (NumObjects > 0) {
1098 90 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1099 15 : state.dataHeatBalMgr->CurrentModuleObject,
1100 : 1,
1101 : AlphaName,
1102 : NumAlpha,
1103 : BuildingNumbers,
1104 : NumNumber,
1105 : IOStat,
1106 15 : state.dataIPShortCut->lNumericFieldBlanks,
1107 15 : state.dataIPShortCut->lAlphaFieldBlanks,
1108 15 : state.dataIPShortCut->cAlphaFieldNames,
1109 15 : state.dataIPShortCut->cNumericFieldNames);
1110 15 : if (NumAlpha > 0) {
1111 : {
1112 30 : auto const SELECT_CASE_var(AlphaName(1));
1113 15 : if (SELECT_CASE_var == "YES") {
1114 14 : state.dataContaminantBalance->Contaminant.CO2Simulation = true;
1115 14 : state.dataContaminantBalance->Contaminant.SimulateContaminants = true;
1116 1 : } else if (SELECT_CASE_var == "NO") {
1117 1 : state.dataContaminantBalance->Contaminant.CO2Simulation = false;
1118 : } else {
1119 0 : state.dataContaminantBalance->Contaminant.CO2Simulation = false;
1120 0 : AlphaName(1) = "NO";
1121 0 : ShowWarningError(state,
1122 0 : state.dataHeatBalMgr->CurrentModuleObject + ": Invalid input of " +
1123 0 : state.dataIPShortCut->cAlphaFieldNames(1) + ". The default choice is assigned = NO");
1124 : }
1125 : }
1126 : }
1127 15 : if (NumAlpha == 1 && state.dataContaminantBalance->Contaminant.CO2Simulation) {
1128 0 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
1129 0 : ShowSevereError(state,
1130 0 : state.dataHeatBalMgr->CurrentModuleObject + ", " + state.dataIPShortCut->cAlphaFieldNames(2) +
1131 : " is required and not given.");
1132 0 : ErrorsFound = true;
1133 : }
1134 15 : } else if (NumAlpha > 1 && state.dataContaminantBalance->Contaminant.CO2Simulation) {
1135 14 : state.dataContaminantBalance->Contaminant.CO2OutdoorSchedPtr = GetScheduleIndex(state, AlphaName(2));
1136 14 : if (state.dataContaminantBalance->Contaminant.CO2OutdoorSchedPtr == 0) {
1137 0 : ShowSevereError(state,
1138 0 : state.dataHeatBalMgr->CurrentModuleObject + ", " + state.dataIPShortCut->cAlphaFieldNames(2) +
1139 0 : " not found: " + AlphaName(2));
1140 0 : ErrorsFound = true;
1141 : }
1142 : }
1143 15 : if (NumAlpha > 2) {
1144 : {
1145 10 : auto const SELECT_CASE_var(AlphaName(3));
1146 5 : if (SELECT_CASE_var == "YES") {
1147 3 : state.dataContaminantBalance->Contaminant.GenericContamSimulation = true;
1148 3 : if (!state.dataContaminantBalance->Contaminant.CO2Simulation)
1149 1 : state.dataContaminantBalance->Contaminant.SimulateContaminants = true;
1150 2 : } else if (SELECT_CASE_var == "NO") {
1151 2 : state.dataContaminantBalance->Contaminant.GenericContamSimulation = false;
1152 : } else {
1153 0 : state.dataContaminantBalance->Contaminant.GenericContamSimulation = false;
1154 0 : AlphaName(3) = "NO";
1155 0 : ShowWarningError(state,
1156 0 : state.dataHeatBalMgr->CurrentModuleObject + ": Invalid input of " +
1157 0 : state.dataIPShortCut->cAlphaFieldNames(3) + ". The default choice is assigned = NO");
1158 : }
1159 : }
1160 5 : if (NumAlpha == 3 && state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
1161 0 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
1162 0 : ShowSevereError(state,
1163 0 : state.dataHeatBalMgr->CurrentModuleObject + ", " + state.dataIPShortCut->cAlphaFieldNames(4) +
1164 : " is required and not given.");
1165 0 : ErrorsFound = true;
1166 : }
1167 5 : } else if (NumAlpha > 3 && state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
1168 3 : state.dataContaminantBalance->Contaminant.GenericContamOutdoorSchedPtr = GetScheduleIndex(state, AlphaName(4));
1169 3 : if (state.dataContaminantBalance->Contaminant.GenericContamOutdoorSchedPtr == 0) {
1170 0 : ShowSevereError(state,
1171 0 : state.dataHeatBalMgr->CurrentModuleObject + ", " + state.dataIPShortCut->cAlphaFieldNames(4) +
1172 0 : " not found: " + AlphaName(4));
1173 0 : ErrorsFound = true;
1174 : }
1175 : }
1176 : }
1177 : } else {
1178 756 : state.dataContaminantBalance->Contaminant.SimulateContaminants = false;
1179 756 : state.dataContaminantBalance->Contaminant.CO2Simulation = false;
1180 756 : state.dataContaminantBalance->Contaminant.GenericContamSimulation = false;
1181 756 : AlphaName(1) = "NO";
1182 756 : AlphaName(3) = "NO";
1183 : }
1184 :
1185 771 : WindowManager::initWindowModel(state);
1186 :
1187 771 : constexpr const char *Format_728("! <Zone Air Carbon Dioxide Balance Simulation>, Simulation {{Yes/No}}, Carbon Dioxide Concentration\n");
1188 771 : print(state.files.eio, Format_728);
1189 771 : constexpr const char *Format_730(" Zone Air Carbon Dioxide Balance Simulation, {},{}\n");
1190 771 : if (state.dataContaminantBalance->Contaminant.SimulateContaminants && state.dataContaminantBalance->Contaminant.CO2Simulation) {
1191 14 : print(state.files.eio, Format_730, "Yes", AlphaName(1));
1192 : } else {
1193 757 : print(state.files.eio, Format_730, "No", "N/A");
1194 : }
1195 :
1196 771 : constexpr const char *Format_729(
1197 : "! <Zone Air Generic Contaminant Balance Simulation>, Simulation {{Yes/No}}, Generic Contaminant Concentration\n");
1198 771 : constexpr const char *Format_731(" Zone Air Generic Contaminant Balance Simulation, {},{}\n");
1199 771 : print(state.files.eio, Format_729);
1200 771 : if (state.dataContaminantBalance->Contaminant.SimulateContaminants && state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
1201 3 : print(state.files.eio, Format_731, "Yes", AlphaName(3));
1202 : } else {
1203 768 : print(state.files.eio, Format_731, "No", "N/A");
1204 : }
1205 :
1206 : // A new object is added by B. Nigusse, 02/14
1207 771 : state.dataHeatBalMgr->CurrentModuleObject = "ZoneAirMassFlowConservation";
1208 771 : NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
1209 771 : state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance = false;
1210 :
1211 771 : if (NumObjects > 0) {
1212 12 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1213 2 : state.dataHeatBalMgr->CurrentModuleObject,
1214 : 1,
1215 : AlphaName,
1216 : NumAlpha,
1217 : BuildingNumbers,
1218 : NumNumber,
1219 : IOStat,
1220 2 : state.dataIPShortCut->lNumericFieldBlanks,
1221 2 : state.dataIPShortCut->lAlphaFieldBlanks,
1222 2 : state.dataIPShortCut->cAlphaFieldNames,
1223 2 : state.dataIPShortCut->cNumericFieldNames);
1224 2 : if (NumAlpha > 0) {
1225 : {
1226 2 : int FlowTypeNum = getEnumerationValue(AdjustmentTypeNamesUC, UtilityRoutines::MakeUPPERCase(AlphaName(1)));
1227 2 : state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment = static_cast<DataHeatBalance::AdjustmentType>(FlowTypeNum);
1228 2 : AlphaName(1) = AdjustmentTypeNamesCC[FlowTypeNum];
1229 2 : if (BITF_TEST_ANY(BITF(state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment),
1230 : BITF(AdjustmentType::AdjustMixingOnly) | BITF(AdjustmentType::AdjustReturnOnly) |
1231 : BITF(AdjustmentType::AdjustMixingThenReturn) | BITF(AdjustmentType::AdjustReturnThenMixing))) {
1232 2 : state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance = true;
1233 : }
1234 2 : if (state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment == AdjustmentType::Invalid) {
1235 0 : state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment = AdjustmentType::NoAdjustReturnAndMixing;
1236 0 : AlphaName(1) = "None";
1237 0 : ShowWarningError(state,
1238 0 : state.dataHeatBalMgr->CurrentModuleObject + ": Invalid input of " +
1239 0 : state.dataIPShortCut->cAlphaFieldNames(1) + ". The default choice is assigned = None");
1240 : }
1241 : }
1242 2 : if (state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment != DataHeatBalance::AdjustmentType::NoAdjustReturnAndMixing)
1243 2 : state.dataHeatBal->ZoneAirMassFlow.AdjustZoneMixingFlow = true;
1244 : }
1245 2 : if (NumAlpha > 1) {
1246 : {
1247 2 : int FlowTypeNum = getEnumerationValue(InfiltrationFlowTypeNamesUC, UtilityRoutines::MakeUPPERCase(AlphaName(2)));
1248 2 : state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment = static_cast<DataHeatBalance::InfiltrationFlow>(FlowTypeNum);
1249 2 : AlphaName(2) = InfiltrationFlowTypeNamesCC[FlowTypeNum];
1250 3 : if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Add ||
1251 1 : state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Adjust) {
1252 2 : state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance = true;
1253 2 : if (!state.dataContaminantBalance->Contaminant.CO2Simulation)
1254 2 : state.dataContaminantBalance->Contaminant.SimulateContaminants = true;
1255 0 : } else if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Invalid) {
1256 0 : state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment = DataHeatBalance::InfiltrationFlow::Add;
1257 0 : state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance = true;
1258 0 : AlphaName(2) = "AddInfiltrationFlow";
1259 0 : ShowWarningError(state,
1260 0 : state.dataHeatBalMgr->CurrentModuleObject + ": Invalid input of " +
1261 0 : state.dataIPShortCut->cAlphaFieldNames(2) + ". The default choice is assigned = AddInfiltrationFlow");
1262 : }
1263 : }
1264 : } else {
1265 0 : state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment = DataHeatBalance::InfiltrationFlow::Add;
1266 0 : state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance = true;
1267 0 : AlphaName(2) = "AddInfiltrationFlow";
1268 : }
1269 2 : if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::No) {
1270 0 : AlphaName(3) = "N/A";
1271 : } else {
1272 2 : if (NumAlpha > 2) {
1273 : {
1274 2 : int FlowTypeNum = getEnumerationValue(InfiltrationZoneTypeNamesUC, UtilityRoutines::MakeUPPERCase(AlphaName(3)));
1275 2 : state.dataHeatBal->ZoneAirMassFlow.InfiltrationForZones = static_cast<DataHeatBalance::InfiltrationZoneType>(FlowTypeNum);
1276 2 : AlphaName(3) = InfiltrationZoneTypeNamesCC[FlowTypeNum];
1277 2 : if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationForZones == DataHeatBalance::InfiltrationZoneType::Invalid) {
1278 0 : state.dataHeatBal->ZoneAirMassFlow.InfiltrationForZones = DataHeatBalance::InfiltrationZoneType::MixingSourceZonesOnly;
1279 0 : AlphaName(3) = "MixingSourceZonesOnly";
1280 0 : ShowWarningError(state,
1281 0 : state.dataHeatBalMgr->CurrentModuleObject + ": Invalid input of " +
1282 0 : state.dataIPShortCut->cAlphaFieldNames(3) +
1283 : ". The default choice is assigned = MixingSourceZonesOnly");
1284 : }
1285 : }
1286 : } else {
1287 0 : state.dataHeatBal->ZoneAirMassFlow.InfiltrationForZones = DataHeatBalance::InfiltrationZoneType::MixingSourceZonesOnly;
1288 0 : AlphaName(3) = "MixingSourceZonesOnly";
1289 : }
1290 : }
1291 : } else {
1292 769 : state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance = false;
1293 : }
1294 771 : if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment != DataHeatBalance::InfiltrationFlow::No)
1295 2 : state.dataHeatBal->ZoneAirMassFlow.AdjustZoneInfiltrationFlow = true;
1296 :
1297 771 : constexpr const char *Format_732(
1298 : "! <Zone Air Mass Flow Balance Simulation>, Enforce Mass Balance, Adjust Zone Mixing and Return {{AdjustMixingOnly | AdjustReturnOnly | "
1299 : "AdjustMixingThenReturn | AdjustReturnThenMixing | None}}, Adjust Zone Infiltration "
1300 : "{{AddInfiltration | AdjustInfiltration | None}}, Infiltration Zones {{MixingSourceZonesOnly | AllZones}}\n");
1301 771 : constexpr const char *Format_733(" Zone Air Mass Flow Balance Simulation, {},{},{},{}\n");
1302 :
1303 771 : print(state.files.eio, Format_732);
1304 771 : if (state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) {
1305 2 : print(state.files.eio, Format_733, "Yes", AlphaName(1), AlphaName(2), AlphaName(3));
1306 : } else {
1307 769 : print(state.files.eio, Format_733, "No", "N/A", "N/A", "N/A");
1308 : }
1309 :
1310 : // A new object is added by L. Gu, 4/17
1311 771 : state.dataHeatBalMgr->CurrentModuleObject = "HVACSystemRootFindingAlgorithm";
1312 771 : NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
1313 771 : if (NumObjects > 0) {
1314 6 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1315 1 : state.dataHeatBalMgr->CurrentModuleObject,
1316 : 1,
1317 : AlphaName,
1318 : NumAlpha,
1319 : BuildingNumbers,
1320 : NumNumber,
1321 : IOStat,
1322 1 : state.dataIPShortCut->lNumericFieldBlanks,
1323 1 : state.dataIPShortCut->lAlphaFieldBlanks,
1324 1 : state.dataIPShortCut->cAlphaFieldNames,
1325 1 : state.dataIPShortCut->cNumericFieldNames);
1326 1 : if (NumAlpha > 0) {
1327 1 : HVACSystemRootFinding.Algorithm = AlphaName(1);
1328 : {
1329 2 : auto const SELECT_CASE_var(AlphaName(1));
1330 1 : if ((SELECT_CASE_var == "REGULAFALSI")) {
1331 0 : HVACSystemRootFinding.HVACSystemRootSolver = HVACSystemRootSolverAlgorithm::RegulaFalsi;
1332 1 : } else if (SELECT_CASE_var == "BISECTION") {
1333 0 : HVACSystemRootFinding.HVACSystemRootSolver = HVACSystemRootSolverAlgorithm::Bisection;
1334 1 : } else if (SELECT_CASE_var == "BISECTIONTHENREGULAFALSI") {
1335 0 : HVACSystemRootFinding.HVACSystemRootSolver = HVACSystemRootSolverAlgorithm::BisectionThenRegulaFalsi;
1336 1 : } else if (SELECT_CASE_var == "REGULAFALSITHENBISECTION") {
1337 1 : HVACSystemRootFinding.HVACSystemRootSolver = HVACSystemRootSolverAlgorithm::RegulaFalsiThenBisection;
1338 0 : } else if (SELECT_CASE_var == "ALTERNATION") {
1339 0 : HVACSystemRootFinding.HVACSystemRootSolver = HVACSystemRootSolverAlgorithm::Alternation;
1340 : } else {
1341 0 : HVACSystemRootFinding.HVACSystemRootSolver = HVACSystemRootSolverAlgorithm::RegulaFalsi;
1342 0 : ShowWarningError(state,
1343 0 : state.dataHeatBalMgr->CurrentModuleObject + ": Invalid input of " +
1344 0 : state.dataIPShortCut->cAlphaFieldNames(1) + ". The default choice is assigned = " + AlphaName(1));
1345 0 : ShowContinueError(
1346 : state, "Valid choices are: RegulaFalsi, Bisection, BisectionThenRegulaFalsi, RegulaFalsiThenBisection, or Alternation.");
1347 : }
1348 : }
1349 : }
1350 1 : if (NumNumber > 0) {
1351 1 : HVACSystemRootFinding.NumOfIter = BuildingNumbers(1);
1352 : }
1353 : } else {
1354 770 : HVACSystemRootFinding.Algorithm = "RegulaFalsi";
1355 770 : HVACSystemRootFinding.HVACSystemRootSolver = HVACSystemRootSolverAlgorithm::RegulaFalsi;
1356 : }
1357 :
1358 : // Write Solution Algorithm to the initialization output file for User Verification
1359 771 : constexpr const char *Format_734(
1360 : "! <HVACSystemRootFindingAlgorithm>, Value {{RegulaFalsi | Bisection | BisectionThenRegulaFalsi | RegulaFalsiThenBisection}}\n");
1361 771 : constexpr const char *Format_735(" HVACSystemRootFindingAlgorithm, {}\n");
1362 771 : print(state.files.eio, Format_734);
1363 771 : print(state.files.eio, Format_735, HVACSystemRootFinding.Algorithm);
1364 771 : }
1365 :
1366 771 : void GetSiteAtmosphereData(EnergyPlusData &state, bool &ErrorsFound)
1367 : {
1368 :
1369 : // SUBROUTINE INFORMATION:
1370 : // AUTHOR Peter Graham Ellis
1371 : // DATE WRITTEN January 2006
1372 : // MODIFIED na
1373 : // RE-ENGINEERED na
1374 :
1375 : // PURPOSE OF THIS SUBROUTINE:
1376 : // Reads the input data for the SITE ATMOSPHERIC VARIATION object.
1377 :
1378 : // Using/Aliasing
1379 :
1380 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1381 : int NumObjects;
1382 : int NumAlphas; // Number of elements in the alpha array
1383 : int NumNums; // Number of elements in the numeric array
1384 : int IOStat; // IO Status when calling get input subroutine
1385 1542 : Array1D_string AlphArray(1); // Character string data
1386 1542 : Array1D<Real64> NumArray(3); // Numeric data
1387 :
1388 : // Formats
1389 771 : constexpr const char *Format_720("Environment:Site Atmospheric Variation,{:.3R},{:.3R},{:.6R}\n");
1390 :
1391 771 : state.dataHeatBalMgr->CurrentModuleObject = "Site:HeightVariation";
1392 771 : NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
1393 :
1394 771 : if (NumObjects == 1) {
1395 6 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1396 1 : state.dataHeatBalMgr->CurrentModuleObject,
1397 : 1,
1398 : AlphArray,
1399 : NumAlphas,
1400 : NumArray,
1401 : NumNums,
1402 : IOStat,
1403 1 : state.dataIPShortCut->lNumericFieldBlanks,
1404 1 : state.dataIPShortCut->lAlphaFieldBlanks,
1405 1 : state.dataIPShortCut->cAlphaFieldNames,
1406 1 : state.dataIPShortCut->cNumericFieldNames);
1407 :
1408 1 : if (NumNums > 0) state.dataEnvrn->SiteWindExp = NumArray(1);
1409 1 : if (NumNums > 1) state.dataEnvrn->SiteWindBLHeight = NumArray(2);
1410 1 : if (NumNums > 2) state.dataEnvrn->SiteTempGradient = NumArray(3);
1411 :
1412 770 : } else if (NumObjects > 1) {
1413 0 : ShowSevereError(state, "Too many " + state.dataHeatBalMgr->CurrentModuleObject + " objects, only 1 allowed.");
1414 0 : ErrorsFound = true;
1415 : } else { // None entered
1416 : // IDD defaults would have this:
1417 : // Building object defaults use Terrain to set SiteWindExp and SiteWindBLHeight but would
1418 : // be overridden by a Site Atmospheric Variation Object.
1419 : // SiteWindExp = 0.22
1420 : // SiteWindBLHeight = 370.0
1421 770 : state.dataEnvrn->SiteTempGradient = 0.0065;
1422 : }
1423 :
1424 : // Write to the initialization output file
1425 771 : print(state.files.eio,
1426 : "! <Environment:Site Atmospheric Variation>,Wind Speed Profile Exponent {{}},Wind Speed Profile Boundary "
1427 771 : "Layer Thickness {{m}},Air Temperature Gradient Coefficient {{K/m}}\n");
1428 :
1429 771 : print(state.files.eio, Format_720, state.dataEnvrn->SiteWindExp, state.dataEnvrn->SiteWindBLHeight, state.dataEnvrn->SiteTempGradient);
1430 771 : }
1431 :
1432 771 : void GetMaterialData(EnergyPlusData &state, bool &ErrorsFound) // set to true if errors found in input
1433 : {
1434 :
1435 : // SUBROUTINE INFORMATION:
1436 : // AUTHOR Richard Liesen
1437 : // DATE WRITTEN September 1997
1438 : // MODIFIED April 1999; L.Lawrie
1439 : // Sept 1999, FCW, Window5 modifications
1440 : // Mar 2001, FCW, WindowShade mods
1441 : // Sep 2001, FCW, add Material:WindowGasMixture
1442 : // Oct 2001, FCW, add Material:WindowBlind
1443 : // Dec 2003, FCW, add glass solar/visible transmittance dirt factor
1444 : // Feb 2009, TH, added WindowMaterial:GlazingGroup:Thermochromic
1445 :
1446 : // RE-ENGINEERED na
1447 :
1448 : // PURPOSE OF THIS SUBROUTINE:
1449 : // The purpose of this subroutine is to serve as a transfer agent
1450 : // between the input file and the material derived type. The new input
1451 : // file is working, and this file reads the material data directly
1452 : // from the input file and transfer that information to the new data
1453 : // structure. Data read in this routine is stored in a
1454 : // derived type (Material) defined in the DataHeatBalance module.
1455 :
1456 : // In April 1999, a new set of material definitions replaced the one "all-purpose"
1457 : // material definition. There are now 10 flavors of materials. Definitions from
1458 : // the IDD appear below before their counterpart "gets".
1459 :
1460 : using Curve::GetCurveIndex;
1461 : using Curve::GetCurveMinMaxValues;
1462 :
1463 : using General::ScanForReports;
1464 :
1465 : // if this has a size, then input has already been gotten
1466 771 : if (state.dataHeatBalMgr->UniqueMaterialNames.size()) {
1467 0 : return;
1468 : }
1469 :
1470 : int IOStat; // IO Status when calling get input subroutine
1471 1542 : Array1D_string MaterialNames(7); // Number of Material Alpha names defined
1472 : int MaterNum; // Counter to keep track of the material number
1473 : int MaterialNumAlpha; // Number of material alpha names being passed
1474 : int MaterialNumProp; // Number of material properties being passed
1475 1542 : Array1D<Real64> MaterialProps(27); // Temporary array to transfer material properties
1476 : int RegMat; // Regular Materials -- full property definition
1477 : int RegRMat; // Regular Materials -- R only property definition
1478 : int AirMat; // Air space materials in opaque constructions
1479 : int IRTMat; // Infrared Transmitting Materials -- R only property definition
1480 :
1481 : int EcoRoofMat; // Materials for ecoRoof
1482 : int NumGas; // Index for loop over gap gases in a mixture
1483 : int NumGases; // Number of gasses in a mixture
1484 : int GasType; // Gas type index: 1=air, 2=argon, 3=krypton, 4=xenon
1485 : int Loop;
1486 : int ICoeff; // Gas property coefficient index
1487 1542 : std::string TypeOfGas; // Type of window gas fill (Air, Argon, Krypton, &
1488 : // Xenon, or Custom
1489 : Real64 MinSlatAngGeom; // Minimum and maximum slat angle allowed by slat geometry (deg)
1490 : Real64 MaxSlatAngGeom;
1491 : Real64 ReflectivitySol; // Glass reflectivity, solar
1492 : Real64 ReflectivityVis; // Glass reflectivity, visible
1493 : Real64 TransmittivitySol; // Glass transmittivity, solar
1494 : Real64 TransmittivityVis; // Glass transmittivity, visible
1495 : Real64 DenomRGas; // Denominator for WindowGas calculations of NominalR
1496 : Real64 Openness; // insect screen openness fraction = (1-d/s)^2
1497 : Real64 minAngValue; // minimum value of angle
1498 : Real64 maxAngValue; // maximum value of angle
1499 : Real64 minLamValue; // minimum value of wavelength
1500 : Real64 maxLamValue; // maximum value of wavelength
1501 :
1502 : // Added TH 1/9/2009 to read the thermochromic glazings
1503 771 : int iTC(0);
1504 771 : int iMat(0);
1505 :
1506 : // Added TH 7/27/2009 for constructions defined with F or C factor method
1507 : int TotFfactorConstructs; // Number of slabs-on-grade or underground floor constructions defined with F factors
1508 : int TotCfactorConstructs; // Number of underground wall constructions defined with C factors
1509 :
1510 : static constexpr std::string_view RoutineName("GetMaterialData: ");
1511 :
1512 771 : RegMat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Material");
1513 771 : RegRMat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Material:NoMass");
1514 771 : IRTMat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Material:InfraredTransparent");
1515 771 : AirMat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Material:AirGap");
1516 771 : state.dataHeatBal->W5GlsMat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Glazing");
1517 771 : state.dataHeatBal->W5GlsMatAlt =
1518 1542 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Glazing:RefractionExtinctionMethod");
1519 771 : state.dataHeatBal->W5GasMat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Gas");
1520 771 : state.dataHeatBal->W5GasMatMixture = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:GasMixture");
1521 771 : state.dataHeatBal->TotShades = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Shade");
1522 771 : state.dataHeatBal->TotComplexShades = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:ComplexShade");
1523 771 : state.dataHeatBal->TotComplexGaps = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Gap");
1524 771 : state.dataHeatBal->TotScreens = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Screen");
1525 771 : state.dataHeatBal->TotBlinds = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Blind");
1526 771 : EcoRoofMat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Material:RoofVegetation");
1527 771 : state.dataHeatBal->TotSimpleWindow =
1528 1542 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:SimpleGlazingSystem");
1529 :
1530 771 : state.dataHeatBal->W5GlsMatEQL =
1531 1542 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Glazing:EquivalentLayer");
1532 771 : state.dataHeatBal->TotShadesEQL =
1533 1542 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Shade:EquivalentLayer");
1534 771 : state.dataHeatBal->TotDrapesEQL =
1535 1542 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Drape:EquivalentLayer");
1536 771 : state.dataHeatBal->TotBlindsEQL =
1537 1542 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Blind:EquivalentLayer");
1538 771 : state.dataHeatBal->TotScreensEQL =
1539 1542 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Screen:EquivalentLayer");
1540 771 : state.dataHeatBal->W5GapMatEQL = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "WindowMaterial:Gap:EquivalentLayer");
1541 :
1542 771 : state.dataHeatBal->TotMaterials =
1543 1542 : RegMat + RegRMat + AirMat + state.dataHeatBal->W5GlsMat + state.dataHeatBal->W5GlsMatAlt + state.dataHeatBal->W5GasMat +
1544 1542 : state.dataHeatBal->W5GasMatMixture + state.dataHeatBal->TotShades + state.dataHeatBal->TotScreens + state.dataHeatBal->TotBlinds +
1545 1542 : EcoRoofMat + IRTMat + state.dataHeatBal->TotSimpleWindow + state.dataHeatBal->TotComplexShades + state.dataHeatBal->TotComplexGaps +
1546 2313 : state.dataHeatBal->W5GlsMatEQL + state.dataHeatBal->TotShadesEQL + state.dataHeatBal->TotDrapesEQL + state.dataHeatBal->TotBlindsEQL +
1547 1542 : state.dataHeatBal->TotScreensEQL + state.dataHeatBal->W5GapMatEQL;
1548 :
1549 771 : TotFfactorConstructs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction:FfactorGroundFloor");
1550 771 : TotCfactorConstructs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction:CfactorUndergroundWall");
1551 :
1552 771 : if (TotFfactorConstructs > 0) {
1553 14 : state.dataHeatBal->NoFfactorConstructionsUsed = false;
1554 : }
1555 :
1556 771 : if (TotCfactorConstructs > 0) {
1557 7 : state.dataHeatBal->NoCfactorConstructionsUsed = false;
1558 : }
1559 :
1560 771 : if (TotFfactorConstructs + TotCfactorConstructs >= 1) {
1561 : // Add a new fictitious insulation layer and a thermal mass layer for each F or C factor defined construction
1562 20 : state.dataHeatBal->TotMaterials += 1 + TotFfactorConstructs + TotCfactorConstructs;
1563 : }
1564 :
1565 771 : state.dataMaterial->Material.allocate(state.dataHeatBal->TotMaterials); // Allocate the array Size to the number of materials
1566 771 : state.dataHeatBalMgr->UniqueMaterialNames.reserve(static_cast<unsigned>(state.dataHeatBal->TotMaterials));
1567 :
1568 771 : state.dataHeatBal->NominalR.dimension(state.dataHeatBal->TotMaterials, 0.0);
1569 :
1570 771 : MaterNum = 0;
1571 :
1572 : // Regular Materials
1573 771 : auto &ip = state.dataInputProcessing->inputProcessor;
1574 :
1575 771 : state.dataHeatBalMgr->CurrentModuleObject = "Material";
1576 1542 : auto const instances = ip->epJSON.find(state.dataHeatBalMgr->CurrentModuleObject);
1577 771 : if (instances != ip->epJSON.end()) {
1578 740 : auto const &objectSchemaProps = ip->getObjectSchemaProps(state, state.dataHeatBalMgr->CurrentModuleObject);
1579 :
1580 740 : int counter = 0;
1581 740 : auto &instancesValue = instances.value();
1582 9086 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1583 8346 : auto const &objectFields = instance.value();
1584 16692 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1585 8346 : ip->markObjectAsUsed(state.dataHeatBalMgr->CurrentModuleObject, instance.key());
1586 16692 : std::string materialName = thisObjectName;
1587 :
1588 25038 : if (GlobalNames::VerifyUniqueInterObjectName(state,
1589 8346 : state.dataHeatBalMgr->UniqueMaterialNames,
1590 : materialName,
1591 8346 : state.dataHeatBalMgr->CurrentModuleObject,
1592 8346 : state.dataIPShortCut->cAlphaFieldNames(1),
1593 : ErrorsFound)) {
1594 0 : continue;
1595 : }
1596 : // For incoming idf, maintain object order
1597 8346 : ++counter;
1598 8346 : MaterNum = ip->getIDFObjNum(state, state.dataHeatBalMgr->CurrentModuleObject, counter);
1599 :
1600 : // Load the material derived type from the input data.
1601 8346 : auto &thisMaterial = state.dataMaterial->Material(MaterNum);
1602 8346 : thisMaterial.Group = DataHeatBalance::MaterialGroup::RegularMaterial;
1603 8346 : thisMaterial.Name = materialName;
1604 :
1605 16692 : std::string roughness = ip->getAlphaFieldValue(objectFields, objectSchemaProps, "roughness");
1606 8346 : ValidateMaterialRoughness(state, MaterNum, roughness, ErrorsFound);
1607 :
1608 8346 : thisMaterial.Thickness = ip->getRealFieldValue(objectFields, objectSchemaProps, "thickness");
1609 8346 : thisMaterial.Conductivity = ip->getRealFieldValue(objectFields, objectSchemaProps, "conductivity");
1610 8346 : thisMaterial.Density = ip->getRealFieldValue(objectFields, objectSchemaProps, "density");
1611 8346 : thisMaterial.SpecHeat = ip->getRealFieldValue(objectFields, objectSchemaProps, "specific_heat");
1612 8346 : thisMaterial.AbsorpThermal = ip->getRealFieldValue(objectFields, objectSchemaProps, "thermal_absorptance");
1613 8346 : thisMaterial.AbsorpThermalInput = thisMaterial.AbsorpThermal;
1614 8346 : thisMaterial.AbsorpSolar = ip->getRealFieldValue(objectFields, objectSchemaProps, "solar_absorptance");
1615 8346 : thisMaterial.AbsorpSolarInput = thisMaterial.AbsorpSolar;
1616 8346 : thisMaterial.AbsorpVisible = ip->getRealFieldValue(objectFields, objectSchemaProps, "visible_absorptance");
1617 8346 : thisMaterial.AbsorpVisibleInput = thisMaterial.AbsorpVisible;
1618 :
1619 8346 : if (thisMaterial.Conductivity > 0.0) {
1620 8346 : state.dataHeatBal->NominalR(MaterNum) = thisMaterial.Thickness / thisMaterial.Conductivity;
1621 8346 : thisMaterial.Resistance = state.dataHeatBal->NominalR(MaterNum);
1622 : } else {
1623 0 : ShowSevereError(state, "Positive thermal conductivity required for material " + thisMaterial.Name);
1624 0 : ErrorsFound = true;
1625 : }
1626 : }
1627 740 : MaterNum = counter; // This works here, because this is the first material type processed
1628 : }
1629 : // Add the 6" heavy concrete for constructions defined with F or C factor method
1630 771 : if (TotFfactorConstructs + TotCfactorConstructs >= 1) {
1631 20 : ++MaterNum;
1632 :
1633 20 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::RegularMaterial;
1634 20 : state.dataMaterial->Material(MaterNum).Name = "~FC_Concrete";
1635 20 : state.dataMaterial->Material(MaterNum).Thickness = 0.15; // m, 0.15m = 6 inches
1636 20 : state.dataMaterial->Material(MaterNum).Conductivity = 1.95; // W/mK
1637 20 : state.dataMaterial->Material(MaterNum).Density = 2240.0; // kg/m3
1638 20 : state.dataMaterial->Material(MaterNum).SpecHeat = 900.0; // J/kgK
1639 20 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough;
1640 20 : state.dataMaterial->Material(MaterNum).AbsorpSolar = 0.7;
1641 20 : state.dataMaterial->Material(MaterNum).AbsorpThermal = 0.9;
1642 20 : state.dataMaterial->Material(MaterNum).AbsorpVisible = 0.7;
1643 20 : state.dataHeatBal->NominalR(MaterNum) =
1644 20 : state.dataMaterial->Material(MaterNum).Thickness / state.dataMaterial->Material(MaterNum).Conductivity;
1645 20 : state.dataMaterial->Material(MaterNum).Resistance = state.dataHeatBal->NominalR(MaterNum);
1646 :
1647 20 : ++RegMat;
1648 : }
1649 :
1650 771 : state.dataHeatBalMgr->CurrentModuleObject = "Material:NoMass";
1651 2514 : for (Loop = 1; Loop <= RegRMat; ++Loop) {
1652 :
1653 : // Call Input Get routine to retrieve material data
1654 10458 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1655 1743 : state.dataHeatBalMgr->CurrentModuleObject,
1656 : Loop,
1657 : MaterialNames,
1658 : MaterialNumAlpha,
1659 : MaterialProps,
1660 : MaterialNumProp,
1661 : IOStat,
1662 1743 : state.dataIPShortCut->lNumericFieldBlanks,
1663 1743 : state.dataIPShortCut->lAlphaFieldBlanks,
1664 1743 : state.dataIPShortCut->cAlphaFieldNames,
1665 1743 : state.dataIPShortCut->cNumericFieldNames);
1666 5229 : if (GlobalNames::VerifyUniqueInterObjectName(state,
1667 1743 : state.dataHeatBalMgr->UniqueMaterialNames,
1668 1743 : MaterialNames(1),
1669 1743 : state.dataHeatBalMgr->CurrentModuleObject,
1670 1743 : state.dataIPShortCut->cAlphaFieldNames(1),
1671 : ErrorsFound)) {
1672 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
1673 0 : continue;
1674 : }
1675 :
1676 : // Load the material derived type from the input data.
1677 1743 : ++MaterNum;
1678 1743 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::RegularMaterial;
1679 1743 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
1680 :
1681 1743 : ValidateMaterialRoughness(state, MaterNum, MaterialNames(2), ErrorsFound);
1682 :
1683 1743 : state.dataMaterial->Material(MaterNum).Resistance = MaterialProps(1);
1684 1743 : state.dataMaterial->Material(MaterNum).ROnly = true;
1685 1743 : if (MaterialNumProp >= 2) {
1686 1609 : state.dataMaterial->Material(MaterNum).AbsorpThermal = MaterialProps(2);
1687 1609 : state.dataMaterial->Material(MaterNum).AbsorpThermalInput = MaterialProps(2);
1688 : } else {
1689 134 : state.dataMaterial->Material(MaterNum).AbsorpThermal = 0.9;
1690 134 : state.dataMaterial->Material(MaterNum).AbsorpThermalInput = 0.9;
1691 : }
1692 1743 : if (MaterialNumProp >= 3) {
1693 1609 : state.dataMaterial->Material(MaterNum).AbsorpSolar = MaterialProps(3);
1694 1609 : state.dataMaterial->Material(MaterNum).AbsorpSolarInput = MaterialProps(3);
1695 : } else {
1696 134 : state.dataMaterial->Material(MaterNum).AbsorpSolar = 0.7;
1697 134 : state.dataMaterial->Material(MaterNum).AbsorpSolarInput = 0.7;
1698 : }
1699 1743 : if (MaterialNumProp >= 4) {
1700 1509 : state.dataMaterial->Material(MaterNum).AbsorpVisible = MaterialProps(4);
1701 1509 : state.dataMaterial->Material(MaterNum).AbsorpVisibleInput = MaterialProps(4);
1702 : } else {
1703 234 : state.dataMaterial->Material(MaterNum).AbsorpVisible = 0.7;
1704 234 : state.dataMaterial->Material(MaterNum).AbsorpVisibleInput = 0.7;
1705 : }
1706 :
1707 1743 : state.dataHeatBal->NominalR(MaterNum) = state.dataMaterial->Material(MaterNum).Resistance;
1708 : }
1709 :
1710 : // Add a fictitious insulation layer for each construction defined with F or C factor method
1711 771 : if (TotFfactorConstructs + TotCfactorConstructs >= 1) {
1712 233 : for (Loop = 1; Loop <= TotFfactorConstructs + TotCfactorConstructs; ++Loop) {
1713 213 : ++MaterNum;
1714 213 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::RegularMaterial;
1715 213 : state.dataMaterial->Material(MaterNum).Name = format("~FC_Insulation_{}", Loop);
1716 213 : state.dataMaterial->Material(MaterNum).ROnly = true;
1717 213 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough;
1718 213 : state.dataMaterial->Material(MaterNum).AbsorpSolar = 0.0;
1719 213 : state.dataMaterial->Material(MaterNum).AbsorpThermal = 0.0;
1720 213 : state.dataMaterial->Material(MaterNum).AbsorpVisible = 0.0;
1721 : }
1722 20 : RegRMat += TotFfactorConstructs + TotCfactorConstructs;
1723 : }
1724 :
1725 : // Air Materials (for air spaces in opaque constructions)
1726 771 : state.dataHeatBalMgr->CurrentModuleObject = "Material:AirGap";
1727 1290 : for (Loop = 1; Loop <= AirMat; ++Loop) {
1728 :
1729 : // Call Input Get routine to retrieve material data
1730 3114 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1731 519 : state.dataHeatBalMgr->CurrentModuleObject,
1732 : Loop,
1733 : MaterialNames,
1734 : MaterialNumAlpha,
1735 : MaterialProps,
1736 : MaterialNumProp,
1737 : IOStat,
1738 519 : state.dataIPShortCut->lNumericFieldBlanks,
1739 519 : state.dataIPShortCut->lAlphaFieldBlanks,
1740 519 : state.dataIPShortCut->cAlphaFieldNames,
1741 519 : state.dataIPShortCut->cNumericFieldNames);
1742 1557 : if (GlobalNames::VerifyUniqueInterObjectName(state,
1743 519 : state.dataHeatBalMgr->UniqueMaterialNames,
1744 519 : MaterialNames(1),
1745 519 : state.dataHeatBalMgr->CurrentModuleObject,
1746 519 : state.dataIPShortCut->cAlphaFieldNames(1),
1747 : ErrorsFound)) {
1748 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
1749 0 : continue;
1750 : }
1751 :
1752 : // Load the material derived type from the input data.
1753 519 : ++MaterNum;
1754 519 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::Air;
1755 519 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
1756 :
1757 519 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough;
1758 :
1759 519 : state.dataMaterial->Material(MaterNum).Resistance = MaterialProps(1);
1760 519 : state.dataMaterial->Material(MaterNum).ROnly = true;
1761 :
1762 519 : state.dataHeatBal->NominalR(MaterNum) = state.dataMaterial->Material(MaterNum).Resistance;
1763 : }
1764 :
1765 771 : state.dataHeatBalMgr->CurrentModuleObject = "Material:InfraredTransparent";
1766 774 : for (Loop = 1; Loop <= IRTMat; ++Loop) {
1767 :
1768 : // Call Input Get routine to retrieve material data
1769 18 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1770 3 : state.dataHeatBalMgr->CurrentModuleObject,
1771 : Loop,
1772 : MaterialNames,
1773 : MaterialNumAlpha,
1774 : MaterialProps,
1775 : MaterialNumProp,
1776 : IOStat,
1777 3 : state.dataIPShortCut->lNumericFieldBlanks,
1778 3 : state.dataIPShortCut->lAlphaFieldBlanks,
1779 3 : state.dataIPShortCut->cAlphaFieldNames,
1780 3 : state.dataIPShortCut->cNumericFieldNames);
1781 9 : if (GlobalNames::VerifyUniqueInterObjectName(state,
1782 3 : state.dataHeatBalMgr->UniqueMaterialNames,
1783 3 : MaterialNames(1),
1784 3 : state.dataHeatBalMgr->CurrentModuleObject,
1785 3 : state.dataIPShortCut->cAlphaFieldNames(1),
1786 : ErrorsFound)) {
1787 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
1788 0 : continue;
1789 : }
1790 :
1791 3 : ++MaterNum;
1792 3 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::IRTMaterial;
1793 :
1794 : // Load the material derived type from the input data.
1795 3 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
1796 :
1797 : // Load data for other properties that need defaults
1798 3 : state.dataMaterial->Material(MaterNum).ROnly = true;
1799 3 : state.dataMaterial->Material(MaterNum).Resistance = 0.01;
1800 3 : state.dataMaterial->Material(MaterNum).AbsorpThermal = 0.9999;
1801 3 : state.dataMaterial->Material(MaterNum).AbsorpThermalInput = 0.9999;
1802 3 : state.dataMaterial->Material(MaterNum).AbsorpSolar = 1.0;
1803 3 : state.dataMaterial->Material(MaterNum).AbsorpSolarInput = 1.0;
1804 3 : state.dataMaterial->Material(MaterNum).AbsorpVisible = 1.0;
1805 3 : state.dataMaterial->Material(MaterNum).AbsorpVisibleInput = 1.0;
1806 :
1807 3 : state.dataHeatBal->NominalR(MaterNum) = state.dataMaterial->Material(MaterNum).Resistance;
1808 : }
1809 :
1810 : // Glass materials, regular input: transmittance and front/back reflectance
1811 :
1812 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Glazing";
1813 2445 : for (Loop = 1; Loop <= state.dataHeatBal->W5GlsMat; ++Loop) {
1814 :
1815 : // Call Input Get routine to retrieve material data
1816 10044 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1817 1674 : state.dataHeatBalMgr->CurrentModuleObject,
1818 : Loop,
1819 : MaterialNames,
1820 : MaterialNumAlpha,
1821 : MaterialProps,
1822 : MaterialNumProp,
1823 : IOStat,
1824 1674 : state.dataIPShortCut->lNumericFieldBlanks,
1825 1674 : state.dataIPShortCut->lAlphaFieldBlanks,
1826 1674 : state.dataIPShortCut->cAlphaFieldNames,
1827 1674 : state.dataIPShortCut->cNumericFieldNames);
1828 5022 : if (GlobalNames::VerifyUniqueInterObjectName(state,
1829 1674 : state.dataHeatBalMgr->UniqueMaterialNames,
1830 1674 : MaterialNames(1),
1831 1674 : state.dataHeatBalMgr->CurrentModuleObject,
1832 1674 : state.dataIPShortCut->cAlphaFieldNames(1),
1833 : ErrorsFound)) {
1834 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
1835 0 : continue;
1836 : }
1837 :
1838 1674 : ++MaterNum;
1839 1674 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::WindowGlass;
1840 :
1841 : // Load the material derived type from the input data.
1842 :
1843 1674 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
1844 1674 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::VerySmooth;
1845 1674 : state.dataMaterial->Material(MaterNum).ROnly = true;
1846 1674 : state.dataMaterial->Material(MaterNum).Thickness = MaterialProps(1);
1847 1674 : if (!UtilityRoutines::SameString(MaterialNames(2), "SpectralAndAngle")) {
1848 1673 : state.dataMaterial->Material(MaterNum).Trans = MaterialProps(2);
1849 1673 : state.dataMaterial->Material(MaterNum).ReflectSolBeamFront = MaterialProps(3);
1850 1673 : state.dataMaterial->Material(MaterNum).ReflectSolBeamBack = MaterialProps(4);
1851 1673 : state.dataMaterial->Material(MaterNum).TransVis = MaterialProps(5);
1852 1673 : state.dataMaterial->Material(MaterNum).ReflectVisBeamFront = MaterialProps(6);
1853 1673 : state.dataMaterial->Material(MaterNum).ReflectVisBeamBack = MaterialProps(7);
1854 1673 : state.dataMaterial->Material(MaterNum).TransThermal = MaterialProps(8);
1855 : }
1856 1674 : state.dataMaterial->Material(MaterNum).AbsorpThermalFront = MaterialProps(9);
1857 1674 : state.dataMaterial->Material(MaterNum).AbsorpThermalBack = MaterialProps(10);
1858 1674 : state.dataMaterial->Material(MaterNum).Conductivity = MaterialProps(11);
1859 1674 : state.dataMaterial->Material(MaterNum).GlassTransDirtFactor = MaterialProps(12);
1860 1674 : state.dataMaterial->Material(MaterNum).YoungModulus = MaterialProps(13);
1861 1674 : state.dataMaterial->Material(MaterNum).PoissonsRatio = MaterialProps(14);
1862 1674 : if (MaterialProps(12) == 0.0) state.dataMaterial->Material(MaterNum).GlassTransDirtFactor = 1.0;
1863 1674 : state.dataMaterial->Material(MaterNum).AbsorpThermal = state.dataMaterial->Material(MaterNum).AbsorpThermalBack;
1864 :
1865 1674 : if (state.dataMaterial->Material(MaterNum).Conductivity > 0.0) {
1866 1674 : state.dataHeatBal->NominalR(MaterNum) =
1867 1674 : state.dataMaterial->Material(MaterNum).Thickness / state.dataMaterial->Material(MaterNum).Conductivity;
1868 1674 : state.dataMaterial->Material(MaterNum).Resistance = state.dataHeatBal->NominalR(MaterNum);
1869 : } else {
1870 0 : ErrorsFound = true;
1871 0 : ShowSevereError(state,
1872 0 : "Window glass material " + state.dataMaterial->Material(MaterNum).Name +
1873 : " has Conductivity = 0.0, must be >0.0, default = .9");
1874 : }
1875 :
1876 1674 : state.dataMaterial->Material(MaterNum).GlassSpectralDataPtr = 0;
1877 1674 : if (state.dataHeatBal->TotSpectralData > 0 && !state.dataIPShortCut->lAlphaFieldBlanks(3)) {
1878 83 : state.dataMaterial->Material(MaterNum).GlassSpectralDataPtr =
1879 83 : UtilityRoutines::FindItemInList(MaterialNames(3), state.dataHeatBal->SpectralData);
1880 : }
1881 1674 : if (UtilityRoutines::SameString(MaterialNames(2), "SpectralAverage")) state.dataMaterial->Material(MaterNum).GlassSpectralDataPtr = 0;
1882 : // No need for spectral data for BSDF either
1883 1674 : if (UtilityRoutines::SameString(MaterialNames(2), "BSDF")) state.dataMaterial->Material(MaterNum).GlassSpectralDataPtr = 0;
1884 1674 : if (UtilityRoutines::SameString(MaterialNames(2), "SpectralAndAngle"))
1885 1 : state.dataMaterial->Material(MaterNum).GlassSpectralAndAngle = true;
1886 :
1887 1674 : if (state.dataMaterial->Material(MaterNum).GlassSpectralDataPtr == 0 && UtilityRoutines::SameString(MaterialNames(2), "Spectral")) {
1888 0 : ErrorsFound = true;
1889 0 : ShowSevereError(state,
1890 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + state.dataMaterial->Material(MaterNum).Name + "\" has " +
1891 0 : state.dataIPShortCut->cAlphaFieldNames(2) +
1892 : " = Spectral but has no matching MaterialProperty:GlazingSpectralData set");
1893 0 : if (state.dataIPShortCut->lAlphaFieldBlanks(3)) {
1894 0 : ShowContinueError(state, "..." + state.dataIPShortCut->cAlphaFieldNames(3) + " is blank.");
1895 : } else {
1896 0 : ShowContinueError(state,
1897 0 : "..." + state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" + MaterialNames(3) +
1898 : "\" not found as item in MaterialProperty:GlazingSpectralData objects.");
1899 : }
1900 : }
1901 :
1902 3465 : if (!UtilityRoutines::SameString(MaterialNames(2), "SpectralAverage") && !UtilityRoutines::SameString(MaterialNames(2), "Spectral") &&
1903 1692 : !UtilityRoutines::SameString(MaterialNames(2), "BSDF") && !UtilityRoutines::SameString(MaterialNames(2), "SpectralAndAngle")) {
1904 0 : ErrorsFound = true;
1905 0 : ShowSevereError(state,
1906 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + state.dataMaterial->Material(MaterNum).Name +
1907 : "\", invalid specification.");
1908 0 : ShowContinueError(state,
1909 0 : state.dataIPShortCut->cAlphaFieldNames(2) +
1910 0 : " must be SpectralAverage, Spectral, BSDF or SpectralAndAngle, value=" + MaterialNames(2));
1911 : }
1912 :
1913 : // TH 8/24/2011, allow glazing properties MaterialProps(2 to 10) to equal 0 or 1: 0.0 =< Prop <= 1.0
1914 : // Fixed CR 8413 - modeling spandrel panels as glazing systems
1915 1674 : if (UtilityRoutines::SameString(MaterialNames(2), "SpectralAverage")) {
1916 :
1917 1574 : if (MaterialProps(2) + MaterialProps(3) > 1.0) {
1918 0 : ErrorsFound = true;
1919 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
1920 0 : ShowContinueError(
1921 0 : state, state.dataIPShortCut->cNumericFieldNames(2) + " + " + state.dataIPShortCut->cNumericFieldNames(3) + " not <= 1.0");
1922 : }
1923 :
1924 1574 : if (MaterialProps(2) + MaterialProps(4) > 1.0) {
1925 0 : ErrorsFound = true;
1926 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
1927 0 : ShowContinueError(
1928 0 : state, state.dataIPShortCut->cNumericFieldNames(2) + " + " + state.dataIPShortCut->cNumericFieldNames(4) + " not <= 1.0");
1929 : }
1930 :
1931 1574 : if (MaterialProps(5) + MaterialProps(6) > 1.0) {
1932 0 : ErrorsFound = true;
1933 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
1934 0 : ShowContinueError(
1935 0 : state, state.dataIPShortCut->cNumericFieldNames(5) + " + " + state.dataIPShortCut->cNumericFieldNames(6) + " not <= 1.0");
1936 : }
1937 :
1938 1574 : if (MaterialProps(5) + MaterialProps(7) > 1.0) {
1939 0 : ErrorsFound = true;
1940 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
1941 0 : ShowContinueError(
1942 0 : state, state.dataIPShortCut->cNumericFieldNames(5) + " + " + state.dataIPShortCut->cNumericFieldNames(7) + " not <= 1.0");
1943 : }
1944 :
1945 1574 : if (MaterialProps(8) + MaterialProps(9) > 1.0) {
1946 0 : ErrorsFound = true;
1947 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
1948 0 : ShowContinueError(
1949 0 : state, state.dataIPShortCut->cNumericFieldNames(8) + " + " + state.dataIPShortCut->cNumericFieldNames(9) + " not <= 1.0");
1950 : }
1951 :
1952 1574 : if (MaterialProps(8) + MaterialProps(10) > 1.0) {
1953 0 : ErrorsFound = true;
1954 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
1955 0 : ShowContinueError(
1956 0 : state, state.dataIPShortCut->cNumericFieldNames(8) + " + " + state.dataIPShortCut->cNumericFieldNames(10) + " not <= 1.0");
1957 : }
1958 :
1959 1574 : if (MaterialProps(2) < 0.0) {
1960 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
1961 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(2) + " not >= 0.0");
1962 0 : ErrorsFound = true;
1963 : }
1964 :
1965 1574 : if (MaterialProps(2) > 1.0) {
1966 0 : ErrorsFound = true;
1967 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
1968 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(2) + " not <= 1.0");
1969 : }
1970 :
1971 1574 : if (MaterialProps(3) < 0.0 || MaterialProps(3) > 1.0) {
1972 0 : ErrorsFound = true;
1973 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
1974 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(3) + " not >= 0.0 and <= 1.0");
1975 : }
1976 :
1977 1574 : if (MaterialProps(4) < 0.0 || MaterialProps(4) > 1.0) {
1978 0 : ErrorsFound = true;
1979 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
1980 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(4) + " not >= 0.0 and <= 1.0");
1981 : }
1982 :
1983 1574 : if (MaterialProps(5) < 0.0) {
1984 0 : ShowWarningError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", minimal value.");
1985 0 : ShowWarningError(state, state.dataIPShortCut->cNumericFieldNames(5) + " not >= 0.0");
1986 : }
1987 :
1988 1574 : if (MaterialProps(5) > 1.0) {
1989 0 : ErrorsFound = true;
1990 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
1991 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(5) + " not <= 1.0");
1992 : }
1993 :
1994 1574 : if (MaterialProps(6) < 0.0 || MaterialProps(6) > 1.0) {
1995 0 : ErrorsFound = true;
1996 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
1997 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(6) + " not >= 0.0 and <= 1.0");
1998 : }
1999 :
2000 1574 : if (MaterialProps(7) < 0.0 || MaterialProps(7) > 1.0) {
2001 0 : ErrorsFound = true;
2002 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2003 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(7) + " not >= 0.0 and <= 1.0");
2004 : }
2005 : }
2006 :
2007 1674 : if (MaterialProps(8) > 1.0) {
2008 0 : ErrorsFound = true;
2009 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2010 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(8) + " not <= 1.0");
2011 : }
2012 :
2013 1674 : if (MaterialProps(9) <= 0.0 || MaterialProps(9) >= 1.0) {
2014 0 : ErrorsFound = true;
2015 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2016 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(9) + " not > 0.0 and < 1.0");
2017 : }
2018 :
2019 1674 : if (MaterialProps(10) <= 0.0 || MaterialProps(10) >= 1.0) {
2020 0 : ErrorsFound = true;
2021 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2022 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(10) + " not > 0.0 and < 1.0");
2023 : }
2024 :
2025 1674 : if (MaterialProps(11) <= 0.0) {
2026 0 : ErrorsFound = true;
2027 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2028 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(11) + " not > 0.0");
2029 : }
2030 :
2031 1674 : if (MaterialProps(13) < 0.0) {
2032 0 : ErrorsFound = true;
2033 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2034 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(13) + " not > 0.0");
2035 : }
2036 :
2037 1674 : if (MaterialProps(14) < 0.0 || MaterialProps(14) >= 1.0) {
2038 0 : ErrorsFound = true;
2039 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2040 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(14) + " not > 0.0 and < 1.0");
2041 : }
2042 :
2043 1674 : if (MaterialNames(4) == "") {
2044 1532 : state.dataMaterial->Material(MaterNum).SolarDiffusing = false;
2045 142 : } else if (MaterialNames(4) == "YES") {
2046 0 : state.dataMaterial->Material(MaterNum).SolarDiffusing = true;
2047 142 : } else if (MaterialNames(4) == "NO") {
2048 142 : state.dataMaterial->Material(MaterNum).SolarDiffusing = false;
2049 : } else {
2050 0 : ErrorsFound = true;
2051 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2052 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(4) + " must be Yes or No, entered value=" + MaterialNames(4));
2053 : }
2054 : // Get SpectralAndAngle table names
2055 1674 : if (state.dataMaterial->Material(MaterNum).GlassSpectralAndAngle) {
2056 1 : if (state.dataIPShortCut->lAlphaFieldBlanks(5)) {
2057 0 : ErrorsFound = true;
2058 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", blank field.");
2059 0 : ShowContinueError(state, " Table name must be entered when the key SpectralAndAngle is selected as Optical Data Type.");
2060 : } else {
2061 1 : state.dataMaterial->Material(MaterNum).GlassSpecAngTransDataPtr = Curve::GetCurveIndex(state, MaterialNames(5));
2062 1 : if (state.dataMaterial->Material(MaterNum).GlassSpecAngTransDataPtr == 0) {
2063 0 : ErrorsFound = true;
2064 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Invalid name.");
2065 0 : ShowContinueError(state,
2066 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2067 0 : " requires a valid table object name, entered input=" + MaterialNames(5));
2068 : } else {
2069 4 : ErrorsFound |= Curve::CheckCurveDims(state,
2070 1 : state.dataMaterial->Material(MaterNum).GlassSpecAngTransDataPtr, // Curve index
2071 : {2}, // Valid dimensions
2072 : RoutineName, // Routine name
2073 1 : state.dataHeatBalMgr->CurrentModuleObject, // Object Type
2074 1 : state.dataMaterial->Material(MaterNum).Name, // Object Name
2075 1 : state.dataIPShortCut->cAlphaFieldNames(5)); // Field Name
2076 :
2077 2 : GetCurveMinMaxValues(state,
2078 1 : state.dataMaterial->Material(MaterNum).GlassSpecAngTransDataPtr,
2079 : minAngValue,
2080 : maxAngValue,
2081 : minLamValue,
2082 : maxLamValue);
2083 1 : if (minAngValue > 1.0e-6) {
2084 0 : ErrorsFound = true;
2085 0 : ShowSevereError(state,
2086 0 : format("{}=\"{}\", Invalid minimum value of angle = {:.2R}.",
2087 0 : state.dataHeatBalMgr->CurrentModuleObject,
2088 : MaterialNames(1),
2089 0 : minAngValue));
2090 0 : ShowContinueError(state,
2091 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2092 0 : " requires the minumum value = 0.0 in the entered table name=" + MaterialNames(5));
2093 : }
2094 1 : if (std::abs(maxAngValue - 90.0) > 1.0e-6) {
2095 0 : ErrorsFound = true;
2096 0 : ShowSevereError(state,
2097 0 : format("{}=\"{}\", Invalid maximum value of angle = {:.2R}.",
2098 0 : state.dataHeatBalMgr->CurrentModuleObject,
2099 : MaterialNames(1),
2100 0 : maxAngValue));
2101 0 : ShowContinueError(state,
2102 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2103 0 : " requires the maximum value = 90.0 in the entered table name=" + MaterialNames(5));
2104 : }
2105 1 : if (minLamValue < 0.1) {
2106 0 : ErrorsFound = true;
2107 0 : ShowSevereError(state,
2108 0 : format("{}=\"{}\", Invalid minimum value of wavelength = {:.2R}.",
2109 0 : state.dataHeatBalMgr->CurrentModuleObject,
2110 : MaterialNames(1),
2111 0 : minLamValue));
2112 0 : ShowContinueError(state,
2113 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2114 0 : " requires the minumum value = 0.1 micron in the entered table name=" + MaterialNames(5));
2115 : }
2116 1 : if (maxLamValue > 4.0) {
2117 0 : ErrorsFound = true;
2118 0 : ShowSevereError(state,
2119 0 : format("{}=\"{}\", Invalid maximum value of wavelength = {:.2R}.",
2120 0 : state.dataHeatBalMgr->CurrentModuleObject,
2121 : MaterialNames(1),
2122 0 : maxLamValue));
2123 0 : ShowContinueError(state,
2124 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2125 0 : " requires the maximum value = 4.0 microns in the entered table name=" + MaterialNames(5));
2126 : }
2127 : }
2128 : }
2129 1 : if (state.dataIPShortCut->lAlphaFieldBlanks(6)) {
2130 0 : ErrorsFound = true;
2131 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", blank field.");
2132 0 : ShowContinueError(state, " Table name must be entered when the key SpectralAndAngle is selected as Optical Data Type.");
2133 : } else {
2134 1 : state.dataMaterial->Material(MaterNum).GlassSpecAngFRefleDataPtr = Curve::GetCurveIndex(state, MaterialNames(6));
2135 1 : if (state.dataMaterial->Material(MaterNum).GlassSpecAngFRefleDataPtr == 0) {
2136 0 : ErrorsFound = true;
2137 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Invalid name.");
2138 0 : ShowContinueError(state,
2139 0 : state.dataIPShortCut->cAlphaFieldNames(6) +
2140 0 : " requires a valid table object name, entered input=" + MaterialNames(6));
2141 : } else {
2142 4 : ErrorsFound |= Curve::CheckCurveDims(state,
2143 1 : state.dataMaterial->Material(MaterNum).GlassSpecAngFRefleDataPtr, // Curve index
2144 : {2}, // Valid dimensions
2145 : RoutineName, // Routine name
2146 1 : state.dataHeatBalMgr->CurrentModuleObject, // Object Type
2147 1 : state.dataMaterial->Material(MaterNum).Name, // Object Name
2148 1 : state.dataIPShortCut->cAlphaFieldNames(6)); // Field Name
2149 :
2150 2 : GetCurveMinMaxValues(state,
2151 1 : state.dataMaterial->Material(MaterNum).GlassSpecAngFRefleDataPtr,
2152 : minAngValue,
2153 : maxAngValue,
2154 : minLamValue,
2155 : maxLamValue);
2156 1 : if (minAngValue > 1.0e-6) {
2157 0 : ErrorsFound = true;
2158 0 : ShowSevereError(state,
2159 0 : format("{}=\"{}\", Invalid minimum value of angle = {:.2R}.",
2160 0 : state.dataHeatBalMgr->CurrentModuleObject,
2161 : MaterialNames(1),
2162 0 : minAngValue));
2163 0 : ShowContinueError(state,
2164 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2165 0 : " requires the minumum value = 0.0 in the entered table name=" + MaterialNames(5));
2166 : }
2167 1 : if (std::abs(maxAngValue - 90.0) > 1.0e-6) {
2168 0 : ErrorsFound = true;
2169 0 : ShowSevereError(state,
2170 0 : format("{}=\"{}\", Invalid maximum value of angle = {:.2R}.",
2171 0 : state.dataHeatBalMgr->CurrentModuleObject,
2172 : MaterialNames(1),
2173 0 : maxAngValue));
2174 0 : ShowContinueError(state,
2175 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2176 0 : " requires the maximum value = 90.0 in the entered table name=" + MaterialNames(5));
2177 : }
2178 1 : if (minLamValue < 0.1) {
2179 0 : ErrorsFound = true;
2180 0 : ShowSevereError(state,
2181 0 : format("{}=\"{}\", Invalid minimum value of wavelength = {:.2R}.",
2182 0 : state.dataHeatBalMgr->CurrentModuleObject,
2183 : MaterialNames(1),
2184 0 : minLamValue));
2185 0 : ShowContinueError(state,
2186 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2187 0 : " requires the minumum value = 0.1 micron in the entered table name=" + MaterialNames(5));
2188 : }
2189 1 : if (maxLamValue > 4.0) {
2190 0 : ErrorsFound = true;
2191 0 : ShowSevereError(state,
2192 0 : format("{}=\"{}\", Invalid maximum value of wavelength = {:.2R}.",
2193 0 : state.dataHeatBalMgr->CurrentModuleObject,
2194 : MaterialNames(1),
2195 0 : maxLamValue));
2196 0 : ShowContinueError(state,
2197 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2198 0 : " requires the maximum value = 4.0 microns in the entered table name=" + MaterialNames(5));
2199 : }
2200 : }
2201 : }
2202 1 : if (state.dataIPShortCut->lAlphaFieldBlanks(7)) {
2203 0 : ErrorsFound = true;
2204 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", blank field.");
2205 0 : ShowContinueError(state, " Table name must be entered when the key SpectralAndAngle is selected as Optical Data Type.");
2206 : } else {
2207 1 : state.dataMaterial->Material(MaterNum).GlassSpecAngBRefleDataPtr = Curve::GetCurveIndex(state, MaterialNames(7));
2208 1 : if (state.dataMaterial->Material(MaterNum).GlassSpecAngBRefleDataPtr == 0) {
2209 0 : ErrorsFound = true;
2210 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Invalid name.");
2211 0 : ShowContinueError(state,
2212 0 : state.dataIPShortCut->cAlphaFieldNames(7) +
2213 0 : " requires a valid table object name, entered input=" + MaterialNames(7));
2214 : } else {
2215 4 : ErrorsFound |= Curve::CheckCurveDims(state,
2216 1 : state.dataMaterial->Material(MaterNum).GlassSpecAngBRefleDataPtr, // Curve index
2217 : {2}, // Valid dimensions
2218 : RoutineName, // Routine name
2219 1 : state.dataHeatBalMgr->CurrentModuleObject, // Object Type
2220 1 : state.dataMaterial->Material(MaterNum).Name, // Object Name
2221 1 : state.dataIPShortCut->cAlphaFieldNames(7)); // Field Name
2222 :
2223 2 : GetCurveMinMaxValues(state,
2224 1 : state.dataMaterial->Material(MaterNum).GlassSpecAngBRefleDataPtr,
2225 : minAngValue,
2226 : maxAngValue,
2227 : minLamValue,
2228 : maxLamValue);
2229 1 : if (minAngValue > 1.0e-6) {
2230 0 : ErrorsFound = true;
2231 0 : ShowSevereError(state,
2232 0 : format("{}=\"{}\", Invalid minimum value of angle = {:.2R}.",
2233 0 : state.dataHeatBalMgr->CurrentModuleObject,
2234 : MaterialNames(1),
2235 0 : minAngValue));
2236 0 : ShowContinueError(state,
2237 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2238 0 : " requires the minumum value = 0.0 in the entered table name=" + MaterialNames(5));
2239 : }
2240 1 : if (std::abs(maxAngValue - 90.0) > 1.0e-6) {
2241 0 : ErrorsFound = true;
2242 0 : ShowSevereError(state,
2243 0 : format("{}=\"{}\", Invalid maximum value of angle = {:.2R}.",
2244 0 : state.dataHeatBalMgr->CurrentModuleObject,
2245 : MaterialNames(1),
2246 0 : maxAngValue));
2247 0 : ShowContinueError(state,
2248 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2249 0 : " requires the maximum value = 90.0 in the entered table name=" + MaterialNames(5));
2250 : }
2251 1 : if (minLamValue < 0.1) {
2252 0 : ErrorsFound = true;
2253 0 : ShowSevereError(state,
2254 0 : format("{}=\"{}\", Invalid minimum value of wavelength = {:.2R}.",
2255 0 : state.dataHeatBalMgr->CurrentModuleObject,
2256 : MaterialNames(1),
2257 0 : minLamValue));
2258 0 : ShowContinueError(state,
2259 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2260 0 : " requires the minumum value = 0.1 micron in the entered table name=" + MaterialNames(5));
2261 : }
2262 1 : if (maxLamValue > 4.0) {
2263 0 : ErrorsFound = true;
2264 0 : ShowSevereError(state,
2265 0 : format("{}=\"{}\", Invalid maximum value of wavelength = {:.2R}.",
2266 0 : state.dataHeatBalMgr->CurrentModuleObject,
2267 : MaterialNames(1),
2268 0 : maxLamValue));
2269 0 : ShowContinueError(state,
2270 0 : state.dataIPShortCut->cAlphaFieldNames(5) +
2271 0 : " requires the maximum value = 4.0 microns in the entered table name=" + MaterialNames(5));
2272 : }
2273 : }
2274 : }
2275 : }
2276 : }
2277 :
2278 : // Glass materials, alternative input: index of refraction and extinction coefficient
2279 :
2280 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Glazing:RefractionExtinctionMethod";
2281 781 : for (Loop = 1; Loop <= state.dataHeatBal->W5GlsMatAlt; ++Loop) {
2282 :
2283 : // Call Input Get routine to retrieve material data
2284 60 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2285 10 : state.dataHeatBalMgr->CurrentModuleObject,
2286 : Loop,
2287 : MaterialNames,
2288 : MaterialNumAlpha,
2289 : MaterialProps,
2290 : MaterialNumProp,
2291 : IOStat,
2292 10 : state.dataIPShortCut->lNumericFieldBlanks,
2293 10 : state.dataIPShortCut->lAlphaFieldBlanks,
2294 10 : state.dataIPShortCut->cAlphaFieldNames,
2295 10 : state.dataIPShortCut->cNumericFieldNames);
2296 30 : if (GlobalNames::VerifyUniqueInterObjectName(state,
2297 10 : state.dataHeatBalMgr->UniqueMaterialNames,
2298 10 : MaterialNames(1),
2299 10 : state.dataHeatBalMgr->CurrentModuleObject,
2300 10 : state.dataIPShortCut->cAlphaFieldNames(1),
2301 : ErrorsFound)) {
2302 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
2303 0 : continue;
2304 : }
2305 :
2306 10 : ++MaterNum;
2307 10 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::WindowGlass;
2308 :
2309 : // Load the material derived type from the input data.
2310 :
2311 10 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
2312 10 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::VerySmooth;
2313 10 : state.dataMaterial->Material(MaterNum).Thickness = MaterialProps(1);
2314 10 : state.dataMaterial->Material(MaterNum).ROnly = true;
2315 :
2316 : // Calculate solar and visible transmittance and reflectance at normal incidence from thickness,
2317 : // index of refraction and extinction coefficient. With the alternative input the front and back
2318 : // properties are assumed to be the same.
2319 :
2320 10 : ReflectivitySol = pow_2((MaterialProps(2) - 1.0) / (MaterialProps(2) + 1.0));
2321 10 : ReflectivityVis = pow_2((MaterialProps(4) - 1.0) / (MaterialProps(4) + 1.0));
2322 10 : TransmittivitySol = std::exp(-MaterialProps(3) * MaterialProps(1));
2323 10 : TransmittivityVis = std::exp(-MaterialProps(5) * MaterialProps(1));
2324 10 : state.dataMaterial->Material(MaterNum).Trans =
2325 10 : TransmittivitySol * pow_2(1.0 - ReflectivitySol) / (1.0 - pow_2(ReflectivitySol * TransmittivitySol));
2326 10 : state.dataMaterial->Material(MaterNum).ReflectSolBeamFront =
2327 10 : ReflectivitySol *
2328 10 : (1.0 + pow_2(1.0 - ReflectivitySol) * pow_2(TransmittivitySol) / (1.0 - pow_2(ReflectivitySol * TransmittivitySol)));
2329 10 : state.dataMaterial->Material(MaterNum).ReflectSolBeamBack = state.dataMaterial->Material(MaterNum).ReflectSolBeamFront;
2330 10 : state.dataMaterial->Material(MaterNum).TransVis =
2331 10 : TransmittivityVis * pow_2(1.0 - ReflectivityVis) / (1.0 - pow_2(ReflectivityVis * TransmittivityVis));
2332 :
2333 10 : state.dataMaterial->Material(MaterNum).ReflectVisBeamFront =
2334 10 : ReflectivityVis *
2335 10 : (1.0 + pow_2(1.0 - ReflectivityVis) * pow_2(TransmittivityVis) / (1.0 - pow_2(ReflectivityVis * TransmittivityVis)));
2336 10 : state.dataMaterial->Material(MaterNum).ReflectVisBeamBack = state.dataMaterial->Material(MaterNum).ReflectSolBeamFront;
2337 10 : state.dataMaterial->Material(MaterNum).TransThermal = MaterialProps(6);
2338 10 : state.dataMaterial->Material(MaterNum).AbsorpThermalFront = MaterialProps(7);
2339 10 : state.dataMaterial->Material(MaterNum).AbsorpThermalBack = MaterialProps(7);
2340 10 : state.dataMaterial->Material(MaterNum).Conductivity = MaterialProps(8);
2341 10 : state.dataMaterial->Material(MaterNum).GlassTransDirtFactor = MaterialProps(9);
2342 10 : if (MaterialProps(9) == 0.0) state.dataMaterial->Material(MaterNum).GlassTransDirtFactor = 1.0;
2343 10 : state.dataMaterial->Material(MaterNum).AbsorpThermal = state.dataMaterial->Material(MaterNum).AbsorpThermalBack;
2344 :
2345 10 : if (state.dataMaterial->Material(MaterNum).Conductivity > 0.0) {
2346 10 : state.dataHeatBal->NominalR(MaterNum) =
2347 10 : state.dataMaterial->Material(MaterNum).Thickness / state.dataMaterial->Material(MaterNum).Conductivity;
2348 10 : state.dataMaterial->Material(MaterNum).Resistance = state.dataHeatBal->NominalR(MaterNum);
2349 : }
2350 :
2351 10 : state.dataMaterial->Material(MaterNum).GlassSpectralDataPtr = 0;
2352 :
2353 10 : if (MaterialProps(6) + MaterialProps(7) >= 1.0) {
2354 0 : ErrorsFound = true;
2355 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
2356 0 : ShowContinueError(state,
2357 0 : state.dataIPShortCut->cNumericFieldNames(6) + " + " + state.dataIPShortCut->cNumericFieldNames(7) + " not < 1.0");
2358 : }
2359 :
2360 10 : if (MaterialNames(2) == "") {
2361 10 : state.dataMaterial->Material(MaterNum).SolarDiffusing = false;
2362 0 : } else if (MaterialNames(2) == "YES") {
2363 0 : state.dataMaterial->Material(MaterNum).SolarDiffusing = true;
2364 0 : } else if (MaterialNames(2) == "NO") {
2365 0 : state.dataMaterial->Material(MaterNum).SolarDiffusing = false;
2366 : } else {
2367 0 : ErrorsFound = true;
2368 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2369 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(2) + " must be Yes or No, entered value=" + MaterialNames(4));
2370 : }
2371 : }
2372 :
2373 : // Glass materials, equivalent layer (ASHWAT) method
2374 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Glazing:EquivalentLayer";
2375 775 : for (Loop = 1; Loop <= state.dataHeatBal->W5GlsMatEQL; ++Loop) {
2376 :
2377 : // Call Input Get routine to retrieve material data
2378 24 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2379 4 : state.dataHeatBalMgr->CurrentModuleObject,
2380 : Loop,
2381 : MaterialNames,
2382 : MaterialNumAlpha,
2383 : MaterialProps,
2384 : MaterialNumProp,
2385 : IOStat,
2386 4 : state.dataIPShortCut->lNumericFieldBlanks,
2387 4 : state.dataIPShortCut->lAlphaFieldBlanks,
2388 4 : state.dataIPShortCut->cAlphaFieldNames,
2389 4 : state.dataIPShortCut->cNumericFieldNames);
2390 12 : if (GlobalNames::VerifyUniqueInterObjectName(state,
2391 4 : state.dataHeatBalMgr->UniqueMaterialNames,
2392 4 : MaterialNames(1),
2393 4 : state.dataHeatBalMgr->CurrentModuleObject,
2394 4 : state.dataIPShortCut->cAlphaFieldNames(1),
2395 : ErrorsFound)) {
2396 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
2397 0 : continue;
2398 : }
2399 :
2400 4 : ++MaterNum;
2401 4 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::GlassEquivalentLayer;
2402 :
2403 : // Load the material derived type from the input data.
2404 4 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
2405 4 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::VerySmooth;
2406 4 : state.dataMaterial->Material(MaterNum).ROnly = true;
2407 :
2408 4 : state.dataMaterial->Material(MaterNum).TausFrontBeamBeam = MaterialProps(1);
2409 4 : state.dataMaterial->Material(MaterNum).TausBackBeamBeam = MaterialProps(2);
2410 4 : state.dataMaterial->Material(MaterNum).ReflFrontBeamBeam = MaterialProps(3);
2411 4 : state.dataMaterial->Material(MaterNum).ReflBackBeamBeam = MaterialProps(4);
2412 4 : state.dataMaterial->Material(MaterNum).TausFrontBeamBeamVis = MaterialProps(5);
2413 4 : state.dataMaterial->Material(MaterNum).TausBackBeamBeamVis = MaterialProps(6);
2414 4 : state.dataMaterial->Material(MaterNum).ReflFrontBeamBeamVis = MaterialProps(7);
2415 4 : state.dataMaterial->Material(MaterNum).ReflBackBeamBeamVis = MaterialProps(8);
2416 4 : state.dataMaterial->Material(MaterNum).TausFrontBeamDiff = MaterialProps(9);
2417 4 : state.dataMaterial->Material(MaterNum).TausBackBeamDiff = MaterialProps(10);
2418 4 : state.dataMaterial->Material(MaterNum).ReflFrontBeamDiff = MaterialProps(11);
2419 4 : state.dataMaterial->Material(MaterNum).ReflBackBeamDiff = MaterialProps(12);
2420 4 : state.dataMaterial->Material(MaterNum).TausFrontBeamDiffVis = MaterialProps(13);
2421 4 : state.dataMaterial->Material(MaterNum).TausBackBeamDiffVis = MaterialProps(14);
2422 4 : state.dataMaterial->Material(MaterNum).ReflFrontBeamDiffVis = MaterialProps(15);
2423 4 : state.dataMaterial->Material(MaterNum).ReflBackBeamDiffVis = MaterialProps(16);
2424 4 : state.dataMaterial->Material(MaterNum).TausDiffDiff = MaterialProps(17);
2425 4 : state.dataMaterial->Material(MaterNum).ReflFrontDiffDiff = MaterialProps(18);
2426 4 : state.dataMaterial->Material(MaterNum).ReflBackDiffDiff = MaterialProps(19);
2427 4 : state.dataMaterial->Material(MaterNum).TausDiffDiffVis = MaterialProps(20);
2428 4 : state.dataMaterial->Material(MaterNum).ReflFrontDiffDiffVis = MaterialProps(21);
2429 4 : state.dataMaterial->Material(MaterNum).ReflBackDiffDiffVis = MaterialProps(22);
2430 4 : state.dataMaterial->Material(MaterNum).TausThermal = MaterialProps(23);
2431 4 : state.dataMaterial->Material(MaterNum).EmissThermalFront = MaterialProps(24);
2432 4 : state.dataMaterial->Material(MaterNum).EmissThermalBack = MaterialProps(25);
2433 4 : state.dataMaterial->Material(MaterNum).Resistance = MaterialProps(26);
2434 4 : if (state.dataMaterial->Material(MaterNum).Resistance <= 0.0)
2435 4 : state.dataMaterial->Material(MaterNum).Resistance = 0.158; // equivalent to single pane of 1/4" inch standard glass
2436 : // Assumes thermal emissivity is the same as thermal absorptance
2437 4 : state.dataMaterial->Material(MaterNum).AbsorpThermalFront = state.dataMaterial->Material(MaterNum).EmissThermalFront;
2438 4 : state.dataMaterial->Material(MaterNum).AbsorpThermalBack = state.dataMaterial->Material(MaterNum).EmissThermalBack;
2439 4 : state.dataMaterial->Material(MaterNum).TransThermal = state.dataMaterial->Material(MaterNum).TausThermal;
2440 :
2441 4 : if (UtilityRoutines::SameString(MaterialNames(2), "SpectralAverage")) state.dataMaterial->Material(MaterNum).GlassSpectralDataPtr = 0;
2442 :
2443 : // IF(dataMaterial.Material(MaterNum)%GlassSpectralDataPtr == 0 .AND. UtilityRoutines::SameString(MaterialNames(2),'Spectral')) THEN
2444 : // ErrorsFound = .TRUE.
2445 : // CALL ShowSevereError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//'="'//Trim(dataMaterial.Material(MaterNum)%Name)// &
2446 : // '" has '//TRIM(cAlphaFieldNames(2))//' = Spectral but has no matching MaterialProperty:GlazingSpectralData set')
2447 : // if (state.dataIPShortCut->lAlphaFieldBlanks(3)) THEN
2448 : // CALL ShowContinueError(state, '...'//TRIM(cAlphaFieldNames(3))//' is blank.')
2449 : // ELSE
2450 : // CALL ShowContinueError(state, '...'//TRIM(cAlphaFieldNames(3))//'="'//TRIM(MaterialNames(3))// &
2451 : // '" not found as item in MaterialProperty:GlazingSpectralData objects.')
2452 : // END IF
2453 : // END IF
2454 :
2455 4 : if (!UtilityRoutines::SameString(MaterialNames(2), "SpectralAverage")) {
2456 0 : ErrorsFound = true;
2457 0 : ShowSevereError(state,
2458 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + state.dataMaterial->Material(MaterNum).Name +
2459 : "\", invalid specification.");
2460 0 : ShowContinueError(state, state.dataIPShortCut->cAlphaFieldNames(2) + " must be SpectralAverage, value=" + MaterialNames(2));
2461 : }
2462 :
2463 : } // W5GlsMatEQL loop
2464 :
2465 : // Window gas materials (for gaps with a single gas)
2466 :
2467 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Gas";
2468 1562 : for (Loop = 1; Loop <= state.dataHeatBal->W5GasMat; ++Loop) {
2469 :
2470 : // Call Input Get routine to retrieve material data
2471 4746 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2472 791 : state.dataHeatBalMgr->CurrentModuleObject,
2473 : Loop,
2474 : MaterialNames,
2475 : MaterialNumAlpha,
2476 : MaterialProps,
2477 : MaterialNumProp,
2478 : IOStat,
2479 791 : state.dataIPShortCut->lNumericFieldBlanks,
2480 791 : state.dataIPShortCut->lAlphaFieldBlanks,
2481 791 : state.dataIPShortCut->cAlphaFieldNames,
2482 791 : state.dataIPShortCut->cNumericFieldNames);
2483 2373 : if (GlobalNames::VerifyUniqueInterObjectName(state,
2484 791 : state.dataHeatBalMgr->UniqueMaterialNames,
2485 791 : MaterialNames(1),
2486 791 : state.dataHeatBalMgr->CurrentModuleObject,
2487 791 : state.dataIPShortCut->cAlphaFieldNames(1),
2488 : ErrorsFound)) {
2489 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
2490 0 : continue;
2491 : }
2492 :
2493 791 : ++MaterNum;
2494 791 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::WindowGas;
2495 791 : state.dataMaterial->Material(MaterNum).GasType(1) = -1;
2496 791 : state.dataMaterial->Material(MaterNum).NumberOfGasesInMixture = 1;
2497 791 : state.dataMaterial->Material(MaterNum).GasFract(1) = 1.0;
2498 :
2499 : // Load the material derived type from the input data.
2500 :
2501 791 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
2502 791 : state.dataMaterial->Material(MaterNum).NumberOfGasesInMixture = 1;
2503 791 : TypeOfGas = MaterialNames(2);
2504 791 : if (TypeOfGas == "AIR") state.dataMaterial->Material(MaterNum).GasType(1) = 1;
2505 791 : if (TypeOfGas == "ARGON") state.dataMaterial->Material(MaterNum).GasType(1) = 2;
2506 791 : if (TypeOfGas == "KRYPTON") state.dataMaterial->Material(MaterNum).GasType(1) = 3;
2507 791 : if (TypeOfGas == "XENON") state.dataMaterial->Material(MaterNum).GasType(1) = 4;
2508 791 : if (TypeOfGas == "CUSTOM") state.dataMaterial->Material(MaterNum).GasType(1) = 0;
2509 :
2510 791 : if (state.dataMaterial->Material(MaterNum).GasType(1) == -1) {
2511 0 : ErrorsFound = true;
2512 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2513 0 : ShowContinueError(state,
2514 0 : state.dataIPShortCut->cAlphaFieldNames(2) + " entered value=\"" + TypeOfGas +
2515 : "\" should be Air, Argon, Krypton, Xenon or Custom.");
2516 : }
2517 :
2518 791 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough;
2519 :
2520 791 : state.dataMaterial->Material(MaterNum).Thickness = MaterialProps(1);
2521 791 : state.dataMaterial->Material(MaterNum).ROnly = true;
2522 :
2523 791 : GasType = state.dataMaterial->Material(MaterNum).GasType(1);
2524 791 : if (GasType >= 1 && GasType <= 4) {
2525 789 : state.dataMaterial->Material(MaterNum).GasWght(1) = GasWght[GasType - 1];
2526 789 : state.dataMaterial->Material(MaterNum).GasSpecHeatRatio(1) = GasSpecificHeatRatio[GasType - 1];
2527 3156 : for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
2528 2367 : state.dataMaterial->Material(MaterNum).GasCon(ICoeff, 1) = GasCoeffsCon[ICoeff - 1][GasType - 1];
2529 2367 : state.dataMaterial->Material(MaterNum).GasVis(ICoeff, 1) = GasCoeffsVis[ICoeff - 1][GasType - 1];
2530 2367 : state.dataMaterial->Material(MaterNum).GasCp(ICoeff, 1) = GasCoeffsCp[ICoeff - 1][GasType - 1];
2531 : }
2532 : }
2533 :
2534 : // Custom gas
2535 :
2536 791 : if (GasType == 0) {
2537 8 : for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
2538 6 : state.dataMaterial->Material(MaterNum).GasCon(ICoeff, 1) = MaterialProps(1 + ICoeff);
2539 6 : state.dataMaterial->Material(MaterNum).GasVis(ICoeff, 1) = MaterialProps(4 + ICoeff);
2540 6 : state.dataMaterial->Material(MaterNum).GasCp(ICoeff, 1) = MaterialProps(7 + ICoeff);
2541 : }
2542 2 : state.dataMaterial->Material(MaterNum).GasWght(1) = MaterialProps(11);
2543 2 : state.dataMaterial->Material(MaterNum).GasSpecHeatRatio(1) = MaterialProps(12);
2544 :
2545 : // Check for errors in custom gas properties
2546 : // IF(dataMaterial.Material(MaterNum)%GasCon(1,1) <= 0.0) THEN
2547 : // ErrorsFound = .TRUE.
2548 : // CALL ShowSevereError(state, 'Conductivity Coefficient A for custom window gas='&
2549 : // //TRIM(MaterialNames(1))//' should be > 0.')
2550 : // END IF
2551 :
2552 2 : if (state.dataMaterial->Material(MaterNum).GasVis(1, 1) <= 0.0) {
2553 0 : ErrorsFound = true;
2554 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2555 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(3 + ICoeff) + " not > 0.0");
2556 : }
2557 2 : if (state.dataMaterial->Material(MaterNum).GasCp(1, 1) <= 0.0) {
2558 0 : ErrorsFound = true;
2559 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2560 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(5 + ICoeff) + " not > 0.0");
2561 : }
2562 2 : if (state.dataMaterial->Material(MaterNum).GasWght(1) <= 0.0) {
2563 0 : ErrorsFound = true;
2564 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2565 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(8) + " not > 0.0");
2566 : }
2567 : }
2568 :
2569 : // Nominal resistance of gap at room temperature
2570 791 : if (!ErrorsFound) {
2571 1582 : DenomRGas = (state.dataMaterial->Material(MaterNum).GasCon(1, 1) + state.dataMaterial->Material(MaterNum).GasCon(2, 1) * 300.0 +
2572 791 : state.dataMaterial->Material(MaterNum).GasCon(3, 1) * 90000.0);
2573 791 : if (DenomRGas > 0.0) {
2574 791 : state.dataHeatBal->NominalR(MaterNum) = state.dataMaterial->Material(MaterNum).Thickness / DenomRGas;
2575 : } else {
2576 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2577 0 : ShowContinueError(
2578 0 : state, format("Nominal resistance of gap at room temperature calculated at a negative Conductivity=[{:.3R}].", DenomRGas));
2579 0 : ErrorsFound = true;
2580 : }
2581 : }
2582 : }
2583 :
2584 : // Window gap materials (for gaps with a single gas for EquivalentLayer)
2585 :
2586 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Gap:EquivalentLayer";
2587 779 : for (Loop = 1; Loop <= state.dataHeatBal->W5GapMatEQL; ++Loop) {
2588 :
2589 : // Call Input Get routine to retrieve material data
2590 48 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2591 8 : state.dataHeatBalMgr->CurrentModuleObject,
2592 : Loop,
2593 : MaterialNames,
2594 : MaterialNumAlpha,
2595 : MaterialProps,
2596 : MaterialNumProp,
2597 : IOStat,
2598 8 : state.dataIPShortCut->lNumericFieldBlanks,
2599 8 : state.dataIPShortCut->lAlphaFieldBlanks,
2600 8 : state.dataIPShortCut->cAlphaFieldNames,
2601 8 : state.dataIPShortCut->cNumericFieldNames);
2602 24 : if (GlobalNames::VerifyUniqueInterObjectName(state,
2603 8 : state.dataHeatBalMgr->UniqueMaterialNames,
2604 8 : MaterialNames(1),
2605 8 : state.dataHeatBalMgr->CurrentModuleObject,
2606 8 : state.dataIPShortCut->cAlphaFieldNames(1),
2607 : ErrorsFound)) {
2608 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
2609 0 : continue;
2610 : }
2611 :
2612 8 : ++MaterNum;
2613 8 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::GapEquivalentLayer;
2614 8 : state.dataMaterial->Material(MaterNum).GasType(1) = -1;
2615 8 : state.dataMaterial->Material(MaterNum).NumberOfGasesInMixture = 1;
2616 8 : state.dataMaterial->Material(MaterNum).GasFract(1) = 1.0;
2617 :
2618 : // Load the material derived type from the input data.
2619 :
2620 8 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
2621 8 : state.dataMaterial->Material(MaterNum).NumberOfGasesInMixture = 1;
2622 8 : TypeOfGas = MaterialNames(2);
2623 8 : state.dataMaterial->Material(MaterNum).GasName = TypeOfGas;
2624 8 : if (TypeOfGas == "AIR") state.dataMaterial->Material(MaterNum).GasType(1) = 1;
2625 8 : if (TypeOfGas == "ARGON") state.dataMaterial->Material(MaterNum).GasType(1) = 2;
2626 8 : if (TypeOfGas == "KRYPTON") state.dataMaterial->Material(MaterNum).GasType(1) = 3;
2627 8 : if (TypeOfGas == "XENON") state.dataMaterial->Material(MaterNum).GasType(1) = 4;
2628 8 : if (TypeOfGas == "CUSTOM") state.dataMaterial->Material(MaterNum).GasType(1) = 0;
2629 :
2630 8 : if (state.dataMaterial->Material(MaterNum).GasType(1) == -1) {
2631 0 : ErrorsFound = true;
2632 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2633 0 : ShowContinueError(
2634 0 : state, state.dataIPShortCut->cAlphaFieldNames(2) + " entered value=\"" + TypeOfGas + "\" should be Air, Argon, Krypton, Xenon");
2635 : }
2636 :
2637 8 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough;
2638 :
2639 8 : state.dataMaterial->Material(MaterNum).Thickness = MaterialProps(1);
2640 8 : state.dataMaterial->Material(MaterNum).ROnly = true;
2641 :
2642 8 : GasType = state.dataMaterial->Material(MaterNum).GasType(1);
2643 8 : if (GasType >= 1 && GasType <= 4) {
2644 8 : state.dataMaterial->Material(MaterNum).GasWght(1) = GasWght[GasType - 1];
2645 8 : state.dataMaterial->Material(MaterNum).GasSpecHeatRatio(1) = GasSpecificHeatRatio[GasType - 1];
2646 32 : for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
2647 24 : state.dataMaterial->Material(MaterNum).GasCon(ICoeff, 1) = GasCoeffsCon[ICoeff - 1][GasType - 1];
2648 24 : state.dataMaterial->Material(MaterNum).GasVis(ICoeff, 1) = GasCoeffsVis[ICoeff - 1][GasType - 1];
2649 24 : state.dataMaterial->Material(MaterNum).GasCp(ICoeff, 1) = GasCoeffsCp[ICoeff - 1][GasType - 1];
2650 : }
2651 : }
2652 :
2653 8 : if (!state.dataIPShortCut->lAlphaFieldBlanks(2)) {
2654 : // Get gap vent type
2655 8 : if (UtilityRoutines::SameString(MaterialNames(3), "Sealed")) {
2656 8 : state.dataMaterial->Material(MaterNum).GapVentType = 1;
2657 0 : } else if (UtilityRoutines::SameString(MaterialNames(3), "VentedIndoor")) {
2658 0 : state.dataMaterial->Material(MaterNum).GapVentType = 2;
2659 0 : } else if (UtilityRoutines::SameString(MaterialNames(3), "VentedOutdoor")) {
2660 0 : state.dataMaterial->Material(MaterNum).GapVentType = 3;
2661 : } else {
2662 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal gap vent type.");
2663 0 : ShowContinueError(state,
2664 0 : "Gap vent type allowed are Sealed, VentedIndoor, or VentedOutdoor." +
2665 0 : state.dataIPShortCut->cAlphaFieldNames(3) + " entered =" + MaterialNames(3));
2666 0 : state.dataMaterial->Material(MaterNum).GapVentType = 1;
2667 : // ErrorsFound=.TRUE.
2668 : }
2669 : }
2670 :
2671 8 : if (GasType == 0) {
2672 0 : for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
2673 0 : state.dataMaterial->Material(MaterNum).GasCon(ICoeff, 1) = MaterialProps(1 + ICoeff);
2674 0 : state.dataMaterial->Material(MaterNum).GasVis(ICoeff, 1) = MaterialProps(4 + ICoeff);
2675 0 : state.dataMaterial->Material(MaterNum).GasCp(ICoeff, 1) = MaterialProps(7 + ICoeff);
2676 : }
2677 0 : state.dataMaterial->Material(MaterNum).GasWght(1) = MaterialProps(11);
2678 0 : state.dataMaterial->Material(MaterNum).GasSpecHeatRatio(1) = MaterialProps(12);
2679 :
2680 0 : if (state.dataMaterial->Material(MaterNum).GasVis(1, 1) <= 0.0) {
2681 0 : ErrorsFound = true;
2682 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2683 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(5) + " not > 0.0");
2684 : }
2685 0 : if (state.dataMaterial->Material(MaterNum).GasCp(1, 1) <= 0.0) {
2686 0 : ErrorsFound = true;
2687 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2688 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(8) + " not > 0.0");
2689 : }
2690 0 : if (state.dataMaterial->Material(MaterNum).GasWght(1) <= 0.0) {
2691 0 : ErrorsFound = true;
2692 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2693 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(11) + " not > 0.0");
2694 : }
2695 : }
2696 :
2697 : // Nominal resistance of gap at room temperature
2698 8 : if (!ErrorsFound) {
2699 16 : DenomRGas = (state.dataMaterial->Material(MaterNum).GasCon(1, 1) + state.dataMaterial->Material(MaterNum).GasCon(2, 1) * 300.0 +
2700 8 : state.dataMaterial->Material(MaterNum).GasCon(3, 1) * 90000.0);
2701 8 : if (DenomRGas > 0.0) {
2702 8 : state.dataHeatBal->NominalR(MaterNum) = state.dataMaterial->Material(MaterNum).Thickness / DenomRGas;
2703 : } else {
2704 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
2705 0 : ShowContinueError(
2706 0 : state, format("Nominal resistance of gap at room temperature calculated at a negative Conductivity=[{:.3R}].", DenomRGas));
2707 0 : ErrorsFound = true;
2708 : }
2709 : }
2710 : }
2711 :
2712 : // Window gas mixtures (for gaps with two or more gases)
2713 :
2714 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:GasMixture";
2715 787 : for (Loop = 1; Loop <= state.dataHeatBal->W5GasMatMixture; ++Loop) {
2716 :
2717 : // Call Input Get routine to retrieve material data
2718 112 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2719 16 : state.dataHeatBalMgr->CurrentModuleObject,
2720 : Loop,
2721 16 : state.dataIPShortCut->cAlphaArgs,
2722 : MaterialNumAlpha,
2723 : MaterialProps,
2724 : MaterialNumProp,
2725 : IOStat,
2726 16 : state.dataIPShortCut->lNumericFieldBlanks,
2727 16 : state.dataIPShortCut->lAlphaFieldBlanks,
2728 16 : state.dataIPShortCut->cAlphaFieldNames,
2729 16 : state.dataIPShortCut->cNumericFieldNames);
2730 48 : if (GlobalNames::VerifyUniqueInterObjectName(state,
2731 16 : state.dataHeatBalMgr->UniqueMaterialNames,
2732 16 : state.dataIPShortCut->cAlphaArgs(1),
2733 16 : state.dataHeatBalMgr->CurrentModuleObject,
2734 16 : state.dataIPShortCut->cAlphaFieldNames(1),
2735 : ErrorsFound)) {
2736 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
2737 0 : continue;
2738 : }
2739 :
2740 16 : ++MaterNum;
2741 16 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::WindowGasMixture;
2742 16 : state.dataMaterial->Material(MaterNum).GasType = -1;
2743 :
2744 : // Load the material derived type from the input data.
2745 :
2746 16 : state.dataMaterial->Material(MaterNum).Name = state.dataIPShortCut->cAlphaArgs(1);
2747 16 : NumGases = MaterialProps(2);
2748 16 : state.dataMaterial->Material(MaterNum).NumberOfGasesInMixture = NumGases;
2749 48 : for (NumGas = 1; NumGas <= NumGases; ++NumGas) {
2750 32 : TypeOfGas = state.dataIPShortCut->cAlphaArgs(1 + NumGas);
2751 32 : if (TypeOfGas == "AIR") state.dataMaterial->Material(MaterNum).GasType(NumGas) = 1;
2752 32 : if (TypeOfGas == "ARGON") state.dataMaterial->Material(MaterNum).GasType(NumGas) = 2;
2753 32 : if (TypeOfGas == "KRYPTON") state.dataMaterial->Material(MaterNum).GasType(NumGas) = 3;
2754 32 : if (TypeOfGas == "XENON") state.dataMaterial->Material(MaterNum).GasType(NumGas) = 4;
2755 32 : if (state.dataMaterial->Material(MaterNum).GasType(NumGas) == -1) {
2756 0 : ErrorsFound = true;
2757 0 : ShowSevereError(state,
2758 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", Illegal value.");
2759 0 : ShowContinueError(state,
2760 0 : state.dataIPShortCut->cAlphaFieldNames(2 + NumGas) + " entered value=\"" + TypeOfGas +
2761 : "\" should be Air, Argon, Krypton, or Xenon.");
2762 : }
2763 : }
2764 :
2765 16 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough; // Unused
2766 :
2767 16 : state.dataMaterial->Material(MaterNum).Thickness = MaterialProps(1);
2768 16 : if (state.dataMaterial->Material(MaterNum).Thickness <= 0.0) {
2769 0 : ShowSevereError(state,
2770 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", Illegal value.");
2771 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(1) + " must be greater than 0.");
2772 : }
2773 16 : state.dataMaterial->Material(MaterNum).ROnly = true;
2774 :
2775 48 : for (NumGas = 1; NumGas <= NumGases; ++NumGas) {
2776 32 : GasType = state.dataMaterial->Material(MaterNum).GasType(NumGas);
2777 32 : if (GasType >= 1 && GasType <= 4) {
2778 32 : state.dataMaterial->Material(MaterNum).GasWght(NumGas) = GasWght[GasType - 1];
2779 32 : state.dataMaterial->Material(MaterNum).GasSpecHeatRatio(NumGas) = GasSpecificHeatRatio[GasType - 1];
2780 32 : state.dataMaterial->Material(MaterNum).GasFract(NumGas) = MaterialProps(2 + NumGas);
2781 128 : for (ICoeff = 1; ICoeff <= 3; ++ICoeff) {
2782 96 : state.dataMaterial->Material(MaterNum).GasCon(ICoeff, NumGas) = GasCoeffsCon[ICoeff - 1][GasType - 1];
2783 96 : state.dataMaterial->Material(MaterNum).GasVis(ICoeff, NumGas) = GasCoeffsVis[ICoeff - 1][GasType - 1];
2784 96 : state.dataMaterial->Material(MaterNum).GasCp(ICoeff, NumGas) = GasCoeffsCp[ICoeff - 1][GasType - 1];
2785 : }
2786 : }
2787 : }
2788 :
2789 : // Nominal resistance of gap at room temperature (based on first gas in mixture)
2790 16 : state.dataHeatBal->NominalR(MaterNum) =
2791 32 : state.dataMaterial->Material(MaterNum).Thickness /
2792 32 : (state.dataMaterial->Material(MaterNum).GasCon(1, 1) + state.dataMaterial->Material(MaterNum).GasCon(2, 1) * 300.0 +
2793 16 : state.dataMaterial->Material(MaterNum).GasCon(3, 1) * 90000.0);
2794 : }
2795 :
2796 : // Window Shade Materials
2797 :
2798 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Shade";
2799 788 : for (Loop = 1; Loop <= state.dataHeatBal->TotShades; ++Loop) {
2800 :
2801 : // Call Input Get routine to retrieve material data
2802 102 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2803 17 : state.dataHeatBalMgr->CurrentModuleObject,
2804 : Loop,
2805 : MaterialNames,
2806 : MaterialNumAlpha,
2807 : MaterialProps,
2808 : MaterialNumProp,
2809 : IOStat,
2810 17 : state.dataIPShortCut->lNumericFieldBlanks,
2811 17 : state.dataIPShortCut->lAlphaFieldBlanks,
2812 17 : state.dataIPShortCut->cAlphaFieldNames,
2813 17 : state.dataIPShortCut->cNumericFieldNames);
2814 51 : if (GlobalNames::VerifyUniqueInterObjectName(state,
2815 17 : state.dataHeatBalMgr->UniqueMaterialNames,
2816 17 : MaterialNames(1),
2817 17 : state.dataHeatBalMgr->CurrentModuleObject,
2818 17 : state.dataIPShortCut->cAlphaFieldNames(1),
2819 : ErrorsFound)) {
2820 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
2821 0 : continue;
2822 : }
2823 :
2824 17 : ++MaterNum;
2825 17 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::Shade;
2826 :
2827 : // Load the material derived type from the input data.
2828 :
2829 17 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
2830 17 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough;
2831 17 : state.dataMaterial->Material(MaterNum).Trans = MaterialProps(1);
2832 17 : state.dataMaterial->Material(MaterNum).ReflectShade = MaterialProps(2);
2833 17 : state.dataMaterial->Material(MaterNum).TransVis = MaterialProps(3);
2834 17 : state.dataMaterial->Material(MaterNum).ReflectShadeVis = MaterialProps(4);
2835 17 : state.dataMaterial->Material(MaterNum).AbsorpThermal = MaterialProps(5);
2836 17 : state.dataMaterial->Material(MaterNum).AbsorpThermalInput = MaterialProps(5);
2837 17 : state.dataMaterial->Material(MaterNum).TransThermal = MaterialProps(6);
2838 17 : state.dataMaterial->Material(MaterNum).Thickness = MaterialProps(7);
2839 17 : state.dataMaterial->Material(MaterNum).Conductivity = MaterialProps(8);
2840 17 : state.dataMaterial->Material(MaterNum).AbsorpSolar =
2841 17 : max(0.0, 1.0 - state.dataMaterial->Material(MaterNum).Trans - state.dataMaterial->Material(MaterNum).ReflectShade);
2842 17 : state.dataMaterial->Material(MaterNum).AbsorpSolarInput = state.dataMaterial->Material(MaterNum).AbsorpSolar;
2843 17 : state.dataMaterial->Material(MaterNum).WinShadeToGlassDist = MaterialProps(9);
2844 17 : state.dataMaterial->Material(MaterNum).WinShadeTopOpeningMult = MaterialProps(10);
2845 17 : state.dataMaterial->Material(MaterNum).WinShadeBottomOpeningMult = MaterialProps(11);
2846 17 : state.dataMaterial->Material(MaterNum).WinShadeLeftOpeningMult = MaterialProps(12);
2847 17 : state.dataMaterial->Material(MaterNum).WinShadeRightOpeningMult = MaterialProps(13);
2848 17 : state.dataMaterial->Material(MaterNum).WinShadeAirFlowPermeability = MaterialProps(14);
2849 17 : state.dataMaterial->Material(MaterNum).ROnly = true;
2850 :
2851 17 : if (state.dataMaterial->Material(MaterNum).Conductivity > 0.0) {
2852 17 : state.dataHeatBal->NominalR(MaterNum) =
2853 17 : state.dataMaterial->Material(MaterNum).Thickness / state.dataMaterial->Material(MaterNum).Conductivity;
2854 : } else {
2855 0 : state.dataHeatBal->NominalR(MaterNum) = 1.0;
2856 : }
2857 :
2858 17 : if (MaterialProps(1) + MaterialProps(2) >= 1.0) {
2859 0 : ErrorsFound = true;
2860 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
2861 0 : ShowContinueError(state,
2862 0 : state.dataIPShortCut->cNumericFieldNames(1) + " + " + state.dataIPShortCut->cNumericFieldNames(2) + " not < 1.0");
2863 : }
2864 :
2865 17 : if (MaterialProps(3) + MaterialProps(4) >= 1.0) {
2866 0 : ErrorsFound = true;
2867 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
2868 0 : ShowContinueError(state,
2869 0 : state.dataIPShortCut->cNumericFieldNames(3) + " + " + state.dataIPShortCut->cNumericFieldNames(4) + " not < 1.0");
2870 : }
2871 :
2872 17 : if (MaterialProps(5) + MaterialProps(6) >= 1.0) {
2873 0 : ErrorsFound = true;
2874 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
2875 0 : ShowContinueError(state,
2876 0 : state.dataIPShortCut->cNumericFieldNames(5) + " + " + state.dataIPShortCut->cNumericFieldNames(6) + " not < 1.0");
2877 : }
2878 : }
2879 :
2880 : // Window Shade Materials
2881 :
2882 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Shade:EquivalentLayer";
2883 773 : for (Loop = 1; Loop <= state.dataHeatBal->TotShadesEQL; ++Loop) {
2884 :
2885 2 : MaterialProps = 0;
2886 :
2887 : // Call Input Get routine to retrieve material data
2888 12 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2889 2 : state.dataHeatBalMgr->CurrentModuleObject,
2890 : Loop,
2891 : MaterialNames,
2892 : MaterialNumAlpha,
2893 : MaterialProps,
2894 : MaterialNumProp,
2895 : IOStat,
2896 2 : state.dataIPShortCut->lNumericFieldBlanks,
2897 2 : state.dataIPShortCut->lAlphaFieldBlanks,
2898 2 : state.dataIPShortCut->cAlphaFieldNames,
2899 2 : state.dataIPShortCut->cNumericFieldNames);
2900 6 : if (GlobalNames::VerifyUniqueInterObjectName(state,
2901 2 : state.dataHeatBalMgr->UniqueMaterialNames,
2902 2 : MaterialNames(1),
2903 2 : state.dataHeatBalMgr->CurrentModuleObject,
2904 2 : state.dataIPShortCut->cAlphaFieldNames(1),
2905 : ErrorsFound)) {
2906 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
2907 0 : continue;
2908 : }
2909 :
2910 2 : ++MaterNum;
2911 2 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::ShadeEquivalentLayer;
2912 :
2913 2 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
2914 2 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough;
2915 2 : state.dataMaterial->Material(MaterNum).ROnly = true;
2916 :
2917 : // Front side and back side have the same beam-Beam Transmittance
2918 2 : state.dataMaterial->Material(MaterNum).TausFrontBeamBeam = MaterialProps(1);
2919 2 : state.dataMaterial->Material(MaterNum).TausBackBeamBeam = MaterialProps(1);
2920 2 : state.dataMaterial->Material(MaterNum).TausFrontBeamDiff = MaterialProps(2);
2921 2 : state.dataMaterial->Material(MaterNum).TausBackBeamDiff = MaterialProps(3);
2922 2 : state.dataMaterial->Material(MaterNum).ReflFrontBeamDiff = MaterialProps(4);
2923 2 : state.dataMaterial->Material(MaterNum).ReflBackBeamDiff = MaterialProps(5);
2924 2 : state.dataMaterial->Material(MaterNum).TausFrontBeamBeamVis = MaterialProps(6);
2925 2 : state.dataMaterial->Material(MaterNum).TausFrontBeamDiffVis = MaterialProps(7);
2926 2 : state.dataMaterial->Material(MaterNum).ReflFrontBeamDiffVis = MaterialProps(8);
2927 2 : state.dataMaterial->Material(MaterNum).TausThermal = MaterialProps(9);
2928 2 : state.dataMaterial->Material(MaterNum).EmissThermalFront = MaterialProps(10);
2929 2 : state.dataMaterial->Material(MaterNum).EmissThermalBack = MaterialProps(11);
2930 : // Assumes thermal emissivity is the same as thermal absorptance
2931 2 : state.dataMaterial->Material(MaterNum).AbsorpThermalFront = state.dataMaterial->Material(MaterNum).EmissThermalFront;
2932 2 : state.dataMaterial->Material(MaterNum).AbsorpThermalBack = state.dataMaterial->Material(MaterNum).EmissThermalBack;
2933 2 : state.dataMaterial->Material(MaterNum).TransThermal = state.dataMaterial->Material(MaterNum).TausThermal;
2934 :
2935 2 : if (MaterialProps(1) + MaterialProps(2) + MaterialProps(4) >= 1.0) {
2936 0 : ErrorsFound = true;
2937 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
2938 0 : ShowContinueError(state,
2939 0 : state.dataIPShortCut->cNumericFieldNames(1) + " + " + state.dataIPShortCut->cNumericFieldNames(2) + " + " +
2940 0 : state.dataIPShortCut->cNumericFieldNames(4) + "not < 1.0");
2941 : }
2942 2 : if (MaterialProps(1) + MaterialProps(3) + MaterialProps(5) >= 1.0) {
2943 0 : ErrorsFound = true;
2944 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
2945 0 : ShowContinueError(state,
2946 0 : state.dataIPShortCut->cNumericFieldNames(1) + " + " + state.dataIPShortCut->cNumericFieldNames(3) + " + " +
2947 0 : state.dataIPShortCut->cNumericFieldNames(5) + "not < 1.0");
2948 : }
2949 2 : if (MaterialProps(6) + MaterialProps(7) + MaterialProps(8) >= 1.0) {
2950 0 : ErrorsFound = true;
2951 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
2952 0 : ShowContinueError(state,
2953 0 : state.dataIPShortCut->cNumericFieldNames(6) + " + " + state.dataIPShortCut->cNumericFieldNames(7) + " + " +
2954 0 : state.dataIPShortCut->cNumericFieldNames(8) + "not < 1.0");
2955 : }
2956 2 : if (MaterialProps(9) + MaterialProps(10) >= 1.0) {
2957 0 : ErrorsFound = true;
2958 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
2959 0 : ShowContinueError(state,
2960 0 : state.dataIPShortCut->cNumericFieldNames(9) + " + " + state.dataIPShortCut->cNumericFieldNames(10) + " not < 1.0");
2961 : }
2962 2 : if (MaterialProps(9) + MaterialProps(11) >= 1.0) {
2963 0 : ErrorsFound = true;
2964 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
2965 0 : ShowContinueError(state,
2966 0 : state.dataIPShortCut->cNumericFieldNames(9) + " + " + state.dataIPShortCut->cNumericFieldNames(11) + " not < 1.0");
2967 : }
2968 :
2969 : } // TotShadesEQL loop
2970 :
2971 : // Window drape materials
2972 :
2973 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Drape:EquivalentLayer";
2974 771 : for (Loop = 1; Loop <= state.dataHeatBal->TotDrapesEQL; ++Loop) {
2975 :
2976 0 : MaterialProps = 0;
2977 :
2978 : // Call Input Get routine to retrieve material data
2979 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2980 0 : state.dataHeatBalMgr->CurrentModuleObject,
2981 : Loop,
2982 : MaterialNames,
2983 : MaterialNumAlpha,
2984 : MaterialProps,
2985 : MaterialNumProp,
2986 : IOStat,
2987 0 : state.dataIPShortCut->lNumericFieldBlanks,
2988 0 : state.dataIPShortCut->lAlphaFieldBlanks,
2989 0 : state.dataIPShortCut->cAlphaFieldNames,
2990 0 : state.dataIPShortCut->cNumericFieldNames);
2991 0 : if (GlobalNames::VerifyUniqueInterObjectName(state,
2992 0 : state.dataHeatBalMgr->UniqueMaterialNames,
2993 0 : MaterialNames(1),
2994 0 : state.dataHeatBalMgr->CurrentModuleObject,
2995 0 : state.dataIPShortCut->cAlphaFieldNames(1),
2996 : ErrorsFound)) {
2997 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
2998 0 : continue;
2999 : }
3000 :
3001 0 : ++MaterNum;
3002 0 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::DrapeEquivalentLayer;
3003 :
3004 0 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
3005 0 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough;
3006 0 : state.dataMaterial->Material(MaterNum).ROnly = true;
3007 :
3008 : // Front side and back side have the same properties
3009 0 : state.dataMaterial->Material(MaterNum).TausFrontBeamBeam = MaterialProps(1);
3010 0 : state.dataMaterial->Material(MaterNum).TausBackBeamBeam = MaterialProps(1);
3011 :
3012 0 : state.dataMaterial->Material(MaterNum).TausFrontBeamDiff = MaterialProps(2);
3013 0 : state.dataMaterial->Material(MaterNum).TausBackBeamDiff = MaterialProps(3);
3014 :
3015 0 : state.dataMaterial->Material(MaterNum).ReflFrontBeamDiff = MaterialProps(4);
3016 0 : state.dataMaterial->Material(MaterNum).ReflBackBeamDiff = MaterialProps(5);
3017 0 : state.dataMaterial->Material(MaterNum).TausFrontBeamBeamVis = MaterialProps(6);
3018 0 : state.dataMaterial->Material(MaterNum).TausFrontBeamDiffVis = MaterialProps(7);
3019 0 : state.dataMaterial->Material(MaterNum).ReflFrontBeamDiffVis = MaterialProps(8);
3020 0 : state.dataMaterial->Material(MaterNum).TausThermal = MaterialProps(9);
3021 0 : state.dataMaterial->Material(MaterNum).EmissThermalFront = MaterialProps(10);
3022 0 : state.dataMaterial->Material(MaterNum).EmissThermalBack = MaterialProps(11);
3023 : // Assumes thermal emissivity is the same as thermal absorptance
3024 0 : state.dataMaterial->Material(MaterNum).AbsorpThermalFront = state.dataMaterial->Material(MaterNum).EmissThermalFront;
3025 0 : state.dataMaterial->Material(MaterNum).AbsorpThermalBack = state.dataMaterial->Material(MaterNum).EmissThermalBack;
3026 0 : state.dataMaterial->Material(MaterNum).TransThermal = state.dataMaterial->Material(MaterNum).TausThermal;
3027 :
3028 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(12) && !state.dataIPShortCut->lNumericFieldBlanks(13)) {
3029 0 : if (MaterialProps(12) != 0.0 && MaterialProps(13) != 0.0) {
3030 0 : state.dataMaterial->Material(MaterNum).PleatedDrapeWidth = MaterialProps(12);
3031 0 : state.dataMaterial->Material(MaterNum).PleatedDrapeLength = MaterialProps(13);
3032 0 : state.dataMaterial->Material(MaterNum).ISPleatedDrape = true;
3033 : }
3034 : } else {
3035 0 : state.dataMaterial->Material(MaterNum).ISPleatedDrape = false;
3036 : }
3037 0 : if (MaterialProps(1) + MaterialProps(2) + MaterialProps(4) >= 1.0) {
3038 0 : ErrorsFound = true;
3039 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3040 0 : ShowContinueError(state,
3041 0 : state.dataIPShortCut->cNumericFieldNames(1) + " + " + state.dataIPShortCut->cNumericFieldNames(2) + " + " +
3042 0 : state.dataIPShortCut->cNumericFieldNames(4) + "not < 1.0");
3043 : }
3044 0 : if (MaterialProps(6) + MaterialProps(7) + MaterialProps(8) >= 1.0) {
3045 0 : ErrorsFound = true;
3046 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3047 0 : ShowContinueError(state,
3048 0 : state.dataIPShortCut->cNumericFieldNames(4) + " + " + state.dataIPShortCut->cNumericFieldNames(5) + " + " +
3049 0 : state.dataIPShortCut->cNumericFieldNames(6) + "not < 1.0");
3050 : }
3051 0 : if (MaterialProps(9) + MaterialProps(10) > 1.0) {
3052 0 : ErrorsFound = true;
3053 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3054 0 : ShowContinueError(state,
3055 0 : state.dataIPShortCut->cNumericFieldNames(9) + " + " + state.dataIPShortCut->cNumericFieldNames(10) + " not < 1.0");
3056 : }
3057 :
3058 : } // TotDrapesEQL loop
3059 :
3060 : // Window Screen Materials
3061 :
3062 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Screen";
3063 773 : for (Loop = 1; Loop <= state.dataHeatBal->TotScreens; ++Loop) {
3064 :
3065 : // Call GetObjectItem routine to retrieve material data
3066 12 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3067 2 : state.dataHeatBalMgr->CurrentModuleObject,
3068 : Loop,
3069 : MaterialNames,
3070 : MaterialNumAlpha,
3071 : MaterialProps,
3072 : MaterialNumProp,
3073 : IOStat,
3074 2 : state.dataIPShortCut->lNumericFieldBlanks,
3075 2 : state.dataIPShortCut->lAlphaFieldBlanks,
3076 2 : state.dataIPShortCut->cAlphaFieldNames,
3077 2 : state.dataIPShortCut->cNumericFieldNames);
3078 6 : if (GlobalNames::VerifyUniqueInterObjectName(state,
3079 2 : state.dataHeatBalMgr->UniqueMaterialNames,
3080 2 : MaterialNames(1),
3081 2 : state.dataHeatBalMgr->CurrentModuleObject,
3082 2 : state.dataIPShortCut->cAlphaFieldNames(1),
3083 : ErrorsFound)) {
3084 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
3085 0 : continue;
3086 : }
3087 :
3088 2 : ++MaterNum;
3089 2 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::Screen;
3090 :
3091 : // Load the material derived type from the input data.
3092 :
3093 2 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
3094 2 : state.dataMaterial->Material(MaterNum).ReflectanceModeling = MaterialNames(2);
3095 6 : if (!(UtilityRoutines::SameString(MaterialNames(2), "DoNotModel") || UtilityRoutines::SameString(MaterialNames(2), "ModelAsDirectBeam") ||
3096 4 : UtilityRoutines::SameString(MaterialNames(2), "ModelAsDiffuse"))) {
3097 0 : ErrorsFound = true;
3098 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3099 0 : ShowContinueError(state,
3100 0 : state.dataIPShortCut->cAlphaFieldNames(2) + "=\"" + MaterialNames(2) +
3101 : "\", must be one of DoNotModel, ModelAsDirectBeam or ModelAsDiffuse.");
3102 : }
3103 2 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough;
3104 2 : state.dataMaterial->Material(MaterNum).ReflectShade = MaterialProps(1);
3105 2 : if (state.dataMaterial->Material(MaterNum).ReflectShade < 0.0 || state.dataMaterial->Material(MaterNum).ReflectShade > 1.0) {
3106 0 : ErrorsFound = true;
3107 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3108 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(1) + " must be >= 0 and <= 1");
3109 : }
3110 2 : state.dataMaterial->Material(MaterNum).ReflectShadeVis = MaterialProps(2);
3111 2 : if (state.dataMaterial->Material(MaterNum).ReflectShadeVis < 0.0 || state.dataMaterial->Material(MaterNum).ReflectShadeVis > 1.0) {
3112 0 : ErrorsFound = true;
3113 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3114 0 : ShowContinueError(state,
3115 0 : state.dataIPShortCut->cNumericFieldNames(2) + " must be >= 0 and <= 1 for material " +
3116 0 : state.dataMaterial->Material(MaterNum).Name + '.');
3117 : }
3118 2 : state.dataMaterial->Material(MaterNum).AbsorpThermal = MaterialProps(3);
3119 2 : state.dataMaterial->Material(MaterNum).AbsorpThermalInput = MaterialProps(3);
3120 2 : if (state.dataMaterial->Material(MaterNum).AbsorpThermal < 0.0 || state.dataMaterial->Material(MaterNum).AbsorpThermal > 1.0) {
3121 0 : ErrorsFound = true;
3122 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3123 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(3) + " must be >= 0 and <= 1");
3124 : }
3125 2 : state.dataMaterial->Material(MaterNum).Conductivity = MaterialProps(4);
3126 2 : state.dataMaterial->Material(MaterNum).Thickness = MaterialProps(6); // thickness = diameter
3127 :
3128 2 : if (MaterialProps(5) > 0.0) {
3129 : // SurfaceScreens(ScNum)%ScreenDiameterToSpacingRatio = MaterialProps(6)/MaterialProps(5) or
3130 : // 1-SQRT(dataMaterial.Material(MaterNum)%Trans
3131 2 : if (MaterialProps(6) / MaterialProps(5) >= 1.0) {
3132 0 : ErrorsFound = true;
3133 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3134 0 : ShowContinueError(
3135 0 : state, state.dataIPShortCut->cNumericFieldNames(6) + " must be less than " + state.dataIPShortCut->cNumericFieldNames(5));
3136 : } else {
3137 : // Calculate direct normal transmittance (open area fraction)
3138 2 : state.dataMaterial->Material(MaterNum).Trans = pow_2(1.0 - MaterialProps(6) / MaterialProps(5));
3139 : }
3140 : } else {
3141 0 : ErrorsFound = true;
3142 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3143 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(5) + " must be > 0.");
3144 0 : MaterialProps(5) = 0.000000001;
3145 : }
3146 :
3147 2 : if (MaterialProps(6) <= 0.0) {
3148 0 : ErrorsFound = true;
3149 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3150 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(6) + " must be > 0.");
3151 : }
3152 :
3153 : // Modify reflectance to account for the open area in the screen assembly
3154 2 : state.dataMaterial->Material(MaterNum).ReflectShade *= (1.0 - state.dataMaterial->Material(MaterNum).Trans);
3155 2 : state.dataMaterial->Material(MaterNum).ReflectShadeVis *= (1.0 - state.dataMaterial->Material(MaterNum).Trans);
3156 :
3157 2 : state.dataMaterial->Material(MaterNum).WinShadeToGlassDist = MaterialProps(7);
3158 4 : if (state.dataMaterial->Material(MaterNum).WinShadeToGlassDist < 0.001 ||
3159 2 : state.dataMaterial->Material(MaterNum).WinShadeToGlassDist > 1.0) {
3160 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3161 0 : ShowContinueError(
3162 0 : state, state.dataIPShortCut->cNumericFieldNames(7) + " must be greater than or equal to 0.001 and less than or equal to 1.");
3163 : }
3164 :
3165 2 : state.dataMaterial->Material(MaterNum).WinShadeTopOpeningMult = MaterialProps(8);
3166 4 : if (state.dataMaterial->Material(MaterNum).WinShadeTopOpeningMult < 0.0 ||
3167 2 : state.dataMaterial->Material(MaterNum).WinShadeTopOpeningMult > 1.0) {
3168 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3169 0 : ShowContinueError(state,
3170 0 : state.dataIPShortCut->cNumericFieldNames(8) + " must be greater than or equal to 0 and less than or equal to 1.");
3171 : }
3172 :
3173 2 : state.dataMaterial->Material(MaterNum).WinShadeBottomOpeningMult = MaterialProps(9);
3174 4 : if (state.dataMaterial->Material(MaterNum).WinShadeBottomOpeningMult < 0.0 ||
3175 2 : state.dataMaterial->Material(MaterNum).WinShadeBottomOpeningMult > 1.0) {
3176 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3177 0 : ShowContinueError(state,
3178 0 : state.dataIPShortCut->cNumericFieldNames(9) + " must be greater than or equal to 0 and less than or equal to 1.");
3179 : }
3180 :
3181 2 : state.dataMaterial->Material(MaterNum).WinShadeLeftOpeningMult = MaterialProps(10);
3182 4 : if (state.dataMaterial->Material(MaterNum).WinShadeLeftOpeningMult < 0.0 ||
3183 2 : state.dataMaterial->Material(MaterNum).WinShadeLeftOpeningMult > 1.0) {
3184 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3185 0 : ShowContinueError(state,
3186 0 : state.dataIPShortCut->cNumericFieldNames(10) + " must be greater than or equal to 0 and less than or equal to 1.");
3187 : }
3188 :
3189 2 : state.dataMaterial->Material(MaterNum).WinShadeRightOpeningMult = MaterialProps(11);
3190 4 : if (state.dataMaterial->Material(MaterNum).WinShadeRightOpeningMult < 0.0 ||
3191 2 : state.dataMaterial->Material(MaterNum).WinShadeRightOpeningMult > 1.0) {
3192 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3193 0 : ShowContinueError(state,
3194 0 : state.dataIPShortCut->cNumericFieldNames(11) + " must be greater than or equal to 0 and less than or equal to 1.");
3195 : }
3196 :
3197 2 : state.dataMaterial->Material(MaterNum).ScreenMapResolution = MaterialProps(12);
3198 4 : if (state.dataMaterial->Material(MaterNum).ScreenMapResolution < 0 || state.dataMaterial->Material(MaterNum).ScreenMapResolution > 5 ||
3199 2 : state.dataMaterial->Material(MaterNum).ScreenMapResolution == 4) {
3200 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3201 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(12) + " must be 0, 1, 2, 3, or 5.");
3202 0 : ErrorsFound = true;
3203 : }
3204 :
3205 : // Default air flow permeability to open area fraction
3206 2 : state.dataMaterial->Material(MaterNum).WinShadeAirFlowPermeability = state.dataMaterial->Material(MaterNum).Trans;
3207 2 : state.dataMaterial->Material(MaterNum).TransThermal = state.dataMaterial->Material(MaterNum).Trans;
3208 2 : state.dataMaterial->Material(MaterNum).TransVis = state.dataMaterial->Material(MaterNum).Trans;
3209 :
3210 2 : state.dataMaterial->Material(MaterNum).ROnly = true;
3211 :
3212 : // Calculate absorptance accounting for the open area in the screen assembly (used only in CreateShadedWindowConstruction)
3213 2 : state.dataMaterial->Material(MaterNum).AbsorpSolar =
3214 2 : max(0.0, 1.0 - state.dataMaterial->Material(MaterNum).Trans - state.dataMaterial->Material(MaterNum).ReflectShade);
3215 2 : state.dataMaterial->Material(MaterNum).AbsorpSolarInput = state.dataMaterial->Material(MaterNum).AbsorpSolar;
3216 2 : state.dataMaterial->Material(MaterNum).AbsorpVisible =
3217 2 : max(0.0, 1.0 - state.dataMaterial->Material(MaterNum).TransVis - state.dataMaterial->Material(MaterNum).ReflectShadeVis);
3218 2 : state.dataMaterial->Material(MaterNum).AbsorpVisibleInput = state.dataMaterial->Material(MaterNum).AbsorpVisible;
3219 2 : state.dataMaterial->Material(MaterNum).AbsorpThermal *= (1.0 - state.dataMaterial->Material(MaterNum).Trans);
3220 2 : state.dataMaterial->Material(MaterNum).AbsorpThermalInput = state.dataMaterial->Material(MaterNum).AbsorpThermal;
3221 :
3222 2 : if (state.dataMaterial->Material(MaterNum).Conductivity > 0.0) {
3223 6 : state.dataHeatBal->NominalR(MaterNum) = (1.0 - state.dataMaterial->Material(MaterNum).Trans) *
3224 4 : state.dataMaterial->Material(MaterNum).Thickness /
3225 2 : state.dataMaterial->Material(MaterNum).Conductivity;
3226 : } else {
3227 0 : state.dataHeatBal->NominalR(MaterNum) = 1.0;
3228 0 : ShowWarningError(
3229 : state,
3230 0 : "Conductivity for material=\"" + state.dataMaterial->Material(MaterNum).Name +
3231 : "\" must be greater than 0 for calculating Nominal R-value, Nominal R is defaulted to 1 and the simulation continues.");
3232 : }
3233 :
3234 2 : if (state.dataMaterial->Material(MaterNum).Trans + state.dataMaterial->Material(MaterNum).ReflectShade >= 1.0) {
3235 0 : ErrorsFound = true;
3236 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3237 0 : ShowContinueError(state, "Calculated solar transmittance + solar reflectance not < 1.0");
3238 0 : ShowContinueError(state, "See Engineering Reference for calculation procedure for solar transmittance.");
3239 : }
3240 :
3241 2 : if (state.dataMaterial->Material(MaterNum).TransVis + state.dataMaterial->Material(MaterNum).ReflectShadeVis >= 1.0) {
3242 0 : ErrorsFound = true;
3243 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3244 0 : ShowContinueError(state, "Calculated visible transmittance + visible reflectance not < 1.0");
3245 0 : ShowContinueError(state, "See Engineering Reference for calculation procedure for visible solar transmittance.");
3246 : }
3247 :
3248 2 : if (state.dataMaterial->Material(MaterNum).TransThermal + state.dataMaterial->Material(MaterNum).AbsorpThermal >= 1.0) {
3249 0 : ErrorsFound = true;
3250 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3251 0 : ShowSevereError(state, "Thermal hemispherical emissivity plus open area fraction (1-diameter/spacing)**2 not < 1.0");
3252 : }
3253 : }
3254 :
3255 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Screen:EquivalentLayer";
3256 772 : for (Loop = 1; Loop <= state.dataHeatBal->TotScreensEQL; ++Loop) {
3257 :
3258 1 : MaterialProps = 0;
3259 :
3260 : // Call GetObjectItem routine to retrieve material data
3261 6 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3262 1 : state.dataHeatBalMgr->CurrentModuleObject,
3263 : Loop,
3264 : MaterialNames,
3265 : MaterialNumAlpha,
3266 : MaterialProps,
3267 : MaterialNumProp,
3268 : IOStat,
3269 1 : state.dataIPShortCut->lNumericFieldBlanks,
3270 1 : state.dataIPShortCut->lAlphaFieldBlanks,
3271 1 : state.dataIPShortCut->cAlphaFieldNames,
3272 1 : state.dataIPShortCut->cNumericFieldNames);
3273 3 : if (GlobalNames::VerifyUniqueInterObjectName(state,
3274 1 : state.dataHeatBalMgr->UniqueMaterialNames,
3275 1 : MaterialNames(1),
3276 1 : state.dataHeatBalMgr->CurrentModuleObject,
3277 1 : state.dataIPShortCut->cAlphaFieldNames(1),
3278 : ErrorsFound)) {
3279 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
3280 0 : continue;
3281 : }
3282 :
3283 1 : ++MaterNum;
3284 1 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::ScreenEquivalentLayer;
3285 :
3286 : // Load the material derived type from the input data.
3287 : // WindowMaterial:Screen:EquivalentLayer,
3288 1 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
3289 1 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough;
3290 1 : state.dataMaterial->Material(MaterNum).ROnly = true;
3291 1 : state.dataMaterial->Material(MaterNum).TausFrontBeamBeam = MaterialProps(1);
3292 1 : state.dataMaterial->Material(MaterNum).TausBackBeamBeam = MaterialProps(1);
3293 1 : state.dataMaterial->Material(MaterNum).TausFrontBeamDiff = MaterialProps(2);
3294 1 : state.dataMaterial->Material(MaterNum).TausBackBeamDiff = MaterialProps(2);
3295 1 : state.dataMaterial->Material(MaterNum).ReflFrontBeamDiff = MaterialProps(3);
3296 1 : state.dataMaterial->Material(MaterNum).ReflBackBeamDiff = MaterialProps(3);
3297 1 : state.dataMaterial->Material(MaterNum).TausFrontBeamBeamVis = MaterialProps(4);
3298 1 : state.dataMaterial->Material(MaterNum).TausFrontBeamDiffVis = MaterialProps(5);
3299 1 : state.dataMaterial->Material(MaterNum).ReflFrontDiffDiffVis = MaterialProps(6);
3300 1 : state.dataMaterial->Material(MaterNum).TausThermal = MaterialProps(7);
3301 1 : state.dataMaterial->Material(MaterNum).EmissThermalFront = MaterialProps(8);
3302 1 : state.dataMaterial->Material(MaterNum).EmissThermalBack = MaterialProps(8);
3303 :
3304 : // Assumes thermal emissivity is the same as thermal absorptance
3305 1 : state.dataMaterial->Material(MaterNum).AbsorpThermalFront = state.dataMaterial->Material(MaterNum).EmissThermalFront;
3306 1 : state.dataMaterial->Material(MaterNum).AbsorpThermalBack = state.dataMaterial->Material(MaterNum).EmissThermalBack;
3307 1 : state.dataMaterial->Material(MaterNum).TransThermal = state.dataMaterial->Material(MaterNum).TausThermal;
3308 :
3309 1 : if (MaterialProps(3) < 0.0 || MaterialProps(3) > 1.0) {
3310 0 : ErrorsFound = true;
3311 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3312 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(3) + " must be >= 0 and <= 1");
3313 : }
3314 :
3315 1 : if (MaterialProps(6) < 0.0 || MaterialProps(6) > 1.0) {
3316 0 : ErrorsFound = true;
3317 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3318 0 : ShowContinueError(state,
3319 0 : state.dataIPShortCut->cNumericFieldNames(6) + " must be >= 0 and <= 1 for material " +
3320 0 : state.dataMaterial->Material(MaterNum).Name + '.');
3321 : }
3322 :
3323 1 : if (!state.dataIPShortCut->lNumericFieldBlanks(9)) {
3324 1 : if (MaterialProps(9) > 0.00001) {
3325 1 : state.dataMaterial->Material(MaterNum).ScreenWireSpacing = MaterialProps(9); // screen wire spacing
3326 : } else {
3327 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3328 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(9) + " must be > 0.");
3329 0 : ShowContinueError(state, "...Setting screen wire spacing to a default value of 0.025m and simulation continues.");
3330 0 : state.dataMaterial->Material(MaterNum).ScreenWireSpacing = 0.025;
3331 : }
3332 : }
3333 :
3334 1 : if (!state.dataIPShortCut->lNumericFieldBlanks(10)) {
3335 1 : if (MaterialProps(10) > 0.00001 && MaterialProps(10) < state.dataMaterial->Material(MaterNum).ScreenWireSpacing) {
3336 1 : state.dataMaterial->Material(MaterNum).ScreenWireDiameter = MaterialProps(10); // screen wire spacing
3337 : } else {
3338 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value.");
3339 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(10) + " must be > 0.");
3340 0 : ShowContinueError(state, "...Setting screen wire diameter to a default value of 0.005m and simulation continues.");
3341 0 : state.dataMaterial->Material(MaterNum).ScreenWireDiameter = 0.005;
3342 : }
3343 : }
3344 :
3345 1 : if (state.dataMaterial->Material(MaterNum).ScreenWireSpacing > 0.0) {
3346 1 : if (state.dataMaterial->Material(MaterNum).ScreenWireDiameter / state.dataMaterial->Material(MaterNum).ScreenWireSpacing >= 1.0) {
3347 0 : ErrorsFound = true;
3348 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3349 0 : ShowContinueError(
3350 0 : state, state.dataIPShortCut->cNumericFieldNames(10) + " must be less than " + state.dataIPShortCut->cNumericFieldNames(9));
3351 : } else {
3352 : // Calculate direct normal transmittance (open area fraction)
3353 2 : Openness = pow_2(1.0 - state.dataMaterial->Material(MaterNum).ScreenWireDiameter /
3354 1 : state.dataMaterial->Material(MaterNum).ScreenWireSpacing);
3355 1 : if ((state.dataMaterial->Material(MaterNum).TausFrontBeamBeam - Openness) / Openness > 0.01) {
3356 0 : ShowSevereError(state,
3357 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", screen openness specified.");
3358 0 : ShowContinueError(state,
3359 0 : state.dataIPShortCut->cNumericFieldNames(1) + " is > 1.0% of the value calculated from input fields:");
3360 0 : ShowContinueError(state,
3361 0 : state.dataIPShortCut->cNumericFieldNames(9) + " and " + (state.dataIPShortCut->cNumericFieldNames(10)));
3362 0 : ShowContinueError(state, " using the formula (1-diameter/spacing)**2");
3363 0 : ShowContinueError(state, " ...the screen diameter is recalculated from the material openness specified ");
3364 0 : ShowContinueError(state, " ...and wire spacing using the formula = wire spacing * (1.0 - SQRT(Opennes))");
3365 0 : state.dataMaterial->Material(MaterNum).ScreenWireDiameter =
3366 0 : state.dataMaterial->Material(MaterNum).ScreenWireSpacing *
3367 0 : (1.0 - std::sqrt(state.dataMaterial->Material(MaterNum).TausFrontBeamBeam));
3368 0 : ShowContinueError(state,
3369 0 : format(" ...Recalculated {}={:.4R} m",
3370 0 : state.dataIPShortCut->cNumericFieldNames(10),
3371 0 : state.dataMaterial->Material(MaterNum).ScreenWireDiameter));
3372 : }
3373 : }
3374 : }
3375 :
3376 1 : if (state.dataMaterial->Material(MaterNum).TausFrontBeamBeam + state.dataMaterial->Material(MaterNum).ReflFrontBeamDiff >= 1.0) {
3377 0 : ErrorsFound = true;
3378 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3379 0 : ShowContinueError(state, "Calculated solar transmittance + solar reflectance not < 1.0");
3380 0 : ShowContinueError(state, "See Engineering Reference for calculation procedure for solar transmittance.");
3381 : }
3382 :
3383 1 : if (state.dataMaterial->Material(MaterNum).TausFrontBeamBeamVis + state.dataMaterial->Material(MaterNum).ReflFrontDiffDiffVis >= 1.0) {
3384 0 : ErrorsFound = true;
3385 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3386 0 : ShowContinueError(state, "Calculated visible transmittance + visible reflectance not < 1.0");
3387 0 : ShowContinueError(state, "See Engineering Reference for calculation procedure for visible solar transmittance.");
3388 : }
3389 1 : if (state.dataMaterial->Material(MaterNum).TransThermal + state.dataMaterial->Material(MaterNum).AbsorpThermal >= 1.0) {
3390 0 : ErrorsFound = true;
3391 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3392 0 : ShowSevereError(state, "Thermal hemispherical emissivity plus open area fraction (1-diameter/spacing)**2 not < 1.0");
3393 : }
3394 :
3395 : } // TotScreensEQL loop
3396 :
3397 : // Window Blind Materials
3398 771 : if ((state.dataHeatBal->TotBlindsEQL == 0) && (state.dataHeatBal->TotBlinds == 0)) {
3399 754 : state.dataSurface->actualMaxSlatAngs = 1; // first slot is used for shades
3400 : }
3401 :
3402 771 : if (state.dataHeatBal->TotBlinds > 0) {
3403 17 : state.dataHeatBal->Blind.allocate(state.dataHeatBal->TotBlinds); // Allocate the array Size to the number of blinds
3404 : }
3405 :
3406 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Blind";
3407 788 : for (Loop = 1; Loop <= state.dataHeatBal->TotBlinds; ++Loop) {
3408 :
3409 : // Call Input Get routine to retrieve material data
3410 102 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3411 17 : state.dataHeatBalMgr->CurrentModuleObject,
3412 : Loop,
3413 : MaterialNames,
3414 : MaterialNumAlpha,
3415 : MaterialProps,
3416 : MaterialNumProp,
3417 : IOStat,
3418 17 : state.dataIPShortCut->lNumericFieldBlanks,
3419 17 : state.dataIPShortCut->lAlphaFieldBlanks,
3420 17 : state.dataIPShortCut->cAlphaFieldNames,
3421 17 : state.dataIPShortCut->cNumericFieldNames);
3422 51 : if (GlobalNames::VerifyUniqueInterObjectName(state,
3423 17 : state.dataHeatBalMgr->UniqueMaterialNames,
3424 17 : MaterialNames(1),
3425 17 : state.dataHeatBalMgr->CurrentModuleObject,
3426 17 : state.dataIPShortCut->cAlphaFieldNames(1),
3427 : ErrorsFound)) {
3428 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
3429 0 : continue;
3430 : }
3431 :
3432 17 : ++MaterNum;
3433 17 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::WindowBlind;
3434 :
3435 : // Load the material derived type from the input data.
3436 :
3437 17 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
3438 17 : state.dataHeatBal->Blind(Loop).Name = MaterialNames(1);
3439 17 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::Rough;
3440 17 : state.dataMaterial->Material(MaterNum).BlindDataPtr = Loop;
3441 17 : state.dataMaterial->Material(MaterNum).ROnly = true;
3442 :
3443 17 : state.dataHeatBal->Blind(Loop).MaterialNumber = MaterNum;
3444 17 : if (UtilityRoutines::SameString(MaterialNames(2), "Horizontal")) {
3445 17 : state.dataHeatBal->Blind(Loop).SlatOrientation = DataWindowEquivalentLayer::Orientation::Horizontal;
3446 0 : } else if (UtilityRoutines::SameString(MaterialNames(2), "Vertical")) {
3447 0 : state.dataHeatBal->Blind(Loop).SlatOrientation = DataWindowEquivalentLayer::Orientation::Vertical;
3448 : }
3449 17 : state.dataHeatBal->Blind(Loop).SlatWidth = MaterialProps(1);
3450 17 : state.dataHeatBal->Blind(Loop).SlatSeparation = MaterialProps(2);
3451 17 : state.dataHeatBal->Blind(Loop).SlatThickness = MaterialProps(3);
3452 17 : state.dataHeatBal->Blind(Loop).SlatAngle = MaterialProps(4);
3453 17 : state.dataHeatBal->Blind(Loop).SlatConductivity = MaterialProps(5);
3454 17 : state.dataHeatBal->Blind(Loop).SlatTransSolBeamDiff = MaterialProps(6);
3455 17 : state.dataHeatBal->Blind(Loop).SlatFrontReflSolBeamDiff = MaterialProps(7);
3456 17 : state.dataHeatBal->Blind(Loop).SlatBackReflSolBeamDiff = MaterialProps(8);
3457 17 : state.dataHeatBal->Blind(Loop).SlatTransSolDiffDiff = MaterialProps(9);
3458 17 : state.dataHeatBal->Blind(Loop).SlatFrontReflSolDiffDiff = MaterialProps(10);
3459 17 : state.dataHeatBal->Blind(Loop).SlatBackReflSolDiffDiff = MaterialProps(11);
3460 17 : state.dataHeatBal->Blind(Loop).SlatTransVisBeamDiff = MaterialProps(12);
3461 17 : state.dataHeatBal->Blind(Loop).SlatFrontReflVisBeamDiff = MaterialProps(13);
3462 17 : state.dataHeatBal->Blind(Loop).SlatBackReflVisBeamDiff = MaterialProps(14);
3463 17 : state.dataHeatBal->Blind(Loop).SlatTransVisDiffDiff = MaterialProps(15);
3464 17 : state.dataHeatBal->Blind(Loop).SlatFrontReflVisDiffDiff = MaterialProps(16);
3465 17 : state.dataHeatBal->Blind(Loop).SlatBackReflVisDiffDiff = MaterialProps(17);
3466 17 : state.dataHeatBal->Blind(Loop).SlatTransIR = MaterialProps(18);
3467 17 : state.dataHeatBal->Blind(Loop).SlatFrontEmissIR = MaterialProps(19);
3468 17 : state.dataHeatBal->Blind(Loop).SlatBackEmissIR = MaterialProps(20);
3469 17 : state.dataHeatBal->Blind(Loop).BlindToGlassDist = MaterialProps(21);
3470 17 : state.dataHeatBal->Blind(Loop).BlindTopOpeningMult = MaterialProps(22);
3471 17 : state.dataHeatBal->Blind(Loop).BlindBottomOpeningMult = MaterialProps(23);
3472 17 : state.dataHeatBal->Blind(Loop).BlindLeftOpeningMult = MaterialProps(24);
3473 17 : state.dataHeatBal->Blind(Loop).BlindRightOpeningMult = MaterialProps(25);
3474 17 : state.dataHeatBal->Blind(Loop).MinSlatAngle = MaterialProps(26);
3475 17 : state.dataHeatBal->Blind(Loop).MaxSlatAngle = MaterialProps(27);
3476 :
3477 : // TH 2/11/2010. For CR 8010
3478 : // By default all blinds have fixed slat angle, new blinds with variable slat angle are created if
3479 : // they are used with window shading controls that adjust slat angles like ScheduledSlatAngle or BlockBeamSolar
3480 17 : state.dataHeatBal->Blind(Loop).SlatAngleType = DataWindowEquivalentLayer::AngleType::Fixed;
3481 :
3482 17 : if (state.dataHeatBal->Blind(Loop).SlatWidth < state.dataHeatBal->Blind(Loop).SlatSeparation) {
3483 0 : ShowWarningError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Slat Angles/Widths");
3484 0 : ShowContinueError(state,
3485 0 : format("{} [{:.2R}] is less than {} [{:.2R}].",
3486 0 : state.dataIPShortCut->cNumericFieldNames(1),
3487 0 : state.dataHeatBal->Blind(Loop).SlatWidth,
3488 0 : state.dataIPShortCut->cNumericFieldNames(2),
3489 0 : state.dataHeatBal->Blind(Loop).SlatSeparation));
3490 0 : ShowContinueError(state, "This will allow direct beam to be transmitted when Slat angle = 0.");
3491 : }
3492 :
3493 17 : if (!UtilityRoutines::SameString(MaterialNames(2), "Horizontal") && !UtilityRoutines::SameString(MaterialNames(2), "Vertical")) {
3494 0 : ErrorsFound = true;
3495 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value");
3496 0 : ShowContinueError(state,
3497 0 : state.dataIPShortCut->cAlphaFieldNames(2) + "=\"" + MaterialNames(2) + "\", must be Horizontal or Vertical.");
3498 : }
3499 :
3500 17 : if ((MaterialProps(6) + MaterialProps(7) >= 1.0)) {
3501 0 : ErrorsFound = true;
3502 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3503 0 : ShowContinueError(state,
3504 0 : state.dataIPShortCut->cNumericFieldNames(6) + " + " + state.dataIPShortCut->cNumericFieldNames(7) + " not < 1.0");
3505 : }
3506 17 : if ((MaterialProps(6) + MaterialProps(8) >= 1.0)) {
3507 0 : ErrorsFound = true;
3508 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3509 0 : ShowContinueError(state,
3510 0 : state.dataIPShortCut->cNumericFieldNames(6) + " + " + state.dataIPShortCut->cNumericFieldNames(8) + " not < 1.0");
3511 : }
3512 :
3513 17 : if ((MaterialProps(9) + MaterialProps(10) >= 1.0)) {
3514 0 : ErrorsFound = true;
3515 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3516 0 : ShowContinueError(state,
3517 0 : state.dataIPShortCut->cNumericFieldNames(9) + " + " + state.dataIPShortCut->cNumericFieldNames(10) + " not < 1.0");
3518 : }
3519 17 : if ((MaterialProps(9) + MaterialProps(11) >= 1.0)) {
3520 0 : ErrorsFound = true;
3521 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3522 0 : ShowContinueError(state,
3523 0 : state.dataIPShortCut->cNumericFieldNames(9) + " + " + state.dataIPShortCut->cNumericFieldNames(11) + " not < 1.0");
3524 : }
3525 :
3526 17 : if ((MaterialProps(12) + MaterialProps(13) >= 1.0) || (MaterialProps(12) + MaterialProps(14) >= 1.0)) {
3527 0 : ErrorsFound = true;
3528 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3529 0 : ShowContinueError(
3530 0 : state, state.dataIPShortCut->cNumericFieldNames(12) + " + " + state.dataIPShortCut->cNumericFieldNames(13) + " not < 1.0 OR");
3531 0 : ShowContinueError(state,
3532 0 : state.dataIPShortCut->cNumericFieldNames(12) + " + " + state.dataIPShortCut->cNumericFieldNames(14) + " not < 1.0");
3533 : }
3534 :
3535 17 : if ((MaterialProps(12) + MaterialProps(13) >= 1.0)) {
3536 0 : ErrorsFound = true;
3537 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3538 0 : ShowContinueError(state,
3539 0 : state.dataIPShortCut->cNumericFieldNames(12) + " + " + state.dataIPShortCut->cNumericFieldNames(13) + " not < 1.0");
3540 : }
3541 17 : if ((MaterialProps(12) + MaterialProps(14) >= 1.0)) {
3542 0 : ErrorsFound = true;
3543 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3544 0 : ShowContinueError(state,
3545 0 : state.dataIPShortCut->cNumericFieldNames(12) + " + " + state.dataIPShortCut->cNumericFieldNames(14) + " not < 1.0");
3546 : }
3547 :
3548 17 : if ((MaterialProps(15) + MaterialProps(16) >= 1.0)) {
3549 0 : ErrorsFound = true;
3550 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3551 0 : ShowContinueError(state,
3552 0 : state.dataIPShortCut->cNumericFieldNames(15) + " + " + state.dataIPShortCut->cNumericFieldNames(16) + " not < 1.0");
3553 : }
3554 17 : if ((MaterialProps(15) + MaterialProps(17) >= 1.0)) {
3555 0 : ErrorsFound = true;
3556 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3557 0 : ShowContinueError(state,
3558 0 : state.dataIPShortCut->cNumericFieldNames(15) + " + " + state.dataIPShortCut->cNumericFieldNames(17) + " not < 1.0");
3559 : }
3560 :
3561 : // Require that beam and diffuse properties be the same
3562 17 : if (std::abs(MaterialProps(9) - MaterialProps(6)) > 1.e-5) {
3563 0 : ErrorsFound = true;
3564 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3565 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(6) + " must equal " + state.dataIPShortCut->cNumericFieldNames(9));
3566 : }
3567 :
3568 17 : if (std::abs(MaterialProps(10) - MaterialProps(7)) > 1.e-5) {
3569 0 : ErrorsFound = true;
3570 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3571 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(7) + " must equal " + state.dataIPShortCut->cNumericFieldNames(10));
3572 : }
3573 :
3574 17 : if (std::abs(MaterialProps(11) - MaterialProps(8)) > 1.e-5) {
3575 0 : ErrorsFound = true;
3576 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3577 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(8) + " must equal " + state.dataIPShortCut->cNumericFieldNames(11));
3578 : }
3579 :
3580 17 : if (std::abs(MaterialProps(15) - MaterialProps(12)) > 1.e-5) {
3581 0 : ErrorsFound = true;
3582 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3583 0 : ShowContinueError(state,
3584 0 : state.dataIPShortCut->cNumericFieldNames(12) + " must equal " + state.dataIPShortCut->cNumericFieldNames(15));
3585 : }
3586 :
3587 17 : if (std::abs(MaterialProps(16) - MaterialProps(13)) > 1.e-5) {
3588 0 : ErrorsFound = true;
3589 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3590 0 : ShowContinueError(state,
3591 0 : state.dataIPShortCut->cNumericFieldNames(13) + " must equal " + state.dataIPShortCut->cNumericFieldNames(16));
3592 : }
3593 :
3594 17 : if (std::abs(MaterialProps(17) - MaterialProps(14)) > 1.e-5) {
3595 0 : ErrorsFound = true;
3596 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3597 0 : ShowContinueError(state,
3598 0 : state.dataIPShortCut->cNumericFieldNames(14) + " must equal " + state.dataIPShortCut->cNumericFieldNames(17));
3599 : }
3600 :
3601 17 : if ((MaterialProps(18) + MaterialProps(19) >= 1.0)) {
3602 0 : ErrorsFound = true;
3603 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3604 0 : ShowContinueError(state,
3605 0 : state.dataIPShortCut->cNumericFieldNames(18) + " + " + state.dataIPShortCut->cNumericFieldNames(19) + " not < 1.0");
3606 : }
3607 17 : if ((MaterialProps(18) + MaterialProps(20) >= 1.0)) {
3608 0 : ErrorsFound = true;
3609 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3610 0 : ShowContinueError(state,
3611 0 : state.dataIPShortCut->cNumericFieldNames(18) + " + " + state.dataIPShortCut->cNumericFieldNames(20) + " not < 1.0");
3612 : }
3613 :
3614 17 : if (state.dataHeatBal->Blind(Loop).BlindToGlassDist < 0.5 * state.dataHeatBal->Blind(Loop).SlatWidth) {
3615 0 : ErrorsFound = true;
3616 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3617 0 : ShowContinueError(
3618 0 : state, state.dataIPShortCut->cNumericFieldNames(21) + " is less than half of the " + state.dataIPShortCut->cNumericFieldNames(1));
3619 : }
3620 :
3621 : // Minimum and maximum slat angles allowed by slat geometry
3622 17 : if (state.dataHeatBal->Blind(Loop).SlatWidth > state.dataHeatBal->Blind(Loop).SlatSeparation) {
3623 51 : MinSlatAngGeom = std::asin(state.dataHeatBal->Blind(Loop).SlatThickness /
3624 34 : (state.dataHeatBal->Blind(Loop).SlatThickness + state.dataHeatBal->Blind(Loop).SlatSeparation)) /
3625 : DataGlobalConstants::DegToRadians;
3626 : } else {
3627 0 : MinSlatAngGeom = 0.0;
3628 : }
3629 17 : MaxSlatAngGeom = 180.0 - MinSlatAngGeom;
3630 :
3631 : // Error if input slat angle not in range allowed by slat geometry
3632 34 : if ((state.dataHeatBal->Blind(Loop).SlatSeparation + state.dataHeatBal->Blind(Loop).SlatThickness) <
3633 17 : state.dataHeatBal->Blind(Loop).SlatWidth) {
3634 17 : if (state.dataHeatBal->Blind(Loop).SlatAngle < MinSlatAngGeom) {
3635 0 : ErrorsFound = true;
3636 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3637 0 : ShowContinueError(state,
3638 0 : format("{}=[{:.1R}], is less than smallest allowed by slat dimensions and spacing, [{:.1R}] deg.",
3639 0 : state.dataIPShortCut->cNumericFieldNames(4),
3640 0 : state.dataHeatBal->Blind(Loop).SlatAngle,
3641 0 : MinSlatAngGeom));
3642 17 : } else if (state.dataHeatBal->Blind(Loop).SlatAngle > MaxSlatAngGeom) {
3643 0 : ErrorsFound = true;
3644 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3645 0 : ShowContinueError(state,
3646 0 : format("{}=[{:.1R}], is greater than largest allowed by slat dimensions and spacing, [{:.1R}] deg.",
3647 0 : state.dataIPShortCut->cNumericFieldNames(4),
3648 0 : state.dataHeatBal->Blind(Loop).SlatAngle,
3649 0 : MinSlatAngGeom));
3650 : }
3651 : }
3652 :
3653 : // By default all Blinds are "fixed" slats. Only with Shading Control is one considered variable and this check
3654 : // is now done when that happens. 9.3.2009 LKL
3655 :
3656 : // IF(Blind(Loop)%SlatAngleType == VariableSlats) THEN
3657 : // ! Error if maximum slat angle less than minimum
3658 : // IF(Blind(Loop)%MaxSlatAngle < Blind(Loop)%MinSlatAngle) THEN
3659 : // ErrorsFound = .TRUE.
3660 : // CALL ShowSevereError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//'="'//TRIM(MaterialNames(1))//'", Illegal value
3661 : // combination.') CALL ShowContinueError(state,
3662 : // TRIM(cNumericFieldNames(26))//'=['//TRIM(RoundSigDigits(Blind(Loop)%MinSlatAngle,1))// &
3663 : // '], is greater than '//TRIM(cNumericFieldNames(27))//'=['// &
3664 : // TRIM(RoundSigDigits(Blind(Loop)%MaxSlatAngle,1))//'] deg.')
3665 : // END IF
3666 : // ! Error if input slat angle not in input min/max range
3667 : // IF(Blind(Loop)%MaxSlatAngle > Blind(Loop)%MinSlatAngle .AND. (Blind(Loop)%SlatAngle < Blind(Loop)%MinSlatAngle &
3668 : // .OR. Blind(Loop)%SlatAngle > Blind(Loop)%MaxSlatAngle)) THEN
3669 : // ErrorsFound = .TRUE.
3670 : // CALL ShowSevereError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//'="'//TRIM(MaterialNames(1))//'", Illegal value
3671 : // combination.') CALL ShowContinueError(state, TRIM(cNumericFieldNames(4))//'=['//TRIM(RoundSigDigits(Blind(Loop)%SlatAngle,1))//
3672 : // &
3673 : // '] is outside of the input min/max range, min=['//TRIM(RoundSigDigits(Blind(Loop)%MinSlatAngle,1))// &
3674 : // '], max=['//TRIM(RoundSigDigits(Blind(Loop)%MaxSlatAngle,1))//'] deg.')
3675 : // END IF
3676 : // ! Error if input minimum slat angle is less than that allowed by slat geometry
3677 : // IF(Blind(Loop)%MinSlatAngle < MinSlatAngGeom) THEN
3678 : // CALL ShowSevereError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//'="'//TRIM(MaterialNames(1))//'", Illegal value
3679 : // combination.') CALL ShowContinueError(state,
3680 : // TRIM(cNumericFieldNames(26))//'=['//TRIM(RoundSigDigits(Blind(Loop)%MinSlatAngle,1))// &
3681 : // '] is less than the smallest allowed by slat dimensions and spacing, min=['// &
3682 : // TRIM(RoundSigDigits(MinSlatAngGeom,1))//'] deg.')
3683 : // CALL ShowContinueError(state, 'Minimum Slat Angle will be set to '//TRIM(RoundSigDigits(MinSlatAngGeom,1))//' deg.')
3684 : // Blind(Loop)%MinSlatAngle = MinSlatAngGeom
3685 : // END IF
3686 : // ! Error if input maximum slat angle is greater than that allowed by slat geometry
3687 : // IF(Blind(Loop)%MaxSlatAngle > MaxSlatAngGeom) THEN
3688 : // CALL ShowWarningError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//'="'//TRIM(MaterialNames(1))//'", Illegal value
3689 : // combination.') CALL ShowContinueError(state,
3690 : // TRIM(cNumericFieldNames(27))//'=['//TRIM(RoundSigDigits(Blind(Loop)%MaxSlatAngle,1))// &
3691 : // '] is greater than the largest allowed by slat dimensions and spacing, ['// &
3692 : // TRIM(RoundSigDigits(MaxSlatAngGeom,1))//'] deg.')
3693 : // CALL ShowContinueError(state, 'Maximum Slat Angle will be set to '//TRIM(RoundSigDigits(MaxSlatAngGeom,1))//' deg.')
3694 : // Blind(Loop)%MaxSlatAngle = MaxSlatAngGeom
3695 : // END IF
3696 : // END IF ! End of check if slat angle is variable
3697 : }
3698 :
3699 : // Window Blind Materials for EquivalentLayer Model
3700 :
3701 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:Blind:EquivalentLayer";
3702 771 : for (Loop = 1; Loop <= state.dataHeatBal->TotBlindsEQL; ++Loop) {
3703 :
3704 : // Call Input Get routine to retrieve material data
3705 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3706 0 : state.dataHeatBalMgr->CurrentModuleObject,
3707 : Loop,
3708 : MaterialNames,
3709 : MaterialNumAlpha,
3710 : MaterialProps,
3711 : MaterialNumProp,
3712 : IOStat,
3713 0 : state.dataIPShortCut->lNumericFieldBlanks,
3714 0 : state.dataIPShortCut->lAlphaFieldBlanks,
3715 0 : state.dataIPShortCut->cAlphaFieldNames,
3716 0 : state.dataIPShortCut->cNumericFieldNames);
3717 0 : if (GlobalNames::VerifyUniqueInterObjectName(state,
3718 0 : state.dataHeatBalMgr->UniqueMaterialNames,
3719 0 : MaterialNames(1),
3720 0 : state.dataHeatBalMgr->CurrentModuleObject,
3721 0 : state.dataIPShortCut->cAlphaFieldNames(1),
3722 : ErrorsFound)) {
3723 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
3724 0 : continue;
3725 : }
3726 :
3727 0 : ++MaterNum;
3728 0 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::BlindEquivalentLayer;
3729 :
3730 0 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
3731 0 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::Rough;
3732 0 : state.dataMaterial->Material(MaterNum).ROnly = true;
3733 :
3734 0 : if (UtilityRoutines::SameString(MaterialNames(2), "Horizontal")) {
3735 0 : state.dataMaterial->Material(MaterNum).SlatOrientation = DataWindowEquivalentLayer::Orientation::Horizontal;
3736 0 : } else if (UtilityRoutines::SameString(MaterialNames(2), "Vertical")) {
3737 0 : state.dataMaterial->Material(MaterNum).SlatOrientation = DataWindowEquivalentLayer::Orientation::Vertical;
3738 : }
3739 0 : state.dataMaterial->Material(MaterNum).SlatWidth = MaterialProps(1);
3740 0 : state.dataMaterial->Material(MaterNum).SlatSeparation = MaterialProps(2);
3741 0 : state.dataMaterial->Material(MaterNum).SlatCrown = MaterialProps(3);
3742 0 : state.dataMaterial->Material(MaterNum).SlatAngle = MaterialProps(4);
3743 :
3744 0 : state.dataMaterial->Material(MaterNum).TausFrontBeamDiff = MaterialProps(5);
3745 0 : state.dataMaterial->Material(MaterNum).TausBackBeamDiff = MaterialProps(6);
3746 0 : state.dataMaterial->Material(MaterNum).ReflFrontBeamDiff = MaterialProps(7);
3747 0 : state.dataMaterial->Material(MaterNum).ReflBackBeamDiff = MaterialProps(8);
3748 :
3749 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(9) && !state.dataIPShortCut->lNumericFieldBlanks(10) &&
3750 0 : !state.dataIPShortCut->lNumericFieldBlanks(11) && !state.dataIPShortCut->lNumericFieldBlanks(12)) {
3751 0 : state.dataMaterial->Material(MaterNum).TausFrontBeamDiffVis = MaterialProps(9);
3752 0 : state.dataMaterial->Material(MaterNum).TausBackBeamDiffVis = MaterialProps(10);
3753 0 : state.dataMaterial->Material(MaterNum).ReflFrontBeamDiffVis = MaterialProps(11);
3754 0 : state.dataMaterial->Material(MaterNum).ReflBackBeamDiffVis = MaterialProps(12);
3755 : }
3756 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(13) && !state.dataIPShortCut->lNumericFieldBlanks(14) &&
3757 0 : !state.dataIPShortCut->lNumericFieldBlanks(15)) {
3758 0 : state.dataMaterial->Material(MaterNum).TausDiffDiff = MaterialProps(13);
3759 0 : state.dataMaterial->Material(MaterNum).ReflFrontDiffDiff = MaterialProps(14);
3760 0 : state.dataMaterial->Material(MaterNum).ReflBackDiffDiff = MaterialProps(15);
3761 : }
3762 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(16) && !state.dataIPShortCut->lNumericFieldBlanks(17) &&
3763 0 : !state.dataIPShortCut->lNumericFieldBlanks(18)) {
3764 0 : state.dataMaterial->Material(MaterNum).TausDiffDiffVis = MaterialProps(13);
3765 0 : state.dataMaterial->Material(MaterNum).ReflFrontDiffDiffVis = MaterialProps(14);
3766 0 : state.dataMaterial->Material(MaterNum).ReflBackDiffDiffVis = MaterialProps(15);
3767 : }
3768 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(19)) {
3769 0 : state.dataMaterial->Material(MaterNum).TausThermal = MaterialProps(19);
3770 : }
3771 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(20)) {
3772 0 : state.dataMaterial->Material(MaterNum).EmissThermalFront = MaterialProps(20);
3773 : }
3774 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(21)) {
3775 0 : state.dataMaterial->Material(MaterNum).EmissThermalBack = MaterialProps(21);
3776 : }
3777 : // Assumes thermal emissivity is the same as thermal absorptance
3778 0 : state.dataMaterial->Material(MaterNum).AbsorpThermalFront = state.dataMaterial->Material(MaterNum).EmissThermalFront;
3779 0 : state.dataMaterial->Material(MaterNum).AbsorpThermalBack = state.dataMaterial->Material(MaterNum).EmissThermalBack;
3780 0 : state.dataMaterial->Material(MaterNum).TransThermal = state.dataMaterial->Material(MaterNum).TausThermal;
3781 :
3782 : // By default all blinds have fixed slat angle,
3783 : // they are used with window shading controls that adjust slat angles like MaximizeSolar or BlockBeamSolar
3784 0 : if (!state.dataIPShortCut->lAlphaFieldBlanks(3)) {
3785 0 : if (UtilityRoutines::SameString(MaterialNames(3), "FixedSlatAngle")) {
3786 0 : state.dataMaterial->Material(MaterNum).SlatAngleType = state.dataWindowEquivalentLayer->lscNONE;
3787 0 : } else if (UtilityRoutines::SameString(MaterialNames(3), "MaximizeSolar")) {
3788 0 : state.dataMaterial->Material(MaterNum).SlatAngleType = state.dataWindowEquivalentLayer->lscVBPROF;
3789 0 : } else if (UtilityRoutines::SameString(MaterialNames(3), "BlockBeamSolar")) {
3790 0 : state.dataMaterial->Material(MaterNum).SlatAngleType = state.dataWindowEquivalentLayer->lscVBNOBM;
3791 : } else {
3792 0 : state.dataMaterial->Material(MaterNum).SlatAngleType = 0;
3793 : }
3794 : } else {
3795 0 : state.dataMaterial->Material(MaterNum).SlatAngleType = 0;
3796 : }
3797 0 : if (state.dataMaterial->Material(MaterNum).SlatWidth < state.dataMaterial->Material(MaterNum).SlatSeparation) {
3798 0 : ShowWarningError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Slat Seperation/Width");
3799 0 : ShowContinueError(state,
3800 0 : format("{} [{:.2R}] is less than {} [{:.2R}].",
3801 0 : state.dataIPShortCut->cNumericFieldNames(1),
3802 0 : state.dataMaterial->Material(MaterNum).SlatWidth,
3803 0 : state.dataIPShortCut->cNumericFieldNames(2),
3804 0 : state.dataMaterial->Material(MaterNum).SlatSeparation));
3805 0 : ShowContinueError(state, "This will allow direct beam to be transmitted when Slat angle = 0.");
3806 : }
3807 0 : if (state.dataMaterial->Material(MaterNum).SlatSeparation < 0.001) {
3808 0 : ShowWarningError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Slat Seperation");
3809 0 : ShowContinueError(state,
3810 0 : format("{} [{:.2R}]. Slate spacing must be > 0.0",
3811 0 : state.dataIPShortCut->cNumericFieldNames(2),
3812 0 : state.dataMaterial->Material(MaterNum).SlatSeparation));
3813 0 : ShowContinueError(state, "...Setting slate spacing to default value of 0.025 m and simulation continues.");
3814 0 : state.dataMaterial->Material(MaterNum).SlatSeparation = 0.025;
3815 : }
3816 0 : if (state.dataMaterial->Material(MaterNum).SlatWidth < 0.001 ||
3817 0 : state.dataMaterial->Material(MaterNum).SlatWidth >= 2.0 * state.dataMaterial->Material(MaterNum).SlatSeparation) {
3818 0 : ShowWarningError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Slat Width");
3819 0 : ShowContinueError(state,
3820 0 : format("{} [{:.2R}]. Slat width range is 0 < Width <= 2*Spacing",
3821 0 : state.dataIPShortCut->cNumericFieldNames(1),
3822 0 : state.dataMaterial->Material(MaterNum).SlatWidth));
3823 0 : ShowContinueError(state, "...Setting slate width equal to slate spacing and simulation continues.");
3824 0 : state.dataMaterial->Material(MaterNum).SlatWidth = state.dataMaterial->Material(MaterNum).SlatSeparation;
3825 : }
3826 0 : if (state.dataMaterial->Material(MaterNum).SlatCrown < 0.0 ||
3827 0 : state.dataMaterial->Material(MaterNum).SlatCrown >= 0.5 * state.dataMaterial->Material(MaterNum).SlatWidth) {
3828 0 : ShowWarningError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Slat Crown");
3829 0 : ShowContinueError(state,
3830 0 : format("{} [{:.2R}]. Slat crwon range is 0 <= crown < 0.5*Width",
3831 0 : state.dataIPShortCut->cNumericFieldNames(3),
3832 0 : state.dataMaterial->Material(MaterNum).SlatCrown));
3833 0 : ShowContinueError(state, "...Setting slate crown to 0.0 and simulation continues.");
3834 0 : state.dataMaterial->Material(MaterNum).SlatCrown = 0.0;
3835 : }
3836 0 : if (state.dataMaterial->Material(MaterNum).SlatAngle < -90.0 || state.dataMaterial->Material(MaterNum).SlatAngle > 90.0) {
3837 0 : ShowWarningError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Slat Angle");
3838 0 : ShowContinueError(state,
3839 0 : format("{} [{:.2R}]. Slat angle range is -90.0 <= Angle < 90.0",
3840 0 : state.dataIPShortCut->cNumericFieldNames(4),
3841 0 : state.dataMaterial->Material(MaterNum).SlatAngle));
3842 0 : ShowContinueError(state, "...Setting slate angle to 0.0 and simulation continues.");
3843 0 : state.dataMaterial->Material(MaterNum).SlatAngle = 0.0;
3844 : }
3845 :
3846 0 : if (!UtilityRoutines::SameString(MaterialNames(2), "Horizontal") && !UtilityRoutines::SameString(MaterialNames(2), "Vertical")) {
3847 0 : ErrorsFound = true;
3848 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value");
3849 0 : ShowContinueError(state,
3850 0 : state.dataIPShortCut->cAlphaFieldNames(2) + "=\"" + MaterialNames(2) + "\", must be Horizontal or Vertical.");
3851 : }
3852 :
3853 0 : if ((MaterialProps(5) + MaterialProps(7) >= 1.0)) {
3854 0 : ErrorsFound = true;
3855 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3856 0 : ShowContinueError(state,
3857 0 : state.dataIPShortCut->cNumericFieldNames(5) + " + " + state.dataIPShortCut->cNumericFieldNames(7) + " not < 1.0");
3858 : }
3859 0 : if ((MaterialProps(6) + MaterialProps(8) >= 1.0)) {
3860 0 : ErrorsFound = true;
3861 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3862 0 : ShowContinueError(state,
3863 0 : state.dataIPShortCut->cNumericFieldNames(6) + " + " + state.dataIPShortCut->cNumericFieldNames(8) + " not < 1.0");
3864 : }
3865 0 : if ((MaterialProps(9) + MaterialProps(11) >= 1.0)) {
3866 0 : ErrorsFound = true;
3867 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3868 0 : ShowContinueError(state,
3869 0 : state.dataIPShortCut->cNumericFieldNames(9) + " + " + state.dataIPShortCut->cNumericFieldNames(11) + " not < 1.0");
3870 : }
3871 0 : if ((MaterialProps(10) + MaterialProps(12) >= 1.0)) {
3872 0 : ErrorsFound = true;
3873 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3874 0 : ShowContinueError(state,
3875 0 : state.dataIPShortCut->cNumericFieldNames(10) + " + " + state.dataIPShortCut->cNumericFieldNames(12) + " not < 1.0");
3876 : }
3877 :
3878 : } // TotBlindsEQL loop
3879 :
3880 : // EcoRoof Materials
3881 : // PSU 2006
3882 771 : state.dataHeatBalMgr->CurrentModuleObject = "Material:RoofVegetation";
3883 783 : for (Loop = 1; Loop <= EcoRoofMat; ++Loop) {
3884 : // Call Input Get Routine to retrieve material data from ecoroof
3885 :
3886 72 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3887 12 : state.dataHeatBalMgr->CurrentModuleObject,
3888 : Loop,
3889 : MaterialNames,
3890 : MaterialNumAlpha,
3891 : MaterialProps,
3892 : MaterialNumProp,
3893 : IOStat,
3894 12 : state.dataIPShortCut->lNumericFieldBlanks,
3895 12 : state.dataIPShortCut->lAlphaFieldBlanks,
3896 12 : state.dataIPShortCut->cAlphaFieldNames,
3897 12 : state.dataIPShortCut->cNumericFieldNames);
3898 36 : if (GlobalNames::VerifyUniqueInterObjectName(state,
3899 12 : state.dataHeatBalMgr->UniqueMaterialNames,
3900 12 : MaterialNames(1),
3901 12 : state.dataHeatBalMgr->CurrentModuleObject,
3902 12 : state.dataIPShortCut->cAlphaFieldNames(1),
3903 : ErrorsFound)) {
3904 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
3905 0 : continue;
3906 : }
3907 :
3908 : // this part is similar to the regular material
3909 : // Load the material derived type from the input data.
3910 12 : ++MaterNum;
3911 12 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::EcoRoof;
3912 :
3913 : // this part is new for Ecoroof properties,
3914 : // especially for the Plant Layer of the ecoroof
3915 12 : state.dataMaterial->Material(MaterNum).HeightOfPlants = MaterialProps(1);
3916 12 : state.dataMaterial->Material(MaterNum).LAI = MaterialProps(2);
3917 12 : state.dataMaterial->Material(MaterNum).Lreflectivity = MaterialProps(3); // Albedo
3918 12 : state.dataMaterial->Material(MaterNum).LEmissitivity = MaterialProps(4);
3919 12 : state.dataMaterial->Material(MaterNum).RStomata = MaterialProps(5);
3920 :
3921 12 : state.dataMaterial->Material(MaterNum).Name = MaterialNames(1);
3922 : // need to treat the A2 with is just the name of the soil(it is
3923 : // not important)
3924 12 : ValidateMaterialRoughness(state, MaterNum, MaterialNames(3), ErrorsFound);
3925 12 : if (UtilityRoutines::SameString(MaterialNames(4), "Simple")) {
3926 6 : state.dataMaterial->Material(MaterNum).EcoRoofCalculationMethod = 1;
3927 6 : } else if (UtilityRoutines::SameString(MaterialNames(4), "Advanced") || state.dataIPShortCut->lAlphaFieldBlanks(4)) {
3928 6 : state.dataMaterial->Material(MaterNum).EcoRoofCalculationMethod = 2;
3929 : } else {
3930 0 : ShowSevereError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value");
3931 0 : ShowContinueError(state, state.dataIPShortCut->cAlphaFieldNames(4) + "=\"" + MaterialNames(4) + "\".");
3932 0 : ShowContinueError(state, "...Valid values are \"Simple\" or \"Advanced\".");
3933 0 : ErrorsFound = true;
3934 : }
3935 :
3936 12 : state.dataMaterial->Material(MaterNum).Thickness = MaterialProps(6);
3937 12 : state.dataMaterial->Material(MaterNum).Conductivity = MaterialProps(7);
3938 12 : state.dataMaterial->Material(MaterNum).Density = MaterialProps(8);
3939 12 : state.dataMaterial->Material(MaterNum).SpecHeat = MaterialProps(9);
3940 12 : state.dataMaterial->Material(MaterNum).AbsorpThermal = MaterialProps(10); // emissivity
3941 12 : state.dataMaterial->Material(MaterNum).AbsorpSolar = MaterialProps(11); // (1 - Albedo)
3942 12 : state.dataMaterial->Material(MaterNum).AbsorpVisible = MaterialProps(12);
3943 12 : state.dataMaterial->Material(MaterNum).Porosity = MaterialProps(13);
3944 12 : state.dataMaterial->Material(MaterNum).MinMoisture = MaterialProps(14);
3945 12 : state.dataMaterial->Material(MaterNum).InitMoisture = MaterialProps(15);
3946 :
3947 12 : if (state.dataMaterial->Material(MaterNum).Conductivity > 0.0) {
3948 12 : state.dataHeatBal->NominalR(MaterNum) =
3949 12 : state.dataMaterial->Material(MaterNum).Thickness / state.dataMaterial->Material(MaterNum).Conductivity;
3950 12 : state.dataMaterial->Material(MaterNum).Resistance = state.dataHeatBal->NominalR(MaterNum);
3951 : } else {
3952 0 : ShowSevereError(
3953 0 : state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\" is not defined correctly.");
3954 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(7) + " is <=0.");
3955 0 : ErrorsFound = true;
3956 : }
3957 :
3958 12 : if (state.dataMaterial->Material(MaterNum).InitMoisture > state.dataMaterial->Material(MaterNum).Porosity) {
3959 0 : ShowWarningError(state, state.dataHeatBalMgr->CurrentModuleObject + "=\"" + MaterialNames(1) + "\", Illegal value combination.");
3960 0 : ShowContinueError(state,
3961 0 : state.dataIPShortCut->cNumericFieldNames(15) + " is greater than " + state.dataIPShortCut->cNumericFieldNames(13) +
3962 : ". It must be less or equal.");
3963 0 : ShowContinueError(
3964 0 : state, format("{} = {:.3T}.", state.dataIPShortCut->cNumericFieldNames(13), state.dataMaterial->Material(MaterNum).Porosity));
3965 0 : ShowContinueError(
3966 0 : state, format("{} = {:.3T}.", state.dataIPShortCut->cNumericFieldNames(15), state.dataMaterial->Material(MaterNum).InitMoisture));
3967 0 : ShowContinueError(state,
3968 0 : format("{} is reset to the maximum (saturation) value = {:.3T}.",
3969 0 : state.dataIPShortCut->cNumericFieldNames(15),
3970 0 : state.dataMaterial->Material(MaterNum).Porosity));
3971 0 : ShowContinueError(state, "Simulation continues.");
3972 0 : state.dataMaterial->Material(MaterNum).InitMoisture = state.dataMaterial->Material(MaterNum).Porosity;
3973 : }
3974 : }
3975 :
3976 : // Thermochromic glazing group
3977 : // get the number of WindowMaterial:GlazingGroup:Thermochromic objects in the idf file
3978 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowMaterial:GlazingGroup:Thermochromic";
3979 771 : state.dataHeatBal->TotTCGlazings =
3980 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
3981 771 : if (state.dataHeatBal->TotTCGlazings >= 1) {
3982 : // Read TC glazings
3983 1 : state.dataHeatBal->TCGlazings.allocate(state.dataHeatBal->TotTCGlazings);
3984 :
3985 2 : for (Loop = 1; Loop <= state.dataHeatBal->TotTCGlazings; ++Loop) {
3986 : // Get each TCGlazings from the input processor
3987 8 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3988 1 : state.dataHeatBalMgr->CurrentModuleObject,
3989 : Loop,
3990 1 : state.dataIPShortCut->cAlphaArgs,
3991 : MaterialNumAlpha,
3992 1 : state.dataIPShortCut->rNumericArgs,
3993 : MaterialNumProp,
3994 : IOStat,
3995 1 : state.dataIPShortCut->lNumericFieldBlanks,
3996 1 : state.dataIPShortCut->lAlphaFieldBlanks,
3997 1 : state.dataIPShortCut->cAlphaFieldNames,
3998 1 : state.dataIPShortCut->cNumericFieldNames);
3999 :
4000 2 : if (UtilityRoutines::IsNameEmpty(
4001 2 : state, state.dataIPShortCut->cAlphaArgs(1), state.dataHeatBalMgr->CurrentModuleObject, ErrorsFound)) {
4002 0 : ShowContinueError(state, "...All Thermochromic Glazing names must be unique regardless of subtype.");
4003 0 : continue;
4004 : }
4005 :
4006 1 : if (MaterialNumProp + 1 != MaterialNumAlpha) {
4007 0 : ShowSevereError(state,
4008 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
4009 : "\" is not defined correctly.");
4010 0 : ShowContinueError(state,
4011 0 : "Check number of " + state.dataIPShortCut->cAlphaFieldNames(2) + " compared to number of " +
4012 0 : state.dataIPShortCut->cNumericFieldNames(1));
4013 0 : ErrorsFound = true;
4014 0 : continue;
4015 : }
4016 :
4017 : // Allocate arrays
4018 1 : state.dataHeatBal->TCGlazings(Loop).SpecTemp.allocate(MaterialNumProp);
4019 1 : state.dataHeatBal->TCGlazings(Loop).LayerName.allocate(MaterialNumProp);
4020 1 : state.dataHeatBal->TCGlazings(Loop).LayerPoint.allocate(MaterialNumProp);
4021 1 : state.dataHeatBal->TCGlazings(Loop).SpecTemp = 0.0;
4022 1 : state.dataHeatBal->TCGlazings(Loop).LayerName = "";
4023 1 : state.dataHeatBal->TCGlazings(Loop).LayerPoint = 0;
4024 :
4025 1 : state.dataHeatBal->TCGlazings(Loop).Name = state.dataIPShortCut->cAlphaArgs(1);
4026 1 : state.dataHeatBal->TCGlazings(Loop).NumGlzMat = MaterialNumProp;
4027 :
4028 20 : for (iTC = 1; iTC <= MaterialNumProp; ++iTC) {
4029 19 : state.dataHeatBal->TCGlazings(Loop).SpecTemp(iTC) = state.dataIPShortCut->rNumericArgs(iTC);
4030 19 : state.dataHeatBal->TCGlazings(Loop).LayerName(iTC) = state.dataIPShortCut->cAlphaArgs(1 + iTC);
4031 :
4032 : // Find this glazing material in the material list
4033 19 : iMat = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(1 + iTC), state.dataMaterial->Material);
4034 19 : if (iMat != 0) {
4035 : // TC glazing
4036 19 : state.dataMaterial->Material(iMat).SpecTemp = state.dataIPShortCut->rNumericArgs(iTC);
4037 19 : state.dataMaterial->Material(iMat).TCParent = Loop;
4038 19 : state.dataHeatBal->TCGlazings(Loop).LayerPoint(iTC) = iMat;
4039 :
4040 : // test that named material is of the right type
4041 19 : if (state.dataMaterial->Material(iMat).Group != DataHeatBalance::MaterialGroup::WindowGlass) {
4042 0 : ShowSevereError(state,
4043 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
4044 : "\" is not defined correctly.");
4045 0 : ShowContinueError(state, "Material named: " + state.dataIPShortCut->cAlphaArgs(1 + iTC) + " is not a window glazing ");
4046 0 : ErrorsFound = true;
4047 : }
4048 :
4049 : } else { // thow error because not found
4050 0 : ShowSevereError(state,
4051 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
4052 : "\" is not defined correctly.");
4053 0 : ShowContinueError(state, "Material named: " + state.dataIPShortCut->cAlphaArgs(1 + iTC) + " was not found ");
4054 0 : ErrorsFound = true;
4055 : }
4056 : }
4057 : }
4058 : }
4059 771 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
4060 771 : cCurrentModuleObject = "WindowMaterial:SimpleGlazingSystem";
4061 871 : for (Loop = 1; Loop <= state.dataHeatBal->TotSimpleWindow; ++Loop) {
4062 :
4063 700 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4064 : cCurrentModuleObject,
4065 : Loop,
4066 100 : state.dataIPShortCut->cAlphaArgs,
4067 : MaterialNumAlpha,
4068 100 : state.dataIPShortCut->rNumericArgs,
4069 : MaterialNumProp,
4070 : IOStat,
4071 100 : state.dataIPShortCut->lNumericFieldBlanks,
4072 100 : state.dataIPShortCut->lAlphaFieldBlanks,
4073 100 : state.dataIPShortCut->cAlphaFieldNames,
4074 100 : state.dataIPShortCut->cNumericFieldNames);
4075 300 : if (GlobalNames::VerifyUniqueInterObjectName(state,
4076 100 : state.dataHeatBalMgr->UniqueMaterialNames,
4077 100 : state.dataIPShortCut->cAlphaArgs(1),
4078 100 : state.dataHeatBalMgr->CurrentModuleObject,
4079 100 : state.dataIPShortCut->cAlphaFieldNames(1),
4080 : ErrorsFound)) {
4081 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
4082 0 : continue;
4083 : }
4084 100 : ++MaterNum;
4085 100 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::WindowSimpleGlazing;
4086 100 : state.dataMaterial->Material(MaterNum).Name = state.dataIPShortCut->cAlphaArgs(1);
4087 100 : state.dataMaterial->Material(MaterNum).SimpleWindowUfactor = state.dataIPShortCut->rNumericArgs(1);
4088 100 : state.dataMaterial->Material(MaterNum).SimpleWindowSHGC = state.dataIPShortCut->rNumericArgs(2);
4089 100 : if (!state.dataIPShortCut->lNumericFieldBlanks(3)) {
4090 45 : state.dataMaterial->Material(MaterNum).SimpleWindowVisTran = state.dataIPShortCut->rNumericArgs(3);
4091 45 : state.dataMaterial->Material(MaterNum).SimpleWindowVTinputByUser = true;
4092 : }
4093 :
4094 100 : SetupSimpleWindowGlazingSystem(state, MaterNum);
4095 : }
4096 :
4097 : // Simon: Place to load materials for complex fenestrations
4098 771 : if ((state.dataHeatBal->TotComplexShades > 0) || (state.dataHeatBal->TotComplexGaps > 0)) {
4099 10 : SetupComplexFenestrationMaterialInput(state, MaterNum, ErrorsFound);
4100 10 : if (ErrorsFound) {
4101 0 : ShowSevereError(state, "Errors found in processing complex fenestration material input");
4102 : }
4103 : }
4104 771 : ScanForReports(state, "Constructions", state.dataHeatBalMgr->DoReport, "Materials");
4105 :
4106 771 : if (state.dataHeatBalMgr->DoReport) {
4107 :
4108 13 : print(state.files.eio,
4109 : "! <Material Details>,Material Name,ThermalResistance {{m2-K/w}},Roughness,Thickness {{m}},Conductivity "
4110 : "{{w/m-K}},Density {{kg/m3}},Specific Heat "
4111 13 : "{{J/kg-K}},Absorptance:Thermal,Absorptance:Solar,Absorptance:Visible\n");
4112 :
4113 13 : print(state.files.eio, "! <Material:Air>,Material Name,ThermalResistance {{m2-K/w}}\n");
4114 :
4115 : // Formats
4116 13 : constexpr const char *Format_701(" Material Details,{},{:.4R},{},{:.4R},{:.3R},{:.3R},{:.3R},{:.4R},{:.4R},{:.4R}\n");
4117 13 : constexpr const char *Format_702(" Material:Air,{},{:.4R}\n");
4118 :
4119 236 : for (MaterNum = 1; MaterNum <= state.dataHeatBal->TotMaterials; ++MaterNum) {
4120 :
4121 223 : switch (state.dataMaterial->Material(MaterNum).Group) {
4122 8 : case DataHeatBalance::MaterialGroup::Air: {
4123 24 : print(
4124 24 : state.files.eio, Format_702, state.dataMaterial->Material(MaterNum).Name, state.dataMaterial->Material(MaterNum).Resistance);
4125 8 : } break;
4126 215 : default: {
4127 2150 : print(state.files.eio,
4128 : Format_701,
4129 215 : state.dataMaterial->Material(MaterNum).Name,
4130 215 : state.dataMaterial->Material(MaterNum).Resistance,
4131 430 : DisplayMaterialRoughness(state.dataMaterial->Material(MaterNum).Roughness),
4132 215 : state.dataMaterial->Material(MaterNum).Thickness,
4133 215 : state.dataMaterial->Material(MaterNum).Conductivity,
4134 215 : state.dataMaterial->Material(MaterNum).Density,
4135 215 : state.dataMaterial->Material(MaterNum).SpecHeat,
4136 215 : state.dataMaterial->Material(MaterNum).AbsorpThermal,
4137 215 : state.dataMaterial->Material(MaterNum).AbsorpSolar,
4138 430 : state.dataMaterial->Material(MaterNum).AbsorpVisible);
4139 215 : } break;
4140 : }
4141 : }
4142 : }
4143 :
4144 : // FORMATS.
4145 :
4146 771 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) { // setup surface property EMS actuators
4147 :
4148 2171 : for (MaterNum = 1; MaterNum <= state.dataHeatBal->TotMaterials; ++MaterNum) {
4149 2100 : if (state.dataMaterial->Material(MaterNum).Group != DataHeatBalance::MaterialGroup::RegularMaterial) continue;
4150 7092 : SetupEMSActuator(state,
4151 : "Material",
4152 1773 : state.dataMaterial->Material(MaterNum).Name,
4153 : "Surface Property Solar Absorptance",
4154 : "[ ]",
4155 1773 : state.dataMaterial->Material(MaterNum).AbsorpSolarEMSOverrideOn,
4156 5319 : state.dataMaterial->Material(MaterNum).AbsorpSolarEMSOverride);
4157 7092 : SetupEMSActuator(state,
4158 : "Material",
4159 1773 : state.dataMaterial->Material(MaterNum).Name,
4160 : "Surface Property Thermal Absorptance",
4161 : "[ ]",
4162 1773 : state.dataMaterial->Material(MaterNum).AbsorpThermalEMSOverrideOn,
4163 5319 : state.dataMaterial->Material(MaterNum).AbsorpThermalEMSOverride);
4164 7092 : SetupEMSActuator(state,
4165 : "Material",
4166 1773 : state.dataMaterial->Material(MaterNum).Name,
4167 : "Surface Property Visible Absorptance",
4168 : "[ ]",
4169 1773 : state.dataMaterial->Material(MaterNum).AbsorpVisibleEMSOverrideOn,
4170 5319 : state.dataMaterial->Material(MaterNum).AbsorpVisibleEMSOverride);
4171 : }
4172 : }
4173 :
4174 : // try assigning phase change material properties for each material, won't do anything for non pcm surfaces
4175 14292 : for (auto &m : state.dataMaterial->Material) {
4176 13521 : m.phaseChange = HysteresisPhaseChange::HysteresisPhaseChange::factory(state, m.Name);
4177 : }
4178 : }
4179 :
4180 771 : void GetWindowGlassSpectralData(EnergyPlusData &state, bool &ErrorsFound) // set to true if errors found in input
4181 : {
4182 :
4183 : // SUBROUTINE INFORMATION:
4184 : // AUTHOR Fred Winkelmann
4185 : // DATE WRITTEN May 2000
4186 : // MODIFIED na
4187 : // RE-ENGINEERED na
4188 :
4189 : // PURPOSE OF THIS SUBROUTINE:
4190 : // Gets spectral data (transmittance, front reflectance, and back
4191 : // reflectance at normal incidence vs. wavelength) for glass
4192 :
4193 : // METHODOLOGY EMPLOYED:
4194 : // na
4195 :
4196 : // REFERENCES:
4197 : // na
4198 :
4199 : // Using/Aliasing
4200 :
4201 : // Locals
4202 : // SUBROUTINE ARGUMENT DEFINITIONS:
4203 :
4204 : // SUBROUTINE PARAMETER DEFINITIONS:
4205 771 : constexpr const char *RoutineName("GetWindowGlassSpectralData: ");
4206 :
4207 : // INTERFACE BLOCK SPECIFICATIONS:
4208 : // na
4209 :
4210 : // DERIVED TYPE DEFINITIONS:
4211 : // na
4212 :
4213 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4214 :
4215 : int IOStat; // IO Status when calling get input subroutine
4216 1542 : Array1D_string SpecDataNames(1); // Spectral data alpha names
4217 : int SpecDataNumAlpha; // Number of spectral data alpha names being passed
4218 : int SpecDataNumProp; // Number of spectral data properties being passed
4219 1542 : Array1D<Real64> SpecDataProps; // Temporary array to transfer spectal data properties
4220 : int Loop;
4221 : int LamNum; // Wavelength number
4222 : int TotLam; // Total wavelengths
4223 : Real64 Lam; // Wavelength (microns)
4224 : Real64 Tau; // Transmittance, front reflectance, back reflectance
4225 : Real64 RhoF;
4226 : Real64 RhoB;
4227 :
4228 771 : state.dataHeatBalMgr->CurrentModuleObject = "MaterialProperty:GlazingSpectralData";
4229 771 : state.dataHeatBal->TotSpectralData =
4230 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
4231 771 : state.dataHeatBal->SpectralData.allocate(state.dataHeatBal->TotSpectralData);
4232 771 : if (state.dataHeatBal->TotSpectralData > 0) SpecDataProps.allocate(Construction::MaxSpectralDataElements * 4);
4233 :
4234 854 : for (Loop = 1; Loop <= state.dataHeatBal->TotSpectralData; ++Loop) {
4235 :
4236 : // Call Input Get routine to retrieve spectral data
4237 : // Name is followed by up to 450 sets of normal-incidence measured values of
4238 : // [wavelength (microns), transmittance, front reflectance, back reflectance] for
4239 : // wavelengths covering the short-wave solar spectrum (from about 0.25 to 2.5 microns)
4240 498 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4241 83 : state.dataHeatBalMgr->CurrentModuleObject,
4242 : Loop,
4243 : SpecDataNames,
4244 : SpecDataNumAlpha,
4245 : SpecDataProps,
4246 : SpecDataNumProp,
4247 : IOStat,
4248 83 : state.dataIPShortCut->lNumericFieldBlanks,
4249 83 : state.dataIPShortCut->lAlphaFieldBlanks,
4250 83 : state.dataIPShortCut->cAlphaFieldNames,
4251 83 : state.dataIPShortCut->cNumericFieldNames);
4252 :
4253 83 : if (UtilityRoutines::IsNameEmpty(state, SpecDataNames(1), state.dataHeatBalMgr->CurrentModuleObject, ErrorsFound)) continue;
4254 :
4255 : // Load the spectral data derived type from the input data.
4256 83 : state.dataHeatBal->SpectralData(Loop).Name = SpecDataNames(1);
4257 83 : TotLam = SpecDataNumProp / 4;
4258 83 : if (mod(SpecDataNumProp, 4) != 0) {
4259 0 : ShowWarningError(state,
4260 0 : std::string{RoutineName} + state.dataHeatBalMgr->CurrentModuleObject + "=\"" + SpecDataNames(1) + "\" invalid set.");
4261 0 : ShowContinueError(
4262 : state,
4263 0 : format("... set not even multiple of 4 items (Wavelength,Trans,ReflFront,ReflBack), number of items in dataset = {}",
4264 0 : SpecDataNumProp));
4265 0 : ShowContinueError(state, format("... remainder after div by 4 = {}, remainder items will be set to 0.0", mod(SpecDataNumProp, 4)));
4266 0 : SpecDataProps({SpecDataNumProp + 1, min(SpecDataNumProp + 4, Construction::MaxSpectralDataElements * 4)}) = 0.0;
4267 : }
4268 83 : if (TotLam > Construction::MaxSpectralDataElements) {
4269 0 : ErrorsFound = true;
4270 0 : ShowSevereError(state,
4271 0 : std::string{RoutineName} + state.dataHeatBalMgr->CurrentModuleObject + "=\"" + SpecDataNames(1) + "\" invalid set.");
4272 0 : ShowContinueError(
4273 : state,
4274 0 : format("... More than max [{}] (Wavelength,Trans,ReflFront,ReflBack) entries in set.", Construction::MaxSpectralDataElements));
4275 0 : continue;
4276 : }
4277 83 : state.dataHeatBal->SpectralData(Loop).NumOfWavelengths = TotLam;
4278 :
4279 83 : state.dataHeatBal->SpectralData(Loop).WaveLength.allocate(TotLam); // Wavelength (microns)
4280 83 : state.dataHeatBal->SpectralData(Loop).Trans.allocate(TotLam); // Transmittance at normal incidence
4281 83 : state.dataHeatBal->SpectralData(Loop).ReflFront.allocate(TotLam); // Front reflectance at normal incidence
4282 83 : state.dataHeatBal->SpectralData(Loop).ReflBack.allocate(TotLam); // Back reflectance at normal incidence
4283 :
4284 27764 : for (LamNum = 1; LamNum <= TotLam; ++LamNum) {
4285 27681 : state.dataHeatBal->SpectralData(Loop).WaveLength(LamNum) = SpecDataProps(4 * LamNum - 3);
4286 27681 : state.dataHeatBal->SpectralData(Loop).Trans(LamNum) = SpecDataProps(4 * LamNum - 2);
4287 : // Following is needed since angular calculation in subr TransAndReflAtPhi
4288 : // fails for Trans = 0.0
4289 27681 : if (state.dataHeatBal->SpectralData(Loop).Trans(LamNum) < 0.001) state.dataHeatBal->SpectralData(Loop).Trans(LamNum) = 0.001;
4290 27681 : state.dataHeatBal->SpectralData(Loop).ReflFront(LamNum) = SpecDataProps(4 * LamNum - 1);
4291 27681 : state.dataHeatBal->SpectralData(Loop).ReflBack(LamNum) = SpecDataProps(4 * LamNum);
4292 : }
4293 :
4294 : // Check integrity of the spectral data
4295 27764 : for (LamNum = 1; LamNum <= TotLam; ++LamNum) {
4296 27681 : Lam = state.dataHeatBal->SpectralData(Loop).WaveLength(LamNum);
4297 27681 : Tau = state.dataHeatBal->SpectralData(Loop).Trans(LamNum);
4298 27681 : RhoF = state.dataHeatBal->SpectralData(Loop).ReflFront(LamNum);
4299 27681 : RhoB = state.dataHeatBal->SpectralData(Loop).ReflBack(LamNum);
4300 27681 : if (LamNum < TotLam) {
4301 27598 : if (state.dataHeatBal->SpectralData(Loop).WaveLength(LamNum + 1) <= Lam) {
4302 0 : ErrorsFound = true;
4303 0 : ShowSevereError(state,
4304 0 : std::string{RoutineName} + state.dataHeatBalMgr->CurrentModuleObject + "=\"" + SpecDataNames(1) +
4305 : "\" invalid set.");
4306 0 : ShowContinueError(state,
4307 0 : format("... Wavelengths not in increasing order. at wavelength#={}, value=[{:.4T}], next is [{:.4T}].",
4308 : LamNum,
4309 : Lam,
4310 0 : state.dataHeatBal->SpectralData(Loop).WaveLength(LamNum + 1)));
4311 : }
4312 : }
4313 :
4314 27681 : if (Lam < 0.1 || Lam > 4.0) {
4315 0 : ErrorsFound = true;
4316 0 : ShowSevereError(
4317 0 : state, std::string{RoutineName} + state.dataHeatBalMgr->CurrentModuleObject + "=\"" + SpecDataNames(1) + "\" invalid value.");
4318 0 : ShowContinueError(
4319 0 : state, format("... A wavelength is not in the range 0.1 to 4.0 microns; at wavelength#={}, value=[{:.4T}].", LamNum, Lam));
4320 : }
4321 :
4322 : // TH 2/15/2011. CR 8343
4323 : // IGDB (International Glazing Database) does not meet the above strict restrictions.
4324 : // Relax rules to allow directly use of spectral data from IGDB
4325 27681 : if (Tau > 1.01) {
4326 0 : ErrorsFound = true;
4327 0 : ShowSevereError(
4328 0 : state, std::string{RoutineName} + state.dataHeatBalMgr->CurrentModuleObject + "=\"" + SpecDataNames(1) + "\" invalid value.");
4329 0 : ShowContinueError(state, format("... A transmittance is > 1.0; at wavelength#={}, value=[{:.4T}].", LamNum, Tau));
4330 : }
4331 :
4332 27681 : if (RhoF < 0.0 || RhoF > 1.02 || RhoB < 0.0 || RhoB > 1.02) {
4333 0 : ErrorsFound = true;
4334 0 : ShowSevereError(
4335 0 : state, std::string{RoutineName} + state.dataHeatBalMgr->CurrentModuleObject + "=\"" + SpecDataNames(1) + "\" invalid value.");
4336 0 : ShowContinueError(state, format("... A reflectance is < 0.0 or > 1.0; at wavelength#={}, RhoF value=[{:.4T}].", LamNum, RhoF));
4337 0 : ShowContinueError(state, format("... A reflectance is < 0.0 or > 1.0; at wavelength#={}, RhoB value=[{:.4T}].", LamNum, RhoB));
4338 : }
4339 :
4340 27681 : if ((Tau + RhoF) > 1.03 || (Tau + RhoB) > 1.03) {
4341 0 : ErrorsFound = true;
4342 0 : ShowSevereError(
4343 0 : state, std::string{RoutineName} + state.dataHeatBalMgr->CurrentModuleObject + "=\"" + SpecDataNames(1) + "\" invalid value.");
4344 0 : ShowContinueError(state,
4345 0 : "... Transmittance + reflectance) > 1.0 for an entry; at wavelength#=" +
4346 0 : format("{}, value(Tau+RhoF)=[{:.4T}], value(Tau+RhoB)=[{:.4T}].", LamNum, (Tau + RhoF), (Tau + RhoB)));
4347 : }
4348 : }
4349 : }
4350 :
4351 771 : if (state.dataHeatBal->TotSpectralData > 0) SpecDataProps.deallocate();
4352 771 : }
4353 :
4354 10101 : void ValidateMaterialRoughness(EnergyPlusData &state,
4355 : int const MaterNum, // Which Material number being validated.
4356 : std::string const &Roughness, // Roughness String
4357 : bool &ErrorsFound // If errors found
4358 : )
4359 : {
4360 :
4361 : // SUBROUTINE INFORMATION:
4362 : // AUTHOR Linda K. Lawrie
4363 : // DATE WRITTEN April 1999
4364 : // MODIFIED na
4365 : // RE-ENGINEERED na
4366 :
4367 : // PURPOSE OF THIS SUBROUTINE:
4368 : // This subroutine compares the input Roughness value against the
4369 : // valid values and sets the correct value in the Material Data Structure.
4370 :
4371 : // METHODOLOGY EMPLOYED:
4372 : // Error message provided if not valid.
4373 :
4374 : // REFERENCES:
4375 : // na
4376 :
4377 : // USE STATEMENTS:
4378 : // na
4379 :
4380 : // Locals
4381 : // SUBROUTINE ARGUMENT DEFINITIONS:
4382 :
4383 : // SUBROUTINE PARAMETER DEFINITIONS:
4384 : // na
4385 :
4386 : // INTERFACE BLOCK SPECIFICATIONS:
4387 : // na
4388 :
4389 : // DERIVED TYPE DEFINITIONS:
4390 : // na
4391 :
4392 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4393 :
4394 : // Select the correct Number for the associated ascii name for the roughness type
4395 10101 : if (UtilityRoutines::SameString(Roughness, "VeryRough"))
4396 1129 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::VeryRough;
4397 10101 : if (UtilityRoutines::SameString(Roughness, "Rough")) state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::Rough;
4398 10101 : if (UtilityRoutines::SameString(Roughness, "MediumRough"))
4399 2026 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough;
4400 10101 : if (UtilityRoutines::SameString(Roughness, "MediumSmooth"))
4401 2048 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumSmooth;
4402 10101 : if (UtilityRoutines::SameString(Roughness, "Smooth"))
4403 1965 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::Smooth;
4404 10101 : if (UtilityRoutines::SameString(Roughness, "VerySmooth"))
4405 8 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::VerySmooth;
4406 :
4407 : // Was it set?
4408 10101 : if (state.dataMaterial->Material(MaterNum).Roughness == DataSurfaces::SurfaceRoughness::Invalid) {
4409 0 : ShowSevereError(state, "Material=" + state.dataMaterial->Material(MaterNum).Name + ",Illegal Roughness=" + Roughness);
4410 0 : ErrorsFound = true;
4411 : }
4412 10101 : }
4413 :
4414 771 : void GetConstructData(EnergyPlusData &state, bool &ErrorsFound) // If errors found in input
4415 : {
4416 :
4417 : // SUBROUTINE INFORMATION:
4418 : // AUTHOR Richard Liesen
4419 : // DATE WRITTEN September 1997
4420 : // MODIFIED January 2003, FCW: accommodate between-glass shading device
4421 : // July 2009, TH: added constructions defined with F and C factors
4422 : // RE-ENGINEERED na
4423 :
4424 : // PURPOSE OF THIS SUBROUTINE:
4425 : // This file reads the input through the input processor for Constructions.
4426 : // Data read in this routine is stored in a derived type (Construct)
4427 : // defined in the DataHeatBalance module.
4428 : // This subroutine only sets those parameters which must be obtained
4429 : // from the input file--all other portions of the Construct derived
4430 : // type are set during the initializations.
4431 :
4432 : // METHODOLOGY EMPLOYED:
4433 : // na
4434 :
4435 : // REFERENCES:
4436 : // na
4437 :
4438 : // Using/Aliasing
4439 : using namespace DataStringGlobals;
4440 :
4441 : // If UniqueConstructionNames size, then input has already been gotten
4442 771 : if (state.dataHeatBalMgr->UniqueConstructNames.size()) return;
4443 :
4444 : int ConstrNum; // Counter to keep track of the construction number
4445 : int Layer; // loop index for each of the construction layers
4446 : int ConstructNumAlpha; // Number of construction alpha names being passed
4447 : int DummyNumProp; // dummy variable for properties being passed
4448 : int IOStat; // IO Status when calling get input subroutine
4449 1542 : Array1D_string ConstructAlphas({0, Construction::MaxLayersInConstruct}); // Construction Alpha names defined
4450 1542 : Array1D<Real64> DummyProps(5); // Temporary array to transfer construction properties
4451 : int Loop;
4452 : int TotRegConstructs; // Number of "regular" constructions (no embedded sources or sinks and
4453 :
4454 : int TotFfactorConstructs; // Number of slabs-on-grade or underground floor constructions defined with F factors
4455 : int TotCfactorConstructs; // Number of underground wall constructions defined with C factors
4456 :
4457 : // int TotSourceConstructs; // Number of constructions with embedded sources or sinks
4458 : int TotWindow5Constructs; // Number of constructions from Window5 data file
4459 : bool ConstructionFound; // True if input window construction name is found in the
4460 : // Window5 data file
4461 : bool EOFonW5File; // True if EOF encountered reading Window5 data file
4462 : DataHeatBalance::MaterialGroup MaterialLayerGroup; // window construction layer material group index
4463 :
4464 : int iMatGlass; // number of glass layers
4465 1542 : Array1D_string WConstructNames;
4466 :
4467 : // Get the Total number of Constructions from the input
4468 771 : TotRegConstructs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction");
4469 771 : int totAirBoundaryConstructs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction:AirBoundary");
4470 :
4471 771 : TotFfactorConstructs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction:FfactorGroundFloor");
4472 771 : TotCfactorConstructs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction:CfactorUndergroundWall");
4473 :
4474 771 : if (TotFfactorConstructs > 0) {
4475 14 : state.dataHeatBal->NoFfactorConstructionsUsed = false;
4476 : }
4477 :
4478 771 : if (TotCfactorConstructs > 0) {
4479 7 : state.dataHeatBal->NoCfactorConstructionsUsed = false;
4480 : }
4481 :
4482 771 : state.dataBSDFWindow->TotComplexFenStates =
4483 1542 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction:ComplexFenestrationState");
4484 771 : TotWindow5Constructs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction:WindowDataFile");
4485 771 : state.dataWindowEquivLayer->TotWinEquivLayerConstructs =
4486 1542 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction:WindowEquivalentLayer");
4487 :
4488 771 : WConstructNames.allocate(TotWindow5Constructs);
4489 :
4490 2313 : state.dataHeatBal->TotConstructs = TotRegConstructs + TotFfactorConstructs + TotCfactorConstructs + totAirBoundaryConstructs +
4491 1542 : state.dataBSDFWindow->TotComplexFenStates + state.dataWindowEquivLayer->TotWinEquivLayerConstructs;
4492 :
4493 771 : state.dataHeatBal->NominalRforNominalUCalculation.dimension(state.dataHeatBal->TotConstructs, 0.0);
4494 771 : state.dataHeatBal->NominalU.dimension(state.dataHeatBal->TotConstructs, 0.0);
4495 771 : state.dataHeatBal->NominalUBeforeAdjusted.dimension(state.dataHeatBal->TotConstructs, 0.0);
4496 771 : state.dataHeatBal->CoeffAdjRatio.dimension(state.dataHeatBal->TotConstructs, 1.0);
4497 :
4498 : // Allocate the array to the number of constructions/initialize selected variables
4499 771 : state.dataConstruction->Construct.allocate(state.dataHeatBal->TotConstructs);
4500 771 : state.dataHeatBalMgr->UniqueConstructNames.reserve(state.dataHeatBal->TotConstructs);
4501 : // Note: If TotWindow5Constructs > 0, additional constructions are created in
4502 : // subr. SearchWindow5DataFile corresponding to those found on the data file.
4503 6592 : for (auto &e : state.dataConstruction->Construct) {
4504 : // Initialize CTF and History terms
4505 5821 : e.NumCTFTerms = 0;
4506 5821 : e.NumHistories = 0;
4507 :
4508 : // Initialize some heat source/sink variables
4509 5821 : e.SourceSinkPresent = false; // "default" is no source or sink present
4510 5821 : e.SolutionDimensions = 1; // "default" is 1-D heat transfer
4511 5821 : e.SourceAfterLayer = 0; // this has no meaning if a source/sink is not present
4512 5821 : e.TempAfterLayer = 0; // this has no meaning if a source/sink is not present
4513 5821 : e.ThicknessPerpend = 0.0; // this has no meaning if a source/sink is not present
4514 :
4515 5821 : e.W5FrameDivider = 0;
4516 5821 : e.FromWindow5DataFile = false;
4517 :
4518 : // these Construct arrays dimensioned based on MaxSolidWinLayers
4519 5821 : e.setArraysBasedOnMaxSolidWinLayers(state);
4520 : }
4521 :
4522 771 : ConstrNum = 0;
4523 :
4524 771 : state.dataHeatBalMgr->CurrentModuleObject = "Construction";
4525 6359 : for (Loop = 1; Loop <= TotRegConstructs; ++Loop) { // Loop through all constructs in the input...
4526 :
4527 : // Get the object names for each construction from the input processor
4528 33528 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4529 5588 : state.dataHeatBalMgr->CurrentModuleObject,
4530 : Loop,
4531 : ConstructAlphas,
4532 : ConstructNumAlpha,
4533 : DummyProps,
4534 : DummyNumProp,
4535 : IOStat,
4536 5588 : state.dataIPShortCut->lNumericFieldBlanks,
4537 5588 : state.dataIPShortCut->lAlphaFieldBlanks,
4538 5588 : state.dataIPShortCut->cAlphaFieldNames,
4539 5588 : state.dataIPShortCut->cNumericFieldNames);
4540 16764 : if (GlobalNames::VerifyUniqueInterObjectName(state,
4541 5588 : state.dataHeatBalMgr->UniqueConstructNames,
4542 5588 : ConstructAlphas(0),
4543 5588 : state.dataHeatBalMgr->CurrentModuleObject,
4544 5588 : state.dataIPShortCut->cAlphaFieldNames(1),
4545 : ErrorsFound)) {
4546 0 : continue;
4547 : }
4548 :
4549 : // Glass layer counter
4550 5588 : iMatGlass = 0;
4551 :
4552 5588 : ++ConstrNum;
4553 : // Assign Construction name to the Derived Type using the zeroth position of the array
4554 5588 : state.dataConstruction->Construct(ConstrNum).Name = ConstructAlphas(0);
4555 :
4556 : // Set the total number of layers for the construction
4557 5588 : state.dataConstruction->Construct(ConstrNum).TotLayers = ConstructNumAlpha - 1;
4558 :
4559 : // Loop through all of the layers of the construct to match the material names.
4560 : // The loop index is the number minus 1
4561 18744 : for (Layer = 1; Layer <= ConstructNumAlpha - 1; ++Layer) {
4562 :
4563 : // Find the material in the list of materials
4564 :
4565 13156 : state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer) =
4566 13156 : UtilityRoutines::FindItemInList(ConstructAlphas(Layer), state.dataMaterial->Material);
4567 :
4568 : // count number of glass layers
4569 13156 : if (state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer) > 0) {
4570 13155 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer)).Group ==
4571 : DataHeatBalance::MaterialGroup::WindowGlass)
4572 1757 : ++iMatGlass;
4573 13155 : MaterialLayerGroup = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer)).Group;
4574 13155 : if ((MaterialLayerGroup == DataHeatBalance::MaterialGroup::GlassEquivalentLayer) ||
4575 13155 : (MaterialLayerGroup == DataHeatBalance::MaterialGroup::ShadeEquivalentLayer) ||
4576 13155 : (MaterialLayerGroup == DataHeatBalance::MaterialGroup::DrapeEquivalentLayer) ||
4577 13155 : (MaterialLayerGroup == DataHeatBalance::MaterialGroup::BlindEquivalentLayer) ||
4578 13155 : (MaterialLayerGroup == DataHeatBalance::MaterialGroup::ScreenEquivalentLayer) ||
4579 : (MaterialLayerGroup == DataHeatBalance::MaterialGroup::GapEquivalentLayer)) {
4580 0 : ShowSevereError(state,
4581 0 : "Invalid material layer type in window " + state.dataHeatBalMgr->CurrentModuleObject + " = " +
4582 0 : state.dataConstruction->Construct(ConstrNum).Name);
4583 0 : ShowSevereError(state,
4584 0 : "Equivalent Layer material type = " + ConstructAlphas(Layer) +
4585 : " is allowed only in Construction:WindowEquivalentLayer window object.");
4586 0 : ErrorsFound = true;
4587 : }
4588 : }
4589 :
4590 13156 : if (state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer) == 0) {
4591 : // This may be a TC GlazingGroup
4592 1 : state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer) =
4593 1 : UtilityRoutines::FindItemInList(ConstructAlphas(Layer), state.dataHeatBal->TCGlazings);
4594 :
4595 1 : if (state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer) > 0) {
4596 : // reset layer pointer to the first glazing in the TC GlazingGroup
4597 1 : state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer) =
4598 1 : state.dataHeatBal->TCGlazings(state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer)).LayerPoint(1);
4599 1 : state.dataConstruction->Construct(ConstrNum).TCLayer = state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer);
4600 1 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer)).Group ==
4601 : DataHeatBalance::MaterialGroup::WindowGlass)
4602 1 : ++iMatGlass;
4603 1 : state.dataConstruction->Construct(ConstrNum).TCFlag = 1;
4604 1 : state.dataConstruction->Construct(ConstrNum).TCMasterConst = ConstrNum;
4605 1 : state.dataConstruction->Construct(ConstrNum).TCGlassID = iMatGlass; // the TC glass layer ID
4606 1 : state.dataConstruction->Construct(ConstrNum).TCLayerID = Layer;
4607 1 : state.dataConstruction->Construct(ConstrNum).TypeIsWindow = true;
4608 : }
4609 : }
4610 :
4611 13156 : if (state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer) == 0) {
4612 0 : ShowSevereError(state,
4613 0 : "Did not find matching material for " + state.dataHeatBalMgr->CurrentModuleObject + ' ' +
4614 0 : state.dataConstruction->Construct(ConstrNum).Name + ", missing material = " + ConstructAlphas(Layer));
4615 0 : ErrorsFound = true;
4616 : } else {
4617 13156 : state.dataHeatBal->NominalRforNominalUCalculation(ConstrNum) +=
4618 13156 : state.dataHeatBal->NominalR(state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer));
4619 26312 : if (state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer)).Group ==
4620 23428 : DataHeatBalance::MaterialGroup::RegularMaterial &&
4621 10272 : !state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer)).ROnly) {
4622 8974 : state.dataHeatBal->NoRegularMaterialsUsed = false;
4623 : }
4624 : }
4625 :
4626 : } // ...end of the Layer DO loop
4627 :
4628 : } // ...end of Regular Construction DO loop
4629 :
4630 771 : TotRegConstructs = ConstrNum;
4631 :
4632 : // Added TH 7/2009 for underground walls and floors constructions
4633 771 : if (TotFfactorConstructs + TotCfactorConstructs >= 1) {
4634 20 : CreateFCfactorConstructions(state, ConstrNum, ErrorsFound);
4635 20 : if (ErrorsFound) {
4636 0 : ShowSevereError(state, "Errors found in creating the constructions defined with Ffactor or Cfactor method");
4637 : }
4638 20 : TotRegConstructs += TotFfactorConstructs + TotCfactorConstructs;
4639 : }
4640 :
4641 771 : if (totAirBoundaryConstructs >= 1) {
4642 3 : CreateAirBoundaryConstructions(state, ConstrNum, ErrorsFound);
4643 3 : if (ErrorsFound) {
4644 0 : ShowSevereError(state, "Errors found in creating the constructions defined with Construction:AirBoundary.");
4645 : }
4646 3 : TotRegConstructs += totAirBoundaryConstructs;
4647 : }
4648 :
4649 : // Added BG 6/2010 for complex fenestration
4650 771 : if (state.dataBSDFWindow->TotComplexFenStates > 0) {
4651 10 : SetupComplexFenestrationStateInput(state, ConstrNum, ErrorsFound);
4652 10 : if (ErrorsFound) {
4653 0 : ShowSevereError(state, "Errors found in processing complex fenestration input");
4654 : }
4655 10 : TotRegConstructs += state.dataBSDFWindow->TotComplexFenStates;
4656 : }
4657 :
4658 771 : state.dataHeatBalMgr->CurrentModuleObject = "ConstructionProperty:InternalHeatSource";
4659 :
4660 1542 : auto instances = state.dataInputProcessing->inputProcessor->epJSON.find(state.dataHeatBalMgr->CurrentModuleObject);
4661 771 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
4662 36 : state.dataHeatBal->AnyInternalHeatSourceInInput = true;
4663 36 : auto &instancesValue = instances.value();
4664 80 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
4665 44 : auto const &fields = instance.value();
4666 88 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
4667 :
4668 88 : std::string construction_name{UtilityRoutines::MakeUPPERCase(fields.at("construction_name").get<std::string>())};
4669 44 : int source_after_layer_number{fields.at("thermal_source_present_after_layer_number")};
4670 44 : int calculation_after_layer_number{fields.at("temperature_calculation_requested_after_layer_number")};
4671 44 : int ctf_dimensions{fields.at("dimensions_for_the_ctf_calculation")};
4672 44 : if ((ctf_dimensions < 1) || (ctf_dimensions > 2)) {
4673 0 : ShowWarningError(state, "ConstructionProperty:InternalHeatSource must be either 1- or 2-D. Reset to 1-D solution.");
4674 0 : ShowContinueError(state, "Construction=" + construction_name + " is affected.");
4675 0 : ctf_dimensions = 1;
4676 : }
4677 44 : Real64 tube_spacing{fields.at("tube_spacing")};
4678 44 : Real64 calculation_position{fields.at("two_dimensional_temperature_calculation_position")};
4679 :
4680 : // Find the construction
4681 44 : int construction_index = UtilityRoutines::FindItemInList(construction_name, state.dataConstruction->Construct);
4682 :
4683 44 : if (construction_index == 0) {
4684 0 : ShowSevereError(state,
4685 0 : "Did not find matching construction for " + state.dataHeatBalMgr->CurrentModuleObject + ' ' + thisObjectName +
4686 0 : ", missing construction = " + construction_name);
4687 0 : ErrorsFound = true;
4688 0 : continue;
4689 : }
4690 :
4691 44 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(state.dataHeatBalMgr->CurrentModuleObject, instance.key());
4692 :
4693 44 : auto &thisConstruct(state.dataConstruction->Construct(construction_index));
4694 :
4695 : // May need some additional validation of the construction here
4696 44 : if (thisConstruct.SourceSinkPresent) {
4697 : // Emulate old behavior by disallowing two sources in a single material
4698 0 : ShowSevereError(
4699 0 : state, "Construction " + construction_name + " has more than one internal heat source referencing it, which is not allowed");
4700 0 : ErrorsFound = true;
4701 0 : continue;
4702 : }
4703 :
4704 44 : thisConstruct.SourceSinkPresent = true;
4705 44 : thisConstruct.SourceAfterLayer = source_after_layer_number;
4706 44 : thisConstruct.TempAfterLayer = calculation_after_layer_number;
4707 44 : thisConstruct.SolutionDimensions = ctf_dimensions;
4708 44 : thisConstruct.ThicknessPerpend = thisConstruct.setThicknessPerpendicular(state, tube_spacing);
4709 44 : thisConstruct.userTemperatureLocationPerpendicular =
4710 44 : thisConstruct.setUserTemperatureLocationPerpendicular(state, calculation_position);
4711 :
4712 : // Set the total number of layers for the construction
4713 44 : if ((thisConstruct.SourceAfterLayer >= thisConstruct.TotLayers) || (thisConstruct.SourceAfterLayer <= 0)) {
4714 0 : ShowWarningError(state, "Construction " + thisConstruct.Name + " must have a source that is between two layers");
4715 0 : ShowContinueError(state, "The source after layer parameter has been set to one less than the number of layers.");
4716 0 : thisConstruct.SourceAfterLayer = thisConstruct.TotLayers - 1;
4717 : }
4718 44 : if ((thisConstruct.TempAfterLayer >= thisConstruct.TotLayers) || (thisConstruct.TempAfterLayer <= 0)) {
4719 0 : ShowWarningError(state, "Construction " + thisConstruct.Name + " must have a temperature calculation that is between two layers");
4720 0 : ShowContinueError(state, "The temperature calculation after layer parameter has been set to one less than the number of layers.");
4721 0 : thisConstruct.TempAfterLayer = thisConstruct.TotLayers - 1;
4722 : }
4723 : }
4724 : }
4725 :
4726 771 : state.dataHeatBal->TotConstructs = TotRegConstructs;
4727 :
4728 771 : if (state.dataHeatBal->TotConstructs > 0 && (state.dataHeatBal->NoRegularMaterialsUsed && state.dataHeatBal->NoCfactorConstructionsUsed &&
4729 0 : state.dataHeatBal->NoFfactorConstructionsUsed)) {
4730 0 : ShowWarningError(state, "This building has no thermal mass which can cause an unstable solution.");
4731 0 : ShowContinueError(state, "Use Material object for all opaque material definitions except very light insulation layers.");
4732 : }
4733 :
4734 771 : ConstrNum = 0;
4735 771 : state.dataHeatBalMgr->CurrentModuleObject = "Construction:WindowEquivalentLayer";
4736 774 : for (Loop = 1; Loop <= state.dataWindowEquivLayer->TotWinEquivLayerConstructs;
4737 : ++Loop) { // Loop through all constructs with Window EquivalentLayer ...
4738 :
4739 : // Get the object names for each construction from the input processor
4740 18 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4741 3 : state.dataHeatBalMgr->CurrentModuleObject,
4742 : Loop,
4743 : ConstructAlphas,
4744 : ConstructNumAlpha,
4745 : DummyProps,
4746 : DummyNumProp,
4747 : IOStat,
4748 3 : state.dataIPShortCut->lNumericFieldBlanks,
4749 3 : state.dataIPShortCut->lAlphaFieldBlanks,
4750 3 : state.dataIPShortCut->cAlphaFieldNames,
4751 3 : state.dataIPShortCut->cNumericFieldNames);
4752 9 : if (GlobalNames::VerifyUniqueInterObjectName(state,
4753 3 : state.dataHeatBalMgr->UniqueConstructNames,
4754 3 : ConstructAlphas(0),
4755 3 : state.dataHeatBalMgr->CurrentModuleObject,
4756 3 : state.dataIPShortCut->cAlphaFieldNames(1),
4757 : ErrorsFound)) {
4758 0 : continue;
4759 : }
4760 :
4761 3 : ++ConstrNum;
4762 : // Assign Construction name to the Derived Type using the zeroth position of the array
4763 3 : state.dataConstruction->Construct(TotRegConstructs + ConstrNum).Name = ConstructAlphas(0);
4764 :
4765 : // Set the total number of layers for the construction
4766 3 : state.dataConstruction->Construct(TotRegConstructs + ConstrNum).TotLayers = ConstructNumAlpha - 1;
4767 3 : if (state.dataConstruction->Construct(TotRegConstructs + ConstrNum).TotLayers < 1) {
4768 0 : ShowSevereError(state,
4769 0 : "Construction " + state.dataConstruction->Construct(TotRegConstructs + ConstrNum).Name +
4770 : " must have at least a single layer");
4771 0 : ErrorsFound = true;
4772 : }
4773 :
4774 : // Loop through all of the layers of the construct to match the material names.
4775 : // The loop index is the number minus 1
4776 22 : for (Layer = 1; Layer <= ConstructNumAlpha - 1; ++Layer) {
4777 :
4778 : // Find the material in the list of materials
4779 19 : state.dataConstruction->Construct(TotRegConstructs + ConstrNum).LayerPoint(Layer) =
4780 19 : UtilityRoutines::FindItemInList(ConstructAlphas(Layer), state.dataMaterial->Material);
4781 :
4782 19 : if (state.dataConstruction->Construct(TotRegConstructs + ConstrNum).LayerPoint(Layer) == 0) {
4783 0 : ShowSevereError(state,
4784 0 : "Did not find matching material for " + state.dataHeatBalMgr->CurrentModuleObject + ' ' +
4785 0 : state.dataConstruction->Construct(ConstrNum).Name + ", missing material = " + ConstructAlphas(Layer));
4786 0 : ErrorsFound = true;
4787 : } else {
4788 19 : MaterialLayerGroup =
4789 19 : state.dataMaterial->Material(state.dataConstruction->Construct(TotRegConstructs + ConstrNum).LayerPoint(Layer)).Group;
4790 27 : if (!((MaterialLayerGroup == DataHeatBalance::MaterialGroup::GlassEquivalentLayer) ||
4791 9 : (MaterialLayerGroup == DataHeatBalance::MaterialGroup::ShadeEquivalentLayer) ||
4792 9 : (MaterialLayerGroup == DataHeatBalance::MaterialGroup::DrapeEquivalentLayer) ||
4793 9 : (MaterialLayerGroup == DataHeatBalance::MaterialGroup::BlindEquivalentLayer) ||
4794 : (MaterialLayerGroup == DataHeatBalance::MaterialGroup::ScreenEquivalentLayer) ||
4795 : (MaterialLayerGroup == DataHeatBalance::MaterialGroup::GapEquivalentLayer))) {
4796 0 : ShowSevereError(state,
4797 0 : "Invalid material layer type in window " + state.dataHeatBalMgr->CurrentModuleObject + " = " +
4798 0 : state.dataConstruction->Construct(TotRegConstructs + ConstrNum).Name);
4799 0 : ShowContinueError(state,
4800 0 : "...Window layer = " + ConstructAlphas(Layer) +
4801 : " is not allowed in Construction:WindowEquivalentLayer window object.");
4802 0 : ShowContinueError(state, "Only materials of type Material:*:EquivalentLayer are allowed");
4803 0 : ErrorsFound = true;
4804 : }
4805 :
4806 19 : if (ConstructNumAlpha <= 2) {
4807 :
4808 : } else {
4809 19 : state.dataHeatBal->NominalRforNominalUCalculation(TotRegConstructs + ConstrNum) +=
4810 19 : state.dataHeatBal->NominalR(state.dataConstruction->Construct(TotRegConstructs + ConstrNum).LayerPoint(Layer));
4811 : }
4812 : }
4813 :
4814 : } // Layer loop
4815 3 : state.dataConstruction->Construct(TotRegConstructs + ConstrNum).EQLConsPtr = ConstrNum;
4816 3 : state.dataConstruction->Construct(TotRegConstructs + ConstrNum).WindowTypeEQL = true;
4817 : } // TotWinEquivLayerConstructs loop
4818 :
4819 771 : state.dataWindowEquivLayer->TotWinEquivLayerConstructs = ConstrNum;
4820 771 : TotRegConstructs += state.dataWindowEquivLayer->TotWinEquivLayerConstructs;
4821 771 : state.dataHeatBal->TotConstructs = TotRegConstructs;
4822 : //-------------------------------------------------------------------------------
4823 771 : ConstrNum = 0;
4824 :
4825 771 : state.dataHeatBalMgr->CurrentModuleObject = "Construction:WindowDataFile";
4826 776 : for (Loop = 1; Loop <= TotWindow5Constructs; ++Loop) { // Loop through all Window5 constructions. These constructions come
4827 : // from the Window5 data file and can be referenced only by windows
4828 :
4829 : // Get the object names for each construction from the input processor
4830 30 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4831 5 : state.dataHeatBalMgr->CurrentModuleObject,
4832 : Loop,
4833 : ConstructAlphas,
4834 : ConstructNumAlpha,
4835 : DummyProps,
4836 : DummyNumProp,
4837 : IOStat,
4838 5 : state.dataIPShortCut->lNumericFieldBlanks,
4839 5 : state.dataIPShortCut->lAlphaFieldBlanks,
4840 5 : state.dataIPShortCut->cAlphaFieldNames,
4841 5 : state.dataIPShortCut->cNumericFieldNames);
4842 5 : if (UtilityRoutines::IsNameEmpty(state, ConstructAlphas(0), state.dataHeatBalMgr->CurrentModuleObject, ErrorsFound)) continue;
4843 :
4844 5 : ++ConstrNum;
4845 5 : WConstructNames(ConstrNum) = ConstructAlphas(0);
4846 :
4847 : // Obtain the data
4848 5 : if (DummyNumProp != 0) {
4849 0 : ShowSevereError(state, "Construction From Window5 Data File: there should be no numerical inputs for " + ConstructAlphas(0));
4850 0 : ErrorsFound = true;
4851 0 : continue;
4852 : }
4853 :
4854 : // See if this construction is in the W5DataFile produced by the WINDOW 5 program;
4855 : // if so, ConstructionFound will be set to true and the Material objects
4856 : // associated with the construction will be created in subr. SearchWindow5DataFile.
4857 : // (If the matching construction on the Window5 data file has two glazing systems, a
4858 : // second construction and its associated materials will be created in subr.
4859 : // SearchWindow5DataFile and TotConstructs WILL BE INCREMENTED BY 1 in that routine.
4860 : // A FrameAndDivider object will also be created if window on data file has a
4861 : // frame or divider.)
4862 :
4863 10 : fs::path window5DataFilePath;
4864 5 : if (ConstructAlphas(1) == "") {
4865 0 : window5DataFilePath = state.dataStrGlobals->CurrentWorkingFolder / "Window5DataFile.dat";
4866 : } else {
4867 5 : window5DataFilePath = ConstructAlphas(1);
4868 : }
4869 5 : DisplayString(state, "Searching Window5 data file for Construction=" + ConstructAlphas(0));
4870 :
4871 5 : SearchWindow5DataFile(state, window5DataFilePath, ConstructAlphas(0), ConstructionFound, EOFonW5File, ErrorsFound);
4872 :
4873 5 : if (EOFonW5File || !ConstructionFound) {
4874 0 : DisplayString(state, "--Construction not found");
4875 0 : ErrorsFound = true;
4876 0 : ShowSevereError(state, "No match on WINDOW5 data file for Construction=" + ConstructAlphas(0) + ", or error in data file.");
4877 0 : ShowContinueError(state, "...Looking on file=" + window5DataFilePath.string()); // TODO: call getAbsolutePath maybe?
4878 0 : continue;
4879 : }
4880 :
4881 : } // ...end of Window5 Constructions DO loop
4882 :
4883 771 : WConstructNames.deallocate();
4884 :
4885 : // set some (default) properties of the Construction Derived Type
4886 6597 : for (ConstrNum = 1; ConstrNum <= state.dataHeatBal->TotConstructs; ++ConstrNum) {
4887 :
4888 : // For air boundaries, skip TypeIsAirBoundary
4889 5826 : if (state.dataConstruction->Construct(ConstrNum).TypeIsAirBoundary) continue;
4890 5823 : if (state.dataHeatBal->NominalRforNominalUCalculation(ConstrNum) != 0.0) {
4891 5823 : state.dataHeatBal->NominalU(ConstrNum) = 1.0 / state.dataHeatBal->NominalRforNominalUCalculation(ConstrNum);
4892 : } else {
4893 0 : if (!state.dataConstruction->Construct(ConstrNum).WindowTypeEQL) {
4894 0 : ShowSevereError(state, "Nominal U is zero, for construction=" + state.dataConstruction->Construct(ConstrNum).Name);
4895 0 : ErrorsFound = true;
4896 : }
4897 : }
4898 :
4899 5823 : CheckAndSetConstructionProperties(state, ConstrNum, ErrorsFound);
4900 :
4901 : } // End of ConstrNum DO loop
4902 : }
4903 :
4904 771 : void GetBuildingData(EnergyPlusData &state, bool &ErrorsFound) // If errors found in input
4905 : {
4906 :
4907 : // SUBROUTINE INFORMATION:
4908 : // AUTHOR Linda K. Lawrie
4909 : // DATE WRITTEN November 1997
4910 : // MODIFIED October 1998, FW; May 1999 FW; Oct 2004 LKL
4911 : // RE-ENGINEERED na
4912 :
4913 : // PURPOSE OF THIS SUBROUTINE:
4914 : // This routine calls other routines to get the Zone, and Surface data
4915 : // from the input file.
4916 :
4917 : // METHODOLOGY EMPLOYED:
4918 : // The GetObjectItem routines are employed to retrieve the data.
4919 :
4920 771 : GetZoneData(state, ErrorsFound); // Read Zone data from input file
4921 :
4922 771 : SurfaceGeometry::SetupZoneGeometry(state, ErrorsFound);
4923 771 : }
4924 :
4925 771 : void GetZoneData(EnergyPlusData &state, bool &ErrorsFound) // If errors found in input
4926 : {
4927 :
4928 : // SUBROUTINE INFORMATION:
4929 : // AUTHOR Linda K. Lawrie
4930 : // DATE WRITTEN November 1997
4931 : // MODIFIED PGE: Added ZONE LIST and ZONE GROUP objects, Nov 2003
4932 : // RJH: Added init of DElight member of ZoneDaylight object, Jan 2004
4933 : // JG: Added Part of Total Floor Area field March 2006
4934 : // RE-ENGINEERED na
4935 :
4936 : // PURPOSE OF THIS SUBROUTINE:
4937 : // This subroutine gets the zone data for each zone in the input file.
4938 :
4939 : // METHODOLOGY EMPLOYED:
4940 : // The GetObjectItem routines are employed to retrieve the data.
4941 :
4942 : // REFERENCES:
4943 : // IDD Definition for Zone object
4944 :
4945 : // Using/Aliasing
4946 : // Locals
4947 : // SUBROUTINE ARGUMENT DEFINITIONS:
4948 :
4949 : // SUBROUTINE PARAMETER DEFINITIONS:
4950 771 : constexpr const char *RoutineName("GetZoneData: ");
4951 : // INTEGER, PARAMETER :: MaxZonesInList = 100 ! This is to allow DIMENSIONing below
4952 :
4953 : // INTERFACE BLOCK SPECIFICATIONS:
4954 : // na
4955 :
4956 : // DERIVED TYPE DEFINITIONS:
4957 : // na
4958 :
4959 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4960 : int NumAlphas;
4961 : int NumNumbers;
4962 : int IOStatus;
4963 : int ZoneLoop;
4964 : std::string::size_type TMP;
4965 : int Loop;
4966 : int ListNum;
4967 : int ZoneNum;
4968 1542 : std::string ZoneName;
4969 : int GroupNum;
4970 771 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
4971 771 : cCurrentModuleObject = "Zone";
4972 771 : state.dataGlobal->NumOfZones = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
4973 :
4974 771 : state.dataHeatBal->Zone.allocate(state.dataGlobal->NumOfZones);
4975 771 : state.dataDaylightingData->ZoneDaylight.allocate(state.dataGlobal->NumOfZones);
4976 : // always allocate as the data structure is needed in output variable Zone Heat Index, Zone Humidity Index
4977 771 : state.dataHeatBal->Resilience.allocate(state.dataGlobal->NumOfZones);
4978 :
4979 771 : ZoneLoop = 0;
4980 :
4981 5585 : for (Loop = 1; Loop <= state.dataGlobal->NumOfZones; ++Loop) {
4982 :
4983 4814 : state.dataIPShortCut->rNumericArgs = 0.0; // Zero out just in case
4984 33698 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4985 : cCurrentModuleObject,
4986 : Loop,
4987 4814 : state.dataIPShortCut->cAlphaArgs,
4988 : NumAlphas,
4989 4814 : state.dataIPShortCut->rNumericArgs,
4990 : NumNumbers,
4991 : IOStatus,
4992 4814 : state.dataIPShortCut->lNumericFieldBlanks,
4993 4814 : state.dataIPShortCut->lAlphaFieldBlanks,
4994 4814 : state.dataIPShortCut->cAlphaFieldNames,
4995 4814 : state.dataIPShortCut->cNumericFieldNames);
4996 4814 : TMP = index(state.dataIPShortCut->cAlphaArgs(1), char(1));
4997 4814 : while (TMP != std::string::npos) {
4998 0 : state.dataIPShortCut->cAlphaArgs(1)[TMP] = ',';
4999 0 : TMP = index(state.dataIPShortCut->cAlphaArgs(1), char(1));
5000 : }
5001 4814 : TMP = index(state.dataIPShortCut->cAlphaArgs(1), char(2));
5002 4814 : while (TMP != std::string::npos) {
5003 0 : state.dataIPShortCut->cAlphaArgs(1)[TMP] = '!';
5004 0 : TMP = index(state.dataIPShortCut->cAlphaArgs(1), char(2));
5005 : }
5006 :
5007 4814 : if (UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), state.dataHeatBalMgr->CurrentModuleObject, ErrorsFound))
5008 0 : continue;
5009 :
5010 4814 : ++ZoneLoop;
5011 28884 : ProcessZoneData(state,
5012 : cCurrentModuleObject,
5013 : ZoneLoop,
5014 4814 : state.dataIPShortCut->cAlphaArgs,
5015 : NumAlphas,
5016 4814 : state.dataIPShortCut->rNumericArgs,
5017 : NumNumbers,
5018 4814 : state.dataIPShortCut->lNumericFieldBlanks,
5019 4814 : state.dataIPShortCut->lAlphaFieldBlanks,
5020 4814 : state.dataIPShortCut->cAlphaFieldNames,
5021 4814 : state.dataIPShortCut->cNumericFieldNames,
5022 : ErrorsFound);
5023 :
5024 : } // Loop
5025 :
5026 5585 : for (Loop = 1; Loop <= state.dataGlobal->NumOfZones; ++Loop) {
5027 : // Check to see if "nominally" controlled -- Zone Name appears in Zone Equip Configuration
5028 : // relies on zone name being the "name" of the Zone Controlled Equip Configuration
5029 14442 : if (state.dataInputProcessing->inputProcessor->getObjectItemNum(
5030 9628 : state, "ZoneHVAC:EquipmentConnections", "zone_name", state.dataHeatBal->Zone(Loop).Name) > 0) {
5031 4104 : state.dataHeatBal->Zone(Loop).isNominalControlled = true;
5032 : } else {
5033 710 : state.dataHeatBal->Zone(Loop).isNominalControlled = false;
5034 : }
5035 : }
5036 :
5037 : // Get ZONE LIST objects
5038 771 : cCurrentModuleObject = "ZoneList";
5039 771 : state.dataHeatBal->NumOfZoneLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
5040 :
5041 771 : if (state.dataHeatBal->NumOfZoneLists > 0) {
5042 :
5043 26 : state.dataHeatBal->ZoneList.allocate(state.dataHeatBal->NumOfZoneLists);
5044 :
5045 63 : for (ListNum = 1; ListNum <= state.dataHeatBal->NumOfZoneLists; ++ListNum) {
5046 259 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5047 : cCurrentModuleObject,
5048 : ListNum,
5049 37 : state.dataIPShortCut->cAlphaArgs,
5050 : NumAlphas,
5051 37 : state.dataIPShortCut->rNumericArgs,
5052 : NumNumbers,
5053 : IOStatus,
5054 37 : state.dataIPShortCut->lNumericFieldBlanks,
5055 37 : state.dataIPShortCut->lAlphaFieldBlanks,
5056 37 : state.dataIPShortCut->cAlphaFieldNames,
5057 37 : state.dataIPShortCut->cNumericFieldNames);
5058 37 : UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
5059 :
5060 37 : state.dataHeatBal->ZoneList(ListNum).Name = state.dataIPShortCut->cAlphaArgs(1);
5061 37 : if (UtilityRoutines::FindItemInList(state.dataHeatBal->ZoneList(ListNum).Name, state.dataHeatBal->Zone) > 0) {
5062 0 : ShowWarningError(state,
5063 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
5064 : "\": is a duplicate of a zone name.");
5065 0 : ShowContinueError(state, "This could be a problem in places where either a Zone Name or a Zone List can be used.");
5066 : }
5067 :
5068 : // List of zones
5069 37 : state.dataHeatBal->ZoneList(ListNum).NumOfZones = NumAlphas - 1;
5070 :
5071 37 : if (state.dataHeatBal->ZoneList(ListNum).NumOfZones < 1) {
5072 0 : ShowSevereError(state,
5073 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
5074 : "\": No zones specified.");
5075 0 : ErrorsFound = true;
5076 : } else {
5077 37 : state.dataHeatBal->ZoneList(ListNum).Zone.allocate(state.dataHeatBal->ZoneList(ListNum).NumOfZones);
5078 37 : state.dataHeatBal->ZoneList(ListNum).Zone = 0;
5079 :
5080 184 : for (ZoneNum = 1; ZoneNum <= state.dataHeatBal->ZoneList(ListNum).NumOfZones; ++ZoneNum) {
5081 147 : ZoneName = state.dataIPShortCut->cAlphaArgs(ZoneNum + 1);
5082 147 : state.dataHeatBal->ZoneList(ListNum).MaxZoneNameLength =
5083 147 : max(state.dataHeatBal->ZoneList(ListNum).MaxZoneNameLength, len(ZoneName));
5084 147 : state.dataHeatBal->ZoneList(ListNum).Zone(ZoneNum) = UtilityRoutines::FindItemInList(ZoneName, state.dataHeatBal->Zone);
5085 147 : if (state.dataHeatBal->ZoneList(ListNum).Zone(ZoneNum) == 0) {
5086 0 : ShowSevereError(state,
5087 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
5088 0 : "\": " + state.dataIPShortCut->cAlphaFieldNames(ZoneNum + 1) + ' ' + ZoneName + " not found.");
5089 0 : ErrorsFound = true;
5090 : }
5091 :
5092 : // Check for duplicate zones
5093 421 : for (Loop = 1; Loop <= ZoneNum - 1; ++Loop) {
5094 274 : if (state.dataHeatBal->ZoneList(ListNum).Zone(ZoneNum) == state.dataHeatBal->ZoneList(ListNum).Zone(Loop)) {
5095 0 : ShowSevereError(state,
5096 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
5097 0 : "\": " + state.dataIPShortCut->cAlphaFieldNames(ZoneNum + 1) + ' ' + ZoneName +
5098 : " appears more than once in list.");
5099 0 : ErrorsFound = true;
5100 : }
5101 : } // Loop
5102 : } // ZoneNum
5103 : }
5104 :
5105 : } // ListNum
5106 : }
5107 :
5108 : // Get ZONE GROUP objects
5109 771 : cCurrentModuleObject = "ZoneGroup";
5110 771 : state.dataHeatBal->NumOfZoneGroups = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
5111 :
5112 771 : if (state.dataHeatBal->NumOfZoneGroups > 0) {
5113 2 : state.dataHeatBal->ZoneGroup.allocate(state.dataHeatBal->NumOfZoneGroups);
5114 :
5115 6 : for (GroupNum = 1; GroupNum <= state.dataHeatBal->NumOfZoneGroups; ++GroupNum) {
5116 28 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5117 : cCurrentModuleObject,
5118 : GroupNum,
5119 4 : state.dataIPShortCut->cAlphaArgs,
5120 : NumAlphas,
5121 4 : state.dataIPShortCut->rNumericArgs,
5122 : NumNumbers,
5123 : IOStatus,
5124 4 : state.dataIPShortCut->lNumericFieldBlanks,
5125 4 : state.dataIPShortCut->lAlphaFieldBlanks,
5126 4 : state.dataIPShortCut->cAlphaFieldNames,
5127 4 : state.dataIPShortCut->cNumericFieldNames);
5128 4 : UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
5129 :
5130 4 : state.dataHeatBal->ZoneGroup(GroupNum).Name = state.dataIPShortCut->cAlphaArgs(1);
5131 :
5132 : // Multiplier - checked already by IDD rules
5133 4 : state.dataHeatBal->ZoneGroup(GroupNum).Multiplier = state.dataIPShortCut->rNumericArgs(1);
5134 :
5135 : // Zone list
5136 4 : ListNum = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(2), state.dataHeatBal->ZoneList);
5137 4 : state.dataHeatBal->ZoneGroup(GroupNum).ZoneList = ListNum;
5138 :
5139 4 : if (ListNum == 0) {
5140 0 : ShowSevereError(state,
5141 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\": " +
5142 0 : state.dataIPShortCut->cAlphaFieldNames(2) + " named " + state.dataIPShortCut->cAlphaArgs(2) + " not found.");
5143 0 : ErrorsFound = true;
5144 : } else {
5145 : // Check to make sure list is not in use by another ZONE GROUP
5146 7 : for (Loop = 1; Loop <= GroupNum - 1; ++Loop) {
5147 3 : if (state.dataHeatBal->ZoneGroup(GroupNum).ZoneList == state.dataHeatBal->ZoneGroup(Loop).ZoneList) {
5148 0 : ShowSevereError(state,
5149 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
5150 0 : "\": " + state.dataIPShortCut->cAlphaFieldNames(2) + " already used by " + cCurrentModuleObject +
5151 0 : " named " + state.dataHeatBal->ZoneGroup(Loop).Name + '.');
5152 0 : ErrorsFound = true;
5153 : }
5154 : } // Loop
5155 :
5156 : // Set group multiplier for each zone in the list
5157 22 : for (Loop = 1; Loop <= state.dataHeatBal->ZoneList(ListNum).NumOfZones; ++Loop) {
5158 18 : ZoneNum = state.dataHeatBal->ZoneList(ListNum).Zone(Loop);
5159 :
5160 18 : if (ZoneNum > 0) {
5161 : // Check to make sure group multiplier was not already set by another ZONE GROUP
5162 18 : if (state.dataHeatBal->Zone(ZoneNum).ListGroup == 0) {
5163 18 : state.dataHeatBal->Zone(ZoneNum).ListMultiplier = state.dataHeatBal->ZoneGroup(GroupNum).Multiplier;
5164 18 : state.dataHeatBal->Zone(ZoneNum).ListGroup = ListNum;
5165 : } else {
5166 0 : ShowSevereError(state,
5167 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
5168 0 : "\": Zone " + state.dataHeatBal->Zone(ZoneNum).Name +
5169 : " in ZoneList already exists in ZoneList of another ZoneGroup.");
5170 0 : ShowContinueError(
5171 0 : state, "Previous ZoneList=" + state.dataHeatBal->ZoneList(state.dataHeatBal->Zone(ZoneNum).ListGroup).Name);
5172 0 : ErrorsFound = true;
5173 : }
5174 : }
5175 : } // Loop
5176 : }
5177 :
5178 : } // GroupNum
5179 : }
5180 :
5181 771 : GetZoneLocalEnvData(state, ErrorsFound);
5182 :
5183 : // allocate the array the holds the predefined report data
5184 771 : state.dataHeatBal->ZonePreDefRep.allocate(state.dataGlobal->NumOfZones);
5185 :
5186 : // Now get Space data after Zones are set up, because Space is optional, Zones are not
5187 771 : GetSpaceData(state, ErrorsFound);
5188 771 : }
5189 :
5190 771 : void GetIncidentSolarMultiplier(EnergyPlusData &state, bool &ErrorsFound)
5191 : {
5192 771 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
5193 771 : cCurrentModuleObject = "SurfaceProperty:IncidentSolarMultiplier";
5194 :
5195 : static constexpr std::string_view RoutineName("GetIncidentSolarMultiplier: ");
5196 :
5197 771 : state.dataSurface->TotSurfIncSolMultiplier = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
5198 :
5199 771 : if (state.dataSurface->TotSurfIncSolMultiplier <= 0) return;
5200 :
5201 1 : if (!allocated(state.dataSurface->SurfIncSolMultiplier)) {
5202 : // could be extended to interior surfaces later
5203 1 : state.dataSurface->SurfIncSolMultiplier.allocate(state.dataSurface->TotSurfaces);
5204 : }
5205 :
5206 : int NumAlpha;
5207 : int NumNumeric;
5208 : int IOStat;
5209 5 : for (int Loop = 1; Loop <= state.dataSurface->TotSurfIncSolMultiplier; ++Loop) {
5210 28 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5211 : cCurrentModuleObject,
5212 : Loop,
5213 4 : state.dataIPShortCut->cAlphaArgs,
5214 : NumAlpha,
5215 4 : state.dataIPShortCut->rNumericArgs,
5216 : NumNumeric,
5217 : IOStat,
5218 4 : state.dataIPShortCut->lNumericFieldBlanks,
5219 4 : state.dataIPShortCut->lAlphaFieldBlanks,
5220 4 : state.dataIPShortCut->cAlphaFieldNames,
5221 4 : state.dataIPShortCut->cNumericFieldNames);
5222 4 : if (UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound)) {
5223 0 : ShowContinueError(
5224 : state,
5225 : "...each SurfaceProperty:IncidentSolarMultiplier name must not duplicate other SurfaceProperty:IncidentSolarMultiplier name");
5226 0 : continue;
5227 : }
5228 :
5229 : // Assign surface number
5230 4 : int SurfNum = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(1), state.dataSurface->Surface);
5231 4 : if (SurfNum == 0) {
5232 0 : ShowSevereError(state,
5233 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
5234 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(1) + " has been found.");
5235 0 : ShowContinueError(state,
5236 0 : state.dataIPShortCut->cAlphaFieldNames(1) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(1) +
5237 : "\" no corresponding surface (ref BuildingSurface:Detailed) has been found in the input file.");
5238 0 : ErrorsFound = true;
5239 0 : continue;
5240 : }
5241 4 : auto &Surf = state.dataSurface->Surface(SurfNum);
5242 4 : if (Surf.Class != DataSurfaces::SurfaceClass::Window) {
5243 0 : ShowSevereError(state, "IncidentSolarMultiplier defined for non-window surfaces");
5244 0 : ErrorsFound = true;
5245 0 : continue;
5246 : }
5247 4 : if (Surf.ExtBoundCond != DataSurfaces::ExternalEnvironment) {
5248 0 : ShowSevereError(state, "IncidentSolarMultiplier defined for interior surfaces");
5249 0 : ErrorsFound = true;
5250 0 : continue;
5251 : }
5252 4 : int ConstrNum = Surf.Construction;
5253 4 : auto const &Constr = state.dataConstruction->Construct(ConstrNum);
5254 4 : int MaterNum = Constr.LayerPoint(Constr.TotLayers);
5255 4 : auto const &Mat = state.dataMaterial->Material(MaterNum);
5256 4 : bool withNoncompatibleShades =
5257 12 : (Mat.Group == DataHeatBalance::MaterialGroup::Shade || Mat.Group == DataHeatBalance::MaterialGroup::WindowBlind ||
5258 12 : Mat.Group == DataHeatBalance::MaterialGroup::Screen || Mat.Group == DataHeatBalance::MaterialGroup::GlassEquivalentLayer ||
5259 8 : Mat.Group == DataHeatBalance::MaterialGroup::GapEquivalentLayer ||
5260 8 : Mat.Group == DataHeatBalance::MaterialGroup::ShadeEquivalentLayer ||
5261 8 : Mat.Group == DataHeatBalance::MaterialGroup::DrapeEquivalentLayer ||
5262 8 : Mat.Group == DataHeatBalance::MaterialGroup::ScreenEquivalentLayer ||
5263 12 : Mat.Group == DataHeatBalance::MaterialGroup::BlindEquivalentLayer || Surf.HasShadeControl);
5264 4 : if (withNoncompatibleShades) {
5265 0 : ShowSevereError(state, "Non-compatible shades defined alongside SurfaceProperty:IncidentSolarMultiplier for the same window");
5266 0 : ErrorsFound = true;
5267 0 : continue;
5268 : }
5269 4 : int ScheduleIdx = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
5270 : // Schedule not found but schedule field is not empty, user had the wrong schedule name
5271 4 : if (ScheduleIdx == 0 && !(state.dataIPShortCut->cAlphaArgs(2).empty())) {
5272 0 : ShowSevereError(state, "Invalid Incident Solar Multiplier Schedule Name in SurfaceProperty:IncidentSolarMultiplier");
5273 0 : continue;
5274 : }
5275 4 : Surf.hasIncSolMultiplier = true;
5276 4 : auto &SurfIncSolMult = state.dataSurface->SurfIncSolMultiplier(SurfNum);
5277 4 : SurfIncSolMult.Name = state.dataIPShortCut->cAlphaArgs(1);
5278 4 : SurfIncSolMult.SurfaceIdx = SurfNum;
5279 4 : SurfIncSolMult.Scaler = state.dataIPShortCut->rNumericArgs(1);
5280 4 : SurfIncSolMult.SchedPtr = ScheduleIdx;
5281 : }
5282 : }
5283 :
5284 771 : void GetZoneLocalEnvData(EnergyPlusData &state, bool &ErrorsFound) // Error flag indicator (true if errors found)
5285 : {
5286 : // SUBROUTINE INFORMATION:
5287 : // AUTHOR X LUO
5288 : // DATE WRITTEN July 2017
5289 : // MODIFIED na
5290 : // RE-ENGINEERED na
5291 :
5292 : // PURPOSE OF THIS SUBROUTINE:
5293 : // load input data for Outdoor Air Node for zones
5294 :
5295 : // Using/Aliasing
5296 : using DataLoopNode::ObjectIsParent;
5297 : using NodeInputManager::GetOnlySingleNode;
5298 : using OutAirNodeManager::CheckOutAirNodeNumber;
5299 :
5300 : // SUBROUTINE PARAMETER DEFINITIONS:
5301 771 : constexpr const char *RoutineName("GetZoneLocalEnvData: ");
5302 :
5303 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5304 : int NumAlpha;
5305 : int NumNumeric;
5306 :
5307 : int Loop;
5308 : int ZoneLoop;
5309 : int ZoneNum; // DO loop counter for zones
5310 : int TotZoneEnv;
5311 : int IOStat;
5312 : int NodeNum;
5313 :
5314 : //-----------------------------------------------------------------------
5315 : // ZoneProperty:LocalEnvironment
5316 : //-----------------------------------------------------------------------
5317 771 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
5318 771 : cCurrentModuleObject = "ZoneProperty:LocalEnvironment";
5319 771 : TotZoneEnv = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
5320 :
5321 771 : if (TotZoneEnv > 0) {
5322 : // Check if IDD definition is correct
5323 1 : state.dataGlobal->AnyLocalEnvironmentsInModel = true;
5324 :
5325 1 : if (!allocated(state.dataHeatBal->ZoneLocalEnvironment)) {
5326 1 : state.dataHeatBal->ZoneLocalEnvironment.allocate(TotZoneEnv);
5327 : }
5328 :
5329 2 : for (Loop = 1; Loop <= TotZoneEnv; ++Loop) {
5330 7 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
5331 : cCurrentModuleObject,
5332 : Loop,
5333 1 : state.dataIPShortCut->cAlphaArgs,
5334 : NumAlpha,
5335 1 : state.dataIPShortCut->rNumericArgs,
5336 : NumNumeric,
5337 : IOStat,
5338 1 : state.dataIPShortCut->lNumericFieldBlanks,
5339 1 : state.dataIPShortCut->lAlphaFieldBlanks,
5340 1 : state.dataIPShortCut->cAlphaFieldNames,
5341 1 : state.dataIPShortCut->cNumericFieldNames);
5342 1 : UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
5343 :
5344 1 : state.dataHeatBal->ZoneLocalEnvironment(Loop).Name = state.dataIPShortCut->cAlphaArgs(1);
5345 :
5346 : // Assign zone number
5347 1 : ZoneNum = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(2), state.dataHeatBal->Zone);
5348 1 : if (ZoneNum == 0) {
5349 0 : ShowSevereError(state,
5350 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
5351 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(2) + " has been found.");
5352 0 : ShowContinueError(state,
5353 0 : state.dataIPShortCut->cAlphaFieldNames(2) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(2) +
5354 : "\" no corresponding zone has been found in the input file.");
5355 0 : ErrorsFound = true;
5356 : } else {
5357 1 : state.dataHeatBal->ZoneLocalEnvironment(Loop).ZonePtr = ZoneNum;
5358 : }
5359 :
5360 : // Assign outdoor air node number;
5361 1 : NodeNum = GetOnlySingleNode(state,
5362 1 : state.dataIPShortCut->cAlphaArgs(3),
5363 : ErrorsFound,
5364 : DataLoopNode::ConnectionObjectType::ZonePropertyLocalEnvironment,
5365 1 : state.dataIPShortCut->cAlphaArgs(1),
5366 : DataLoopNode::NodeFluidType::Air,
5367 : DataLoopNode::ConnectionType::Inlet,
5368 : NodeInputManager::CompFluidStream::Primary,
5369 1 : ObjectIsParent);
5370 1 : if (NodeNum == 0 && CheckOutAirNodeNumber(state, NodeNum)) {
5371 0 : ShowSevereError(state,
5372 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
5373 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(3) + " has been found.");
5374 0 : ShowContinueError(state,
5375 0 : state.dataIPShortCut->cAlphaFieldNames(3) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(3) +
5376 : "\" no corresponding schedule has been found in the input file.");
5377 0 : ErrorsFound = true;
5378 : } else {
5379 1 : state.dataHeatBal->ZoneLocalEnvironment(Loop).OutdoorAirNodePtr = NodeNum;
5380 : }
5381 : }
5382 : }
5383 : // Link zone properties to zone object
5384 5585 : for (ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) {
5385 4819 : for (Loop = 1; Loop <= TotZoneEnv; ++Loop) {
5386 5 : if (state.dataHeatBal->ZoneLocalEnvironment(Loop).ZonePtr == ZoneLoop) {
5387 1 : if (state.dataHeatBal->ZoneLocalEnvironment(Loop).OutdoorAirNodePtr != 0) {
5388 1 : state.dataHeatBal->Zone(ZoneLoop).LinkedOutAirNode = state.dataHeatBal->ZoneLocalEnvironment(Loop).OutdoorAirNodePtr;
5389 : }
5390 : }
5391 : }
5392 : }
5393 771 : }
5394 :
5395 4814 : void ProcessZoneData(EnergyPlusData &state,
5396 : std::string const &cCurrentModuleObject,
5397 : int const ZoneLoop,
5398 : Array1D_string const &cAlphaArgs,
5399 : int &NumAlphas,
5400 : Array1D<Real64> const &rNumericArgs,
5401 : int &NumNumbers,
5402 : [[maybe_unused]] Array1D_bool const &lNumericFieldBlanks, // Unused
5403 : Array1D_bool const &lAlphaFieldBlanks,
5404 : Array1D_string const &cAlphaFieldNames,
5405 : [[maybe_unused]] Array1D_string const &cNumericFieldNames, // Unused
5406 : bool &ErrorsFound // If errors found in input
5407 : )
5408 : {
5409 :
5410 : // SUBROUTINE INFORMATION:
5411 : // AUTHOR Linda K. Lawrie
5412 : // DATE WRITTEN November 1997
5413 : // MODIFIED PGE: Added ZONE LIST and ZONE GROUP objects, Nov 2003
5414 : // RJH: Added init of DElight member of ZoneDaylight object, Jan 2004
5415 : // JG: Added Part of Total Floor Area field March 2006
5416 : // RE-ENGINEERED MJW: Split out processing zone input to facilitate unit testing, Nov 2014
5417 :
5418 : // PURPOSE OF THIS SUBROUTINE:
5419 : // This subroutine gets the zone data for each zone in the input file.
5420 :
5421 4814 : constexpr const char *RoutineName("ProcessZoneData: ");
5422 :
5423 4814 : state.dataHeatBal->Zone(ZoneLoop).Name = cAlphaArgs(1);
5424 4814 : if (NumNumbers >= 1) state.dataHeatBal->Zone(ZoneLoop).RelNorth = rNumericArgs(1);
5425 4814 : if (NumNumbers >= 2) state.dataHeatBal->Zone(ZoneLoop).OriginX = rNumericArgs(2);
5426 4814 : if (NumNumbers >= 3) state.dataHeatBal->Zone(ZoneLoop).OriginY = rNumericArgs(3);
5427 4814 : if (NumNumbers >= 4) state.dataHeatBal->Zone(ZoneLoop).OriginZ = rNumericArgs(4);
5428 4814 : if (NumNumbers >= 5) state.dataHeatBal->Zone(ZoneLoop).OfType = rNumericArgs(5);
5429 4814 : state.dataHeatBal->Zone(ZoneLoop).OfType = StandardZone;
5430 4814 : if (NumNumbers >= 6) state.dataHeatBal->Zone(ZoneLoop).Multiplier = rNumericArgs(6);
5431 4814 : if (NumNumbers >= 7) state.dataHeatBal->Zone(ZoneLoop).CeilingHeight = rNumericArgs(7);
5432 4814 : if (NumNumbers >= 8) state.dataHeatBal->Zone(ZoneLoop).Volume = rNumericArgs(8);
5433 4814 : if (NumNumbers >= 9) state.dataHeatBal->Zone(ZoneLoop).UserEnteredFloorArea = rNumericArgs(9);
5434 :
5435 4814 : if (NumAlphas > 1 && !state.dataIPShortCut->lAlphaFieldBlanks(2)) {
5436 : {
5437 190 : auto const SELECT_CASE_var(cAlphaArgs(2));
5438 :
5439 95 : if (SELECT_CASE_var == "SIMPLE") {
5440 9 : state.dataHeatBal->Zone(ZoneLoop).InsideConvectionAlgo = ConvectionConstants::HcInt_ASHRAESimple;
5441 :
5442 86 : } else if ((SELECT_CASE_var == "TARP")) {
5443 84 : state.dataHeatBal->Zone(ZoneLoop).InsideConvectionAlgo = ConvectionConstants::HcInt_ASHRAETARP;
5444 :
5445 2 : } else if (SELECT_CASE_var == "CEILINGDIFFUSER") {
5446 0 : state.dataHeatBal->Zone(ZoneLoop).InsideConvectionAlgo = ConvectionConstants::HcInt_CeilingDiffuser;
5447 :
5448 2 : } else if (SELECT_CASE_var == "TROMBEWALL") {
5449 1 : state.dataHeatBal->Zone(ZoneLoop).InsideConvectionAlgo = ConvectionConstants::HcInt_TrombeWall;
5450 :
5451 1 : } else if (SELECT_CASE_var == "ADAPTIVECONVECTIONALGORITHM") {
5452 0 : state.dataHeatBal->Zone(ZoneLoop).InsideConvectionAlgo = ConvectionConstants::HcInt_AdaptiveConvectionAlgorithm;
5453 :
5454 1 : } else if (SELECT_CASE_var == "ASTMC1340") {
5455 1 : state.dataHeatBal->Zone(ZoneLoop).InsideConvectionAlgo = ConvectionConstants::HcInt_ASTMC1340;
5456 :
5457 : } else {
5458 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataHeatBal->Zone(ZoneLoop).Name + "\".");
5459 0 : ShowContinueError(state, "Invalid value for " + cAlphaFieldNames(2) + "=\"" + cAlphaArgs(2) + "\".");
5460 0 : ErrorsFound = true;
5461 : }
5462 : }
5463 : } else {
5464 : // No zone specific algorithm specified, use default Inside Convection Algorithm
5465 4719 : state.dataHeatBal->Zone(ZoneLoop).InsideConvectionAlgo = state.dataHeatBal->DefaultInsideConvectionAlgo;
5466 : }
5467 :
5468 4814 : if (NumAlphas > 2 && !state.dataIPShortCut->lAlphaFieldBlanks(3)) {
5469 : {
5470 30 : auto const SELECT_CASE_var(cAlphaArgs(3));
5471 :
5472 15 : if ((SELECT_CASE_var == "SIMPLECOMBINED")) {
5473 9 : state.dataHeatBal->Zone(ZoneLoop).OutsideConvectionAlgo = ConvectionConstants::HcExt_ASHRAESimple;
5474 :
5475 6 : } else if ((SELECT_CASE_var == "TARP")) {
5476 2 : state.dataHeatBal->Zone(ZoneLoop).OutsideConvectionAlgo = ConvectionConstants::HcExt_ASHRAETARP;
5477 :
5478 4 : } else if (SELECT_CASE_var == "MOWITT") {
5479 0 : state.dataHeatBal->Zone(ZoneLoop).OutsideConvectionAlgo = ConvectionConstants::HcExt_MoWiTTHcOutside;
5480 :
5481 4 : } else if (SELECT_CASE_var == "DOE-2") {
5482 2 : state.dataHeatBal->Zone(ZoneLoop).OutsideConvectionAlgo = ConvectionConstants::HcExt_DOE2HcOutside;
5483 :
5484 2 : } else if (SELECT_CASE_var == "ADAPTIVECONVECTIONALGORITHM") {
5485 2 : state.dataHeatBal->Zone(ZoneLoop).OutsideConvectionAlgo = ConvectionConstants::HcExt_AdaptiveConvectionAlgorithm;
5486 :
5487 : } else {
5488 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataHeatBal->Zone(ZoneLoop).Name + "\".");
5489 0 : ShowContinueError(state, "Invalid value for " + cAlphaFieldNames(3) + "=\"" + cAlphaArgs(3) + "\".");
5490 0 : ErrorsFound = true;
5491 : }
5492 : }
5493 : } else {
5494 : // No zone specific algorithm specified, use default Outside Convection Algorithm
5495 4799 : state.dataHeatBal->Zone(ZoneLoop).OutsideConvectionAlgo = state.dataHeatBal->DefaultOutsideConvectionAlgo;
5496 : }
5497 :
5498 : // Process the input field: Part of Total Floor Area
5499 : // The default value is YES and so only NO needs to be handled
5500 4814 : if (NumAlphas > 3) {
5501 2180 : if (UtilityRoutines::SameString("No", cAlphaArgs(4))) {
5502 135 : state.dataHeatBal->Zone(ZoneLoop).isPartOfTotalArea = false;
5503 2045 : } else if (UtilityRoutines::SameString("Yes", cAlphaArgs(4)) || lAlphaFieldBlanks(4)) {
5504 2045 : state.dataHeatBal->Zone(ZoneLoop).isPartOfTotalArea = true;
5505 : } else {
5506 0 : ShowSevereError(state, std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataHeatBal->Zone(ZoneLoop).Name + "\".");
5507 0 : ShowContinueError(state, "Invalid value for " + cAlphaFieldNames(4) + "=\"" + cAlphaArgs(4) + "\".");
5508 0 : ErrorsFound = true;
5509 : }
5510 : }
5511 :
5512 : // Zone outdoor environmental variables, used for zone infiltration/ventilation
5513 19256 : SetupOutputVariable(state,
5514 : "Zone Outdoor Air Drybulb Temperature",
5515 : OutputProcessor::Unit::C,
5516 4814 : state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp,
5517 : OutputProcessor::SOVTimeStepType::Zone,
5518 : OutputProcessor::SOVStoreType::Average,
5519 9628 : state.dataHeatBal->Zone(ZoneLoop).Name);
5520 19256 : SetupOutputVariable(state,
5521 : "Zone Outdoor Air Wetbulb Temperature",
5522 : OutputProcessor::Unit::C,
5523 4814 : state.dataHeatBal->Zone(ZoneLoop).OutWetBulbTemp,
5524 : OutputProcessor::SOVTimeStepType::Zone,
5525 : OutputProcessor::SOVStoreType::Average,
5526 9628 : state.dataHeatBal->Zone(ZoneLoop).Name);
5527 19256 : SetupOutputVariable(state,
5528 : "Zone Outdoor Air Wind Speed",
5529 : OutputProcessor::Unit::m_s,
5530 4814 : state.dataHeatBal->Zone(ZoneLoop).WindSpeed,
5531 : OutputProcessor::SOVTimeStepType::Zone,
5532 : OutputProcessor::SOVStoreType::Average,
5533 9628 : state.dataHeatBal->Zone(ZoneLoop).Name);
5534 19256 : SetupOutputVariable(state,
5535 : "Zone Outdoor Air Wind Direction",
5536 : OutputProcessor::Unit::deg,
5537 4814 : state.dataHeatBal->Zone(ZoneLoop).WindDir,
5538 : OutputProcessor::SOVTimeStepType::Zone,
5539 : OutputProcessor::SOVStoreType::Average,
5540 9628 : state.dataHeatBal->Zone(ZoneLoop).Name);
5541 4814 : }
5542 :
5543 771 : void GetSpaceData(EnergyPlusData &state, bool &ErrorsFound) // If errors found in input
5544 : {
5545 771 : constexpr const char *RoutineName("GetSpaceData: ");
5546 1542 : std::string cCurrentModuleObject = "Space";
5547 771 : auto &ip = state.dataInputProcessing->inputProcessor;
5548 1542 : auto const instances = ip->epJSON.find(cCurrentModuleObject);
5549 771 : if (instances != ip->epJSON.end()) {
5550 2 : auto const &objectSchemaProps = ip->getObjectSchemaProps(state, cCurrentModuleObject);
5551 2 : auto &instancesValue = instances.value();
5552 2 : int numSpaces = instancesValue.size();
5553 2 : int spaceNum = 0;
5554 : // Allow for one additional Space per zone if some surfaces do not have a Space assigned in input
5555 2 : state.dataHeatBal->space.allocate(size_t(numSpaces + state.dataGlobal->NumOfZones));
5556 : // Allow for one additional "General" space type for auto-generated spaces
5557 2 : state.dataHeatBal->spaceTypes.allocate(size_t(numSpaces + 1));
5558 :
5559 11 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
5560 9 : ++spaceNum;
5561 9 : auto const &objectFields = instance.value();
5562 9 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
5563 9 : thisSpace.Name = UtilityRoutines::MakeUPPERCase(instance.key());
5564 9 : ip->markObjectAsUsed(cCurrentModuleObject, instance.key());
5565 18 : std::string zoneName = ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_name");
5566 9 : thisSpace.CeilingHeight = ip->getRealFieldValue(objectFields, objectSchemaProps, "ceiling_height");
5567 9 : thisSpace.Volume = ip->getRealFieldValue(objectFields, objectSchemaProps, "volume");
5568 9 : thisSpace.userEnteredFloorArea = ip->getRealFieldValue(objectFields, objectSchemaProps, "floor_area");
5569 9 : int zoneNum = UtilityRoutines::FindItemInList(zoneName, state.dataHeatBal->Zone);
5570 9 : if (zoneNum > 0) {
5571 9 : thisSpace.zoneNum = zoneNum;
5572 9 : state.dataHeatBal->Zone(zoneNum).spaceIndexes.emplace_back(spaceNum);
5573 9 : ++state.dataHeatBal->Zone(zoneNum).numSpaces;
5574 : } else {
5575 0 : ShowSevereError(state, RoutineName + cCurrentModuleObject + "=" + thisSpace.Name);
5576 0 : ShowContinueError(state, "Zone Name =" + zoneName + "not found.");
5577 0 : ErrorsFound = true;
5578 : }
5579 9 : thisSpace.spaceType = ip->getAlphaFieldValue(objectFields, objectSchemaProps, "space_type");
5580 9 : bool spaceTypeFound = false;
5581 15 : for (int spaceTypePtr = 1; spaceTypePtr <= state.dataGlobal->numSpaceTypes; ++spaceTypePtr) {
5582 10 : if (UtilityRoutines::SameString(thisSpace.spaceType, state.dataHeatBal->spaceTypes(spaceTypePtr))) {
5583 4 : thisSpace.spaceTypeNum = spaceTypePtr;
5584 4 : spaceTypeFound = true;
5585 4 : break;
5586 : }
5587 : }
5588 9 : if (!spaceTypeFound) {
5589 5 : ++state.dataGlobal->numSpaceTypes;
5590 5 : state.dataHeatBal->spaceTypes(state.dataGlobal->numSpaceTypes) = thisSpace.spaceType;
5591 5 : thisSpace.spaceTypeNum = state.dataGlobal->numSpaceTypes;
5592 : }
5593 :
5594 18 : auto extensibles = objectFields.find("tags");
5595 9 : auto const &extensionSchemaProps = objectSchemaProps["tags"]["items"]["properties"];
5596 9 : if (extensibles != objectFields.end()) {
5597 16 : auto extensiblesArray = extensibles.value();
5598 24 : for (auto extensibleInstance : extensiblesArray) {
5599 16 : thisSpace.tags.emplace_back(ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "tag"));
5600 : }
5601 : }
5602 : }
5603 2 : state.dataGlobal->numSpaces = spaceNum;
5604 : } else {
5605 : // If no Spaces are defined, then allow for one Space per zone, and one spaceType
5606 769 : state.dataHeatBal->space.allocate(state.dataGlobal->NumOfZones);
5607 769 : state.dataHeatBal->spaceTypes.allocate(1);
5608 : }
5609 :
5610 771 : cCurrentModuleObject = "SpaceList";
5611 1542 : auto const instances2 = ip->epJSON.find(cCurrentModuleObject);
5612 771 : if (instances2 != ip->epJSON.end()) {
5613 2 : auto const &objectSchemaProps = ip->getObjectSchemaProps(state, cCurrentModuleObject);
5614 2 : auto &instancesValue = instances2.value();
5615 2 : int numSpaceLists = instancesValue.size();
5616 2 : int spaceListNum = 0;
5617 2 : state.dataHeatBal->spaceList.allocate(numSpaceLists);
5618 4 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
5619 2 : ++spaceListNum;
5620 2 : auto const &objectFields = instance.value();
5621 2 : auto &thisSpaceList = state.dataHeatBal->spaceList(spaceListNum);
5622 2 : thisSpaceList.Name = UtilityRoutines::MakeUPPERCase(instance.key());
5623 2 : ip->markObjectAsUsed(cCurrentModuleObject, instance.key());
5624 :
5625 2 : if (UtilityRoutines::FindItemInList(thisSpaceList.Name, state.dataHeatBal->Zone) > 0) {
5626 0 : ShowSevereError(state, RoutineName + cCurrentModuleObject + "=\"" + thisSpaceList.Name + "\": is a duplicate of a zone name.");
5627 0 : ErrorsFound = true;
5628 : }
5629 2 : if (UtilityRoutines::FindItemInList(thisSpaceList.Name, state.dataHeatBal->space) > 0) {
5630 0 : ShowSevereError(state, RoutineName + cCurrentModuleObject + "=\"" + thisSpaceList.Name + "\": is a duplicate of a space name.");
5631 0 : ErrorsFound = true;
5632 : }
5633 :
5634 : // List of spaces
5635 2 : thisSpaceList.numListSpaces = 0;
5636 4 : auto extensibles = objectFields.find("spaces");
5637 2 : auto const &extensionSchemaProps = objectSchemaProps["spaces"]["items"]["properties"];
5638 2 : if (extensibles != objectFields.end()) {
5639 4 : auto extensiblesArray = extensibles.value();
5640 11 : for (auto extensibleInstance : extensiblesArray) {
5641 18 : std::string thisSpaceName = ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "space_name");
5642 9 : int thisSpaceNum = UtilityRoutines::FindItemInList(thisSpaceName, state.dataHeatBal->space);
5643 9 : if (thisSpaceNum > 0) {
5644 9 : thisSpaceList.spaces.emplace_back(thisSpaceNum);
5645 9 : ++thisSpaceList.numListSpaces;
5646 : } else {
5647 0 : ShowSevereError(state, RoutineName + cCurrentModuleObject + "=" + thisSpaceList.Name);
5648 0 : ShowContinueError(state, "Space Name=" + thisSpaceName + " not found.");
5649 0 : ErrorsFound = true;
5650 : }
5651 9 : thisSpaceList.maxSpaceNameLength = max(thisSpaceList.maxSpaceNameLength, len(thisSpaceName));
5652 : // Check for duplicate spaces
5653 37 : for (int loop = 1; loop <= int(thisSpaceList.spaces.size()) - 1; ++loop) {
5654 28 : if (thisSpaceNum == thisSpaceList.spaces(loop)) {
5655 0 : ShowSevereError(state,
5656 0 : RoutineName + cCurrentModuleObject + "=\"" + thisSpaceList.Name + "\": Space Name " + thisSpaceName +
5657 : " appears more than once in list.");
5658 0 : ErrorsFound = true;
5659 : }
5660 : }
5661 : }
5662 : }
5663 : }
5664 : }
5665 :
5666 : // Make sure every zone has at least one space
5667 5585 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5668 4814 : auto &thisZone = state.dataHeatBal->Zone(zoneNum);
5669 4814 : if (thisZone.spaceIndexes.empty()) {
5670 4808 : ++state.dataGlobal->numSpaces;
5671 4808 : state.dataHeatBal->space(state.dataGlobal->numSpaces).zoneNum = zoneNum;
5672 4808 : state.dataHeatBal->space(state.dataGlobal->numSpaces).Name = thisZone.Name;
5673 4808 : state.dataHeatBal->space(state.dataGlobal->numSpaces).spaceType = "GENERAL";
5674 4808 : state.dataHeatBal->space(state.dataGlobal->numSpaces).spaceTypeNum = GetGeneralSpaceTypeNum(state);
5675 : // Add to zone's list of spaces
5676 4808 : thisZone.spaceIndexes.emplace_back(state.dataGlobal->numSpaces);
5677 4808 : ++state.dataHeatBal->Zone(zoneNum).numSpaces;
5678 : }
5679 : }
5680 771 : }
5681 :
5682 4809 : int GetGeneralSpaceTypeNum(EnergyPlusData &state)
5683 : {
5684 : // If "General" exists as a space type return the index
5685 4809 : bool generalSpaceTypeExists = false;
5686 4809 : int generalSpaceTypeNum = 0;
5687 4817 : for (int spaceTypePtr = 1; spaceTypePtr <= state.dataGlobal->numSpaceTypes; ++spaceTypePtr) {
5688 4077 : if (UtilityRoutines::SameString(state.dataHeatBal->spaceTypes(spaceTypePtr), "GENERAL")) {
5689 4069 : generalSpaceTypeNum = spaceTypePtr;
5690 4069 : generalSpaceTypeExists = true;
5691 4069 : break;
5692 : }
5693 : }
5694 : // Add General space type if it doesn't exist yet
5695 4809 : if (!generalSpaceTypeExists) {
5696 740 : ++state.dataGlobal->numSpaceTypes;
5697 740 : state.dataHeatBal->spaceTypes(state.dataGlobal->numSpaceTypes) = "GENERAL";
5698 740 : generalSpaceTypeNum = state.dataGlobal->numSpaceTypes;
5699 : }
5700 4809 : return generalSpaceTypeNum;
5701 : }
5702 : // End of Get Input subroutines for the HB Module
5703 : //******************************************************************************
5704 :
5705 : // Beginning Initialization Section of the Module
5706 : //******************************************************************************
5707 :
5708 2568313 : void InitHeatBalance(EnergyPlusData &state)
5709 : {
5710 :
5711 : // SUBROUTINE INFORMATION:
5712 : // AUTHOR Rick Strand
5713 : // DATE WRITTEN April 1997
5714 : // MODIFIED na
5715 : // RE-ENGINEERED na
5716 :
5717 : // PURPOSE OF THIS SUBROUTINE:
5718 : // This subroutine is the main driver for initializations within the
5719 : // heat balance.
5720 :
5721 : // METHODOLOGY EMPLOYED:
5722 : // Uses the status flags to trigger initialization events. Some of the files
5723 : // have been moved to other heat balance managers. More of these initializations
5724 : // will have to continue to be re-structured.
5725 :
5726 : // REFERENCES:
5727 : // na
5728 :
5729 : // Using/Aliasing
5730 : using namespace WindowManager;
5731 : using namespace SolarShading;
5732 : using DaylightingDevices::InitDaylightingDevices;
5733 : using OutAirNodeManager::SetOutAirNodes;
5734 : using WindowEquivalentLayer::InitEquivalentLayerWindowCalculations;
5735 :
5736 : int StormWinNum; // Number of StormWindow object
5737 :
5738 2568313 : if (state.dataGlobal->BeginSimFlag) {
5739 771 : AllocateHeatBalArrays(state); // Allocate the Module Arrays
5740 771 : if (state.dataHeatBal->AnyCTF || state.dataHeatBal->AnyEMPD) {
5741 759 : DisplayString(state, "Initializing Response Factors");
5742 759 : InitConductionTransferFunctions(state); // Initialize the response factors
5743 : }
5744 771 : HeatBalanceSurfaceManager::InitSurfacePropertyViewFactors(state);
5745 771 : DisplayString(state, "Initializing Window Optical Properties");
5746 771 : InitEquivalentLayerWindowCalculations(state); // Initialize the EQL window optical properties
5747 : // InitGlassOpticalCalculations(); // Initialize the window optical properties
5748 771 : InitWindowOpticalCalculations(state);
5749 771 : InitDaylightingDevices(state); // Initialize any daylighting devices
5750 771 : DisplayString(state, "Initializing Solar Calculations");
5751 771 : InitSolarCalculations(state); // Initialize the shadowing calculations
5752 : }
5753 :
5754 2568313 : if (state.dataGlobal->BeginEnvrnFlag) {
5755 6218 : state.dataHeatBalMgr->MaxHeatLoadPrevDay = 0.0;
5756 6218 : state.dataHeatBalMgr->MaxCoolLoadPrevDay = 0.0;
5757 6218 : state.dataHeatBalMgr->MaxTempPrevDay = 0.0;
5758 6218 : state.dataHeatBalMgr->MinTempPrevDay = 0.0;
5759 6218 : state.dataHeatBalMgr->MaxHeatLoadZone = -9999.0;
5760 6218 : state.dataHeatBalMgr->MaxCoolLoadZone = -9999.0;
5761 6218 : state.dataHeatBalMgr->MaxTempZone = -9999.0;
5762 6218 : state.dataHeatBalMgr->MinTempZone = 1000.0;
5763 6218 : state.dataHeatBalMgr->TempZone = -9999.0;
5764 6218 : state.dataHeatBalMgr->LoadZone = -9999.0;
5765 6218 : state.dataHeatBalMgr->TempZonePrevDay = 1000.0;
5766 6218 : state.dataHeatBalMgr->LoadZonePrevDay = -9999.0;
5767 6218 : state.dataHeatBalMgr->TempZoneSecPrevDay = 1000.0;
5768 6218 : state.dataHeatBalMgr->TempZoneSecPrevDay = -9999.0;
5769 6218 : state.dataHeatBalMgr->WarmupTempDiff = 0.0;
5770 6218 : state.dataHeatBalMgr->WarmupLoadDiff = 0.0;
5771 6218 : state.dataHeatBalMgr->TempZoneRpt = 0.0;
5772 6218 : state.dataHeatBalMgr->LoadZoneRpt = 0.0;
5773 6218 : state.dataHeatBalMgr->MaxLoadZoneRpt = 0.0;
5774 6218 : state.dataHeatBalMgr->CountWarmupDayPoints = 0;
5775 :
5776 426543 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) {
5777 420325 : state.dataSurface->SurfaceWindow(SurfNum).ThetaFace = 296.15;
5778 420325 : state.dataSurface->SurfWinEffInsSurfTemp(SurfNum) = 23.0;
5779 : }
5780 : }
5781 :
5782 2568313 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
5783 280891 : HeatBalanceSurfaceManager::InitEMSControlledConstructions(state);
5784 280891 : HeatBalanceSurfaceManager::InitEMSControlledSurfaceProperties(state);
5785 : }
5786 :
5787 : // Init storm window pointers
5788 2568313 : if (state.dataSurface->TotStormWin > 0) {
5789 2022 : if (state.dataGlobal->BeginDayFlag) {
5790 16 : SetStormWindowControl(state);
5791 16 : state.dataHeatBalMgr->ChangeSet = false;
5792 2006 : } else if (!state.dataHeatBalMgr->ChangeSet) {
5793 16 : state.dataHeatBal->StormWinChangeThisDay = false;
5794 32 : for (StormWinNum = 1; StormWinNum <= state.dataSurface->TotStormWin; ++StormWinNum) {
5795 16 : int SurfNum = state.dataSurface->StormWindow(StormWinNum).BaseWindowNum;
5796 16 : state.dataSurface->SurfWinStormWinFlagPrevDay(SurfNum) = state.dataSurface->SurfWinStormWinFlag(SurfNum);
5797 : }
5798 16 : state.dataHeatBalMgr->ChangeSet = true;
5799 : }
5800 8088 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5801 12132 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5802 6066 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
5803 6066 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
5804 6066 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
5805 8088 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
5806 3033 : if (state.dataSurface->SurfWinStormWinFlag(SurfNum) == 1 &&
5807 1011 : state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed) {
5808 1011 : state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfWinStormWinConstr(SurfNum);
5809 : } else {
5810 1011 : state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->Surface(SurfNum).Construction;
5811 : }
5812 : }
5813 : }
5814 : }
5815 : }
5816 :
5817 2568313 : if (state.dataGlobal->BeginSimFlag && state.dataGlobal->DoWeathSim && state.dataSysVars->ReportExtShadingSunlitFrac) {
5818 0 : OpenShadingFile(state);
5819 : }
5820 :
5821 2568313 : if (state.dataGlobal->BeginDayFlag) {
5822 23416 : if (!state.dataGlobal->WarmupFlag) {
5823 3324 : if (state.dataGlobal->DayOfSim == 1) {
5824 2529 : state.dataHeatBalMgr->MaxHeatLoadZone = -9999.0;
5825 2529 : state.dataHeatBalMgr->MaxCoolLoadZone = -9999.0;
5826 2529 : state.dataHeatBalMgr->MaxTempZone = -9999.0;
5827 2529 : state.dataHeatBalMgr->MinTempZone = 1000.0;
5828 : }
5829 : }
5830 23416 : if (!state.dataSysVars->DetailedSolarTimestepIntegration) {
5831 23350 : PerformSolarCalculations(state);
5832 : }
5833 : }
5834 :
5835 2568313 : if (state.dataSysVars->DetailedSolarTimestepIntegration) { // always redo solar calcs
5836 8094 : PerformSolarCalculations(state);
5837 : }
5838 :
5839 5163366 : if (state.dataGlobal->BeginDayFlag && !state.dataGlobal->WarmupFlag &&
5840 2572368 : state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather && state.dataSysVars->ReportExtShadingSunlitFrac) {
5841 0 : for (int iHour = 1; iHour <= 24; ++iHour) { // Do for all hours.
5842 0 : for (int TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
5843 0 : constexpr const char *ShdFracFmt1(" {:02}/{:02} {:02}:{:02},");
5844 0 : if (TS == state.dataGlobal->NumOfTimeStepInHour) {
5845 0 : print(state.files.shade, ShdFracFmt1, state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, iHour, 0);
5846 : } else {
5847 0 : print(state.files.shade,
5848 : ShdFracFmt1,
5849 0 : state.dataEnvrn->Month,
5850 0 : state.dataEnvrn->DayOfMonth,
5851 0 : iHour - 1,
5852 0 : (60 / state.dataGlobal->NumOfTimeStepInHour) * TS);
5853 : }
5854 0 : for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
5855 0 : constexpr const char *ShdFracFmt2("{:10.8F},");
5856 0 : print(state.files.shade, ShdFracFmt2, state.dataHeatBal->SurfSunlitFrac(iHour, TS, SurfNum));
5857 : }
5858 0 : print(state.files.shade, "\n");
5859 : }
5860 : }
5861 : }
5862 :
5863 : // Initialize zone outdoor environmental variables
5864 : // Bulk Initialization for Temperatures & WindSpeed
5865 : // using the zone, modify the zone Dry/Wet BulbTemps
5866 2568313 : SetZoneOutBulbTempAt(state);
5867 2568313 : CheckZoneOutBulbTempAt(state);
5868 :
5869 : // set zone level wind dir to global value
5870 2568313 : SetZoneWindSpeedAt(state);
5871 2568313 : SetZoneWindDirAt(state);
5872 :
5873 : // Set zone data to linked air node value if defined.
5874 2568313 : if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
5875 7436 : SetOutAirNodes(state);
5876 45980 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5877 38544 : if (state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode > 0) {
5878 1353 : if (state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirDryBulbSchedNum > 0) {
5879 1353 : state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp = GetCurrentScheduleValue(
5880 1353 : state, state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirDryBulbSchedNum);
5881 : } else {
5882 0 : state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp =
5883 0 : state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirDryBulb;
5884 : }
5885 1353 : if (state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirWetBulbSchedNum > 0) {
5886 1353 : state.dataHeatBal->Zone(ZoneNum).OutWetBulbTemp = GetCurrentScheduleValue(
5887 1353 : state, state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirWetBulbSchedNum);
5888 : } else {
5889 0 : state.dataHeatBal->Zone(ZoneNum).OutWetBulbTemp =
5890 0 : state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirWetBulb;
5891 : }
5892 1353 : if (state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirWindSpeedSchedNum > 0) {
5893 1353 : state.dataHeatBal->Zone(ZoneNum).WindSpeed = GetCurrentScheduleValue(
5894 1353 : state, state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirWindSpeedSchedNum);
5895 : } else {
5896 0 : state.dataHeatBal->Zone(ZoneNum).WindSpeed =
5897 0 : state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirWindSpeed;
5898 : }
5899 1353 : if (state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirWindDirSchedNum > 0) {
5900 1353 : state.dataHeatBal->Zone(ZoneNum).WindDir = GetCurrentScheduleValue(
5901 1353 : state, state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirWindDirSchedNum);
5902 : } else {
5903 0 : state.dataHeatBal->Zone(ZoneNum).WindDir =
5904 0 : state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirWindDir;
5905 : }
5906 : }
5907 : }
5908 : }
5909 :
5910 : // Overwriting surface and zone level environmental data with EMS override value
5911 2568313 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
5912 4321039 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5913 4040148 : if (state.dataHeatBal->Zone(ZoneNum).OutDryBulbTempEMSOverrideOn) {
5914 0 : state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp = state.dataHeatBal->Zone(ZoneNum).OutDryBulbTempEMSOverrideValue;
5915 : }
5916 4040148 : if (state.dataHeatBal->Zone(ZoneNum).OutWetBulbTempEMSOverrideOn) {
5917 0 : state.dataHeatBal->Zone(ZoneNum).OutWetBulbTemp = state.dataHeatBal->Zone(ZoneNum).OutWetBulbTempEMSOverrideValue;
5918 : }
5919 4040148 : if (state.dataHeatBal->Zone(ZoneNum).WindSpeedEMSOverrideOn) {
5920 0 : state.dataHeatBal->Zone(ZoneNum).WindSpeed = state.dataHeatBal->Zone(ZoneNum).WindSpeedEMSOverrideValue;
5921 : }
5922 4040148 : if (state.dataHeatBal->Zone(ZoneNum).WindDirEMSOverrideOn) {
5923 0 : state.dataHeatBal->Zone(ZoneNum).WindDir = state.dataHeatBal->Zone(ZoneNum).WindDirEMSOverrideValue;
5924 : }
5925 : }
5926 : }
5927 :
5928 2568313 : if (state.dataGlobal->BeginSimFlag) {
5929 5585 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5930 9632 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
5931 4818 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
5932 4818 : int const firstSurfWin = thisSpace.WindowSurfaceFirst;
5933 4818 : int const lastSurfWin = thisSpace.WindowSurfaceLast;
5934 10792 : for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
5935 11924 : if (state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::BSDF &&
5936 5950 : state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::EQL) {
5937 5947 : state.dataSurface->SurfWinWindowModelType(SurfNum) = DataSurfaces::WindowModel::Detailed;
5938 : }
5939 : }
5940 : }
5941 : }
5942 : }
5943 2568313 : }
5944 :
5945 771 : void AllocateZoneHeatBalArrays(EnergyPlusData &state)
5946 : {
5947 : // Allocate zone / encl hb arrays
5948 :
5949 : // TODO MJW: Punt for now, sometimes unit test will get here and need these to be allocated, but simulations need them sooner
5950 771 : if (!state.dataHeatBal->ZoneIntGain.allocated()) {
5951 0 : DataHeatBalance::AllocateIntGains(state);
5952 : }
5953 771 : state.dataHeatBal->ZoneMRT.allocate(state.dataGlobal->NumOfZones);
5954 5585 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5955 4814 : state.dataHeatBal->ZoneMRT(zoneNum) = 0.0;
5956 : }
5957 771 : state.dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state.dataGlobal->NumOfZones);
5958 : // Always allocate spaceHeatBalance, even if doSpaceHeatBalance is false, because it's used to gather some of the zone totals
5959 771 : state.dataZoneTempPredictorCorrector->spaceHeatBalance.allocate(state.dataGlobal->numSpaces);
5960 :
5961 771 : state.dataHeatBal->EnclSolQSDifSol.allocate(state.dataViewFactor->NumOfSolarEnclosures);
5962 771 : state.dataHeatBal->EnclSolQD.allocate(state.dataViewFactor->NumOfSolarEnclosures);
5963 771 : state.dataHeatBal->EnclSolQDforDaylight.allocate(state.dataViewFactor->NumOfSolarEnclosures);
5964 771 : state.dataHeatBal->EnclSolDB.allocate(state.dataViewFactor->NumOfSolarEnclosures);
5965 771 : state.dataHeatBal->EnclSolDBSSG.allocate(state.dataViewFactor->NumOfSolarEnclosures);
5966 771 : state.dataHeatBal->EnclSolDBIntWin.allocate(state.dataViewFactor->NumOfSolarEnclosures);
5967 771 : state.dataHeatBal->EnclSolQSWRad.allocate(state.dataViewFactor->NumOfSolarEnclosures);
5968 771 : state.dataHeatBal->EnclSolQSWRadLights.allocate(state.dataViewFactor->NumOfSolarEnclosures);
5969 5582 : for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
5970 4811 : state.dataHeatBal->EnclSolQSDifSol(enclosureNum) = 0.0;
5971 4811 : state.dataHeatBal->EnclSolQD(enclosureNum) = 0.0;
5972 4811 : state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) = 0.0;
5973 4811 : state.dataHeatBal->EnclSolQSWRad(enclosureNum) = 0.0;
5974 4811 : state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) = 0.0;
5975 4811 : state.dataHeatBal->EnclSolDB(enclosureNum) = 0.0;
5976 4811 : state.dataHeatBal->EnclSolDBSSG(enclosureNum) = 0.0;
5977 4811 : state.dataHeatBal->EnclSolDBIntWin(enclosureNum) = 0.0;
5978 : }
5979 771 : }
5980 771 : void AllocateHeatBalArrays(EnergyPlusData &state)
5981 : {
5982 :
5983 : // SUBROUTINE INFORMATION:
5984 : // AUTHOR Richard Liesen
5985 : // DATE WRITTEN February 1998
5986 :
5987 : // Use the total number of zones or surfaces to allocate variables to avoid a limit
5988 771 : AllocateZoneHeatBalArrays(state);
5989 771 : state.dataHeatBalFanSys->SumConvHTRadSys.dimension(state.dataGlobal->NumOfZones, 0.0);
5990 771 : state.dataHeatBalFanSys->SumLatentHTRadSys.dimension(state.dataGlobal->NumOfZones, 0.0);
5991 771 : state.dataHeatBalFanSys->SumConvPool.dimension(state.dataGlobal->NumOfZones, 0.0);
5992 771 : state.dataHeatBalFanSys->SumLatentPool.dimension(state.dataGlobal->NumOfZones, 0.0);
5993 771 : state.dataHeatBalFanSys->ZoneQdotRadHVACToPerson.dimension(state.dataGlobal->NumOfZones, 0.0);
5994 771 : state.dataHeatBalFanSys->ZoneQHTRadSysToPerson.dimension(state.dataGlobal->NumOfZones, 0.0);
5995 771 : state.dataHeatBalFanSys->ZoneQHWBaseboardToPerson.dimension(state.dataGlobal->NumOfZones, 0.0);
5996 771 : state.dataHeatBalFanSys->ZoneQSteamBaseboardToPerson.dimension(state.dataGlobal->NumOfZones, 0.0);
5997 771 : state.dataHeatBalFanSys->ZoneQElecBaseboardToPerson.dimension(state.dataGlobal->NumOfZones, 0.0);
5998 771 : state.dataHeatBalFanSys->ZoneQCoolingPanelToPerson.dimension(state.dataGlobal->NumOfZones, 0.0);
5999 771 : state.dataHeatBalFanSys->ZoneReOrder.allocate(state.dataGlobal->NumOfZones);
6000 771 : state.dataHeatBalFanSys->ZoneMassBalanceFlag.dimension(state.dataGlobal->NumOfZones, false);
6001 771 : state.dataHeatBalFanSys->ZoneInfiltrationFlag.dimension(state.dataGlobal->NumOfZones, false);
6002 771 : state.dataHeatBalFanSys->ZoneReOrder = 0;
6003 771 : state.dataHeatBalFanSys->TempTstatAir.dimension(state.dataGlobal->NumOfZones, DataHeatBalance::ZoneInitialTemp);
6004 771 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
6005 14 : state.dataContaminantBalance->OutdoorCO2 = GetCurrentScheduleValue(state, state.dataContaminantBalance->Contaminant.CO2OutdoorSchedPtr);
6006 14 : state.dataContaminantBalance->ZoneAirCO2.dimension(state.dataGlobal->NumOfZones, state.dataContaminantBalance->OutdoorCO2);
6007 14 : state.dataContaminantBalance->ZoneAirCO2Temp.dimension(state.dataGlobal->NumOfZones, state.dataContaminantBalance->OutdoorCO2);
6008 14 : state.dataContaminantBalance->ZoneAirCO2Avg.dimension(state.dataGlobal->NumOfZones, state.dataContaminantBalance->OutdoorCO2);
6009 : }
6010 771 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
6011 3 : state.dataContaminantBalance->OutdoorGC =
6012 3 : GetCurrentScheduleValue(state, state.dataContaminantBalance->Contaminant.GenericContamOutdoorSchedPtr);
6013 3 : state.dataContaminantBalance->ZoneAirGC.dimension(state.dataGlobal->NumOfZones, state.dataContaminantBalance->OutdoorGC);
6014 3 : state.dataContaminantBalance->ZoneAirGCTemp.dimension(state.dataGlobal->NumOfZones, state.dataContaminantBalance->OutdoorGC);
6015 3 : state.dataContaminantBalance->ZoneAirGCAvg.dimension(state.dataGlobal->NumOfZones, state.dataContaminantBalance->OutdoorGC);
6016 : }
6017 771 : state.dataHeatBalMgr->MaxTempPrevDay.dimension(state.dataGlobal->NumOfZones, 0.0);
6018 771 : state.dataHeatBalMgr->MinTempPrevDay.dimension(state.dataGlobal->NumOfZones, 0.0);
6019 771 : state.dataHeatBalMgr->MaxHeatLoadPrevDay.dimension(state.dataGlobal->NumOfZones, 0.0);
6020 771 : state.dataHeatBalMgr->MaxCoolLoadPrevDay.dimension(state.dataGlobal->NumOfZones, 0.0);
6021 771 : state.dataHeatBalMgr->MaxHeatLoadZone.dimension(state.dataGlobal->NumOfZones, -9999.0);
6022 771 : state.dataHeatBalMgr->MaxCoolLoadZone.dimension(state.dataGlobal->NumOfZones, -9999.0);
6023 771 : state.dataHeatBalMgr->MaxTempZone.dimension(state.dataGlobal->NumOfZones, -9999.0);
6024 771 : state.dataHeatBalMgr->MinTempZone.dimension(state.dataGlobal->NumOfZones, 1000.0);
6025 771 : state.dataHeatBalMgr->TempZonePrevDay.dimension(state.dataGlobal->NumOfZones, 0.0);
6026 771 : state.dataHeatBalMgr->LoadZonePrevDay.dimension(state.dataGlobal->NumOfZones, 0.0);
6027 771 : state.dataHeatBalMgr->TempZoneSecPrevDay.dimension(state.dataGlobal->NumOfZones, 0.0);
6028 771 : state.dataHeatBalMgr->LoadZoneSecPrevDay.dimension(state.dataGlobal->NumOfZones, 0.0);
6029 771 : state.dataHeatBalMgr->WarmupTempDiff.dimension(state.dataGlobal->NumOfZones, 0.0);
6030 771 : state.dataHeatBalMgr->WarmupLoadDiff.dimension(state.dataGlobal->NumOfZones, 0.0);
6031 771 : state.dataHeatBalMgr->TempZone.dimension(state.dataGlobal->NumOfZones, 0.0);
6032 771 : state.dataHeatBalMgr->LoadZone.dimension(state.dataGlobal->NumOfZones, 0.0);
6033 771 : state.dataHeatBalMgr->TempZoneRpt.dimension(state.dataGlobal->NumOfZones, state.dataGlobal->NumOfTimeStepInHour * 24, 0.0);
6034 771 : state.dataHeatBalMgr->LoadZoneRpt.dimension(state.dataGlobal->NumOfZones, state.dataGlobal->NumOfTimeStepInHour * 24, 0.0);
6035 771 : state.dataHeatBalMgr->MaxLoadZoneRpt.dimension(state.dataGlobal->NumOfZones, state.dataGlobal->NumOfTimeStepInHour * 24, 0.0);
6036 771 : state.dataHeatBalMgr->WarmupConvergenceValues.allocate(state.dataGlobal->NumOfZones);
6037 771 : state.dataHeatBalMgr->TempZoneRptStdDev.allocate(state.dataGlobal->NumOfTimeStepInHour * 24);
6038 771 : state.dataHeatBalMgr->LoadZoneRptStdDev.allocate(state.dataGlobal->NumOfTimeStepInHour * 24);
6039 : // MassConservation.allocate( NumOfZones );
6040 :
6041 771 : state.dataHeatBalFanSys->CrossedColdThreshRepPeriod.allocate(state.dataGlobal->NumOfZones, state.dataWeatherManager->TotThermalReportPers);
6042 771 : state.dataHeatBalFanSys->CrossedHeatThreshRepPeriod.allocate(state.dataGlobal->NumOfZones, state.dataWeatherManager->TotThermalReportPers);
6043 771 : state.dataHeatBalFanSys->CrossedColdThreshRepPeriod = false;
6044 771 : state.dataHeatBalFanSys->CrossedHeatThreshRepPeriod = false;
6045 771 : if (state.dataWeatherManager->TotThermalReportPers > 0) {
6046 12 : state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6047 12 : state.dataWeatherManager->TotThermalReportPers);
6048 12 : state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6049 12 : state.dataWeatherManager->TotThermalReportPers);
6050 12 : state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6051 12 : state.dataWeatherManager->TotThermalReportPers);
6052 12 : state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6053 12 : state.dataWeatherManager->TotThermalReportPers);
6054 12 : state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6055 12 : state.dataWeatherManager->TotThermalReportPers);
6056 12 : state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6057 12 : state.dataWeatherManager->TotThermalReportPers);
6058 12 : state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6059 12 : state.dataWeatherManager->TotThermalReportPers);
6060 12 : state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6061 12 : state.dataWeatherManager->TotThermalReportPers);
6062 12 : state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6063 12 : state.dataWeatherManager->TotThermalReportPers);
6064 12 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6065 12 : state.dataWeatherManager->TotThermalReportPers);
6066 12 : state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6067 12 : state.dataWeatherManager->TotThermalReportPers);
6068 : }
6069 :
6070 771 : if (state.dataWeatherManager->TotCO2ReportPers > 0) {
6071 2 : state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones, state.dataWeatherManager->TotCO2ReportPers);
6072 6 : state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6073 6 : state.dataWeatherManager->TotCO2ReportPers);
6074 6 : state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6075 6 : state.dataWeatherManager->TotCO2ReportPers);
6076 : }
6077 771 : if (state.dataWeatherManager->TotVisualReportPers > 0) {
6078 6 : state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6079 6 : state.dataWeatherManager->TotVisualReportPers);
6080 6 : state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6081 6 : state.dataWeatherManager->TotVisualReportPers);
6082 6 : state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod.allocate(state.dataGlobal->NumOfZones,
6083 6 : state.dataWeatherManager->TotVisualReportPers);
6084 : }
6085 :
6086 771 : state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod.allocate(state.dataGlobal->NumOfZones, state.dataWeatherManager->TotThermalReportPers);
6087 771 : state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod.allocate(state.dataGlobal->NumOfZones, state.dataWeatherManager->TotThermalReportPers);
6088 771 : state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod.allocate(state.dataGlobal->NumOfZones, state.dataWeatherManager->TotThermalReportPers);
6089 771 : state.dataHeatBalFanSys->highSETLongestHoursRepPeriod.allocate(state.dataGlobal->NumOfZones, state.dataWeatherManager->TotThermalReportPers);
6090 771 : state.dataHeatBalFanSys->lowSETLongestStartRepPeriod.allocate(state.dataGlobal->NumOfZones, state.dataWeatherManager->TotThermalReportPers);
6091 771 : state.dataHeatBalFanSys->highSETLongestStartRepPeriod.allocate(state.dataGlobal->NumOfZones, state.dataWeatherManager->TotThermalReportPers);
6092 :
6093 771 : state.dataHeatBalMgr->CountWarmupDayPoints = 0;
6094 :
6095 5585 : for (int loop = 1; loop <= state.dataGlobal->NumOfZones; ++loop) {
6096 : // CurrentModuleObject='Zone'
6097 14442 : SetupOutputVariable(state,
6098 : "Zone Mean Radiant Temperature",
6099 : OutputProcessor::Unit::C,
6100 4814 : state.dataHeatBal->ZoneMRT(loop),
6101 : OutputProcessor::SOVTimeStepType::Zone,
6102 : OutputProcessor::SOVStoreType::State,
6103 9628 : state.dataHeatBal->Zone(loop).Name);
6104 : }
6105 771 : }
6106 :
6107 : // End Initialization Section of the Module
6108 : //******************************************************************************
6109 :
6110 : // Beginning of Record Keeping subroutines for the HB Module
6111 : // *****************************************************************************
6112 :
6113 2568312 : void RecKeepHeatBalance(EnergyPlusData &state)
6114 : {
6115 :
6116 : // SUBROUTINE INFORMATION:
6117 : // AUTHOR Rick Strand
6118 : // DATE WRITTEN April 1997
6119 : // MODIFIED June 2011, Daeho Kang for individual zone maximums & convergence outputs
6120 : // July 2016, Rick Strand for movable insulation bug fix
6121 :
6122 : // PURPOSE OF THIS SUBROUTINE:
6123 : // This subroutine is the main driver for record keeping within the
6124 : // heat balance.
6125 :
6126 : // Using/Aliasing
6127 :
6128 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6129 : int ZoneNum;
6130 :
6131 : // Record Maxs & Mins for individual zone
6132 21013695 : for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6133 18445383 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
6134 18445383 : auto &thisZoneSysEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum);
6135 18445383 : if (thisZoneHB.ZTAV > state.dataHeatBalMgr->MaxTempZone(ZoneNum)) {
6136 3390494 : state.dataHeatBalMgr->MaxTempZone(ZoneNum) = thisZoneHB.ZTAV;
6137 : }
6138 18445383 : if (thisZoneHB.ZTAV < state.dataHeatBalMgr->MinTempZone(ZoneNum)) {
6139 3565597 : state.dataHeatBalMgr->MinTempZone(ZoneNum) = thisZoneHB.ZTAV;
6140 : }
6141 18445383 : if (thisZoneSysEnergyDemand.ZoneSNLoadHeatRate > state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum)) {
6142 2765243 : state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum) = thisZoneSysEnergyDemand.ZoneSNLoadHeatRate;
6143 : }
6144 18445383 : if (thisZoneSysEnergyDemand.ZoneSNLoadCoolRate > state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum)) {
6145 2254686 : state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum) = thisZoneSysEnergyDemand.ZoneSNLoadCoolRate;
6146 : }
6147 :
6148 : // Record temperature and load for individual zone
6149 18445383 : state.dataHeatBalMgr->TempZoneSecPrevDay(ZoneNum) = state.dataHeatBalMgr->TempZonePrevDay(ZoneNum);
6150 18445383 : state.dataHeatBalMgr->LoadZoneSecPrevDay(ZoneNum) = state.dataHeatBalMgr->LoadZonePrevDay(ZoneNum);
6151 18445383 : state.dataHeatBalMgr->TempZonePrevDay(ZoneNum) = state.dataHeatBalMgr->TempZone(ZoneNum);
6152 18445383 : state.dataHeatBalMgr->LoadZonePrevDay(ZoneNum) = state.dataHeatBalMgr->LoadZone(ZoneNum);
6153 18445383 : state.dataHeatBalMgr->TempZone(ZoneNum) = thisZoneHB.ZTAV;
6154 18445383 : state.dataHeatBalMgr->LoadZone(ZoneNum) =
6155 18445383 : max(thisZoneSysEnergyDemand.ZoneSNLoadHeatRate, std::abs(thisZoneSysEnergyDemand.ZoneSNLoadCoolRate));
6156 :
6157 : // Calculate differences in temperature and load for the last two warmup days
6158 22191303 : if (!state.dataGlobal->WarmupFlag && state.dataGlobal->DayOfSim == 1 &&
6159 3382080 : (!state.dataGlobal->DoingSizing || state.dataGlobal->DoPureLoadCalc)) {
6160 1369920 : state.dataHeatBalMgr->WarmupTempDiff(ZoneNum) =
6161 1369920 : std::abs(state.dataHeatBalMgr->TempZoneSecPrevDay(ZoneNum) - state.dataHeatBalMgr->TempZonePrevDay(ZoneNum));
6162 1369920 : state.dataHeatBalMgr->WarmupLoadDiff(ZoneNum) =
6163 1369920 : std::abs(state.dataHeatBalMgr->LoadZoneSecPrevDay(ZoneNum) - state.dataHeatBalMgr->LoadZonePrevDay(ZoneNum));
6164 1369920 : if (ZoneNum == 1) ++state.dataHeatBalMgr->CountWarmupDayPoints;
6165 1369920 : state.dataHeatBalMgr->TempZoneRpt(ZoneNum, state.dataHeatBalMgr->CountWarmupDayPoints) =
6166 1369920 : state.dataHeatBalMgr->WarmupTempDiff(ZoneNum);
6167 1369920 : state.dataHeatBalMgr->LoadZoneRpt(ZoneNum, state.dataHeatBalMgr->CountWarmupDayPoints) =
6168 1369920 : state.dataHeatBalMgr->WarmupLoadDiff(ZoneNum);
6169 1369920 : state.dataHeatBalMgr->MaxLoadZoneRpt(ZoneNum, state.dataHeatBalMgr->CountWarmupDayPoints) = state.dataHeatBalMgr->LoadZone(ZoneNum);
6170 :
6171 1369920 : if (state.dataSysVars->ReportDetailedWarmupConvergence) { // only do this detailed thing when requested by user is on
6172 : // Write Warmup Convergence Information to the initialization output file
6173 1152 : if (state.dataHeatBalMgr->FirstWarmupWrite) {
6174 1 : constexpr const char *Format_732{"! <Warmup Convergence Information>,Zone Name,Time Step,Hour of Day,Warmup Temperature "
6175 : "Difference {{deltaC}},Warmup Load Difference {{W}}\n"};
6176 1 : print(state.files.eio, Format_732);
6177 1 : state.dataHeatBalMgr->FirstWarmupWrite = false;
6178 : }
6179 1152 : constexpr const char *Format_731{" Warmup Convergence Information, {},{},{},{:.10R},{:.10R}\n"};
6180 6912 : print(state.files.eio,
6181 : Format_731,
6182 1152 : state.dataHeatBal->Zone(ZoneNum).Name,
6183 1152 : state.dataGlobal->TimeStep,
6184 1152 : state.dataGlobal->HourOfDay,
6185 1152 : state.dataHeatBalMgr->WarmupTempDiff(ZoneNum),
6186 2304 : state.dataHeatBalMgr->WarmupLoadDiff(ZoneNum));
6187 : }
6188 : }
6189 : }
6190 :
6191 : // Update interior movable insulation flag--needed at the end of a zone time step so that the interior radiant
6192 : // exchange algorithm knows whether there has been a change in interior movable insulation or not.
6193 2568312 : if (state.dataSurface->AnyMovableInsulation) {
6194 20244 : for (int surfNum : state.dataHeatBalSurf->SurfMovInsulIndexList) {
6195 10122 : state.dataHeatBalSurf->SurfMovInsulIntPresentPrevTS(surfNum) = state.dataHeatBalSurf->SurfMovInsulIntPresent(surfNum);
6196 : }
6197 : }
6198 :
6199 : // For non-complex windows, update a report variable so this shows up in the output as something other than zero
6200 2568312 : UpdateWindowFaceTempsNonBSDFWin(state);
6201 2568312 : }
6202 :
6203 16403 : void CheckWarmupConvergence(EnergyPlusData &state)
6204 : {
6205 :
6206 : // SUBROUTINE INFORMATION:
6207 : // AUTHOR Rick Strand
6208 : // DATE WRITTEN April 1997
6209 : // MODIFIED June 2011, Daeho Kang for individual zone comparison
6210 : // RE-ENGINEERED na
6211 :
6212 : // PURPOSE OF THIS SUBROUTINE:
6213 : // This subroutine checks warmup convergence values.
6214 :
6215 : // METHODOLOGY EMPLOYED:
6216 : // na
6217 :
6218 : // REFERENCES:
6219 : // na
6220 :
6221 : // Using/Aliasing
6222 :
6223 : // Locals
6224 : // SUBROUTINE ARGUMENT DEFINITIONS:
6225 : // na
6226 :
6227 : // SUBROUTINE PARAMETER DEFINITIONS:
6228 16403 : Real64 constexpr MinLoad(100.0); // Minimum loads for convergence check
6229 : // To avoid big percentage difference in low load situations
6230 :
6231 : // INTERFACE BLOCK SPECIFICATIONS:
6232 : // na
6233 :
6234 : // DERIVED TYPE DEFINITIONS:
6235 : // na
6236 :
6237 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6238 : int ZoneNum;
6239 : bool ConvergenceChecksFailed;
6240 :
6241 : // Convergence criteria for warmup days:
6242 : // Perform another warmup day unless both the % change in loads and
6243 : // absolute change in zone temp min & max are less than their criteria.
6244 :
6245 16403 : ConvergenceChecksFailed = false;
6246 :
6247 16403 : if (state.dataGlobal->NumOfZones <= 0) { // if there are no zones, immediate convergence
6248 58 : state.dataGlobal->WarmupFlag = false;
6249 : } else {
6250 140236 : for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6251 :
6252 123891 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMaxTempValue =
6253 123891 : std::abs(state.dataHeatBalMgr->MaxTempPrevDay(ZoneNum) - state.dataHeatBalMgr->MaxTempZone(ZoneNum));
6254 123891 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMinTempValue =
6255 123891 : std::abs(state.dataHeatBalMgr->MinTempPrevDay(ZoneNum) - state.dataHeatBalMgr->MinTempZone(ZoneNum));
6256 123891 : if (state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMaxTempValue <= state.dataHeatBal->TempConvergTol) {
6257 89014 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(1) = 2;
6258 : } else {
6259 34877 : ConvergenceChecksFailed = true;
6260 34877 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(1) = 1;
6261 : }
6262 :
6263 123891 : if (state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMinTempValue <= state.dataHeatBal->TempConvergTol) {
6264 90146 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(2) = 2;
6265 : } else {
6266 33745 : ConvergenceChecksFailed = true;
6267 33745 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(2) = 1;
6268 : }
6269 :
6270 123891 : if (state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum) > 1.0e-4) { // make sure load big enough to divide
6271 62261 : state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum) = std::abs(max(state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum), MinLoad));
6272 62261 : state.dataHeatBalMgr->MaxHeatLoadPrevDay(ZoneNum) = std::abs(max(state.dataHeatBalMgr->MaxHeatLoadPrevDay(ZoneNum), MinLoad));
6273 62261 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMaxHeatLoadValue =
6274 124522 : std::abs((state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum) - state.dataHeatBalMgr->MaxHeatLoadPrevDay(ZoneNum)) /
6275 62261 : state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum));
6276 62261 : if (state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMaxHeatLoadValue <= state.dataHeatBal->LoadsConvergTol) {
6277 44460 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(3) = 2;
6278 : } else {
6279 17801 : ConvergenceChecksFailed = true;
6280 17801 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(3) = 1;
6281 : }
6282 : } else {
6283 61630 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(3) = 2;
6284 : }
6285 :
6286 123891 : if (state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum) > 1.0e-4) {
6287 62178 : state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum) = std::abs(max(state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum), MinLoad));
6288 62178 : state.dataHeatBalMgr->MaxCoolLoadPrevDay(ZoneNum) = std::abs(max(state.dataHeatBalMgr->MaxCoolLoadPrevDay(ZoneNum), MinLoad));
6289 62178 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMaxCoolLoadValue =
6290 124356 : std::abs((state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum) - state.dataHeatBalMgr->MaxCoolLoadPrevDay(ZoneNum)) /
6291 62178 : state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum));
6292 62178 : if (state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMaxCoolLoadValue <= state.dataHeatBal->LoadsConvergTol) {
6293 43146 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(4) = 2;
6294 : } else {
6295 19032 : ConvergenceChecksFailed = true;
6296 19032 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(4) = 1;
6297 : }
6298 : } else {
6299 61713 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(4) = 2;
6300 : }
6301 :
6302 123891 : if (state.dataGlobal->DayOfSim >= state.dataHeatBal->MaxNumberOfWarmupDays && state.dataGlobal->WarmupFlag) {
6303 : // Check convergence for individual zone
6304 117 : if (sum(state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag) != 8) { // pass=2 * 4 values for convergence
6305 63 : ShowSevereError(state,
6306 84 : format("CheckWarmupConvergence: Loads Initialization, Zone=\"{}\" did not converge after {} warmup days.",
6307 21 : state.dataHeatBal->Zone(ZoneNum).Name,
6308 42 : state.dataHeatBal->MaxNumberOfWarmupDays));
6309 21 : if (!state.dataHeatBalMgr->WarmupConvergenceWarning && !state.dataGlobal->DoingSizing) {
6310 14 : ShowContinueError(state, "See Warmup Convergence Information in .eio file for details.");
6311 14 : state.dataHeatBalMgr->WarmupConvergenceWarning = true;
6312 7 : } else if (!state.dataHeatBalMgr->SizingWarmupConvergenceWarning && state.dataGlobal->DoingSizing) {
6313 0 : ShowContinueError(state, "Warmup Convergence failing during sizing.");
6314 0 : state.dataHeatBalMgr->SizingWarmupConvergenceWarning = true;
6315 : }
6316 21 : if (state.dataEnvrn->RunPeriodEnvironment) {
6317 0 : ShowContinueError(state, "...Environment(RunPeriod)=\"" + state.dataEnvrn->EnvironmentName + "\"");
6318 : } else {
6319 21 : ShowContinueError(state, "...Environment(SizingPeriod)=\"" + state.dataEnvrn->EnvironmentName + "\"");
6320 : }
6321 :
6322 63 : ShowContinueError(state,
6323 105 : format("..Max Temp Comparison = {:.2R} vs Temperature Convergence Tolerance={:.2R} - {} Convergence",
6324 21 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMaxTempValue,
6325 21 : state.dataHeatBal->TempConvergTol,
6326 42 : PassFail(state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(1))));
6327 63 : ShowContinueError(state,
6328 105 : format("..Min Temp Comparison = {:.2R} vs Temperature Convergence Tolerance={:.2R} - {} Convergence",
6329 21 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMinTempValue,
6330 21 : state.dataHeatBal->TempConvergTol,
6331 42 : PassFail(state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(2))));
6332 63 : ShowContinueError(state,
6333 105 : format("..Max Heat Load Comparison = {:.4R} vs Loads Convergence Tolerance={:.2R} - {} Convergence",
6334 21 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMaxHeatLoadValue,
6335 21 : state.dataHeatBal->LoadsConvergTol,
6336 42 : PassFail(state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(3))));
6337 63 : ShowContinueError(state,
6338 105 : format("..Max Cool Load Comparison = {:.4R} vs Loads Convergence Tolerance={:.2R} - {} Convergence",
6339 21 : state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).TestMaxCoolLoadValue,
6340 21 : state.dataHeatBal->LoadsConvergTol,
6341 42 : PassFail(state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(4))));
6342 : }
6343 : }
6344 :
6345 : // Transfer current daily max and min loads and temperatures to the
6346 : // variables containing the last day's values
6347 123891 : state.dataHeatBalMgr->MaxHeatLoadPrevDay(ZoneNum) = state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum);
6348 123891 : state.dataHeatBalMgr->MaxCoolLoadPrevDay(ZoneNum) = state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum);
6349 123891 : state.dataHeatBalMgr->MaxTempPrevDay(ZoneNum) = state.dataHeatBalMgr->MaxTempZone(ZoneNum);
6350 123891 : state.dataHeatBalMgr->MinTempPrevDay(ZoneNum) = state.dataHeatBalMgr->MinTempZone(ZoneNum);
6351 :
6352 123891 : state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum) = -9999.0;
6353 123891 : state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum) = -9999.0;
6354 123891 : state.dataHeatBalMgr->MaxTempZone(ZoneNum) = -9999.0;
6355 123891 : state.dataHeatBalMgr->MinTempZone(ZoneNum) = 1000.0;
6356 : }
6357 :
6358 : // Limit the number of warmup days, regardless of the number of zones
6359 : // in the building, to some arbitrary value based on common sense and
6360 : // experience with the (I)BLAST program. If too many warmup days were
6361 : // required, notify the program user.
6362 :
6363 16345 : if ((state.dataGlobal->DayOfSim >= state.dataHeatBal->MaxNumberOfWarmupDays) && state.dataGlobal->WarmupFlag && ConvergenceChecksFailed) {
6364 15 : if (state.dataHeatBal->MaxNumberOfWarmupDays < DefaultMaxNumberOfWarmupDays) {
6365 6 : ShowSevereError(state,
6366 6 : format("CheckWarmupConvergence: User supplied maximum warmup days={} is insufficient.",
6367 4 : state.dataHeatBal->MaxNumberOfWarmupDays));
6368 2 : ShowContinueError(state, format("Suggest setting maximum number of warmup days to at least {}.", DefaultMaxNumberOfWarmupDays));
6369 : }
6370 : }
6371 :
6372 : // Set warmup flag to true depending on value of ConvergenceChecksFailed (true=fail)
6373 : // and minimum number of warmup days
6374 16345 : if (!ConvergenceChecksFailed && state.dataGlobal->DayOfSim >= state.dataHeatBal->MinNumberOfWarmupDays) {
6375 2456 : state.dataGlobal->WarmupFlag = false;
6376 13889 : } else if (!ConvergenceChecksFailed && state.dataGlobal->DayOfSim < state.dataHeatBal->MinNumberOfWarmupDays) {
6377 5409 : state.dataGlobal->WarmupFlag = true;
6378 : }
6379 :
6380 : // If max warmup days reached and still WarmupFlag, then go to non-warmup state.
6381 : // prior messages will have been displayed
6382 16345 : if ((state.dataGlobal->DayOfSim >= state.dataHeatBal->MaxNumberOfWarmupDays) && state.dataGlobal->WarmupFlag) {
6383 15 : state.dataGlobal->WarmupFlag = false;
6384 : }
6385 : }
6386 16403 : }
6387 :
6388 1645 : void ReportWarmupConvergence(EnergyPlusData &state)
6389 : {
6390 :
6391 : // SUBROUTINE INFORMATION:
6392 : // AUTHOR Linda Lawrie
6393 : // DATE WRITTEN October 2011
6394 : // MODIFIED na
6395 : // RE-ENGINEERED na
6396 :
6397 : // PURPOSE OF THIS SUBROUTINE:
6398 : // na
6399 :
6400 : // METHODOLOGY EMPLOYED:
6401 : // na
6402 :
6403 : // REFERENCES:
6404 : // na
6405 :
6406 : // Using/Aliasing
6407 :
6408 : // Locals
6409 : // SUBROUTINE ARGUMENT DEFINITIONS:
6410 : // na
6411 :
6412 : // SUBROUTINE PARAMETER DEFINITIONS:
6413 : // na
6414 :
6415 : // INTERFACE BLOCK SPECIFICATIONS:
6416 : // na
6417 :
6418 : // DERIVED TYPE DEFINITIONS:
6419 : // na
6420 :
6421 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6422 : int ZoneNum;
6423 : Real64 AverageZoneTemp;
6424 : Real64 AverageZoneLoad;
6425 : Real64 StdDevZoneTemp;
6426 : Real64 StdDevZoneLoad;
6427 3290 : std::string EnvHeader;
6428 : int Num; // loop control
6429 :
6430 : // Formats
6431 1645 : constexpr const char *Format_730("! <Warmup Convergence Information>,Zone Name,Environment Type/Name,Average Warmup Temperature Difference "
6432 : "{{deltaC}},Std Dev Warmup Temperature Difference {{deltaC}},Max Temperature Pass/Fail Convergence,Min "
6433 : "Temperature Pass/Fail Convergence,Average Warmup Load Difference {{W}},Std Dev Warmup Load Difference "
6434 : "{{W}},Heating Load Pass/Fail Convergence,Cooling Load Pass/Fail Convergence\n");
6435 :
6436 1645 : if (!state.dataGlobal->WarmupFlag) { // Report out average/std dev
6437 : // Write Warmup Convervence Information to the initialization output file
6438 1645 : if (state.dataHeatBalMgr->ReportWarmupConvergenceFirstWarmupWrite && state.dataGlobal->NumOfZones > 0) {
6439 739 : print(state.files.eio, Format_730);
6440 739 : state.dataHeatBalMgr->ReportWarmupConvergenceFirstWarmupWrite = false;
6441 : }
6442 :
6443 1645 : state.dataHeatBalMgr->TempZoneRptStdDev = 0.0;
6444 1645 : state.dataHeatBalMgr->LoadZoneRptStdDev = 0.0;
6445 :
6446 1645 : if (state.dataEnvrn->RunPeriodEnvironment) {
6447 2 : EnvHeader = "RunPeriod:";
6448 : } else {
6449 1643 : EnvHeader = "SizingPeriod:";
6450 : }
6451 :
6452 12333 : for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
6453 21376 : AverageZoneTemp = sum(state.dataHeatBalMgr->TempZoneRpt(ZoneNum, {1, state.dataHeatBalMgr->CountWarmupDayPoints})) /
6454 10688 : double(state.dataHeatBalMgr->CountWarmupDayPoints);
6455 1380608 : for (Num = 1; Num <= state.dataHeatBalMgr->CountWarmupDayPoints; ++Num) {
6456 1369920 : if (state.dataHeatBalMgr->MaxLoadZoneRpt(ZoneNum, Num) > 1.e-4) {
6457 1090793 : state.dataHeatBalMgr->LoadZoneRpt(ZoneNum, Num) /= state.dataHeatBalMgr->MaxLoadZoneRpt(ZoneNum, Num);
6458 : } else {
6459 279127 : state.dataHeatBalMgr->LoadZoneRpt(ZoneNum, Num) = 0.0;
6460 : }
6461 : }
6462 21376 : AverageZoneLoad = sum(state.dataHeatBalMgr->LoadZoneRpt(ZoneNum, {1, state.dataHeatBalMgr->CountWarmupDayPoints})) /
6463 10688 : double(state.dataHeatBalMgr->CountWarmupDayPoints);
6464 10688 : StdDevZoneTemp = 0.0;
6465 10688 : StdDevZoneLoad = 0.0;
6466 1380608 : for (Num = 1; Num <= state.dataHeatBalMgr->CountWarmupDayPoints; ++Num) {
6467 1369920 : state.dataHeatBalMgr->TempZoneRptStdDev(Num) = pow_2(state.dataHeatBalMgr->TempZoneRpt(ZoneNum, Num) - AverageZoneTemp);
6468 1369920 : state.dataHeatBalMgr->LoadZoneRptStdDev(Num) = pow_2(state.dataHeatBalMgr->LoadZoneRpt(ZoneNum, Num) - AverageZoneLoad);
6469 : }
6470 21376 : StdDevZoneTemp = std::sqrt(sum(state.dataHeatBalMgr->TempZoneRptStdDev({1, state.dataHeatBalMgr->CountWarmupDayPoints})) /
6471 10688 : double(state.dataHeatBalMgr->CountWarmupDayPoints));
6472 21376 : StdDevZoneLoad = std::sqrt(sum(state.dataHeatBalMgr->LoadZoneRptStdDev({1, state.dataHeatBalMgr->CountWarmupDayPoints})) /
6473 10688 : double(state.dataHeatBalMgr->CountWarmupDayPoints));
6474 :
6475 10688 : constexpr const char *Format_731(" Warmup Convergence Information,{},{},{:.10R},{:.10R},{},{},{:.10R},{:.10R},{},{}\n");
6476 64128 : print(state.files.eio,
6477 : Format_731,
6478 10688 : state.dataHeatBal->Zone(ZoneNum).Name,
6479 21376 : EnvHeader + ' ' + state.dataEnvrn->EnvironmentName,
6480 : AverageZoneTemp,
6481 : StdDevZoneTemp,
6482 10688 : PassFail(state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(1)),
6483 10688 : PassFail(state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(2)),
6484 : AverageZoneLoad,
6485 : StdDevZoneLoad,
6486 10688 : PassFail(state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(3)),
6487 21376 : PassFail(state.dataHeatBalMgr->WarmupConvergenceValues(ZoneNum).PassFlag(4)));
6488 : }
6489 : }
6490 1645 : }
6491 :
6492 2568312 : void UpdateWindowFaceTempsNonBSDFWin(EnergyPlusData &state)
6493 : {
6494 24578385 : for (int SurfNum : state.dataSurface->AllHTWindowSurfaceList) {
6495 22010073 : auto &thisConstruction = state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction);
6496 22010073 : if (thisConstruction.WindowTypeBSDF) continue;
6497 21970533 : state.dataHeatBal->SurfWinFenLaySurfTempFront(SurfNum, 1) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
6498 21970533 : state.dataHeatBal->SurfWinFenLaySurfTempBack(SurfNum, thisConstruction.TotLayers) = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
6499 : }
6500 2568312 : }
6501 :
6502 : // End of Record Keeping subroutines for the HB Module
6503 : // *****************************************************************************
6504 :
6505 : // Beginning of Reporting subroutines for the HB Module
6506 : // *****************************************************************************
6507 :
6508 2568312 : void ReportHeatBalance(EnergyPlusData &state)
6509 : {
6510 :
6511 : // SUBROUTINE INFORMATION:
6512 : // AUTHOR Rick Strand
6513 : // DATE WRITTEN July 1997
6514 : // MODIFIED na
6515 : // RE-ENGINEERED na
6516 :
6517 : // PURPOSE OF THIS SUBROUTINE:
6518 : // This subroutine is the main driver for reporting within the heat
6519 : // balance.
6520 :
6521 : // METHODOLOGY EMPLOYED:
6522 : // Uses the status flags to trigger record keeping events.
6523 :
6524 : // REFERENCES:
6525 : // na
6526 :
6527 : // Using/Aliasing
6528 : using EconomicTariff::UpdateUtilityBills; // added for computing annual utility costs
6529 : using NodeInputManager::CalcMoreNodeInfo;
6530 : using OutputReportTabular::UpdateTabularReports;
6531 : using ScheduleManager::ReportScheduleValues;
6532 :
6533 2568312 : ReportScheduleValues(state);
6534 :
6535 2568312 : if (!state.dataGlobal->WarmupFlag && state.dataGlobal->DoOutputReporting) {
6536 299088 : if (!state.dataGlobal->DoingSizing) {
6537 299088 : CalcMoreNodeInfo(state);
6538 : }
6539 299088 : UpdateDataandReport(state, OutputProcessor::TimeStepType::Zone);
6540 593952 : if (state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeDesignDay ||
6541 294864 : state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeRunPeriodDesign) {
6542 4224 : if (state.dataHVACSizingSimMgr->hvacSizingSimulationManager)
6543 4224 : state.dataHVACSizingSimMgr->hvacSizingSimulationManager->UpdateSizingLogsZoneStep(state);
6544 : }
6545 :
6546 299088 : UpdateTabularReports(state, OutputProcessor::TimeStepType::Zone);
6547 299088 : UpdateUtilityBills(state);
6548 2269224 : } else if (!state.dataGlobal->KickOffSimulation && state.dataGlobal->DoOutputReporting && state.dataSysVars->ReportDuringWarmup) {
6549 0 : if (state.dataGlobal->BeginDayFlag && !state.dataEnvrn->PrintEnvrnStampWarmupPrinted) {
6550 0 : state.dataEnvrn->PrintEnvrnStampWarmup = true;
6551 0 : state.dataEnvrn->PrintEnvrnStampWarmupPrinted = true;
6552 : }
6553 0 : if (!state.dataGlobal->BeginDayFlag) state.dataEnvrn->PrintEnvrnStampWarmupPrinted = false;
6554 0 : if (state.dataEnvrn->PrintEnvrnStampWarmup) {
6555 0 : if (state.dataReportFlag->PrintEndDataDictionary && state.dataGlobal->DoOutputReporting) {
6556 0 : constexpr const char *EndOfHeaderString("End of Data Dictionary"); // End of data dictionary marker
6557 0 : print(state.files.eso, "{}\n", EndOfHeaderString);
6558 0 : print(state.files.mtr, "{}\n", EndOfHeaderString);
6559 0 : state.dataReportFlag->PrintEndDataDictionary = false;
6560 : }
6561 0 : if (state.dataGlobal->DoOutputReporting) {
6562 0 : constexpr const char *EnvironmentStampFormatStr("{},{},{:7.2F},{:7.2F},{:7.2F},{:7.2F}\n"); // Format descriptor for environ stamp
6563 0 : print(state.files.eso,
6564 : EnvironmentStampFormatStr,
6565 : "1",
6566 0 : "Warmup {" + state.dataReportFlag->cWarmupDay + "} " + state.dataEnvrn->EnvironmentName,
6567 0 : state.dataEnvrn->Latitude,
6568 0 : state.dataEnvrn->Longitude,
6569 0 : state.dataEnvrn->TimeZoneNumber,
6570 0 : state.dataEnvrn->Elevation);
6571 :
6572 0 : print(state.files.mtr,
6573 : EnvironmentStampFormatStr,
6574 : "1",
6575 0 : "Warmup {" + state.dataReportFlag->cWarmupDay + "} " + state.dataEnvrn->EnvironmentName,
6576 0 : state.dataEnvrn->Latitude,
6577 0 : state.dataEnvrn->Longitude,
6578 0 : state.dataEnvrn->TimeZoneNumber,
6579 0 : state.dataEnvrn->Elevation);
6580 0 : state.dataEnvrn->PrintEnvrnStampWarmup = false;
6581 : }
6582 : }
6583 0 : if (!state.dataGlobal->DoingSizing) {
6584 0 : CalcMoreNodeInfo(state);
6585 : }
6586 0 : UpdateDataandReport(state, OutputProcessor::TimeStepType::Zone);
6587 0 : if (state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeDesignDay ||
6588 0 : state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeRunPeriodDesign) {
6589 0 : if (state.dataHVACSizingSimMgr->hvacSizingSimulationManager)
6590 0 : state.dataHVACSizingSimMgr->hvacSizingSimulationManager->UpdateSizingLogsZoneStep(state);
6591 : }
6592 :
6593 2269224 : } else if (state.dataSysVars->UpdateDataDuringWarmupExternalInterface) { // added for FMI
6594 0 : UpdateDataandReport(state, OutputProcessor::TimeStepType::Zone);
6595 0 : if (state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeDesignDay ||
6596 0 : state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeRunPeriodDesign) {
6597 0 : if (state.dataHVACSizingSimMgr->hvacSizingSimulationManager)
6598 0 : state.dataHVACSizingSimMgr->hvacSizingSimulationManager->UpdateSizingLogsZoneStep(state);
6599 : }
6600 : }
6601 : // There is no hourly reporting in the heat balance.
6602 :
6603 : // There is no daily reporting in the heat balance.
6604 :
6605 : // There is no simulation level record keeping in the heat balance.
6606 2568312 : }
6607 :
6608 : // End of Reporting subroutines for the HB Module
6609 :
6610 0 : void OpenShadingFile(EnergyPlusData &state)
6611 : {
6612 :
6613 : // SUBROUTINE INFORMATION:
6614 : // AUTHOR X Luo
6615 : // DATE WRITTEN August 2017
6616 : // MODIFIED na
6617 : // RE-ENGINEERED na
6618 :
6619 : // PURPOSE OF THIS SUBROUTINE:
6620 : // Open and set up headers for a external shading fraction export file.
6621 :
6622 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6623 : int SurfNum;
6624 :
6625 0 : state.files.shade.ensure_open(state, "OpenOutputFiles", state.files.outputControl.extshd);
6626 0 : print(state.files.shade, "Surface Name,");
6627 0 : for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
6628 0 : print(state.files.shade, "{},", state.dataSurface->Surface(SurfNum).Name);
6629 : }
6630 0 : print(state.files.shade, "()\n");
6631 0 : }
6632 771 : void GetFrameAndDividerData(EnergyPlusData &state, bool &ErrorsFound) // set to true if errors found in input
6633 : {
6634 :
6635 : // SUBROUTINE INFORMATION:
6636 : // AUTHOR Fred Winkelmann
6637 : // DATE WRITTEN May 2000
6638 : // MODIFIED April 2002 (FCW): get window reveal data
6639 : // RE-ENGINEERED na
6640 :
6641 : // PURPOSE OF THIS SUBROUTINE:
6642 : // Gets input data for window frame and/or divider and/or window
6643 : // inside/outside reveal.
6644 :
6645 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6646 :
6647 : int IOStat; // IO Status when calling get input subroutine
6648 801 : Array1D_string FrameDividerAlphas(3); // Frame/Divider Alpha names
6649 : int FrameDividerNum; // Counter to keep track of the frame/divider number
6650 : int FrameDividerNumAlpha; // Number of frame/divider alpha names being passed
6651 : int FrameDividerNumProp; // Number of frame/divider properties being passed
6652 801 : Array1D<Real64> FrameDividerProps(23); // Temporary array to transfer frame/divider properties
6653 : int Loop;
6654 :
6655 771 : constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcProductNamesUC = {
6656 : "CASEMENTDOUBLE", "CASEMENTSINGLE", "DUALACTION",
6657 : "FIXED", "GARAGE", "GREENHOUSE",
6658 : "HINGEDESCAPE", "HORIZONTALSLIDER", "JAL",
6659 : "PIVOTED", "PROJECTINGSINGLE", "PROJECTINGDUAL",
6660 : "DOORSIDELITE", "SKYLIGHT", "SLIDINGPATIODOOR",
6661 : "CURTAINWALL", "SPANDRELPANEL", "SIDEHINGEDDOOR",
6662 : "DOORTRANSOM", "TROPICALAWNING", "TUBULARDAYLIGHTINGDEVICE",
6663 : "VERTICALSLIDER"};
6664 :
6665 771 : constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::FrameDividerType::Num)> FrameDividerTypeNamesUC = {
6666 : "DIVIDEDLITE", // 0
6667 : "SUSPENDED" // 1
6668 : };
6669 :
6670 771 : state.dataHeatBalMgr->CurrentModuleObject = "WindowProperty:FrameAndDivider";
6671 771 : state.dataHeatBal->TotFrameDivider =
6672 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHeatBalMgr->CurrentModuleObject);
6673 771 : state.dataSurface->FrameDivider.allocate(state.dataHeatBal->TotFrameDivider);
6674 771 : if (state.dataHeatBal->TotFrameDivider == 0) return;
6675 :
6676 30 : FrameDividerNum = 0;
6677 :
6678 67 : for (Loop = 1; Loop <= state.dataHeatBal->TotFrameDivider; ++Loop) {
6679 :
6680 : // Call Input Get routine to retrieve frame/divider data
6681 222 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
6682 37 : state.dataHeatBalMgr->CurrentModuleObject,
6683 : Loop,
6684 : FrameDividerAlphas,
6685 : FrameDividerNumAlpha,
6686 : FrameDividerProps,
6687 : FrameDividerNumProp,
6688 : IOStat,
6689 37 : state.dataIPShortCut->lNumericFieldBlanks,
6690 37 : state.dataIPShortCut->lAlphaFieldBlanks,
6691 37 : state.dataIPShortCut->cAlphaFieldNames,
6692 37 : state.dataIPShortCut->cNumericFieldNames);
6693 37 : if (UtilityRoutines::IsNameEmpty(state, FrameDividerAlphas(1), state.dataHeatBalMgr->CurrentModuleObject, ErrorsFound)) continue;
6694 :
6695 : // Load the frame/divider derived type from the input data.
6696 37 : ++FrameDividerNum;
6697 37 : auto &frameDivider = state.dataSurface->FrameDivider(FrameDividerNum);
6698 37 : frameDivider.Name = FrameDividerAlphas(1);
6699 37 : frameDivider.FrameWidth = FrameDividerProps(1);
6700 37 : frameDivider.FrameProjectionOut = FrameDividerProps(2);
6701 37 : frameDivider.FrameProjectionIn = FrameDividerProps(3);
6702 37 : if (frameDivider.FrameWidth == 0.0) {
6703 6 : frameDivider.FrameProjectionOut = 0.0;
6704 6 : frameDivider.FrameProjectionIn = 0.0;
6705 : }
6706 37 : frameDivider.FrameConductance = FrameDividerProps(4);
6707 37 : frameDivider.FrEdgeToCenterGlCondRatio = FrameDividerProps(5);
6708 37 : frameDivider.FrameSolAbsorp = FrameDividerProps(6);
6709 37 : frameDivider.FrameVisAbsorp = FrameDividerProps(7);
6710 37 : frameDivider.FrameEmis = FrameDividerProps(8);
6711 :
6712 : DataSurfaces::FrameDividerType currentDividerType =
6713 37 : DataSurfaces::FrameDividerType(getEnumerationValue(FrameDividerTypeNamesUC, FrameDividerAlphas(2)));
6714 37 : if (currentDividerType == DataSurfaces::FrameDividerType::Invalid) {
6715 0 : ShowWarningError(state,
6716 0 : fmt::format("{}={}, Invalid {}",
6717 0 : state.dataHeatBalMgr->CurrentModuleObject,
6718 0 : std::quoted(FrameDividerAlphas(1)),
6719 0 : state.dataIPShortCut->cAlphaFieldNames(2)));
6720 0 : ShowContinueError(
6721 : state,
6722 0 : fmt::format("Entered={}, must be DividedLite or Suspended. Will be set to DividedLite.", std::quoted(FrameDividerAlphas(2))));
6723 0 : frameDivider.DividerType = DataSurfaces::FrameDividerType::DividedLite;
6724 : } else {
6725 37 : frameDivider.DividerType = currentDividerType;
6726 : }
6727 :
6728 37 : frameDivider.DividerWidth = FrameDividerProps(9);
6729 37 : frameDivider.HorDividers = FrameDividerProps(10);
6730 37 : frameDivider.VertDividers = FrameDividerProps(11);
6731 37 : frameDivider.DividerProjectionOut = FrameDividerProps(12);
6732 37 : frameDivider.DividerProjectionIn = FrameDividerProps(13);
6733 37 : if (frameDivider.DividerWidth == 0.0 || frameDivider.DividerType == DataSurfaces::FrameDividerType::Suspended) {
6734 17 : frameDivider.DividerProjectionOut = 0.0;
6735 17 : frameDivider.DividerProjectionIn = 0.0;
6736 : }
6737 37 : frameDivider.DividerConductance = FrameDividerProps(14);
6738 37 : frameDivider.DivEdgeToCenterGlCondRatio = FrameDividerProps(15);
6739 37 : frameDivider.DividerSolAbsorp = FrameDividerProps(16);
6740 37 : frameDivider.DividerVisAbsorp = FrameDividerProps(17);
6741 37 : frameDivider.DividerEmis = FrameDividerProps(18);
6742 :
6743 : // look up the NFRC Product Type for Assembly Calculations using the DataSurfaces::NfrcProductName
6744 37 : frameDivider.NfrcProductType = DataSurfaces::NfrcProductOptions(getEnumerationValue(NfrcProductNamesUC, FrameDividerAlphas(3)));
6745 37 : if (frameDivider.NfrcProductType == DataSurfaces::NfrcProductOptions::Invalid) {
6746 0 : frameDivider.NfrcProductType = DataSurfaces::NfrcProductOptions::CurtainWall;
6747 : }
6748 :
6749 37 : frameDivider.OutsideRevealSolAbs = FrameDividerProps(19);
6750 37 : frameDivider.InsideSillDepth = FrameDividerProps(20);
6751 37 : frameDivider.InsideSillSolAbs = FrameDividerProps(21);
6752 37 : frameDivider.InsideReveal = FrameDividerProps(22);
6753 37 : frameDivider.InsideRevealSolAbs = FrameDividerProps(23);
6754 :
6755 37 : if (frameDivider.DividerWidth > 0.0 && (frameDivider.HorDividers == 0 && frameDivider.VertDividers == 0)) {
6756 0 : ShowWarningError(state,
6757 0 : state.dataHeatBalMgr->CurrentModuleObject + ": In FrameAndDivider " + frameDivider.Name + ' ' +
6758 0 : state.dataIPShortCut->cNumericFieldNames(9) + " > 0 ");
6759 0 : ShowContinueError(state,
6760 0 : "...but " + state.dataIPShortCut->cNumericFieldNames(10) + " = 0 and " +
6761 0 : state.dataIPShortCut->cNumericFieldNames(11) + " = 0.");
6762 0 : ShowContinueError(state, "..." + state.dataIPShortCut->cNumericFieldNames(9) + " set to 0.");
6763 0 : frameDivider.DividerWidth = 0.0;
6764 : }
6765 : // Prevent InsideSillDepth < InsideReveal
6766 37 : if (frameDivider.InsideSillDepth < state.dataSurface->FrameDivider(FrameDividerNum).InsideReveal) {
6767 0 : ShowWarningError(state,
6768 0 : state.dataHeatBalMgr->CurrentModuleObject + ": In FrameAndDivider " + frameDivider.Name + ' ' +
6769 0 : state.dataIPShortCut->cNumericFieldNames(20) + " is less than " + state.dataIPShortCut->cNumericFieldNames(22) +
6770 0 : "; it will be set to " + state.dataIPShortCut->cNumericFieldNames(22) + '.');
6771 0 : frameDivider.InsideSillDepth = state.dataSurface->FrameDivider(FrameDividerNum).InsideReveal;
6772 : }
6773 :
6774 : // ! Warn if InsideSillDepth OR InsideReveal > 0.2meters to warn of inaccuracies
6775 : // IF(FrameDivider(FrameDividerNum)%InsideSillDepth > 0.2d0) THEN
6776 : // CALL ShowWarningError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//': In FrameAndDivider
6777 : // '//TRIM(FrameDivider(FrameDividerNum)%Name)// &
6778 : // ' '//TRIM(cNumericFieldNames(20))//' is greater than 0.2 meters, which could cause inaccuracies in zone cooling energy.')
6779 : // END IF
6780 : // IF(FrameDivider(FrameDividerNum)%InsideReveal > 0.2d0) THEN
6781 : // CALL ShowWarningError(state, TRIM(state.dataHeatBalMgr->CurrentModuleObject)//': In FrameAndDivider
6782 : // '//TRIM(FrameDivider(FrameDividerNum)%Name)// &
6783 : // ' '//TRIM(cNumericFieldNames(22))//' is greater than 0.2 meters, which could cause inaccuracies in zone cooling energy.')
6784 : // END IF
6785 : }
6786 : }
6787 :
6788 5 : void SearchWindow5DataFile(EnergyPlusData &state,
6789 : fs::path const &DesiredFilePath, // File path that contains the Window5 constructions.
6790 : std::string const &DesiredConstructionName, // Name that will be searched for in the Window5 data file
6791 : bool &ConstructionFound, // True if DesiredConstructionName is in the Window5 data file
6792 : bool &EOFonFile, // True if EOF during file read
6793 : bool &ErrorsFound // True if there is a problem with the entry requested from the data file
6794 : )
6795 : {
6796 :
6797 : // SUBROUTINE INFORMATION:
6798 : // AUTHOR Fred Winkelmann
6799 : // DATE WRITTEN August 2001
6800 : // MODIFIED June 2002, FW: do all reallocation here for constructions found on
6801 : // data file; 1 new construction of entry has one glazing system;
6802 : // 2 new constructions if entry has two glazing systems.
6803 : // Nov 2002, FW: skip read of mullion data line if one glazing system;
6804 : // add error messages for bad data; increase length of input line
6805 : // from 132 to 200 to handle case where Window5 puts in extra blanks
6806 : // in gas data line.
6807 : // Feb 2007, LKL: Add more checks on Window5DataFile
6808 : // Jan 2008, LKL: Change Edge/Cond ratio check.
6809 : // RE-ENGINEERED na
6810 :
6811 : // PURPOSE OF THIS SUBROUTINE:
6812 : // Searches the WINDOW5 data file for a window with the name "DesiredConstructionName,"
6813 : // which is the name of an idf Construction input using CONSTRUCTION FROM WINDOW5 DATA FILE.
6814 : // (The WINDOW5 data file contains data for one or more complete windows --
6815 : // glazing, frame, mullion, and divider.
6816 : // WINDOW5 writes the data file for export to EnergyPlus so that an annual energy
6817 : // analysis can be done on exactly the same window without having to re-input into
6818 : // EnergyPlus.)
6819 :
6820 : // If a match is found, a Construction is created and the Material objects associated with
6821 : // the Construction are created. If there is an associated frame or
6822 : // divider in the Window5 data file for this Construction, a FrameAndDivider object will
6823 : // also be created.
6824 :
6825 : // If the window on the data file has two glazing systems, a second Construction (and its
6826 : // associated materials) corresponding to the second glazing system is created.
6827 :
6828 : // Using/Aliasing
6829 : using namespace DataStringGlobals;
6830 : using DataSystemVariables::CheckForActualFilePath;
6831 : using General::POLYF; // POLYF ! Polynomial in cosine of angle of incidence
6832 :
6833 : // SUBROUTINE PARAMETER DEFINITIONS:
6834 5 : Array1D_string const NumName(5, {"1", "2", "3", "4", "5"});
6835 :
6836 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6837 : int FileLineCount; // counter for number of lines read (used in some error messages)
6838 5 : Array1D_string DataLine(100); // Array of data lines
6839 5 : std::string WindowNameInW5DataFile;
6840 5 : std::string W5Name;
6841 5 : Array1D_string GasName(3); // Gas name from data file
6842 5 : std::string LayerName; // Layer name from data file
6843 5 : std::string MullionOrientation; // Horizontal, vertical or none
6844 : int LineNum;
6845 5 : Array1D_int NGlass(2); // Number of glass layers in glazing system
6846 5 : Array2D_int NumGases(4, 2); // Number of gases in each gap of a glazing system
6847 5 : Array2D_int MaterNumSysGlass(5, 2); // Material numbers for glazing system / glass combinations
6848 5 : Array2D_int MaterNumSysGap(4, 2); // Material numbers for glazing system / gap combinations
6849 : int TotMaterialsPrev; // Number of materials before adding ones from W5DataFile
6850 : int TotFrameDividerPrev; // Number of FrameAndDivider objects before adding ones from W5DataFile
6851 5 : Array1D_int NGaps(2); // Number of gaps in window construction
6852 : int NGlSys; // Number of glazing systems (normally 1, but 2 for mullioned window
6853 : // with two different glazing systems
6854 : int loop; // DO loop counter
6855 : int ILine; // Line counter
6856 : int ConstrNum; // Construction number
6857 : int IGlass; // Glass layer counter
6858 : int IGap; // Gap counter
6859 : int IGas; // Gas counter
6860 : // INTEGER :: ICoeff ! Gas property coefficient counter
6861 : int IGlSys; // Glazing system counter
6862 : int MaterNum; // Material number
6863 : int MatNum;
6864 : int FrDivNum; // FrameDivider number
6865 5 : Array1D<Real64> WinHeight(2); // Height, width for glazing system (m)
6866 5 : Array1D<Real64> WinWidth(2);
6867 5 : Array1D<Real64> UValCenter(2); // Center of glass U-value (W/m2-K) for glazing system
6868 5 : Array1D<Real64> SCCenter(2); // Center of glass shading coefficient for glazing system
6869 5 : Array1D<Real64> SHGCCenter(2); // Center of glass solar heat gain coefficient for glazing system
6870 5 : Array1D<Real64> TVisCenter(2); // Center of glass visible transmittance for glazing system
6871 5 : Array1D<Real64> Tsol(11); // Solar transmittance vs incidence angle; diffuse trans.
6872 5 : Array2D<Real64> AbsSol(11, 5); // Solar absorptance vs inc. angle in each glass layer
6873 5 : Array1D<Real64> Rfsol(11); // Front solar reflectance vs inc. angle
6874 5 : Array1D<Real64> Rbsol(11); // Back solar reflectance vs inc. angle
6875 5 : Array1D<Real64> Tvis(11); // Visible transmittance vs inc. angle
6876 5 : Array1D<Real64> Rfvis(11); // Front visible reflectance vs inc. angle
6877 5 : Array1D<Real64> Rbvis(11); // Back visible reflectance vs inc. angle
6878 5 : Array1D<Real64> CosPhiIndepVar(10); // Cosine of incidence angle from 0 to 90 deg in 10 deg increments
6879 : int IPhi; // Incidence angle counter
6880 : Real64 Phi; // Incidence angle (deg)
6881 5 : Array1D<Real64> CosPhi(10); // Cosine of incidence angle
6882 5 : Array1D<Real64> tsolFit(10); // Fitted solar transmittance vs incidence angle
6883 5 : Array1D<Real64> tvisFit(10); // Fitted visible transmittance vs incidence angle
6884 5 : Array1D<Real64> rfsolFit(10); // Fitted solar front reflectance vs incidence angle
6885 5 : Array2D<Real64> solabsFit(5, 10); // Fitted solar absorptance vs incidence angle for each glass layer
6886 5 : Array1D_string DividerType(2); // Divider type: DividedLite or Suspended
6887 : Real64 FrameWidth;
6888 : Real64 MullionWidth;
6889 : Real64 FrameProjectionOut;
6890 : Real64 FrameProjectionIn;
6891 : Real64 FrameConductance;
6892 : Real64 FrEdgeToCenterGlCondRatio;
6893 : Real64 FrameSolAbsorp;
6894 : Real64 FrameVisAbsorp;
6895 : Real64 FrameEmis;
6896 5 : Array1D_int HorDividers(2); // For divider: number horizontal for each glazing system
6897 5 : Array1D_int VertDividers(2); // For divider: number vertical for each glazing system
6898 5 : Array1D<Real64> DividerWidth(2);
6899 5 : Array1D<Real64> DividerProjectionOut(2);
6900 5 : Array1D<Real64> DividerProjectionIn(2);
6901 5 : Array1D<Real64> DividerConductance(2);
6902 5 : Array1D<Real64> DivEdgeToCenterGlCondRatio(2);
6903 5 : Array1D<Real64> DividerSolAbsorp(2);
6904 5 : Array1D<Real64> DividerVisAbsorp(2);
6905 5 : Array1D<Real64> DividerEmis(2);
6906 : std::string::size_type endcol;
6907 :
6908 : // Object Data
6909 :
6910 : // In the following four gas-related data sets, the first
6911 : // index is gas type (1=air, 2=Argon, 3=Krypton, 4=Xenon)
6912 : // and the second index gives a,b,c in the expression
6913 : // property value = a + bT(K) + cT(K)**2, where T is mean
6914 : // gap temperature in deg K.
6915 :
6916 5 : ConstructionFound = false;
6917 : // ErrorsFound = .FALSE.
6918 5 : EOFonFile = false;
6919 5 : std::string contextString = "HeatBalanceManager::SearchWindow5DataFile: ";
6920 :
6921 5 : state.files.TempFullFilePath.filePath = CheckForActualFilePath(state, DesiredFilePath, contextString);
6922 :
6923 : // INQUIRE(FILE=TRIM(DesiredFileName), EXIST=exists)
6924 5 : if (state.files.TempFullFilePath.filePath.empty()) {
6925 0 : ShowFatalError(state, "Program terminates due to these conditions.");
6926 : }
6927 :
6928 5 : auto W5DataFile = state.files.TempFullFilePath.open(state, "SearchWindow5DataFile");
6929 5 : auto NextLine = W5DataFile.readLine();
6930 5 : endcol = len(NextLine.data);
6931 5 : if (endcol > 0) {
6932 5 : if (int(NextLine.data[endcol - 1]) == DataSystemVariables::iUnicode_end) {
6933 0 : ShowSevereError(state,
6934 0 : "SearchWindow5DataFile: For \"" + DesiredConstructionName + "\" in " + DesiredFilePath.string() +
6935 : " fiile, appears to be a Unicode or binary file.");
6936 0 : ShowContinueError(state, "...This file cannot be read by this program. Please save as PC or Unix file and try again");
6937 0 : ShowFatalError(state, "Program terminates due to previous condition.");
6938 : }
6939 : }
6940 5 : W5DataFile.rewind();
6941 5 : FileLineCount = 0;
6942 :
6943 5 : NextLine = W5DataFile.readLine();
6944 5 : if (NextLine.eof) goto Label1000;
6945 5 : ++FileLineCount;
6946 5 : if (!has_prefixi(NextLine.data, "WINDOW5")) {
6947 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Data File=" + DesiredFilePath.string());
6948 0 : ShowFatalError(
6949 0 : state, "Error reading Window5 Data File: first word of window entry is \"" + NextLine.data.substr(0, 7) + "\", should be Window5.");
6950 : }
6951 :
6952 10 : Label10:;
6953 25 : for (LineNum = 2; LineNum <= 5; ++LineNum) {
6954 20 : NextLine = W5DataFile.readLine();
6955 20 : if (NextLine.eof) goto Label1000;
6956 20 : DataLine(LineNum) = NextLine.data;
6957 20 : ++FileLineCount;
6958 : }
6959 :
6960 : // Get window name and check for match
6961 5 : W5Name = std::string{DataLine(4).substr(19)};
6962 5 : WindowNameInW5DataFile = UtilityRoutines::MakeUPPERCase(W5Name);
6963 5 : if (DesiredConstructionName != WindowNameInW5DataFile) {
6964 : // Doesn't match; read through file until next window entry is found
6965 0 : Label20:;
6966 0 : NextLine = W5DataFile.readLine();
6967 0 : if (NextLine.eof) goto Label1000;
6968 0 : ++FileLineCount;
6969 0 : if (!has_prefixi(NextLine.data, "WINDOW5")) goto Label20;
6970 : // Beginning of next window entry found
6971 0 : goto Label10;
6972 : } else {
6973 : // Match found
6974 5 : ConstructionFound = true;
6975 :
6976 : // Create Material:WindowGlass, Material:WindowGas, Construction
6977 : // and WindowFrameAndDividerObjects for this window
6978 :
6979 5 : NextLine = W5DataFile.readLine();
6980 5 : if (NextLine.eof) goto Label1000;
6981 5 : ++FileLineCount;
6982 5 : bool error = false;
6983 5 : NGlSys = static_cast<int>(UtilityRoutines::ProcessNumber(NextLine.data.substr(19), error));
6984 5 : if (NGlSys <= 0 || NGlSys > 2 || error) {
6985 0 : ShowFatalError(
6986 : state,
6987 0 : format("Construction={} from the Window5 data file cannot be used: it has {} glazing systems; only 1 or 2 are allowed.",
6988 : DesiredConstructionName,
6989 0 : NGlSys));
6990 : }
6991 5 : NextLine = W5DataFile.readLine();
6992 5 : if (NextLine.eof) goto Label1000;
6993 5 : ++FileLineCount;
6994 10 : for (IGlSys = 1; IGlSys <= NGlSys; ++IGlSys) {
6995 5 : NextLine = W5DataFile.readLine();
6996 5 : if (NextLine.eof) goto Label1000;
6997 5 : ++FileLineCount;
6998 :
6999 10 : const auto succeeded = readList(NextLine.data.substr(19),
7000 : WinHeight(IGlSys),
7001 : WinWidth(IGlSys),
7002 : NGlass(IGlSys),
7003 : UValCenter(IGlSys),
7004 : SCCenter(IGlSys),
7005 : SHGCCenter(IGlSys),
7006 5 : TVisCenter(IGlSys));
7007 5 : if (!succeeded) {
7008 0 : ShowSevereError(
7009 : state,
7010 0 : format("HeatBalanceManager: SearchWindow5DataFile: Error in Read of glazing system values. For glazing system={}", IGlSys));
7011 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount, NextLine.data.substr(0, 100)));
7012 0 : ErrorsFound = true;
7013 : }
7014 5 : if (WinHeight(IGlSys) == 0.0 || WinWidth(IGlSys) == 0.0) {
7015 0 : ShowSevereError(state,
7016 0 : format("HeatBalanceManager: SearchWindow5DataFile: Construction={} from the Window5 data file cannot be used: it "
7017 : "has window height or width = 0 for glazing system {}",
7018 : DesiredConstructionName,
7019 0 : IGlSys));
7020 0 : ErrorsFound = true;
7021 : }
7022 5 : if (NGlass(IGlSys) <= 0 || NGlass(IGlSys) > 4) {
7023 0 : ShowSevereError(state,
7024 0 : format("HeatBalanceManager: SearchWindow5DataFile: Construction={} from the Window5 data file cannot be used: it "
7025 : "has 0 or more than 4 glass layers in glazing system {}",
7026 : DesiredConstructionName,
7027 0 : IGlSys));
7028 0 : ErrorsFound = true;
7029 : }
7030 5 : if (UValCenter(IGlSys) <= 0.0) {
7031 0 : ShowSevereError(state,
7032 0 : format("HeatBalanceManager: SearchWindow5DataFile: Construction={} from the Window5 data file cannot be used: it "
7033 : "has Center-of-Glass U-value <= 0 in glazing system {}",
7034 : DesiredConstructionName,
7035 0 : IGlSys));
7036 0 : ErrorsFound = true;
7037 : }
7038 5 : if (SCCenter(IGlSys) <= 0.0) {
7039 0 : ShowWarningError(
7040 : state,
7041 0 : format("HeatBalanceManager: SearchWindow5DataFile: Construction={} from the Window5 data file has flawed data: it "
7042 : "has a Shading Coefficient <= 0 in glazing system {}",
7043 : DesiredConstructionName,
7044 0 : IGlSys));
7045 : }
7046 5 : if (SHGCCenter(IGlSys) <= 0.0) {
7047 0 : ShowWarningError(
7048 : state,
7049 0 : format("HeatBalanceManager: SearchWindow5DataFile: Construction={} from the Window5 data file has flawed data: it "
7050 : "has a SHGC <= 0 in glazing system {}",
7051 : DesiredConstructionName,
7052 0 : IGlSys));
7053 : }
7054 5 : WinHeight(IGlSys) *= 0.001;
7055 5 : WinWidth(IGlSys) *= 0.001;
7056 : }
7057 60 : for (LineNum = 1; LineNum <= 11; ++LineNum) {
7058 55 : NextLine = W5DataFile.readLine();
7059 55 : if (NextLine.eof) goto Label1000;
7060 55 : DataLine(LineNum) = NextLine.data;
7061 : }
7062 :
7063 : // Mullion width and orientation
7064 5 : MullionWidth = 0.0;
7065 5 : MullionOrientation = "Vertical";
7066 5 : if (NGlSys == 2) {
7067 0 : error = false;
7068 0 : MullionWidth = UtilityRoutines::ProcessNumber(DataLine(10).substr(19), error);
7069 0 : if (error) {
7070 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Mullion Width.");
7071 0 : ShowContinueError(state,
7072 0 : format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 10, DataLine(10).substr(0, 100)));
7073 0 : ErrorsFound = true;
7074 : }
7075 0 : MullionWidth *= 0.001;
7076 0 : MullionOrientation = UtilityRoutines::ProcessNumber(DataLine(10).substr(88), error);
7077 0 : if (error) {
7078 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Mullion Orientation.");
7079 0 : ShowContinueError(state,
7080 0 : format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 10, DataLine(10).substr(0, 100)));
7081 0 : ErrorsFound = true;
7082 : }
7083 : }
7084 :
7085 : // Frame data; if there are two glazing systems, the frame is assumed to be
7086 : // the same for both.
7087 5 : FrameWidth = 0.0;
7088 5 : FrameProjectionOut = 0.0;
7089 5 : FrameProjectionIn = 0.0;
7090 5 : FrameConductance = 0.0;
7091 5 : FrEdgeToCenterGlCondRatio = 0.0;
7092 5 : FrameSolAbsorp = 0.0;
7093 5 : FrameVisAbsorp = 0.0;
7094 5 : FrameEmis = 0.0;
7095 10 : const bool succeeded = readList(DataLine(11).substr(19),
7096 : FrameWidth,
7097 : FrameProjectionOut,
7098 : FrameProjectionIn,
7099 : FrameConductance,
7100 : FrEdgeToCenterGlCondRatio,
7101 : FrameSolAbsorp,
7102 : FrameVisAbsorp,
7103 5 : FrameEmis);
7104 5 : if (!succeeded) {
7105 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of frame data values.");
7106 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 11, DataLine(11).substr(0, 100)));
7107 0 : ErrorsFound = true;
7108 : }
7109 5 : if (FrameWidth > 0.0) {
7110 5 : if (FrameConductance <= 0.0) {
7111 0 : ShowSevereError(state,
7112 0 : "HeatBalanceManager: SearchWindow5DataFile: Construction=" + DesiredConstructionName +
7113 : " from the Window5 data file cannot be used: it has Frame Conductance <= 0.0");
7114 0 : ErrorsFound = true;
7115 : }
7116 : // Relax this check for Window5 data: 1/28/2008.
7117 : // IF(FrEdgeToCenterGlCondRatio < 1.0) THEN
7118 : // CALL ShowSevereError(state, 'HeatBalanceManager: SearchWindow5DataFile: Construction='//TRIM(DesiredConstructionName)//
7119 : // & ' from the Window5 data file cannot be used: it has Frame Edge-of-Glass Conduction Ratio < 1.0')
7120 : // ErrorsFound = .TRUE.
7121 : // END IF
7122 5 : if (FrameSolAbsorp < 0.0 || FrameSolAbsorp > 1.0) {
7123 0 : ShowSevereError(state,
7124 0 : "HeatBalanceManager: SearchWindow5DataFile: Construction=" + DesiredConstructionName +
7125 : " from the Window5 data file cannot be used: it has Frame Solar Absorptance < 0.0 or > 1.0");
7126 0 : ErrorsFound = true;
7127 : }
7128 5 : if (FrameEmis <= 0.0 || FrameEmis >= 1.0) {
7129 0 : ShowSevereError(state,
7130 0 : "HeatBalanceManager: SearchWindow5DataFile: Construction=" + DesiredConstructionName +
7131 : " from the Window5 data file cannot be used: it has Frame Emissivity <= 0.0 or >= 1.0");
7132 0 : ErrorsFound = true;
7133 : }
7134 : }
7135 5 : FrameWidth *= 0.001;
7136 5 : FrameProjectionOut *= 0.001;
7137 5 : FrameProjectionIn *= 0.001;
7138 5 : FileLineCount += 11;
7139 :
7140 5 : NextLine = W5DataFile.readLine();
7141 5 : if (NextLine.eof) goto Label1000;
7142 5 : ++FileLineCount;
7143 :
7144 : // Divider data for each glazing system
7145 10 : for (IGlSys = 1; IGlSys <= NGlSys; ++IGlSys) {
7146 5 : NextLine = W5DataFile.readLine();
7147 5 : if (NextLine.eof) goto Label1000;
7148 5 : ++FileLineCount;
7149 :
7150 10 : const bool dividerReadSucceeded = readList(NextLine.data.substr(19),
7151 : DividerWidth(IGlSys),
7152 : DividerProjectionOut(IGlSys),
7153 : DividerProjectionIn(IGlSys),
7154 : DividerConductance(IGlSys),
7155 : DivEdgeToCenterGlCondRatio(IGlSys),
7156 : DividerSolAbsorp(IGlSys),
7157 : DividerVisAbsorp(IGlSys),
7158 : DividerEmis(IGlSys),
7159 : DividerType(IGlSys),
7160 : HorDividers(IGlSys),
7161 5 : VertDividers(IGlSys));
7162 5 : if (!dividerReadSucceeded) {
7163 0 : ShowSevereError(
7164 : state,
7165 0 : format("HeatBalanceManager: SearchWindow5DataFile: Error in Read of divider data values. For Glazing System={}", IGlSys));
7166 0 : ShowContinueError(state,
7167 0 : format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 11, NextLine.data.substr(0, 100)));
7168 0 : ErrorsFound = true;
7169 : }
7170 5 : uppercase(DividerType(IGlSys));
7171 5 : if (DividerWidth(IGlSys) > 0.0) {
7172 5 : if (HorDividers(IGlSys) == 0 && VertDividers(IGlSys) == 0) {
7173 0 : ShowSevereError(state,
7174 0 : "HeatBalanceManager: SearchWindow5DataFile: Construction=" + DesiredConstructionName +
7175 : " from the Window5 data file cannot be used:");
7176 0 : ShowContinueError(
7177 0 : state, format("glazing system {} has a divider but number of horizontal and vertical divider elements = 0", IGlSys));
7178 0 : ErrorsFound = true;
7179 : }
7180 5 : if (DividerConductance(IGlSys) <= 0.0) {
7181 0 : ShowSevereError(state,
7182 0 : "HeatBalanceManager: SearchWindow5DataFile: Construction=" + DesiredConstructionName +
7183 : " from the Window5 data file cannot be used:");
7184 0 : ShowContinueError(state, format("glazing system {} has Divider Conductance <= 0.0", IGlSys));
7185 0 : ErrorsFound = true;
7186 : }
7187 5 : if (DivEdgeToCenterGlCondRatio(IGlSys) < 1.0) {
7188 0 : ShowSevereError(state,
7189 0 : "HeatBalanceManager: SearchWindow5DataFile: Construction=" + DesiredConstructionName +
7190 : " from the Window5 data file cannot be used:");
7191 0 : ShowContinueError(state, format("glazing system {} has Divider Edge-Of-Glass Conduction Ratio < 1.0", IGlSys));
7192 0 : ErrorsFound = true;
7193 : }
7194 5 : if (DividerSolAbsorp(IGlSys) < 0.0 || DividerSolAbsorp(IGlSys) > 1.0) {
7195 0 : ShowSevereError(state,
7196 0 : "HeatBalanceManager: SearchWindow5DataFile: Construction=" + DesiredConstructionName +
7197 : " from the Window5 data file cannot be used:");
7198 0 : ShowContinueError(state, format("glazing system {} has Divider Solar Absorptance < 0.0 or > 1.0", IGlSys));
7199 0 : ErrorsFound = true;
7200 : }
7201 5 : if (DividerEmis(IGlSys) <= 0.0 || DividerEmis(IGlSys) >= 1.0) {
7202 0 : ShowSevereError(state,
7203 0 : "HeatBalanceManager: SearchWindow5DataFile: Construction=" + DesiredConstructionName +
7204 : " from the Window5 data file cannot be used:");
7205 0 : ShowContinueError(state, format("glazing system {} has Divider Emissivity <= 0.0 or >= 1.0", IGlSys));
7206 0 : ErrorsFound = true;
7207 : }
7208 5 : if (DividerType(IGlSys) != "DIVIDEDLITE" && DividerType(IGlSys) != "SUSPENDED") {
7209 0 : ShowSevereError(state,
7210 0 : "HeatBalanceManager: SearchWindow5DataFile: Construction=" + DesiredConstructionName +
7211 : " from the Window5 data file cannot be used:");
7212 0 : ShowContinueError(
7213 : state,
7214 0 : format("glazing system {} has Divider Type = {}; it should be DIVIDEDLITE or SUSPENDED.", IGlSys, DividerType(IGlSys)));
7215 0 : ErrorsFound = true;
7216 : }
7217 : }
7218 5 : DividerWidth(IGlSys) *= 0.001;
7219 5 : if (DividerType(IGlSys) == "DIVIDEDLITE") {
7220 0 : DividerProjectionOut(IGlSys) *= 0.001;
7221 0 : DividerProjectionIn(IGlSys) *= 0.001;
7222 : } else {
7223 5 : DividerProjectionOut(IGlSys) = 0.0;
7224 5 : DividerProjectionIn(IGlSys) = 0.0;
7225 : }
7226 : }
7227 :
7228 5 : if (ErrorsFound)
7229 0 : ShowFatalError(state,
7230 0 : "HeatBalanceManager: SearchWindow5DataFile: Construction=" + DesiredConstructionName +
7231 : " from the Window5 data file cannot be used because of above errors");
7232 :
7233 5 : TotMaterialsPrev = state.dataHeatBal->TotMaterials;
7234 10 : for (IGlSys = 1; IGlSys <= NGlSys; ++IGlSys) {
7235 5 : NGaps(IGlSys) = NGlass(IGlSys) - 1;
7236 5 : state.dataHeatBal->TotMaterials += NGlass(IGlSys) + NGaps(IGlSys);
7237 : }
7238 :
7239 : // Create Material objects
7240 :
7241 : // reallocate Material type
7242 :
7243 5 : state.dataMaterial->Material.redimension(state.dataHeatBal->TotMaterials);
7244 5 : state.dataHeatBal->NominalR.redimension(state.dataHeatBal->TotMaterials, 0.0);
7245 :
7246 : // Initialize new materials
7247 20 : for (loop = TotMaterialsPrev + 1; loop <= state.dataHeatBal->TotMaterials; ++loop) {
7248 15 : state.dataMaterial->Material(loop).Name = "";
7249 15 : state.dataMaterial->Material(loop).Group = DataHeatBalance::MaterialGroup::Invalid;
7250 15 : state.dataMaterial->Material(loop).Roughness = DataSurfaces::SurfaceRoughness::Invalid;
7251 15 : state.dataMaterial->Material(loop).Conductivity = 0.0;
7252 15 : state.dataMaterial->Material(loop).Density = 0.0;
7253 15 : state.dataMaterial->Material(loop).IsoMoistCap = 0.0;
7254 15 : state.dataMaterial->Material(loop).Porosity = 0.0;
7255 15 : state.dataMaterial->Material(loop).Resistance = 0.0;
7256 15 : state.dataMaterial->Material(loop).SpecHeat = 0.0;
7257 15 : state.dataMaterial->Material(loop).ThermGradCoef = 0.0;
7258 15 : state.dataMaterial->Material(loop).Thickness = 0.0;
7259 15 : state.dataMaterial->Material(loop).VaporDiffus = 0.0;
7260 15 : state.dataMaterial->Material(loop).AbsorpSolar = 0.0;
7261 15 : state.dataMaterial->Material(loop).AbsorpThermal = 0.0;
7262 15 : state.dataMaterial->Material(loop).AbsorpVisible = 0.0;
7263 15 : state.dataMaterial->Material(loop).ReflectShade = 0.0;
7264 15 : state.dataMaterial->Material(loop).Trans = 0.0;
7265 15 : state.dataMaterial->Material(loop).ReflectShadeVis = 0.0;
7266 15 : state.dataMaterial->Material(loop).TransVis = 0.0;
7267 15 : state.dataMaterial->Material(loop).GlassTransDirtFactor = 1.0;
7268 15 : state.dataMaterial->Material(loop).SolarDiffusing = false;
7269 15 : state.dataMaterial->Material(loop).AbsorpThermalBack = 0.0;
7270 15 : state.dataMaterial->Material(loop).AbsorpThermalFront = 0.0;
7271 15 : state.dataMaterial->Material(loop).ReflectSolBeamBack = 0.0;
7272 15 : state.dataMaterial->Material(loop).ReflectSolBeamFront = 0.0;
7273 15 : state.dataMaterial->Material(loop).ReflectSolDiffBack = 0.0;
7274 15 : state.dataMaterial->Material(loop).ReflectSolDiffFront = 0.0;
7275 15 : state.dataMaterial->Material(loop).ReflectVisBeamBack = 0.0;
7276 15 : state.dataMaterial->Material(loop).ReflectVisBeamFront = 0.0;
7277 15 : state.dataMaterial->Material(loop).ReflectVisDiffBack = 0.0;
7278 15 : state.dataMaterial->Material(loop).ReflectVisDiffFront = 0.0;
7279 15 : state.dataMaterial->Material(loop).TransSolBeam = 0.0;
7280 15 : state.dataMaterial->Material(loop).TransThermal = 0.0;
7281 15 : state.dataMaterial->Material(loop).TransVisBeam = 0.0;
7282 15 : state.dataMaterial->Material(loop).GlassSpectralDataPtr = 0;
7283 15 : state.dataMaterial->Material(loop).NumberOfGasesInMixture = 0;
7284 15 : state.dataMaterial->Material(loop).GasCon = 0.0;
7285 15 : state.dataMaterial->Material(loop).GasVis = 0.0;
7286 15 : state.dataMaterial->Material(loop).GasCp = 0.0;
7287 15 : state.dataMaterial->Material(loop).GasType = 0;
7288 15 : state.dataMaterial->Material(loop).GasWght = 0.0;
7289 15 : state.dataMaterial->Material(loop).GasSpecHeatRatio = 0.0;
7290 15 : state.dataMaterial->Material(loop).GasFract = 0.0;
7291 15 : state.dataMaterial->Material(loop).WinShadeToGlassDist = 0.0;
7292 15 : state.dataMaterial->Material(loop).WinShadeTopOpeningMult = 0.0;
7293 15 : state.dataMaterial->Material(loop).WinShadeBottomOpeningMult = 0.0;
7294 15 : state.dataMaterial->Material(loop).WinShadeLeftOpeningMult = 0.0;
7295 15 : state.dataMaterial->Material(loop).WinShadeRightOpeningMult = 0.0;
7296 15 : state.dataMaterial->Material(loop).WinShadeAirFlowPermeability = 0.0;
7297 15 : state.dataMaterial->Material(loop).BlindDataPtr = 0;
7298 15 : state.dataMaterial->Material(loop).EMPDmu = 0.0;
7299 15 : state.dataMaterial->Material(loop).MoistACoeff = 0.0;
7300 15 : state.dataMaterial->Material(loop).MoistBCoeff = 0.0;
7301 15 : state.dataMaterial->Material(loop).MoistCCoeff = 0.0;
7302 15 : state.dataMaterial->Material(loop).MoistDCoeff = 0.0;
7303 15 : state.dataMaterial->Material(loop).EMPDSurfaceDepth = 0.0;
7304 15 : state.dataMaterial->Material(loop).EMPDDeepDepth = 0.0;
7305 15 : state.dataMaterial->Material(loop).EMPDmuCoating = 0.0;
7306 15 : state.dataMaterial->Material(loop).EMPDCoatingThickness = 0.0;
7307 : }
7308 :
7309 : // Glass objects
7310 5 : NextLine = W5DataFile.readLine();
7311 5 : if (NextLine.eof) goto Label1000;
7312 5 : ++FileLineCount;
7313 5 : MaterNum = TotMaterialsPrev;
7314 10 : for (IGlSys = 1; IGlSys <= NGlSys; ++IGlSys) {
7315 15 : for (IGlass = 1; IGlass <= NGlass(IGlSys); ++IGlass) {
7316 10 : ++MaterNum;
7317 10 : MaterNumSysGlass(IGlass, IGlSys) = MaterNum;
7318 10 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::WindowGlass;
7319 10 : NextLine = W5DataFile.readLine();
7320 10 : ++FileLineCount;
7321 :
7322 110 : readList(NextLine.data.substr(25),
7323 10 : state.dataMaterial->Material(MaterNum).Thickness,
7324 10 : state.dataMaterial->Material(MaterNum).Conductivity,
7325 10 : state.dataMaterial->Material(MaterNum).Trans,
7326 10 : state.dataMaterial->Material(MaterNum).ReflectSolBeamFront,
7327 10 : state.dataMaterial->Material(MaterNum).ReflectSolBeamBack,
7328 10 : state.dataMaterial->Material(MaterNum).TransVis,
7329 10 : state.dataMaterial->Material(MaterNum).ReflectVisBeamFront,
7330 10 : state.dataMaterial->Material(MaterNum).ReflectVisBeamBack,
7331 10 : state.dataMaterial->Material(MaterNum).TransThermal,
7332 10 : state.dataMaterial->Material(MaterNum).AbsorpThermalFront,
7333 10 : state.dataMaterial->Material(MaterNum).AbsorpThermalBack,
7334 : LayerName);
7335 :
7336 10 : state.dataMaterial->Material(MaterNum).Thickness *= 0.001;
7337 10 : if (state.dataMaterial->Material(MaterNum).Thickness <= 0.0) {
7338 : }
7339 10 : if (NGlSys == 1) {
7340 10 : state.dataMaterial->Material(MaterNum).Name = "W5:" + DesiredConstructionName + ":GLASS" + NumName(IGlass);
7341 : } else {
7342 0 : state.dataMaterial->Material(MaterNum).Name =
7343 0 : "W5:" + DesiredConstructionName + ':' + NumName(IGlSys) + ":GLASS" + NumName(IGlass);
7344 : }
7345 10 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::VerySmooth;
7346 10 : state.dataMaterial->Material(MaterNum).AbsorpThermal = state.dataMaterial->Material(MaterNum).AbsorpThermalBack;
7347 10 : if (state.dataMaterial->Material(MaterNum).Thickness <= 0.0) {
7348 0 : ShowSevereError(state,
7349 0 : "SearchWindow5DataFile: Material=\"" + state.dataMaterial->Material(MaterNum).Name +
7350 : "\" has thickness of 0.0. Will be set to thickness = .001 but inaccuracies may result.");
7351 0 : ShowContinueError(state, "Line being read=" + NextLine.data);
7352 0 : ShowContinueError(state, "Thickness field starts at column 26=" + NextLine.data.substr(25));
7353 0 : state.dataMaterial->Material(MaterNum).Thickness = 0.001;
7354 : }
7355 : }
7356 : }
7357 :
7358 : // Gap objects
7359 5 : NextLine = W5DataFile.readLine();
7360 5 : if (NextLine.eof) goto Label1000;
7361 5 : ++FileLineCount;
7362 10 : for (IGlSys = 1; IGlSys <= NGlSys; ++IGlSys) {
7363 10 : for (IGap = 1; IGap <= NGaps(IGlSys); ++IGap) {
7364 5 : ++MaterNum;
7365 5 : MaterNumSysGap(IGap, IGlSys) = MaterNum;
7366 5 : NextLine = W5DataFile.readLine();
7367 5 : ++FileLineCount;
7368 5 : readList(NextLine.data.substr(23), state.dataMaterial->Material(MaterNum).Thickness, NumGases(IGap, IGlSys));
7369 5 : if (NGlSys == 1) {
7370 5 : state.dataMaterial->Material(MaterNum).Name = "W5:" + DesiredConstructionName + ":GAP" + NumName(IGap);
7371 : } else {
7372 0 : state.dataMaterial->Material(MaterNum).Name =
7373 0 : "W5:" + DesiredConstructionName + ':' + NumName(IGlSys) + ":GAP" + NumName(IGap);
7374 : }
7375 5 : state.dataMaterial->Material(MaterNum).Thickness *= 0.001;
7376 5 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::MediumRough; // Unused
7377 : }
7378 : }
7379 :
7380 5 : NextLine = W5DataFile.readLine();
7381 5 : if (NextLine.eof) goto Label1000;
7382 5 : ++FileLineCount;
7383 10 : for (IGlSys = 1; IGlSys <= NGlSys; ++IGlSys) {
7384 10 : for (IGap = 1; IGap <= NGaps(IGlSys); ++IGap) {
7385 5 : MaterNum = MaterNumSysGap(IGap, IGlSys);
7386 5 : state.dataMaterial->Material(MaterNum).NumberOfGasesInMixture = NumGases(IGap, IGlSys);
7387 5 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::WindowGas;
7388 5 : if (NumGases(IGap, IGlSys) > 1) state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::WindowGasMixture;
7389 10 : for (IGas = 1; IGas <= NumGases(IGap, IGlSys); ++IGas) {
7390 5 : NextLine = W5DataFile.readLine();
7391 5 : ++FileLineCount;
7392 10 : readList(NextLine.data.substr(19),
7393 : GasName(IGas),
7394 5 : state.dataMaterial->Material(MaterNum).GasFract(IGas),
7395 5 : state.dataMaterial->Material(MaterNum).GasWght(IGas),
7396 10 : state.dataMaterial->Material(MaterNum).GasCon(_, IGas),
7397 10 : state.dataMaterial->Material(MaterNum).GasVis(_, IGas),
7398 10 : state.dataMaterial->Material(MaterNum).GasCp(_, IGas));
7399 : // Nominal resistance of gap at room temperature (based on first gas in mixture)
7400 5 : state.dataHeatBal->NominalR(MaterNum) =
7401 10 : state.dataMaterial->Material(MaterNum).Thickness /
7402 10 : (state.dataMaterial->Material(MaterNum).GasCon(1, 1) + state.dataMaterial->Material(MaterNum).GasCon(2, 1) * 300.0 +
7403 5 : state.dataMaterial->Material(MaterNum).GasCon(3, 1) * 90000.0);
7404 : }
7405 : }
7406 : }
7407 :
7408 : // Construction objects
7409 :
7410 : // reallocate Construct types
7411 5 : state.dataHeatBal->TotConstructs += NGlSys;
7412 5 : state.dataConstruction->Construct.redimension(state.dataHeatBal->TotConstructs);
7413 5 : state.dataHeatBal->NominalRforNominalUCalculation.redimension(state.dataHeatBal->TotConstructs);
7414 5 : state.dataHeatBal->NominalU.redimension(state.dataHeatBal->TotConstructs);
7415 5 : state.dataHeatBal->NominalUBeforeAdjusted.redimension(state.dataHeatBal->TotConstructs);
7416 5 : state.dataHeatBal->CoeffAdjRatio.redimension(state.dataHeatBal->TotConstructs) = 1.0;
7417 :
7418 : // these Construct arrays dimensioned based on MaxSolidWinLayers
7419 10 : for (int i = (state.dataHeatBal->TotConstructs - NGlSys + 1); i <= state.dataHeatBal->TotConstructs; ++i) {
7420 5 : auto &e(state.dataConstruction->Construct(i));
7421 5 : e.setArraysBasedOnMaxSolidWinLayers(state);
7422 : }
7423 :
7424 5 : NextLine = W5DataFile.readLine();
7425 5 : if (NextLine.eof) goto Label1000;
7426 5 : ++FileLineCount;
7427 :
7428 : // Pre-calculate constants
7429 55 : for (IPhi = 1; IPhi <= 10; ++IPhi) {
7430 50 : CosPhiIndepVar(IPhi) = std::cos((IPhi - 1) * 10.0 * DataGlobalConstants::DegToRadians);
7431 : }
7432 :
7433 : // Pre-calculate constants
7434 55 : for (IPhi = 1; IPhi <= 10; ++IPhi) {
7435 50 : Phi = double(IPhi - 1) * 10.0;
7436 50 : CosPhi(IPhi) = std::cos(Phi * DataGlobalConstants::DegToRadians);
7437 50 : if (std::abs(CosPhi(IPhi)) < 0.0001) CosPhi(IPhi) = 0.0;
7438 : }
7439 :
7440 10 : for (IGlSys = 1; IGlSys <= NGlSys; ++IGlSys) {
7441 5 : ConstrNum = state.dataHeatBal->TotConstructs - NGlSys + IGlSys;
7442 5 : if (IGlSys == 1) {
7443 5 : state.dataConstruction->Construct(ConstrNum).Name = DesiredConstructionName;
7444 : } else {
7445 0 : state.dataConstruction->Construct(ConstrNum).Name = DesiredConstructionName + ":2";
7446 : }
7447 60 : for (loop = 1; loop <= Construction::MaxLayersInConstruct; ++loop) {
7448 55 : state.dataConstruction->Construct(ConstrNum).LayerPoint(loop) = 0;
7449 : }
7450 5 : state.dataConstruction->Construct(ConstrNum).InsideAbsorpSolar = 0.0;
7451 5 : state.dataConstruction->Construct(ConstrNum).OutsideAbsorpSolar = 0.0;
7452 5 : state.dataConstruction->Construct(ConstrNum).DayltPropPtr = 0;
7453 5 : state.dataConstruction->Construct(ConstrNum).CTFCross = 0.0;
7454 5 : state.dataConstruction->Construct(ConstrNum).CTFFlux = 0.0;
7455 5 : state.dataConstruction->Construct(ConstrNum).CTFInside = 0.0;
7456 5 : state.dataConstruction->Construct(ConstrNum).CTFOutside = 0.0;
7457 5 : state.dataConstruction->Construct(ConstrNum).CTFSourceIn = 0.0;
7458 5 : state.dataConstruction->Construct(ConstrNum).CTFSourceOut = 0.0;
7459 5 : state.dataConstruction->Construct(ConstrNum).CTFTimeStep = 0.0;
7460 5 : state.dataConstruction->Construct(ConstrNum).CTFTSourceOut = 0.0;
7461 5 : state.dataConstruction->Construct(ConstrNum).CTFTSourceIn = 0.0;
7462 5 : state.dataConstruction->Construct(ConstrNum).CTFTSourceQ = 0.0;
7463 5 : state.dataConstruction->Construct(ConstrNum).CTFTUserOut = 0.0;
7464 5 : state.dataConstruction->Construct(ConstrNum).CTFTUserIn = 0.0;
7465 5 : state.dataConstruction->Construct(ConstrNum).CTFTUserSource = 0.0;
7466 5 : state.dataConstruction->Construct(ConstrNum).NumHistories = 0;
7467 5 : state.dataConstruction->Construct(ConstrNum).NumCTFTerms = 0;
7468 5 : state.dataConstruction->Construct(ConstrNum).UValue = 0.0;
7469 5 : state.dataConstruction->Construct(ConstrNum).SourceSinkPresent = false;
7470 5 : state.dataConstruction->Construct(ConstrNum).SolutionDimensions = 0;
7471 5 : state.dataConstruction->Construct(ConstrNum).SourceAfterLayer = 0;
7472 5 : state.dataConstruction->Construct(ConstrNum).TempAfterLayer = 0;
7473 5 : state.dataConstruction->Construct(ConstrNum).ThicknessPerpend = 0.0;
7474 5 : state.dataConstruction->Construct(ConstrNum).AbsDiff = 0.0;
7475 5 : state.dataConstruction->Construct(ConstrNum).AbsDiffBack = 0.0;
7476 5 : state.dataConstruction->Construct(ConstrNum).AbsDiffShade = 0.0;
7477 5 : state.dataConstruction->Construct(ConstrNum).AbsDiffBackShade = 0.0;
7478 5 : state.dataConstruction->Construct(ConstrNum).ShadeAbsorpThermal = 0.0;
7479 5 : state.dataConstruction->Construct(ConstrNum).AbsBeamShadeCoef = 0.0;
7480 5 : state.dataConstruction->Construct(ConstrNum).AbsDiffIn = 0.0;
7481 5 : state.dataConstruction->Construct(ConstrNum).AbsDiffOut = 0.0;
7482 5 : state.dataConstruction->Construct(ConstrNum).TransDiff = 0.0;
7483 5 : state.dataConstruction->Construct(ConstrNum).TransDiffVis = 0.0;
7484 5 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack = 0.0;
7485 5 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront = 0.0;
7486 5 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack = 0.0;
7487 5 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront = 0.0;
7488 5 : state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef = 0.0;
7489 5 : state.dataConstruction->Construct(ConstrNum).TransVisBeamCoef = 0.0;
7490 5 : state.dataConstruction->Construct(ConstrNum).ReflSolBeamFrontCoef = 0.0;
7491 5 : state.dataConstruction->Construct(ConstrNum).ReflSolBeamBackCoef = 0.0;
7492 5 : state.dataConstruction->Construct(ConstrNum).W5FrameDivider = 0;
7493 5 : state.dataConstruction->Construct(ConstrNum).TotLayers = NGlass(IGlSys) + NGaps(IGlSys);
7494 5 : state.dataConstruction->Construct(ConstrNum).TotGlassLayers = NGlass(IGlSys);
7495 5 : state.dataConstruction->Construct(ConstrNum).TotSolidLayers = NGlass(IGlSys);
7496 :
7497 40 : for (int Layer = 1; Layer <= state.dataHeatBal->MaxSolidWinLayers; ++Layer) {
7498 245 : for (int index = 1; index <= DataSurfaces::MaxPolyCoeff; ++index) {
7499 210 : state.dataConstruction->Construct(ConstrNum).AbsBeamCoef(Layer)(index) = 0.0;
7500 210 : state.dataConstruction->Construct(ConstrNum).AbsBeamBackCoef(Layer)(index) = 0.0;
7501 : }
7502 : }
7503 :
7504 15 : for (IGlass = 1; IGlass <= NGlass(IGlSys); ++IGlass) {
7505 10 : state.dataConstruction->Construct(ConstrNum).LayerPoint(2 * IGlass - 1) = MaterNumSysGlass(IGlass, IGlSys);
7506 10 : if (IGlass < NGlass(IGlSys)) state.dataConstruction->Construct(ConstrNum).LayerPoint(2 * IGlass) = MaterNumSysGap(IGlass, IGlSys);
7507 : }
7508 :
7509 5 : state.dataConstruction->Construct(ConstrNum).OutsideRoughness = DataSurfaces::SurfaceRoughness::VerySmooth;
7510 5 : state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal =
7511 5 : state.dataMaterial->Material(TotMaterialsPrev + NGlass(IGlSys)).AbsorpThermalBack;
7512 5 : state.dataConstruction->Construct(ConstrNum).OutsideAbsorpThermal =
7513 5 : state.dataMaterial->Material(TotMaterialsPrev + 1).AbsorpThermalFront;
7514 5 : state.dataConstruction->Construct(ConstrNum).TypeIsWindow = true;
7515 5 : state.dataConstruction->Construct(ConstrNum).FromWindow5DataFile = true;
7516 5 : state.dataConstruction->Construct(ConstrNum).W5FileGlazingSysHeight = WinHeight(IGlSys);
7517 5 : state.dataConstruction->Construct(ConstrNum).W5FileGlazingSysWidth = WinWidth(IGlSys);
7518 5 : if (UtilityRoutines::SameString(MullionOrientation, "Vertical")) {
7519 5 : state.dataConstruction->Construct(ConstrNum).W5FileMullionOrientation = DataWindowEquivalentLayer::Orientation::Vertical;
7520 0 : } else if (UtilityRoutines::SameString(MullionOrientation, "Horizontal")) {
7521 0 : state.dataConstruction->Construct(ConstrNum).W5FileMullionOrientation = DataWindowEquivalentLayer::Orientation::Horizontal;
7522 : } else {
7523 : }
7524 5 : state.dataConstruction->Construct(ConstrNum).W5FileMullionWidth = MullionWidth;
7525 :
7526 : // Fill Construct with system transmission, reflection and absorption properties
7527 :
7528 5 : NextLine = W5DataFile.readLine();
7529 5 : if (NextLine.eof) goto Label1000;
7530 5 : ++FileLineCount;
7531 5 : if (IGlSys == 1) {
7532 5 : NextLine = W5DataFile.readLine();
7533 5 : if (NextLine.eof) goto Label1000;
7534 5 : ++FileLineCount;
7535 : }
7536 5 : NextLine = W5DataFile.readLine();
7537 5 : if (NextLine.eof) goto Label1000;
7538 5 : ++FileLineCount;
7539 5 : if (!readItem(NextLine.data.substr(5), Tsol)) {
7540 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of TSol values.");
7541 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount, NextLine.data.substr(0, 100)));
7542 0 : ErrorsFound = true;
7543 5 : } else if (any_lt(Tsol, 0.0) || any_gt(Tsol, 1.0)) {
7544 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of TSol values. (out of range [0,1])");
7545 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount, NextLine.data.substr(0, 100)));
7546 0 : ErrorsFound = true;
7547 : }
7548 15 : for (IGlass = 1; IGlass <= NGlass(IGlSys); ++IGlass) {
7549 10 : NextLine = W5DataFile.readLine();
7550 10 : ++FileLineCount;
7551 10 : if (!readItem(NextLine.data.substr(5), AbsSol(_, IGlass))) {
7552 0 : ShowSevereError(state,
7553 0 : format("HeatBalanceManager: SearchWindow5DataFile: Error in Read of AbsSol values. For Glass={}", IGlass));
7554 0 : ShowContinueError(state,
7555 0 : format("Line (~{}) in error (first 100 characters)={}", FileLineCount, NextLine.data.substr(0, 100)));
7556 0 : ErrorsFound = true;
7557 10 : } else if (any_lt(AbsSol(_, IGlass), 0.0) || any_gt(AbsSol(_, IGlass), 1.0)) {
7558 0 : ShowSevereError(
7559 : state,
7560 0 : format("HeatBalanceManager: SearchWindow5DataFile: Error in Read of AbsSol values. (out of range [0,1]) For Glass={}",
7561 0 : IGlass));
7562 0 : ShowContinueError(state,
7563 0 : format("Line (~{}) in error (first 100 characters)={}", FileLineCount, NextLine.data.substr(0, 100)));
7564 0 : ErrorsFound = true;
7565 : }
7566 : }
7567 30 : for (ILine = 1; ILine <= 5; ++ILine) {
7568 25 : NextLine = W5DataFile.readLine();
7569 25 : DataLine(ILine) = NextLine.data;
7570 : }
7571 :
7572 5 : if (!readItem(DataLine(1).substr(5), Rfsol)) {
7573 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of RfSol values.");
7574 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 1, DataLine(1).substr(0, 100)));
7575 0 : ErrorsFound = true;
7576 5 : } else if (any_lt(Rfsol, 0.0) || any_gt(Rfsol, 1.0)) {
7577 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of RfSol values. (out of range [0,1])");
7578 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 1, DataLine(1).substr(0, 100)));
7579 0 : ErrorsFound = true;
7580 : }
7581 :
7582 5 : if (!readItem(DataLine(2).substr(5), Rbsol)) {
7583 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of RbSol values.");
7584 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 2, DataLine(2).substr(0, 100)));
7585 0 : ErrorsFound = true;
7586 5 : } else if (any_lt(Rbsol, 0.0) || any_gt(Rbsol, 1.0)) {
7587 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of RbSol values. (out of range [0,1])");
7588 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 2, DataLine(2).substr(0, 100)));
7589 0 : ErrorsFound = true;
7590 : }
7591 5 : if (!readItem(DataLine(3).substr(5), Tvis)) {
7592 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Tvis values.");
7593 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 3, DataLine(3).substr(0, 100)));
7594 0 : ErrorsFound = true;
7595 5 : } else if (any_lt(Tvis, 0.0) || any_gt(Tvis, 1.0)) {
7596 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Tvis values. (out of range [0,1])");
7597 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 3, DataLine(3).substr(0, 100)));
7598 0 : ErrorsFound = true;
7599 : }
7600 5 : if (!readItem(DataLine(4).substr(5), Rfvis)) {
7601 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Rfvis values.");
7602 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 4, DataLine(4).substr(0, 100)));
7603 0 : ErrorsFound = true;
7604 5 : } else if (any_lt(Rfvis, 0.0) || any_gt(Rfvis, 1.0)) {
7605 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Rfvis values. (out of range [0,1])");
7606 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 4, DataLine(4).substr(0, 100)));
7607 0 : ErrorsFound = true;
7608 : }
7609 5 : if (!readItem(DataLine(5).substr(5), Rbvis)) {
7610 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Rbvis values.");
7611 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 5, DataLine(5).substr(0, 100)));
7612 0 : ErrorsFound = true;
7613 5 : } else if (any_lt(Rbvis, 0.0) || any_gt(Rbvis, 1.0)) {
7614 0 : ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Rbvis values. (out of range [0,1])");
7615 0 : ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 5, DataLine(5).substr(0, 100)));
7616 0 : ErrorsFound = true;
7617 : }
7618 5 : FileLineCount += 5;
7619 :
7620 5 : if (ErrorsFound)
7621 0 : ShowFatalError(state,
7622 0 : "HeatBalanceManager: SearchWindow5DataFile: Construction=" + DesiredConstructionName +
7623 : " from the Window5 data file cannot be used because of above errors");
7624 :
7625 : // Hemis
7626 5 : state.dataConstruction->Construct(ConstrNum).TransDiff = Tsol(11);
7627 5 : state.dataConstruction->Construct(ConstrNum).TransDiffVis = Tvis(11);
7628 5 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffFront = Rfsol(11);
7629 5 : state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack = Rbsol(11);
7630 5 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffFront = Rfvis(11);
7631 5 : state.dataConstruction->Construct(ConstrNum).ReflectVisDiffBack = Rbvis(11);
7632 :
7633 5 : W5LsqFit(CosPhiIndepVar, Tsol, 6, 1, 10, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
7634 5 : W5LsqFit(CosPhiIndepVar, Tvis, 6, 1, 10, state.dataConstruction->Construct(ConstrNum).TransVisBeamCoef);
7635 5 : W5LsqFit(CosPhiIndepVar, Rfsol, 6, 1, 10, state.dataConstruction->Construct(ConstrNum).ReflSolBeamFrontCoef);
7636 15 : for (IGlass = 1; IGlass <= NGlass(IGlSys); ++IGlass) {
7637 10 : W5LsqFit(CosPhiIndepVar, AbsSol(_, IGlass), 6, 1, 10, state.dataConstruction->Construct(ConstrNum).AbsBeamCoef(IGlass));
7638 : }
7639 :
7640 : // For comparing fitted vs. input distribution in incidence angle
7641 55 : for (IPhi = 1; IPhi <= 10; ++IPhi) {
7642 50 : tsolFit(IPhi) = POLYF(CosPhi(IPhi), state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef);
7643 50 : tvisFit(IPhi) = POLYF(CosPhi(IPhi), state.dataConstruction->Construct(ConstrNum).TransVisBeamCoef);
7644 50 : rfsolFit(IPhi) = POLYF(CosPhi(IPhi), state.dataConstruction->Construct(ConstrNum).ReflSolBeamFrontCoef);
7645 150 : for (IGlass = 1; IGlass <= NGlass(IGlSys); ++IGlass) {
7646 100 : solabsFit(IGlass, IPhi) = POLYF(CosPhi(IPhi), state.dataConstruction->Construct(ConstrNum).AbsBeamCoef(IGlass));
7647 : }
7648 : }
7649 : // end
7650 :
7651 : // NominalRforNominalUCalculation of this construction (actually the total resistance of all of its layers; gas layer
7652 : // conductivity here ignores convective effects in gap.)
7653 5 : state.dataHeatBal->NominalRforNominalUCalculation(ConstrNum) = 0.0;
7654 20 : for (loop = 1; loop <= NGlass(IGlSys) + NGaps(IGlSys); ++loop) {
7655 15 : MatNum = state.dataConstruction->Construct(ConstrNum).LayerPoint(loop);
7656 15 : if (state.dataMaterial->Material(MatNum).Group == DataHeatBalance::MaterialGroup::WindowGlass) {
7657 10 : state.dataHeatBal->NominalRforNominalUCalculation(ConstrNum) +=
7658 10 : state.dataMaterial->Material(MatNum).Thickness / state.dataMaterial->Material(MatNum).Conductivity;
7659 5 : } else if (state.dataMaterial->Material(MatNum).Group == DataHeatBalance::MaterialGroup::WindowGas ||
7660 0 : state.dataMaterial->Material(MatNum).Group == DataHeatBalance::MaterialGroup::WindowGasMixture) {
7661 : // If mixture, use conductivity of first gas in mixture
7662 5 : state.dataHeatBal->NominalRforNominalUCalculation(ConstrNum) +=
7663 10 : state.dataMaterial->Material(MatNum).Thickness /
7664 10 : (state.dataMaterial->Material(MatNum).GasCon(1, 1) + state.dataMaterial->Material(MatNum).GasCon(2, 1) * 300.0 +
7665 5 : state.dataMaterial->Material(MatNum).GasCon(3, 1) * 90000.0);
7666 : }
7667 : }
7668 :
7669 : } // End of loop over glazing systems
7670 :
7671 : // WindowFrameAndDivider objects
7672 :
7673 5 : TotFrameDividerPrev = state.dataHeatBal->TotFrameDivider;
7674 10 : for (IGlSys = 1; IGlSys <= NGlSys; ++IGlSys) {
7675 5 : if (FrameWidth > 0.0 || DividerWidth(IGlSys) > 0.0) {
7676 5 : ++state.dataHeatBal->TotFrameDivider;
7677 5 : state.dataConstruction->Construct(state.dataHeatBal->TotConstructs - NGlSys + IGlSys).W5FrameDivider =
7678 5 : state.dataHeatBal->TotFrameDivider;
7679 : }
7680 : }
7681 :
7682 5 : if (state.dataHeatBal->TotFrameDivider > TotFrameDividerPrev) {
7683 5 : state.dataSurface->FrameDivider.redimension(state.dataHeatBal->TotFrameDivider);
7684 : }
7685 :
7686 10 : for (IGlSys = 1; IGlSys <= NGlSys; ++IGlSys) {
7687 5 : if (FrameWidth > 0.0 || DividerWidth(IGlSys) > 0.0) {
7688 5 : FrDivNum = state.dataConstruction->Construct(state.dataHeatBal->TotConstructs - NGlSys + IGlSys).W5FrameDivider;
7689 5 : state.dataSurface->FrameDivider(FrDivNum).FrameWidth = FrameWidth;
7690 5 : state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut = FrameProjectionOut;
7691 5 : state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn = FrameProjectionIn;
7692 5 : state.dataSurface->FrameDivider(FrDivNum).FrameConductance = FrameConductance;
7693 5 : state.dataSurface->FrameDivider(FrDivNum).FrEdgeToCenterGlCondRatio = FrEdgeToCenterGlCondRatio;
7694 5 : state.dataSurface->FrameDivider(FrDivNum).FrameSolAbsorp = FrameSolAbsorp;
7695 5 : state.dataSurface->FrameDivider(FrDivNum).FrameVisAbsorp = FrameVisAbsorp;
7696 5 : state.dataSurface->FrameDivider(FrDivNum).FrameEmis = FrameEmis;
7697 5 : state.dataSurface->FrameDivider(FrDivNum).FrameEdgeWidth = 0.06355; // 2.5 in
7698 5 : if (UtilityRoutines::SameString(MullionOrientation, "Vertical")) {
7699 5 : state.dataSurface->FrameDivider(FrDivNum).MullionOrientation = DataWindowEquivalentLayer::Orientation::Vertical;
7700 0 : } else if (UtilityRoutines::SameString(MullionOrientation, "Horizontal")) {
7701 0 : state.dataSurface->FrameDivider(FrDivNum).MullionOrientation = DataWindowEquivalentLayer::Orientation::Horizontal;
7702 : }
7703 5 : if (UtilityRoutines::SameString(DividerType(IGlSys), "DividedLite")) {
7704 0 : state.dataSurface->FrameDivider(FrDivNum).DividerType = DataSurfaces::FrameDividerType::DividedLite;
7705 5 : } else if (UtilityRoutines::SameString(DividerType(IGlSys), "Suspended")) {
7706 5 : state.dataSurface->FrameDivider(FrDivNum).DividerType = DataSurfaces::FrameDividerType::Suspended;
7707 : }
7708 5 : state.dataSurface->FrameDivider(FrDivNum).DividerWidth = DividerWidth(IGlSys);
7709 5 : state.dataSurface->FrameDivider(FrDivNum).HorDividers = HorDividers(IGlSys);
7710 5 : state.dataSurface->FrameDivider(FrDivNum).VertDividers = VertDividers(IGlSys);
7711 5 : state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut = DividerProjectionOut(IGlSys);
7712 5 : state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn = DividerProjectionIn(IGlSys);
7713 5 : state.dataSurface->FrameDivider(FrDivNum).DividerConductance = DividerConductance(IGlSys);
7714 5 : state.dataSurface->FrameDivider(FrDivNum).DivEdgeToCenterGlCondRatio = DivEdgeToCenterGlCondRatio(IGlSys);
7715 5 : state.dataSurface->FrameDivider(FrDivNum).DividerSolAbsorp = DividerSolAbsorp(IGlSys);
7716 5 : state.dataSurface->FrameDivider(FrDivNum).DividerVisAbsorp = DividerVisAbsorp(IGlSys);
7717 5 : state.dataSurface->FrameDivider(FrDivNum).DividerEmis = DividerEmis(IGlSys);
7718 5 : state.dataSurface->FrameDivider(FrDivNum).DividerEdgeWidth = 0.06355; // 2.5 in
7719 5 : if (NGlSys == 1) {
7720 5 : state.dataSurface->FrameDivider(FrDivNum).Name = "W5:" + DesiredConstructionName;
7721 : } else {
7722 0 : state.dataSurface->FrameDivider(FrDivNum).Name = "W5:" + DesiredConstructionName + ':' + NumName(IGlSys);
7723 : }
7724 : }
7725 : }
7726 :
7727 5 : if (FrameWidth > 0.0 && DividerWidth(1) > 0.0) {
7728 5 : DisplayString(state, "--Construction and associated frame and divider found");
7729 0 : } else if (FrameWidth > 0.0) {
7730 0 : DisplayString(state, "--Construction and associated frame found");
7731 0 : } else if (DividerWidth(1) > 0.0) {
7732 0 : DisplayString(state, "--Construction and associated divider found");
7733 : } else {
7734 0 : DisplayString(state, "--Construction without frame or divider found");
7735 : }
7736 : }
7737 :
7738 5 : return;
7739 :
7740 0 : Label1000:;
7741 0 : EOFonFile = true;
7742 : }
7743 :
7744 16 : void SetStormWindowControl(EnergyPlusData &state)
7745 : {
7746 :
7747 : // SUBROUTINE INFORMATION:
7748 : // AUTHOR Fred Winkelmann
7749 : // DATE WRITTEN Jan 2004
7750 : // MODIFIED na
7751 : // RE-ENGINEERED na
7752 :
7753 : // PURPOSE OF THIS SUBROUTINE:
7754 : // Sets the storm window flag for each window, which is:
7755 : // -1: if storm window is not applicable (this will always be the value for interior
7756 : // windows since storm windows can only be applied to exterior windows
7757 : // 0: if the window has a storm window but it is off
7758 : // 1: if the window has a storm window and it is on
7759 :
7760 : // A "storm window" is a single layer of exterior glass separated from the main window by air gap.
7761 : // Whether the storm window is in place is determined by the following values, which
7762 : // which are specified in the Storm Window object for the window:
7763 : // -Month that Storm Window Is Put On
7764 : // -Day of Month that Storm Window Is Put On
7765 : // -Month that Storm Window Is Taken Off
7766 : // -Day of Month that Storm Window Is Taken Off
7767 :
7768 : // Using/Aliasing
7769 : using General::BetweenDates;
7770 :
7771 : int SurfNum; // Surface number
7772 : int StormWinNum; // Number of storm window object
7773 : int StormWinFlag; // Storm window flag; this routine sets the following values:
7774 : // 0: if the storm window is off this time step
7775 : // 1: if the storm window is on this time step
7776 : int DateOff; // Date Off for calculation
7777 :
7778 16 : state.dataHeatBal->StormWinChangeThisDay = false;
7779 :
7780 32 : for (StormWinNum = 1; StormWinNum <= state.dataSurface->TotStormWin; ++StormWinNum) {
7781 16 : SurfNum = state.dataSurface->StormWindow(StormWinNum).BaseWindowNum;
7782 16 : state.dataSurface->SurfWinStormWinFlagPrevDay(SurfNum) = state.dataSurface->SurfWinStormWinFlag(SurfNum);
7783 16 : DateOff = state.dataSurface->StormWindow(StormWinNum).DateOff - 1;
7784 : // Note: Dateon = Dateoff is not allowed and will have produced an error in getinput.
7785 16 : if (DateOff == 0) DateOff = 366;
7786 16 : if (BetweenDates(state.dataEnvrn->DayOfYear_Schedule, state.dataSurface->StormWindow(StormWinNum).DateOn, DateOff)) {
7787 8 : StormWinFlag = 1;
7788 : } else {
7789 8 : StormWinFlag = 0;
7790 : }
7791 16 : state.dataSurface->SurfWinStormWinFlag(SurfNum) = StormWinFlag;
7792 16 : if (state.dataGlobal->BeginSimFlag) state.dataSurface->SurfWinStormWinFlagPrevDay(SurfNum) = StormWinFlag;
7793 16 : if (state.dataSurface->SurfWinStormWinFlag(SurfNum) != state.dataSurface->SurfWinStormWinFlagPrevDay(SurfNum))
7794 3 : state.dataHeatBal->StormWinChangeThisDay = true;
7795 : }
7796 16 : }
7797 :
7798 20 : void CreateFCfactorConstructions(EnergyPlusData &state,
7799 : int &ConstrNum, // Counter for Constructions
7800 : bool &ErrorsFound // If errors found in input
7801 : )
7802 : {
7803 :
7804 : // SUBROUTINE INFORMATION:
7805 : // AUTHOR Tianzhen Hong
7806 : // DATE WRITTEN July 2009
7807 : // MODIFIED
7808 : // RE-ENGINEERED na
7809 :
7810 : // PURPOSE OF THIS SUBROUTINE:
7811 : // This subroutine goes through each construction defined with Ffactor or Cfactor method,
7812 : // and creates a construction (concrete + insulation) used in the heat transfer calculation.
7813 : // This subroutine only gets called once in the GetConstructionData subroutine
7814 :
7815 : // METHODOLOGY EMPLOYED:
7816 : // na
7817 :
7818 : // REFERENCES:
7819 : // na
7820 :
7821 : // Using/Aliasing
7822 : using namespace DataStringGlobals;
7823 :
7824 : // Locals
7825 : // SUBROUTINE ARGUMENT DEFINITIONS:
7826 :
7827 : // SUBROUTINE PARAMETER DEFINITIONS:
7828 :
7829 : // ASHRAE Handbook Fundamental 2005
7830 : // Thermal resistance of the inside air film, m2.K/W. Average of 0.14 (heat flow up) and 0.11 (heat flow down)
7831 20 : Real64 constexpr Rfilm_in(0.125);
7832 : // Thermal resistance of the outside air film used in calculating the Ffactor, m2.K/W. 0.17/5.678
7833 20 : Real64 constexpr Rfilm_out(0.03);
7834 :
7835 : // INTERFACE BLOCK SPECIFICATIONS:
7836 : // na
7837 :
7838 : // DERIVED TYPE DEFINITIONS:
7839 : // na
7840 :
7841 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7842 : int ConstructNumAlpha; // Number of construction alpha names being passed
7843 : int DummyNumProp; // dummy variable for properties being passed
7844 : int IOStat; // IO Status when calling get input subroutine
7845 40 : Array1D_string ConstructAlphas(1); // Construction Alpha names defined
7846 40 : Array1D<Real64> DummyProps(4); // Temporary array to transfer construction properties
7847 : int Loop;
7848 :
7849 : int TotFfactorConstructs; // Number of slabs-on-grade or underground floor constructions defined with F factors
7850 : int TotCfactorConstructs; // Number of underground wall constructions defined with C factors
7851 :
7852 : Real64 Ffactor; // Ffactor in W/m-K, applies to deltaT of outside - indoor air temperature
7853 : Real64 Cfactor; // Cfactor in W/m2-K, does not include soil or air films
7854 : Real64 Area; // floor area in m2
7855 : Real64 PerimeterExposed; // perimeter exposed in m
7856 : Real64 Height; // Height of the underground wall in m
7857 :
7858 : Real64 Reff; // Effective thermal resistance, m2.K/W
7859 : Real64 Rcon; // Concrete layer thermal resistance, m2.K/W
7860 : Real64 Rfic; // Thermal resistance of the fictitious material, m2.K/W
7861 : int MaterNum; // Material index
7862 : Real64 Rsoilequ; // Effective R-value of soil for underground walls
7863 : int iFCConcreteLayer; // Layer pointer to the materials array
7864 :
7865 : // First get the concrete layer
7866 20 : iFCConcreteLayer = UtilityRoutines::FindItemInList("~FC_Concrete", state.dataMaterial->Material);
7867 20 : Rcon = state.dataMaterial->Material(iFCConcreteLayer).Resistance;
7868 :
7869 : // Count number of constructions defined with Ffactor or Cfactor method
7870 20 : TotFfactorConstructs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction:FfactorGroundFloor");
7871 20 : TotCfactorConstructs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Construction:CfactorUndergroundWall");
7872 :
7873 20 : if (TotFfactorConstructs > 0) {
7874 14 : state.dataHeatBal->NoFfactorConstructionsUsed = false;
7875 : }
7876 :
7877 20 : if (TotCfactorConstructs > 0) {
7878 7 : state.dataHeatBal->NoCfactorConstructionsUsed = false;
7879 : }
7880 :
7881 : // First create ground floor constructions defined with F factor method if any
7882 20 : state.dataHeatBalMgr->CurrentModuleObject = "Construction:FfactorGroundFloor";
7883 :
7884 : // Loop through all constructs defined with Ffactor method
7885 199 : for (Loop = 1; Loop <= TotFfactorConstructs; ++Loop) {
7886 :
7887 : // Get the object names for each construction from the input processor
7888 1074 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
7889 179 : state.dataHeatBalMgr->CurrentModuleObject,
7890 : Loop,
7891 : ConstructAlphas,
7892 : ConstructNumAlpha,
7893 : DummyProps,
7894 : DummyNumProp,
7895 : IOStat,
7896 179 : state.dataIPShortCut->lNumericFieldBlanks,
7897 179 : state.dataIPShortCut->lAlphaFieldBlanks,
7898 179 : state.dataIPShortCut->cAlphaFieldNames,
7899 179 : state.dataIPShortCut->cNumericFieldNames);
7900 537 : if (GlobalNames::VerifyUniqueInterObjectName(state,
7901 179 : state.dataHeatBalMgr->UniqueConstructNames,
7902 179 : ConstructAlphas(1),
7903 179 : state.dataHeatBalMgr->CurrentModuleObject,
7904 179 : state.dataIPShortCut->cAlphaFieldNames(1),
7905 : ErrorsFound)) {
7906 0 : continue;
7907 : }
7908 :
7909 179 : ++ConstrNum;
7910 :
7911 179 : state.dataConstruction->Construct(ConstrNum).Name = ConstructAlphas(1);
7912 179 : state.dataConstruction->Construct(ConstrNum).TypeIsFfactorFloor = true;
7913 :
7914 179 : Ffactor = DummyProps(1);
7915 179 : Area = DummyProps(2);
7916 179 : PerimeterExposed = DummyProps(3);
7917 :
7918 179 : state.dataConstruction->Construct(ConstrNum).Area = Area;
7919 179 : state.dataConstruction->Construct(ConstrNum).PerimeterExposed = PerimeterExposed;
7920 179 : state.dataConstruction->Construct(ConstrNum).FFactor = Ffactor;
7921 :
7922 179 : if (Ffactor <= 0.0) {
7923 0 : ShowSevereError(state,
7924 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + ConstructAlphas(1) + "\" has " +
7925 0 : state.dataIPShortCut->cNumericFieldNames(1) + " <= 0.0, must be > 0.0.");
7926 0 : ShowContinueError(state, format("Entered value=[{:.2R}]", Ffactor));
7927 0 : ErrorsFound = true;
7928 : }
7929 :
7930 179 : if (Area <= 0.0) {
7931 0 : ShowSevereError(state,
7932 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + ConstructAlphas(1) + "\" has " +
7933 0 : state.dataIPShortCut->cNumericFieldNames(2) + " <= 0.0, must be > 0.0.");
7934 0 : ShowContinueError(state, format("Entered value=[{:.2R}]", Area));
7935 0 : ErrorsFound = true;
7936 : }
7937 :
7938 179 : if (PerimeterExposed < 0.0) {
7939 0 : ShowSevereError(state,
7940 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + ConstructAlphas(1) + "\" has " +
7941 0 : state.dataIPShortCut->cNumericFieldNames(3) + " <= 0.0, must be > 0.0.");
7942 0 : ShowContinueError(state, format("Entered value=[{:.2R}]", PerimeterExposed));
7943 0 : ErrorsFound = true;
7944 : }
7945 :
7946 : // The construction has two layers which have been created in GetMaterialData
7947 179 : state.dataConstruction->Construct(ConstrNum).TotLayers = 2;
7948 :
7949 : // The concrete is the inside layer
7950 179 : state.dataConstruction->Construct(ConstrNum).LayerPoint(2) = iFCConcreteLayer;
7951 :
7952 : // The fictitious insulation is the outside layer
7953 179 : MaterNum = UtilityRoutines::FindItemInList(format("~FC_Insulation_{}", Loop), state.dataMaterial->Material);
7954 179 : state.dataConstruction->Construct(ConstrNum).LayerPoint(1) = MaterNum;
7955 :
7956 : // Calculate the thermal resistance of the fictitious insulation layer
7957 : // effective thermal resistance excludes inside and outside air films
7958 179 : if (PerimeterExposed > 0.0) {
7959 145 : Reff = Area / (PerimeterExposed * Ffactor) - Rfilm_in - Rfilm_out;
7960 : } else { // PerimeterExposed = 0 for underground floor, assume R-1000 (IP)
7961 34 : Reff = 177.0;
7962 : }
7963 :
7964 179 : Rfic = Reff - Rcon;
7965 179 : if (Rfic <= 0.0) {
7966 0 : ShowSevereError(state,
7967 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + ConstructAlphas(1) +
7968 : "\" has calculated R value <= 0.0, must be > 0.0.");
7969 0 : ShowContinueError(state, format("Calculated value=[{:.2R}] Check definition.", Rfic));
7970 0 : ErrorsFound = true;
7971 : }
7972 :
7973 179 : state.dataMaterial->Material(MaterNum).Resistance = Rfic;
7974 179 : state.dataHeatBal->NominalR(MaterNum) = Rfic;
7975 :
7976 : // excluding thermal resistance of inside or outside air film
7977 : // 1/Reff gets reported as the "U-Factor no Film" in the summary report Envelope Summary | Opaque Exterior
7978 179 : state.dataHeatBal->NominalRforNominalUCalculation(ConstrNum) = Reff;
7979 : }
7980 :
7981 : // Then create underground wall constructions defined with C factor method if any
7982 20 : state.dataHeatBalMgr->CurrentModuleObject = "Construction:CfactorUndergroundWall";
7983 :
7984 54 : for (Loop = 1; Loop <= TotCfactorConstructs; ++Loop) { // Loop through all constructs defined with Ffactor method
7985 :
7986 : // Get the object names for each construction from the input processor
7987 204 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
7988 34 : state.dataHeatBalMgr->CurrentModuleObject,
7989 : Loop,
7990 : ConstructAlphas,
7991 : ConstructNumAlpha,
7992 : DummyProps,
7993 : DummyNumProp,
7994 : IOStat,
7995 34 : state.dataIPShortCut->lNumericFieldBlanks,
7996 34 : state.dataIPShortCut->lAlphaFieldBlanks,
7997 34 : state.dataIPShortCut->cAlphaFieldNames,
7998 34 : state.dataIPShortCut->cNumericFieldNames);
7999 102 : if (GlobalNames::VerifyUniqueInterObjectName(state,
8000 34 : state.dataHeatBalMgr->UniqueConstructNames,
8001 34 : ConstructAlphas(1),
8002 34 : state.dataHeatBalMgr->CurrentModuleObject,
8003 34 : state.dataIPShortCut->cAlphaFieldNames(1),
8004 : ErrorsFound)) {
8005 0 : continue;
8006 : }
8007 :
8008 34 : ++ConstrNum;
8009 :
8010 34 : state.dataConstruction->Construct(ConstrNum).Name = ConstructAlphas(1);
8011 34 : state.dataConstruction->Construct(ConstrNum).TypeIsCfactorWall = true;
8012 :
8013 34 : Cfactor = DummyProps(1);
8014 34 : Height = DummyProps(2);
8015 :
8016 34 : state.dataConstruction->Construct(ConstrNum).Height = Height;
8017 34 : state.dataConstruction->Construct(ConstrNum).CFactor = Cfactor;
8018 :
8019 34 : if (Cfactor <= 0.0) {
8020 0 : ShowSevereError(state,
8021 0 : state.dataHeatBalMgr->CurrentModuleObject + ' ' + ConstructAlphas(1) + " has " +
8022 0 : state.dataIPShortCut->cNumericFieldNames(1) + " <= 0.0, must be > 0.0.");
8023 0 : ShowContinueError(state, format("Entered value=[{:.2R}]", Cfactor));
8024 0 : ErrorsFound = true;
8025 : }
8026 :
8027 34 : if (Height <= 0.0) {
8028 0 : ShowSevereError(state,
8029 0 : state.dataHeatBalMgr->CurrentModuleObject + ' ' + ConstructAlphas(1) + " has " +
8030 0 : state.dataIPShortCut->cNumericFieldNames(2) + " <= 0.0, must be > 0.0.");
8031 0 : ShowContinueError(state, format("Entered value=[{:.2R}]", Height));
8032 0 : ErrorsFound = true;
8033 : }
8034 :
8035 : // The construction has two layers which have been created in GetMaterialData
8036 34 : state.dataConstruction->Construct(ConstrNum).TotLayers = 2;
8037 :
8038 : // The concrete is the inside layer
8039 34 : state.dataConstruction->Construct(ConstrNum).LayerPoint(2) = iFCConcreteLayer;
8040 :
8041 : // The fictitious insulation is the outside layer
8042 34 : MaterNum = UtilityRoutines::FindItemInList("~FC_Insulation_" + fmt::to_string(Loop + TotFfactorConstructs), state.dataMaterial->Material);
8043 34 : state.dataConstruction->Construct(ConstrNum).LayerPoint(1) = MaterNum;
8044 :
8045 : // CR 8886 Rsoil should be in SI unit. From ASHRAE 90.1-2010 SI
8046 34 : if (Height <= 0.25) {
8047 0 : Rsoilequ = 0.12; // m2K/W
8048 34 : } else if (Height >= 2.5) {
8049 2 : Rsoilequ = 0.92;
8050 : } else { // regression from ASHRAE 90.1-2010 SI TABLE C6.10.1 Effective R-Value of Soil, R2 = 0.9967
8051 32 : Rsoilequ = 0.0607 + 0.3479 * Height;
8052 : }
8053 :
8054 : // effective thermal resistance excludes inside and outside air films
8055 34 : Reff = 1.0 / Cfactor + Rsoilequ; // Cfactor does not include air films
8056 :
8057 34 : Rfic = Reff - Rcon;
8058 34 : if (Rfic <= 0) {
8059 0 : ShowSevereError(state,
8060 0 : state.dataHeatBalMgr->CurrentModuleObject + "=\"" + ConstructAlphas(1) +
8061 : "\" has calculated R value <= 0.0, must be > 0.0.");
8062 0 : ShowContinueError(state, format("Calculated value=[{:.2R}] Check definition.", Rfic));
8063 0 : ErrorsFound = true;
8064 : }
8065 :
8066 34 : state.dataMaterial->Material(MaterNum).Resistance = Rfic;
8067 34 : state.dataHeatBal->NominalR(MaterNum) = Rfic;
8068 :
8069 : // Reff includes the wall itself and soil, but excluding thermal resistance of inside or outside air film
8070 : // 1/Reff gets reported as the "U-Factor no Film" in the summary report Envelope Summary | Opaque Exterior
8071 34 : state.dataHeatBal->NominalRforNominalUCalculation(ConstrNum) = Reff;
8072 : }
8073 20 : }
8074 :
8075 3 : void CreateAirBoundaryConstructions(EnergyPlusData &state,
8076 : int &constrNum, // Counter for Constructions
8077 : bool &errorsFound // If errors found in input
8078 : )
8079 : {
8080 3 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
8081 3 : cCurrentModuleObject = "Construction:AirBoundary";
8082 : static constexpr std::string_view RoutineName = "CreateAirBoundaryConstructions";
8083 3 : int numAirBoundaryConstructs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
8084 3 : if (numAirBoundaryConstructs > 0) {
8085 6 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
8086 3 : if (instances == state.dataInputProcessing->inputProcessor->epJSON.end()) {
8087 : // Cannot imagine how you would have numAirBoundaryConstructs > 0 and yet the instances is empty
8088 : // this would indicate a major problem in the input processor, not a problem here
8089 : // I'll still catch this with errorsFound but I cannot make a unit test for it so excluding the line from coverage
8090 : ShowSevereError(state, // LCOV_EXCL_LINE
8091 : cCurrentModuleObject + ": Somehow getNumObjectsFound was > 0 but epJSON.find found 0"); // LCOV_EXCL_LINE
8092 : errorsFound = true; // LCOV_EXCL_LINE
8093 : }
8094 3 : auto &instancesValue = instances.value();
8095 6 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
8096 3 : auto const &fields = instance.value();
8097 6 : auto thisObjectName = instance.key();
8098 3 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjectName);
8099 :
8100 6 : if (GlobalNames::VerifyUniqueInterObjectName(
8101 6 : state, state.dataHeatBalMgr->UniqueConstructNames, thisObjectName, cCurrentModuleObject, "Name", errorsFound)) {
8102 0 : continue;
8103 : }
8104 :
8105 3 : ++constrNum;
8106 3 : auto &thisConstruct = state.dataConstruction->Construct(constrNum);
8107 :
8108 3 : thisConstruct.Name = UtilityRoutines::MakeUPPERCase(thisObjectName);
8109 3 : thisConstruct.TypeIsAirBoundary = true;
8110 3 : thisConstruct.IsUsedCTF = false;
8111 :
8112 : // Air Exchange Method
8113 6 : std::string airMethod = "None";
8114 3 : if (fields.find("air_exchange_method") != fields.end()) {
8115 2 : airMethod = fields.at("air_exchange_method").get<std::string>();
8116 : }
8117 3 : if (UtilityRoutines::SameString(airMethod, "SimpleMixing")) {
8118 2 : thisConstruct.TypeIsAirBoundaryMixing = true;
8119 2 : if (fields.find("simple_mixing_air_changes_per_hour") != fields.end()) {
8120 2 : thisConstruct.AirBoundaryACH = fields.at("simple_mixing_air_changes_per_hour").get<Real64>();
8121 : } else {
8122 0 : if (!state.dataInputProcessing->inputProcessor->getDefaultValue(
8123 : state, cCurrentModuleObject, "simple_mixing_air_changes_per_hour", thisConstruct.AirBoundaryACH)) {
8124 0 : errorsFound = true;
8125 : }
8126 : }
8127 2 : if (fields.find("simple_mixing_schedule_name") != fields.end()) {
8128 0 : const std::string &schedName = fields.at("simple_mixing_schedule_name").get<std::string>();
8129 0 : thisConstruct.AirBoundaryMixingSched = ScheduleManager::GetScheduleIndex(state, UtilityRoutines::MakeUPPERCase(schedName));
8130 0 : if (thisConstruct.AirBoundaryMixingSched == 0) {
8131 0 : ShowSevereError(state,
8132 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + thisConstruct.Name +
8133 0 : "\", invalid (not found) " + "Simple Mixing Schedule Name" + "=\"" + schedName + "\".");
8134 0 : errorsFound = true;
8135 : }
8136 : } else {
8137 2 : thisConstruct.AirBoundaryMixingSched = DataGlobalConstants::ScheduleAlwaysOn;
8138 : }
8139 : }
8140 : }
8141 : }
8142 3 : }
8143 :
8144 771 : void GetScheduledSurfaceGains(EnergyPlusData &state, bool &ErrorsFound) // If errors found in input
8145 : {
8146 :
8147 : // SUBROUTINE INFORMATION:
8148 : // AUTHOR Simon Vidanovic
8149 : // DATE WRITTEN June 2013
8150 : // MODIFIED
8151 : // RE-ENGINEERED na
8152 :
8153 : // PURPOSE OF THIS SUBROUTINE:
8154 : // Loads scheduled surface gains for solar incident on interior side of the surfaces and absorbed solar energy in
8155 : // window layers
8156 :
8157 : // Using/Aliasing
8158 : using ScheduleManager::GetScheduleIndex;
8159 :
8160 : // SUBROUTINE PARAMETER DEFINITIONS:
8161 771 : constexpr const char *RoutineName("GetScheduledSurfaceGains: ");
8162 :
8163 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8164 : int NumArgs;
8165 : int NumAlpha;
8166 : int NumNumeric;
8167 : int Loop;
8168 : int IOStat;
8169 : int SurfNum;
8170 : int ConstrNum;
8171 : int ScheduleNum;
8172 : int i;
8173 : int NumOfScheduledLayers;
8174 : bool NumOfLayersMatch;
8175 : int iZone;
8176 :
8177 : //-----------------------------------------------------------------------
8178 : // SurfaceProperty:SolarIncidentInside
8179 : //-----------------------------------------------------------------------
8180 771 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
8181 771 : cCurrentModuleObject = "SurfaceProperty:SolarIncidentInside";
8182 :
8183 : // Check if IDD definition is correct
8184 771 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlpha, NumNumeric);
8185 771 : if (NumAlpha != 4) {
8186 0 : ShowSevereError(
8187 : state,
8188 0 : format("{}{}: Object Definition indicates not = 4 Alpha Objects, Number Indicated={}", RoutineName, cCurrentModuleObject, NumAlpha));
8189 0 : ErrorsFound = true;
8190 : }
8191 :
8192 771 : state.dataSurface->TotSurfIncSolSSG = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
8193 771 : if (state.dataSurface->TotSurfIncSolSSG > 0) {
8194 1 : if (!allocated(state.dataSurface->SurfIncSolSSG)) {
8195 1 : state.dataSurface->SurfIncSolSSG.allocate(state.dataSurface->TotSurfIncSolSSG);
8196 : }
8197 :
8198 7 : for (Loop = 1; Loop <= state.dataSurface->TotSurfIncSolSSG; ++Loop) {
8199 42 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
8200 : cCurrentModuleObject,
8201 : Loop,
8202 6 : state.dataIPShortCut->cAlphaArgs,
8203 : NumAlpha,
8204 6 : state.dataIPShortCut->rNumericArgs,
8205 : NumNumeric,
8206 : IOStat,
8207 6 : state.dataIPShortCut->lNumericFieldBlanks,
8208 6 : state.dataIPShortCut->lAlphaFieldBlanks,
8209 6 : state.dataIPShortCut->cAlphaFieldNames,
8210 6 : state.dataIPShortCut->cNumericFieldNames);
8211 6 : if (UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound)) {
8212 0 : ShowContinueError(
8213 : state, "...each SurfaceProperty:SolarIncidentInside name must not duplicate other SurfaceProperty:SolarIncidentInside name");
8214 0 : continue;
8215 : }
8216 :
8217 6 : state.dataSurface->SurfIncSolSSG(Loop).Name = state.dataIPShortCut->cAlphaArgs(1);
8218 :
8219 : // Assign surface number
8220 6 : SurfNum = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(2), state.dataSurface->Surface);
8221 6 : if (SurfNum == 0) {
8222 0 : ShowSevereError(state,
8223 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8224 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(2) + " has been found.");
8225 0 : ShowContinueError(state,
8226 0 : state.dataIPShortCut->cAlphaFieldNames(2) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(2) +
8227 : "\" no corresponding surface (ref BuildingSurface:Detailed) has been found in the input file.");
8228 0 : ErrorsFound = true;
8229 : } else {
8230 6 : state.dataSurface->SurfIncSolSSG(Loop).SurfPtr = SurfNum;
8231 6 : if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
8232 0 : int repSurfNum = state.dataSurface->Surface(SurfNum).RepresentativeCalcSurfNum;
8233 0 : if (repSurfNum != SurfNum) {
8234 : // Do not use representative surfaces
8235 :
8236 : // remove surface from representative constituent list
8237 0 : auto &vec = state.dataSurface->Surface(repSurfNum).ConstituentSurfaceNums;
8238 0 : vec.erase(std::remove(vec.begin(), vec.end(), SurfNum), vec.end());
8239 :
8240 : // reset representative surface number
8241 0 : state.dataSurface->Surface(SurfNum).RepresentativeCalcSurfNum = SurfNum;
8242 : }
8243 : }
8244 : }
8245 :
8246 : // Assign construction number
8247 6 : ConstrNum = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(3), state.dataConstruction->Construct);
8248 6 : if (ConstrNum == 0) {
8249 0 : ShowSevereError(state,
8250 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8251 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(3) + " has been found.");
8252 0 : ShowContinueError(state,
8253 0 : state.dataIPShortCut->cAlphaFieldNames(3) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(3) +
8254 : "\" no corresponding construction (ref Construction) has been found in the input file.");
8255 0 : ErrorsFound = true;
8256 : } else {
8257 6 : state.dataSurface->SurfIncSolSSG(Loop).ConstrPtr = ConstrNum;
8258 : }
8259 :
8260 : // Assign schedule number
8261 6 : ScheduleNum = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(4));
8262 6 : if (ScheduleNum == 0) {
8263 0 : ShowSevereError(state,
8264 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8265 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(4) + " has been found.");
8266 0 : ShowContinueError(state,
8267 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(4) +
8268 : "\" no corresponding schedule has been found in the input file.");
8269 0 : ErrorsFound = true;
8270 : } else {
8271 6 : state.dataSurface->SurfIncSolSSG(Loop).SchedPtr = ScheduleNum;
8272 : }
8273 : }
8274 : }
8275 :
8276 : //-----------------------------------------------------------------------
8277 : // SurfaceProperty:SolarIncidentInside
8278 : //-----------------------------------------------------------------------
8279 771 : cCurrentModuleObject = "ComplexFenestrationProperty:SolarAbsorbedLayers";
8280 :
8281 771 : state.dataSurface->TotFenLayAbsSSG = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
8282 771 : if (state.dataSurface->TotFenLayAbsSSG > 0) {
8283 1 : if (!allocated(state.dataSurface->FenLayAbsSSG)) {
8284 1 : state.dataSurface->FenLayAbsSSG.allocate(state.dataSurface->TotFenLayAbsSSG);
8285 : }
8286 :
8287 2 : for (Loop = 1; Loop <= state.dataSurface->TotFenLayAbsSSG; ++Loop) {
8288 7 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
8289 : cCurrentModuleObject,
8290 : Loop,
8291 1 : state.dataIPShortCut->cAlphaArgs,
8292 : NumAlpha,
8293 1 : state.dataIPShortCut->rNumericArgs,
8294 : NumNumeric,
8295 : IOStat,
8296 1 : state.dataIPShortCut->lNumericFieldBlanks,
8297 1 : state.dataIPShortCut->lAlphaFieldBlanks,
8298 1 : state.dataIPShortCut->cAlphaFieldNames,
8299 1 : state.dataIPShortCut->cNumericFieldNames);
8300 1 : if (UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound)) {
8301 0 : ShowContinueError(state,
8302 : "...each ComplexFenestrationProperty:SolarAbsorbedLayers name must not duplicate other "
8303 : "ComplexFenestrationProperty:SolarAbsorbedLayers name");
8304 0 : continue;
8305 : }
8306 :
8307 1 : state.dataSurface->FenLayAbsSSG(Loop).Name = state.dataIPShortCut->cAlphaArgs(1);
8308 :
8309 : // Assign surface number
8310 1 : SurfNum = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(2), state.dataSurface->Surface);
8311 1 : if (SurfNum == 0) {
8312 0 : ShowSevereError(state,
8313 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8314 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(2) + " has been found.");
8315 0 : ShowContinueError(state,
8316 0 : state.dataIPShortCut->cAlphaFieldNames(2) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(2) +
8317 : "\" no corresponding surface (ref BuildingSurface:Detailed) has been found in the input file.");
8318 0 : ErrorsFound = true;
8319 : } else {
8320 1 : state.dataSurface->FenLayAbsSSG(Loop).SurfPtr = SurfNum;
8321 : }
8322 :
8323 : // Assign construction number
8324 1 : ConstrNum = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(3), state.dataConstruction->Construct);
8325 1 : if (ConstrNum == 0) {
8326 0 : ShowSevereError(state,
8327 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8328 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(3) + " has been found.");
8329 0 : ShowContinueError(state,
8330 0 : state.dataIPShortCut->cAlphaFieldNames(3) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(3) +
8331 : "\" no corresponding construction (ref Construction) has been found in the input file.");
8332 0 : ErrorsFound = true;
8333 : } else {
8334 1 : state.dataSurface->FenLayAbsSSG(Loop).ConstrPtr = ConstrNum;
8335 1 : NumOfScheduledLayers = NumAlpha - 3;
8336 1 : NumOfLayersMatch = false;
8337 : // Check if number of layers in construction matches number of layers in schedule surface gains object
8338 1 : if (NumOfScheduledLayers == state.dataConstruction->Construct(ConstrNum).TotSolidLayers) {
8339 1 : NumOfLayersMatch = true;
8340 : }
8341 :
8342 1 : if (!NumOfLayersMatch) {
8343 0 : ShowSevereError(state,
8344 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8345 : ", object. Number of scheduled surface gains for each layer does not match number of layers in "
8346 : "referenced construction.");
8347 0 : ShowContinueError(state,
8348 0 : format("{} have {} schedule layers and {} have {} layers.",
8349 0 : state.dataIPShortCut->cAlphaArgs(1),
8350 : NumOfScheduledLayers,
8351 0 : state.dataIPShortCut->cAlphaArgs(3),
8352 0 : state.dataConstruction->Construct(ConstrNum).TotSolidLayers));
8353 0 : ErrorsFound = true;
8354 : }
8355 :
8356 1 : if (!allocated(state.dataSurface->FenLayAbsSSG(Loop).SchedPtrs)) {
8357 1 : state.dataSurface->FenLayAbsSSG(Loop).SchedPtrs.allocate(NumOfScheduledLayers);
8358 : }
8359 :
8360 1 : state.dataSurface->FenLayAbsSSG(Loop).NumOfSched = NumOfScheduledLayers;
8361 :
8362 4 : for (i = 1; i <= NumOfScheduledLayers; ++i) {
8363 3 : ScheduleNum = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(i + 3));
8364 3 : if (ScheduleNum == 0) {
8365 0 : ShowSevereError(state,
8366 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8367 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(NumOfScheduledLayers + 3) +
8368 : " has been found.");
8369 0 : ShowContinueError(state,
8370 0 : state.dataIPShortCut->cAlphaFieldNames(NumOfScheduledLayers + 3) + " entered value = \"" +
8371 0 : state.dataIPShortCut->cAlphaArgs(NumOfScheduledLayers + 3) +
8372 : "\" no corresponding schedule has been found in the input file.");
8373 0 : ErrorsFound = true;
8374 : } else {
8375 3 : state.dataSurface->FenLayAbsSSG(Loop).SchedPtrs(i) = ScheduleNum;
8376 : }
8377 : }
8378 : }
8379 : }
8380 : }
8381 :
8382 : // Check if scheduled surface gains are assigined to each surface in every zone. If not then warning message to user will be
8383 : // issued
8384 771 : if ((state.dataSurface->TotSurfIncSolSSG > 0) || (state.dataSurface->TotFenLayAbsSSG > 0)) {
8385 2 : for (iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
8386 1 : CheckScheduledSurfaceGains(state, iZone);
8387 : }
8388 : }
8389 771 : }
8390 :
8391 1 : void CheckScheduledSurfaceGains(EnergyPlusData &state, int const ZoneNum) // Zone number for which error check will be performed
8392 : {
8393 :
8394 : // SUBROUTINE INFORMATION:
8395 : // AUTHOR Simon Vidanovic
8396 : // DATE WRITTEN July 2013
8397 : // MODIFIED
8398 : // RE-ENGINEERED na
8399 :
8400 : // PURPOSE OF THIS SUBROUTINE:
8401 : // Check if all surfaces within zone are scheduled with surface gains. If not all surfaces within zone are scheduled,
8402 : // warning message will be issued and program will continue to execute.
8403 :
8404 : // METHODOLOGY EMPLOYED:
8405 : // na
8406 :
8407 : // REFERENCES:
8408 : // na
8409 :
8410 : // Using/Aliasing
8411 : using SolarShading::SurfaceScheduledSolarInc;
8412 : using SolarShading::WindowScheduledSolarAbs;
8413 : using namespace DataSurfaces;
8414 :
8415 : // Locals
8416 : // SUBROUTINE ARGUMENT DEFINITIONS:
8417 :
8418 : // SUBROUTINE PARAMETER DEFINITIONS:
8419 : // na
8420 :
8421 : // INTERFACE BLOCK SPECIFICATIONS:
8422 : // na
8423 :
8424 : // DERIVED TYPE DEFINITIONS:
8425 : // na
8426 :
8427 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8428 : int SchedPtr; // scheduled surface gains pointer
8429 : bool ZoneUnscheduled; // true if all surfaces in the zone are unscheduled
8430 : bool ZoneScheduled; // true if all surfaces in the zone are scheduled
8431 :
8432 1 : ZoneUnscheduled = false;
8433 1 : ZoneScheduled = false;
8434 :
8435 1 : bool firstZoneSurface = true;
8436 2 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
8437 1 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
8438 8 : for (int iSurf = thisSpace.HTSurfaceFirst; iSurf <= thisSpace.HTSurfaceLast; ++iSurf) {
8439 7 : int iConst = state.dataSurface->Surface(iSurf).Construction;
8440 7 : if (state.dataSurface->Surface(iSurf).Class == SurfaceClass::Window) {
8441 1 : SchedPtr = WindowScheduledSolarAbs(state, iSurf, iConst);
8442 : } else {
8443 6 : SchedPtr = SurfaceScheduledSolarInc(state, iSurf, iConst);
8444 : }
8445 7 : if (firstZoneSurface) {
8446 1 : if (SchedPtr != 0) {
8447 1 : ZoneScheduled = true;
8448 1 : ZoneUnscheduled = false;
8449 : } else {
8450 0 : ZoneScheduled = false;
8451 0 : ZoneUnscheduled = true;
8452 : }
8453 1 : firstZoneSurface = false;
8454 : } else {
8455 6 : if (SchedPtr != 0) {
8456 6 : ZoneUnscheduled = false;
8457 : } else {
8458 0 : ZoneScheduled = false;
8459 : }
8460 : }
8461 : }
8462 : }
8463 1 : if ((!ZoneScheduled) && (!ZoneUnscheduled)) {
8464 : // zone is nor scheduled nor unscheduled
8465 0 : ShowWarningError(state, "Zone " + state.dataHeatBal->Zone(ZoneNum).Name + " does not have all surfaces scheduled with surface gains.");
8466 0 : ShowContinueError(state,
8467 : "If at least one surface in the zone is scheduled with surface gains, then all other surfaces within the same zone "
8468 : "should be scheduled as well.");
8469 : }
8470 :
8471 1 : if ((!ZoneScheduled) && (!ZoneUnscheduled)) {
8472 0 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
8473 0 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
8474 0 : for (int iSurf = thisSpace.HTSurfaceFirst; iSurf <= thisSpace.HTSurfaceLast; ++iSurf) {
8475 0 : int iConst = state.dataSurface->Surface(iSurf).Construction;
8476 0 : if (state.dataSurface->Surface(iSurf).Class == SurfaceClass::Window) {
8477 0 : SchedPtr = WindowScheduledSolarAbs(state, iSurf, iConst);
8478 : } else {
8479 0 : SchedPtr = SurfaceScheduledSolarInc(state, iSurf, iConst);
8480 : }
8481 :
8482 0 : if (SchedPtr == 0) {
8483 0 : ShowContinueError(state, "Surface " + state.dataSurface->Surface(iSurf).Name + " does not have scheduled surface gains.");
8484 : }
8485 : }
8486 : }
8487 : }
8488 1 : }
8489 :
8490 771 : void CreateTCConstructions(EnergyPlusData &state, [[maybe_unused]] bool &ErrorsFound) // If errors found in input
8491 : {
8492 :
8493 : // SUBROUTINE INFORMATION:
8494 : // AUTHOR Tianzhen Hong
8495 : // DATE WRITTEN January 2009
8496 : // MODIFIED
8497 : // RE-ENGINEERED na
8498 :
8499 : // PURPOSE OF THIS SUBROUTINE:
8500 : // This subroutine goes through each TC master construction and creates a complete series
8501 : // of the slave thermochromic constructions.
8502 : // This subroutine only gets called once in the GetHeatBalanceInput subroutine
8503 : // after materials, constructions and building geometry data are read.
8504 :
8505 : // METHODOLOGY EMPLOYED:
8506 : // na
8507 :
8508 : // REFERENCES:
8509 : // na
8510 :
8511 : // USE STATEMENTS:
8512 :
8513 : // Using/Aliasing
8514 : using namespace DataStringGlobals;
8515 :
8516 : // Locals
8517 : // SUBROUTINE ARGUMENT DEFINITIONS:
8518 :
8519 : // SUBROUTINE PARAMETER DEFINITIONS:
8520 : // na
8521 :
8522 : // INTERFACE BLOCK SPECIFICATIONS:
8523 : // na
8524 :
8525 : // DERIVED TYPE DEFINITIONS:
8526 : // na
8527 :
8528 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8529 :
8530 : int Loop;
8531 771 : int iTC(0);
8532 771 : int iMat(0);
8533 771 : int NumNewConst(0);
8534 771 : int iTCG(0);
8535 :
8536 771 : NumNewConst = 0;
8537 6620 : for (Loop = 1; Loop <= state.dataHeatBal->TotConstructs; ++Loop) {
8538 5849 : if (state.dataConstruction->Construct(Loop).TCFlag == 1) {
8539 1 : iTCG = state.dataMaterial->Material(state.dataConstruction->Construct(Loop).TCLayer).TCParent;
8540 1 : if (iTCG == 0) continue; // hope this was caught already
8541 1 : iMat = state.dataHeatBal->TCGlazings(iTCG).NumGlzMat;
8542 20 : for (iTC = 1; iTC <= iMat; ++iTC) {
8543 19 : ++NumNewConst;
8544 : }
8545 : }
8546 : }
8547 :
8548 771 : if (NumNewConst == 0) return; // no need to go further
8549 :
8550 : // Increase Construct() and copy the extra constructions
8551 1 : state.dataConstruction->Construct.redimension(state.dataHeatBal->TotConstructs + NumNewConst);
8552 1 : state.dataHeatBal->NominalRforNominalUCalculation.redimension(state.dataHeatBal->TotConstructs + NumNewConst);
8553 1 : state.dataHeatBal->NominalU.redimension(state.dataHeatBal->TotConstructs + NumNewConst);
8554 1 : state.dataHeatBal->NominalUBeforeAdjusted.redimension(state.dataHeatBal->TotConstructs + NumNewConst);
8555 1 : state.dataHeatBal->CoeffAdjRatio.redimension(state.dataHeatBal->TotConstructs + NumNewConst) = 1.0;
8556 :
8557 1 : NumNewConst = state.dataHeatBal->TotConstructs;
8558 14 : for (Loop = 1; Loop <= state.dataHeatBal->TotConstructs; ++Loop) {
8559 13 : if (state.dataConstruction->Construct(Loop).TCFlag == 1) {
8560 1 : iTCG = state.dataMaterial->Material(state.dataConstruction->Construct(Loop).TCLayer).TCParent;
8561 1 : if (iTCG == 0) continue; // hope this was caught already
8562 1 : iMat = state.dataHeatBal->TCGlazings(iTCG).NumGlzMat;
8563 20 : for (iTC = 1; iTC <= iMat; ++iTC) {
8564 19 : ++NumNewConst;
8565 19 : state.dataConstruction->Construct(NumNewConst) = state.dataConstruction->Construct(Loop); // copy data
8566 38 : state.dataConstruction->Construct(NumNewConst).Name =
8567 57 : format("{}_TC_{:.0R}", state.dataConstruction->Construct(Loop).Name, state.dataHeatBal->TCGlazings(iTCG).SpecTemp(iTC));
8568 19 : state.dataConstruction->Construct(NumNewConst).TCLayer = state.dataHeatBal->TCGlazings(iTCG).LayerPoint(iTC);
8569 19 : state.dataConstruction->Construct(NumNewConst).LayerPoint(state.dataConstruction->Construct(Loop).TCLayerID) =
8570 19 : state.dataConstruction->Construct(NumNewConst).TCLayer;
8571 19 : state.dataConstruction->Construct(NumNewConst).TCFlag = 1;
8572 19 : state.dataConstruction->Construct(NumNewConst).TCMasterConst = Loop;
8573 19 : state.dataConstruction->Construct(NumNewConst).TCLayerID = state.dataConstruction->Construct(Loop).TCLayerID;
8574 19 : state.dataConstruction->Construct(NumNewConst).TCGlassID = state.dataConstruction->Construct(Loop).TCGlassID;
8575 19 : state.dataConstruction->Construct(NumNewConst).TypeIsWindow = true;
8576 : }
8577 : }
8578 : }
8579 1 : state.dataHeatBal->TotConstructs = NumNewConst;
8580 : }
8581 :
8582 100 : void SetupSimpleWindowGlazingSystem(EnergyPlusData &state, int &MaterNum)
8583 : {
8584 :
8585 : // SUBROUTINE INFORMATION:
8586 : // AUTHOR B. Griffith
8587 : // DATE WRITTEN January 2009
8588 : // MODIFIED na
8589 : // RE-ENGINEERED na
8590 :
8591 : // PURPOSE OF THIS SUBROUTINE:
8592 : // Convert simple window performance indices into all the properties needed to
8593 : // describe a single, equivalent glass layer
8594 :
8595 : // METHODOLOGY EMPLOYED:
8596 : // The simple window indices are converted to a single materal layer using a "block model"
8597 :
8598 : // REFERENCES:
8599 : // draft paper by Arasteh, Kohler, and Griffith
8600 :
8601 : // USE STATEMENTS:
8602 : // na
8603 :
8604 : // Locals
8605 : // SUBROUTINE ARGUMENT DEFINITIONS:
8606 :
8607 : // SUBROUTINE PARAMETER DEFINITIONS:
8608 : // na
8609 :
8610 : // INTERFACE BLOCK SPECIFICATIONS:
8611 : // na
8612 :
8613 : // DERIVED TYPE DEFINITIONS:
8614 : // na
8615 :
8616 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8617 100 : Real64 Riw(0.0); // thermal resistance of interior film coefficient under winter conditions (m2-K/W)
8618 100 : Real64 Row(0.0); // theraml resistance of exterior film coefficient under winter conditions (m2-K/W)
8619 100 : Real64 Rlw(0.0); // thermal resistance of block model layer (m2-K/W)
8620 100 : Real64 Ris(0.0); // thermal resistance of interior film coefficient under summer conditions (m2-K/W)
8621 100 : Real64 Ros(0.0); // theraml resistance of exterior film coefficient under summer conditions (m2-K/W)
8622 100 : Real64 InflowFraction(0.0); // inward flowing fraction for SHGC, intermediate value non dimensional
8623 100 : Real64 SolarAbsorb(0.0); // solar aborptance
8624 100 : bool ErrorsFound(false);
8625 100 : Real64 TsolLowSide(0.0); // intermediate solar transmission for interpolating
8626 100 : Real64 TsolHiSide(0.0); // intermediate solar transmission for interpolating
8627 100 : Real64 DeltaSHGCandTsol(0.0); // intermediate difference
8628 100 : Real64 RLowSide(0.0);
8629 100 : Real64 RHiSide(0.0);
8630 :
8631 : // first fill out defaults
8632 100 : state.dataMaterial->Material(MaterNum).GlassSpectralDataPtr = 0;
8633 100 : state.dataMaterial->Material(MaterNum).SolarDiffusing = false;
8634 100 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::VerySmooth;
8635 100 : state.dataMaterial->Material(MaterNum).TransThermal = 0.0;
8636 100 : state.dataMaterial->Material(MaterNum).AbsorpThermalBack = 0.84;
8637 100 : state.dataMaterial->Material(MaterNum).AbsorpThermalFront = 0.84;
8638 100 : state.dataMaterial->Material(MaterNum).AbsorpThermal = state.dataMaterial->Material(MaterNum).AbsorpThermalBack;
8639 :
8640 : // step 1. Determine U-factor without film coefficients
8641 : // Simple window model has its own correlation for film coefficients (m2-K/W) under Winter conditions as function of U-factor
8642 100 : if (state.dataMaterial->Material(MaterNum).SimpleWindowUfactor < 5.85) {
8643 99 : Riw = 1.0 / (0.359073 * std::log(state.dataMaterial->Material(MaterNum).SimpleWindowUfactor) + 6.949915);
8644 : } else {
8645 1 : Riw = 1.0 / (1.788041 * state.dataMaterial->Material(MaterNum).SimpleWindowUfactor - 2.886625);
8646 : }
8647 100 : Row = 1.0 / (0.025342 * state.dataMaterial->Material(MaterNum).SimpleWindowUfactor + 29.163853);
8648 :
8649 : // determine 1/U without film coefficients
8650 100 : Rlw = (1.0 / state.dataMaterial->Material(MaterNum).SimpleWindowUfactor) - Riw - Row;
8651 100 : if (Rlw <= 0.0) { // U factor of film coefficients is better than user input.
8652 0 : Rlw = max(Rlw, 0.001);
8653 0 : ShowWarningError(state,
8654 0 : "WindowMaterial:SimpleGlazingSystem: " + state.dataMaterial->Material(MaterNum).Name +
8655 : " has U-factor higher than that provided by surface film resistances, Check value of U-factor");
8656 : }
8657 :
8658 : // Step 2. determine layer thickness.
8659 :
8660 100 : if ((1.0 / Rlw) > 7.0) {
8661 60 : state.dataMaterial->Material(MaterNum).Thickness = 0.002;
8662 : } else {
8663 40 : state.dataMaterial->Material(MaterNum).Thickness = 0.05914 - (0.00714 / Rlw);
8664 : }
8665 :
8666 : // Step 3. determine effective conductivity
8667 :
8668 100 : state.dataMaterial->Material(MaterNum).Conductivity = state.dataMaterial->Material(MaterNum).Thickness / Rlw;
8669 100 : if (state.dataMaterial->Material(MaterNum).Conductivity > 0.0) {
8670 100 : state.dataHeatBal->NominalR(MaterNum) = Rlw;
8671 100 : state.dataMaterial->Material(MaterNum).Resistance = Rlw;
8672 : } else {
8673 0 : ErrorsFound = true;
8674 0 : ShowSevereError(state,
8675 0 : "WindowMaterial:SimpleGlazingSystem: " + state.dataMaterial->Material(MaterNum).Name +
8676 : " has Conductivity <= 0.0, must be >0.0, Check value of U-factor");
8677 : }
8678 :
8679 : // step 4. determine solar transmission (revised to 10-1-2009 version from LBNL.)
8680 :
8681 100 : if (state.dataMaterial->Material(MaterNum).SimpleWindowUfactor > 4.5) {
8682 :
8683 2 : if (state.dataMaterial->Material(MaterNum).SimpleWindowSHGC < 0.7206) {
8684 :
8685 2 : state.dataMaterial->Material(MaterNum).Trans = 0.939998 * pow_2(state.dataMaterial->Material(MaterNum).SimpleWindowSHGC) +
8686 1 : 0.20332 * state.dataMaterial->Material(MaterNum).SimpleWindowSHGC;
8687 : } else { // >= 0.7206
8688 :
8689 1 : state.dataMaterial->Material(MaterNum).Trans = 1.30415 * state.dataMaterial->Material(MaterNum).SimpleWindowSHGC - 0.30515;
8690 : }
8691 :
8692 98 : } else if (state.dataMaterial->Material(MaterNum).SimpleWindowUfactor < 3.4) {
8693 :
8694 96 : if (state.dataMaterial->Material(MaterNum).SimpleWindowSHGC <= 0.15) {
8695 0 : state.dataMaterial->Material(MaterNum).Trans = 0.41040 * state.dataMaterial->Material(MaterNum).SimpleWindowSHGC;
8696 : } else { // > 0.15
8697 288 : state.dataMaterial->Material(MaterNum).Trans = 0.085775 * pow_2(state.dataMaterial->Material(MaterNum).SimpleWindowSHGC) +
8698 192 : 0.963954 * state.dataMaterial->Material(MaterNum).SimpleWindowSHGC - 0.084958;
8699 : }
8700 : } else { // interpolate. 3.4 <= Ufactor <= 4.5
8701 :
8702 2 : if (state.dataMaterial->Material(MaterNum).SimpleWindowSHGC < 0.7206) {
8703 4 : TsolHiSide = 0.939998 * pow_2(state.dataMaterial->Material(MaterNum).SimpleWindowSHGC) +
8704 2 : 0.20332 * state.dataMaterial->Material(MaterNum).SimpleWindowSHGC;
8705 : } else { // >= 0.7206
8706 0 : TsolHiSide = 1.30415 * state.dataMaterial->Material(MaterNum).SimpleWindowSHGC - 0.30515;
8707 : }
8708 :
8709 2 : if (state.dataMaterial->Material(MaterNum).SimpleWindowSHGC <= 0.15) {
8710 0 : TsolLowSide = 0.41040 * state.dataMaterial->Material(MaterNum).SimpleWindowSHGC;
8711 : } else { // > 0.15
8712 4 : TsolLowSide = 0.085775 * pow_2(state.dataMaterial->Material(MaterNum).SimpleWindowSHGC) +
8713 2 : 0.963954 * state.dataMaterial->Material(MaterNum).SimpleWindowSHGC - 0.084958;
8714 : }
8715 :
8716 2 : state.dataMaterial->Material(MaterNum).Trans =
8717 2 : ((state.dataMaterial->Material(MaterNum).SimpleWindowUfactor - 3.4) / (4.5 - 3.4)) * (TsolHiSide - TsolLowSide) + TsolLowSide;
8718 : }
8719 100 : if (state.dataMaterial->Material(MaterNum).Trans < 0.0) state.dataMaterial->Material(MaterNum).Trans = 0.0;
8720 :
8721 : // step 5. determine solar reflectances
8722 :
8723 100 : DeltaSHGCandTsol = state.dataMaterial->Material(MaterNum).SimpleWindowSHGC - state.dataMaterial->Material(MaterNum).Trans;
8724 :
8725 100 : if (state.dataMaterial->Material(MaterNum).SimpleWindowUfactor > 4.5) {
8726 :
8727 2 : Ris = 1.0 / (29.436546 * pow_3(DeltaSHGCandTsol) - 21.943415 * pow_2(DeltaSHGCandTsol) + 9.945872 * DeltaSHGCandTsol + 7.426151);
8728 2 : Ros = 1.0 / (2.225824 * DeltaSHGCandTsol + 20.577080);
8729 98 : } else if (state.dataMaterial->Material(MaterNum).SimpleWindowUfactor < 3.4) {
8730 :
8731 96 : Ris = 1.0 / (199.8208128 * pow_3(DeltaSHGCandTsol) - 90.639733 * pow_2(DeltaSHGCandTsol) + 19.737055 * DeltaSHGCandTsol + 6.766575);
8732 96 : Ros = 1.0 / (5.763355 * DeltaSHGCandTsol + 20.541528);
8733 : } else { // interpolate. 3.4 <= Ufactor <= 4.5
8734 : // inside first
8735 2 : RLowSide = 1.0 / (199.8208128 * pow_3(DeltaSHGCandTsol) - 90.639733 * pow_2(DeltaSHGCandTsol) + 19.737055 * DeltaSHGCandTsol + 6.766575);
8736 2 : RHiSide = 1.0 / (29.436546 * pow_3(DeltaSHGCandTsol) - 21.943415 * pow_2(DeltaSHGCandTsol) + 9.945872 * DeltaSHGCandTsol + 7.426151);
8737 2 : Ris = ((state.dataMaterial->Material(MaterNum).SimpleWindowUfactor - 3.4) / (4.5 - 3.4)) * (RLowSide - RHiSide) + RLowSide;
8738 : // then outside
8739 2 : RLowSide = 1.0 / (5.763355 * DeltaSHGCandTsol + 20.541528);
8740 2 : RHiSide = 1.0 / (2.225824 * DeltaSHGCandTsol + 20.577080);
8741 2 : Ros = ((state.dataMaterial->Material(MaterNum).SimpleWindowUfactor - 3.4) / (4.5 - 3.4)) * (RLowSide - RHiSide) + RLowSide;
8742 : }
8743 :
8744 100 : InflowFraction = (Ros + 0.5 * Rlw) / (Ros + Rlw + Ris);
8745 :
8746 100 : SolarAbsorb = (state.dataMaterial->Material(MaterNum).SimpleWindowSHGC - state.dataMaterial->Material(MaterNum).Trans) / InflowFraction;
8747 100 : state.dataMaterial->Material(MaterNum).ReflectSolBeamBack = 1.0 - state.dataMaterial->Material(MaterNum).Trans - SolarAbsorb;
8748 100 : state.dataMaterial->Material(MaterNum).ReflectSolBeamFront = state.dataMaterial->Material(MaterNum).ReflectSolBeamBack;
8749 :
8750 : // step 6. determine visible properties.
8751 100 : if (state.dataMaterial->Material(MaterNum).SimpleWindowVTinputByUser) {
8752 45 : state.dataMaterial->Material(MaterNum).TransVis = state.dataMaterial->Material(MaterNum).SimpleWindowVisTran;
8753 135 : state.dataMaterial->Material(MaterNum).ReflectVisBeamBack = -0.7409 * pow_3(state.dataMaterial->Material(MaterNum).TransVis) +
8754 90 : 1.6531 * pow_2(state.dataMaterial->Material(MaterNum).TransVis) -
8755 90 : 1.2299 * state.dataMaterial->Material(MaterNum).TransVis + 0.4545;
8756 45 : if (state.dataMaterial->Material(MaterNum).TransVis + state.dataMaterial->Material(MaterNum).ReflectVisBeamBack >= 1.0) {
8757 4 : state.dataMaterial->Material(MaterNum).ReflectVisBeamBack = 0.999 - state.dataMaterial->Material(MaterNum).TransVis;
8758 : }
8759 :
8760 135 : state.dataMaterial->Material(MaterNum).ReflectVisBeamFront = -0.0622 * pow_3(state.dataMaterial->Material(MaterNum).TransVis) +
8761 90 : 0.4277 * pow_2(state.dataMaterial->Material(MaterNum).TransVis) -
8762 90 : 0.4169 * state.dataMaterial->Material(MaterNum).TransVis + 0.2399;
8763 45 : if (state.dataMaterial->Material(MaterNum).TransVis + state.dataMaterial->Material(MaterNum).ReflectVisBeamFront >= 1.0) {
8764 4 : state.dataMaterial->Material(MaterNum).ReflectVisBeamFront = 0.999 - state.dataMaterial->Material(MaterNum).TransVis;
8765 : }
8766 : } else {
8767 55 : state.dataMaterial->Material(MaterNum).TransVis = state.dataMaterial->Material(MaterNum).Trans;
8768 55 : state.dataMaterial->Material(MaterNum).ReflectVisBeamBack = state.dataMaterial->Material(MaterNum).ReflectSolBeamBack;
8769 55 : state.dataMaterial->Material(MaterNum).ReflectVisBeamFront = state.dataMaterial->Material(MaterNum).ReflectSolBeamFront;
8770 : }
8771 :
8772 : // step 7. The dependence on incident angle is in subroutine TransAndReflAtPhi
8773 :
8774 : // step 8. Hemispherical terms are averaged using standard method
8775 :
8776 100 : if (ErrorsFound) {
8777 0 : ShowFatalError(state, "Program halted because of input problem(s) in WindowMaterial:SimpleGlazingSystem");
8778 : }
8779 100 : }
8780 :
8781 10 : void SetupComplexFenestrationMaterialInput(EnergyPlusData &state,
8782 : int &MaterNum, // num of material items thus far
8783 : bool &ErrorsFound)
8784 : {
8785 :
8786 : // SUBROUTINE INFORMATION:
8787 : // AUTHOR Simon Vidanovic
8788 : // DATE WRITTEN March 2012
8789 : // MODIFIED May 2013 (Simon Vidanovic)
8790 : // RE-ENGINEERED na
8791 :
8792 : // PURPOSE OF THIS SUBROUTINE:
8793 : // get input for complex fenestration materials
8794 :
8795 : // METHODOLOGY EMPLOYED:
8796 : // usual GetInput processing.
8797 :
8798 : // REFERENCES:
8799 : // na
8800 :
8801 : // Using/Aliasing
8802 :
8803 : // SUBROUTINE ARGUMENT DEFINITIONS:
8804 :
8805 : // Locals
8806 : // SUBROUTINE PARAMETER DEFINITIONS
8807 10 : constexpr const char *RoutineName("SetupComplexFenestrationMaterialInput: ");
8808 :
8809 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8810 20 : Array1D_string MaterialNames(5); // Number of Material Alpha names defined
8811 20 : Array1D<Real64> MaterialProps(27); // Temporary array to transfer material properties
8812 : int Loop;
8813 : int NumAlphas; // Number of Alphas for each GetObjectItem call
8814 : int NumNumbers; // Number of Numbers for each GetObjectItem call
8815 : int IOStatus; // Used in GetObjectItem
8816 :
8817 : // Reading WindowGap:SupportPillar
8818 10 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
8819 10 : cCurrentModuleObject = "WindowGap:SupportPillar";
8820 10 : state.dataHeatBal->W7SupportPillars = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
8821 10 : state.dataHeatBal->SupportPillar.allocate(state.dataHeatBal->W7SupportPillars);
8822 11 : for (Loop = 1; Loop <= state.dataHeatBal->W7SupportPillars; ++Loop) {
8823 7 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
8824 : cCurrentModuleObject,
8825 : Loop,
8826 1 : state.dataIPShortCut->cAlphaArgs,
8827 : NumAlphas,
8828 1 : state.dataIPShortCut->rNumericArgs,
8829 : NumNumbers,
8830 : IOStatus,
8831 1 : state.dataIPShortCut->lNumericFieldBlanks,
8832 1 : state.dataIPShortCut->lAlphaFieldBlanks,
8833 1 : state.dataIPShortCut->cAlphaFieldNames,
8834 1 : state.dataIPShortCut->cNumericFieldNames);
8835 1 : if (UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), state.dataHeatBalMgr->CurrentModuleObject, ErrorsFound)) {
8836 0 : ShowSevereError(state,
8837 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8838 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(1) + " has been found.");
8839 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
8840 0 : continue;
8841 : }
8842 :
8843 1 : state.dataHeatBal->SupportPillar(Loop).Name = state.dataIPShortCut->cAlphaArgs(1);
8844 1 : state.dataHeatBal->SupportPillar(Loop).Spacing = state.dataIPShortCut->rNumericArgs(1);
8845 1 : state.dataHeatBal->SupportPillar(Loop).Radius = state.dataIPShortCut->rNumericArgs(2);
8846 :
8847 1 : if (state.dataIPShortCut->rNumericArgs(1) <= 0.0) {
8848 0 : ErrorsFound = true;
8849 0 : ShowSevereError(state,
8850 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8851 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(1) + " has been found.");
8852 0 : ShowContinueError(state,
8853 0 : format("{} must be > 0, entered value = {:.2R}",
8854 0 : state.dataIPShortCut->cNumericFieldNames(1),
8855 0 : state.dataIPShortCut->rNumericArgs(1)));
8856 : }
8857 :
8858 1 : if (state.dataIPShortCut->rNumericArgs(2) <= 0.0) {
8859 0 : ErrorsFound = true;
8860 0 : ShowSevereError(state,
8861 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8862 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(2) + " has been found.");
8863 0 : ShowContinueError(state,
8864 0 : format("{} must be > 0, entered value = {:.2R}",
8865 0 : state.dataIPShortCut->cNumericFieldNames(2),
8866 0 : state.dataIPShortCut->rNumericArgs(2)));
8867 : }
8868 : }
8869 :
8870 : // Reading WindowGap:DeflectionState
8871 10 : cCurrentModuleObject = "WindowGap:DeflectionState";
8872 10 : state.dataHeatBal->W7DeflectionStates = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
8873 10 : state.dataHeatBal->DeflectionState.allocate(state.dataHeatBal->W7DeflectionStates);
8874 13 : for (Loop = 1; Loop <= state.dataHeatBal->W7DeflectionStates; ++Loop) {
8875 21 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
8876 : cCurrentModuleObject,
8877 : Loop,
8878 3 : state.dataIPShortCut->cAlphaArgs,
8879 : NumAlphas,
8880 3 : state.dataIPShortCut->rNumericArgs,
8881 : NumNumbers,
8882 : IOStatus,
8883 3 : state.dataIPShortCut->lNumericFieldBlanks,
8884 3 : state.dataIPShortCut->lAlphaFieldBlanks,
8885 3 : state.dataIPShortCut->cAlphaFieldNames,
8886 3 : state.dataIPShortCut->cNumericFieldNames);
8887 3 : if (UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), state.dataHeatBalMgr->CurrentModuleObject, ErrorsFound)) {
8888 0 : ShowSevereError(state,
8889 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8890 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(1) + " has been found.");
8891 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
8892 0 : continue;
8893 : }
8894 :
8895 3 : state.dataHeatBal->DeflectionState(Loop).Name = state.dataIPShortCut->cAlphaArgs(1);
8896 3 : state.dataHeatBal->DeflectionState(Loop).DeflectedThickness = state.dataIPShortCut->rNumericArgs(1);
8897 3 : if (state.dataIPShortCut->rNumericArgs(1) < 0.0) {
8898 0 : ErrorsFound = true;
8899 0 : ShowSevereError(state,
8900 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8901 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(1) + " has been found.");
8902 0 : ShowContinueError(state,
8903 0 : format("{} must be >= 0, entered value = {:.2R}",
8904 0 : state.dataIPShortCut->cNumericFieldNames(1),
8905 0 : state.dataIPShortCut->rNumericArgs(1)));
8906 : }
8907 : }
8908 :
8909 : // Reading WindowMaterial:Gap
8910 :
8911 10 : cCurrentModuleObject = "WindowMaterial:Gap";
8912 10 : state.dataHeatBal->W7MaterialGaps = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
8913 : // ALLOCATE(DeflectionState(W7DeflectionStates))
8914 24 : for (Loop = 1; Loop <= state.dataHeatBal->W7MaterialGaps; ++Loop) {
8915 98 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
8916 : cCurrentModuleObject,
8917 : Loop,
8918 14 : state.dataIPShortCut->cAlphaArgs,
8919 : NumAlphas,
8920 14 : state.dataIPShortCut->rNumericArgs,
8921 : NumNumbers,
8922 : IOStatus,
8923 14 : state.dataIPShortCut->lNumericFieldBlanks,
8924 14 : state.dataIPShortCut->lAlphaFieldBlanks,
8925 14 : state.dataIPShortCut->cAlphaFieldNames,
8926 14 : state.dataIPShortCut->cNumericFieldNames);
8927 42 : if (GlobalNames::VerifyUniqueInterObjectName(state,
8928 14 : state.dataHeatBalMgr->UniqueMaterialNames,
8929 14 : state.dataIPShortCut->cAlphaArgs(1),
8930 14 : state.dataHeatBalMgr->CurrentModuleObject,
8931 14 : state.dataIPShortCut->cAlphaFieldNames(1),
8932 : ErrorsFound)) {
8933 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
8934 0 : continue;
8935 : }
8936 :
8937 14 : ++MaterNum;
8938 14 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::ComplexWindowGap;
8939 14 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::Rough;
8940 14 : state.dataMaterial->Material(MaterNum).ROnly = true;
8941 :
8942 14 : state.dataMaterial->Material(MaterNum).Name = state.dataIPShortCut->cAlphaArgs(1);
8943 :
8944 14 : state.dataMaterial->Material(MaterNum).Thickness = state.dataIPShortCut->rNumericArgs(1);
8945 14 : if (state.dataIPShortCut->rNumericArgs(1) <= 0.0) {
8946 0 : ErrorsFound = true;
8947 0 : ShowSevereError(state,
8948 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8949 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(1) + " has been found.");
8950 0 : ShowContinueError(
8951 : state,
8952 0 : format("{} must be > 0, entered {:.2R}", state.dataIPShortCut->cNumericFieldNames(1), state.dataIPShortCut->rNumericArgs(1)));
8953 : }
8954 :
8955 14 : state.dataMaterial->Material(MaterNum).Pressure = state.dataIPShortCut->rNumericArgs(2);
8956 14 : if (state.dataIPShortCut->rNumericArgs(2) <= 0.0) {
8957 0 : ErrorsFound = true;
8958 0 : ShowSevereError(state,
8959 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8960 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(2) + " has been found.");
8961 0 : ShowContinueError(
8962 : state,
8963 0 : format("{} must be > 0, entered {:.2R}", state.dataIPShortCut->cNumericFieldNames(2), state.dataIPShortCut->rNumericArgs(2)));
8964 : }
8965 :
8966 14 : if (!state.dataIPShortCut->lAlphaFieldBlanks(2)) {
8967 14 : state.dataMaterial->Material(MaterNum).GasPointer =
8968 14 : UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(2), state.dataMaterial->Material);
8969 : } else {
8970 0 : ShowSevereError(state,
8971 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
8972 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(1) + " has been found.");
8973 0 : ShowContinueError(state, cCurrentModuleObject + " does not have assigned WindowMaterial:Gas or WindowMaterial:GasMixutre.");
8974 : }
8975 14 : if (!state.dataIPShortCut->lAlphaFieldBlanks(3)) {
8976 1 : state.dataMaterial->Material(MaterNum).DeflectionStatePtr =
8977 1 : UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(3), state.dataHeatBal->DeflectionState);
8978 : }
8979 14 : if (!state.dataIPShortCut->lAlphaFieldBlanks(4)) {
8980 1 : state.dataMaterial->Material(MaterNum).SupportPillarPtr =
8981 1 : UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(4), state.dataHeatBal->SupportPillar);
8982 : }
8983 : }
8984 :
8985 : // Reading WindowMaterial:ComplexShade
8986 10 : cCurrentModuleObject = "WindowMaterial:ComplexShade";
8987 10 : state.dataHeatBal->TotComplexShades = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
8988 :
8989 10 : if (state.dataHeatBal->TotComplexShades > 0) {
8990 6 : state.dataHeatBal->ComplexShade.allocate(state.dataHeatBal->TotComplexShades); // Allocate the array Size to the number of complex shades
8991 : }
8992 :
8993 19 : for (Loop = 1; Loop <= state.dataHeatBal->TotComplexShades; ++Loop) {
8994 63 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
8995 : cCurrentModuleObject,
8996 : Loop,
8997 9 : state.dataIPShortCut->cAlphaArgs,
8998 : NumAlphas,
8999 9 : state.dataIPShortCut->rNumericArgs,
9000 : NumNumbers,
9001 : IOStatus,
9002 9 : state.dataIPShortCut->lNumericFieldBlanks,
9003 9 : state.dataIPShortCut->lAlphaFieldBlanks,
9004 9 : state.dataIPShortCut->cAlphaFieldNames,
9005 9 : state.dataIPShortCut->cNumericFieldNames);
9006 9 : if (UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), state.dataHeatBalMgr->CurrentModuleObject, ErrorsFound)) {
9007 0 : ShowSevereError(state,
9008 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9009 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(1) + " has been found.");
9010 0 : ShowContinueError(state, "...All Material names must be unique regardless of subtype.");
9011 0 : continue;
9012 : }
9013 :
9014 9 : ++MaterNum;
9015 9 : state.dataMaterial->Material(MaterNum).Group = DataHeatBalance::MaterialGroup::ComplexWindowShade;
9016 9 : state.dataMaterial->Material(MaterNum).Roughness = DataSurfaces::SurfaceRoughness::Rough;
9017 9 : state.dataMaterial->Material(MaterNum).ROnly = true;
9018 :
9019 : // Assign pointer to ComplexShade
9020 9 : state.dataMaterial->Material(MaterNum).ComplexShadePtr = Loop;
9021 :
9022 9 : state.dataMaterial->Material(MaterNum).Name = state.dataIPShortCut->cAlphaArgs(1);
9023 9 : state.dataHeatBal->ComplexShade(Loop).Name = state.dataIPShortCut->cAlphaArgs(1);
9024 :
9025 : {
9026 18 : auto const SELECT_CASE_var(state.dataIPShortCut->cAlphaArgs(2));
9027 :
9028 9 : if (SELECT_CASE_var == "OTHERSHADINGTYPE") {
9029 0 : state.dataHeatBal->ComplexShade(Loop).LayerType = TARCOGParams::TARCOGLayerType::DIFFSHADE;
9030 9 : } else if (SELECT_CASE_var == "VENETIANHORIZONTAL") {
9031 2 : state.dataHeatBal->ComplexShade(Loop).LayerType = TARCOGParams::TARCOGLayerType::VENETBLIND_HORIZ;
9032 7 : } else if (SELECT_CASE_var == "VENETIANVERTICAL") {
9033 1 : state.dataHeatBal->ComplexShade(Loop).LayerType = TARCOGParams::TARCOGLayerType::VENETBLIND_VERT;
9034 6 : } else if (SELECT_CASE_var == "WOVEN") {
9035 2 : state.dataHeatBal->ComplexShade(Loop).LayerType = TARCOGParams::TARCOGLayerType::WOVSHADE;
9036 4 : } else if (SELECT_CASE_var == "PERFORATED") {
9037 3 : state.dataHeatBal->ComplexShade(Loop).LayerType = TARCOGParams::TARCOGLayerType::PERFORATED;
9038 1 : } else if (SELECT_CASE_var == "BSDF") {
9039 1 : state.dataHeatBal->ComplexShade(Loop).LayerType = TARCOGParams::TARCOGLayerType::BSDF;
9040 : } else {
9041 0 : ErrorsFound = true;
9042 0 : ShowSevereError(state,
9043 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9044 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(2) + " has been found.");
9045 0 : ShowContinueError(state,
9046 0 : state.dataIPShortCut->cAlphaFieldNames(2) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(2) +
9047 : "\" should be OtherShadingType, Venetian, Woven, Perforated or BSDF.");
9048 : }
9049 : }
9050 :
9051 9 : state.dataHeatBal->ComplexShade(Loop).Thickness = state.dataIPShortCut->rNumericArgs(1);
9052 9 : state.dataMaterial->Material(MaterNum).Thickness = state.dataIPShortCut->rNumericArgs(1);
9053 9 : state.dataHeatBal->ComplexShade(Loop).Conductivity = state.dataIPShortCut->rNumericArgs(2);
9054 9 : state.dataMaterial->Material(MaterNum).Conductivity = state.dataIPShortCut->rNumericArgs(2);
9055 9 : state.dataHeatBal->ComplexShade(Loop).IRTransmittance = state.dataIPShortCut->rNumericArgs(3);
9056 9 : state.dataHeatBal->ComplexShade(Loop).FrontEmissivity = state.dataIPShortCut->rNumericArgs(4);
9057 9 : state.dataHeatBal->ComplexShade(Loop).BackEmissivity = state.dataIPShortCut->rNumericArgs(5);
9058 :
9059 : // Simon: in heat balance radiation exchange routines AbsorpThermal is used
9060 : // and program will crash if value is not assigned. Not sure if this is correct
9061 : // or some additional calculation is necessary. Simon TODO
9062 9 : state.dataMaterial->Material(MaterNum).AbsorpThermal = state.dataIPShortCut->rNumericArgs(5);
9063 9 : state.dataMaterial->Material(MaterNum).AbsorpThermalFront = state.dataIPShortCut->rNumericArgs(4);
9064 9 : state.dataMaterial->Material(MaterNum).AbsorpThermalBack = state.dataIPShortCut->rNumericArgs(5);
9065 :
9066 9 : state.dataHeatBal->ComplexShade(Loop).TopOpeningMultiplier = state.dataIPShortCut->rNumericArgs(6);
9067 9 : state.dataHeatBal->ComplexShade(Loop).BottomOpeningMultiplier = state.dataIPShortCut->rNumericArgs(7);
9068 9 : state.dataHeatBal->ComplexShade(Loop).LeftOpeningMultiplier = state.dataIPShortCut->rNumericArgs(8);
9069 9 : state.dataHeatBal->ComplexShade(Loop).RightOpeningMultiplier = state.dataIPShortCut->rNumericArgs(9);
9070 9 : state.dataHeatBal->ComplexShade(Loop).FrontOpeningMultiplier = state.dataIPShortCut->rNumericArgs(10);
9071 :
9072 9 : state.dataHeatBal->ComplexShade(Loop).SlatWidth = state.dataIPShortCut->rNumericArgs(11);
9073 9 : state.dataHeatBal->ComplexShade(Loop).SlatSpacing = state.dataIPShortCut->rNumericArgs(12);
9074 9 : state.dataHeatBal->ComplexShade(Loop).SlatThickness = state.dataIPShortCut->rNumericArgs(13);
9075 9 : state.dataHeatBal->ComplexShade(Loop).SlatAngle = state.dataIPShortCut->rNumericArgs(14);
9076 9 : state.dataHeatBal->ComplexShade(Loop).SlatConductivity = state.dataIPShortCut->rNumericArgs(15);
9077 9 : state.dataHeatBal->ComplexShade(Loop).SlatCurve = state.dataIPShortCut->rNumericArgs(16);
9078 :
9079 : // IF (dataMaterial.Material(MaterNum)%Conductivity > 0.0) THEN
9080 : // NominalR(MaterNum)=dataMaterial.Material(MaterNum)%Thickness/dataMaterial.Material(MaterNum)%Conductivity
9081 : // ELSE
9082 : // NominalR(MaterNum)=1.0
9083 : // ENDIF
9084 :
9085 9 : if (state.dataIPShortCut->rNumericArgs(1) <= 0.0) {
9086 0 : ErrorsFound = true;
9087 0 : ShowSevereError(state,
9088 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9089 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(1) + " has been found.");
9090 0 : ShowContinueError(state,
9091 0 : format("{} must be > 0, entered value = {:.2R}",
9092 0 : state.dataIPShortCut->cNumericFieldNames(1),
9093 0 : state.dataIPShortCut->rNumericArgs(1)));
9094 : }
9095 :
9096 9 : if (state.dataIPShortCut->rNumericArgs(2) <= 0.0) {
9097 0 : ErrorsFound = true;
9098 0 : ShowSevereError(state,
9099 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9100 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(2) + " has been found.");
9101 0 : ShowContinueError(state,
9102 0 : format("{} must be > 0, entered value = {:.2R}",
9103 0 : state.dataIPShortCut->cNumericFieldNames(2),
9104 0 : state.dataIPShortCut->rNumericArgs(2)));
9105 : }
9106 :
9107 9 : if ((state.dataIPShortCut->rNumericArgs(3) < 0.0) || (state.dataIPShortCut->rNumericArgs(3) > 1.0)) {
9108 0 : ErrorsFound = true;
9109 0 : ShowSevereError(state,
9110 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9111 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(3) + " has been found.");
9112 0 : ShowContinueError(state,
9113 0 : format("{} value must be >= 0 and <= 1, entered value = {:.2R}",
9114 0 : state.dataIPShortCut->cNumericFieldNames(3),
9115 0 : state.dataIPShortCut->rNumericArgs(3)));
9116 : }
9117 :
9118 9 : if ((state.dataIPShortCut->rNumericArgs(4) <= 0.0) || (state.dataIPShortCut->rNumericArgs(4) > 1.0)) {
9119 0 : ErrorsFound = true;
9120 0 : ShowSevereError(state,
9121 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9122 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(4) + " has been found.");
9123 0 : ShowContinueError(state,
9124 0 : format("{} value must be >= 0 and <= 1, entered value = {:.2R}",
9125 0 : state.dataIPShortCut->cNumericFieldNames(4),
9126 0 : state.dataIPShortCut->rNumericArgs(4)));
9127 : }
9128 :
9129 9 : if ((state.dataIPShortCut->rNumericArgs(5) <= 0.0) || (state.dataIPShortCut->rNumericArgs(5) > 1.0)) {
9130 0 : ErrorsFound = true;
9131 0 : ShowSevereError(state,
9132 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9133 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(5) + " has been found.");
9134 0 : ShowContinueError(state,
9135 0 : format("{} value must be >= 0 and <= 1, entered value = {:.2R}",
9136 0 : state.dataIPShortCut->cNumericFieldNames(5),
9137 0 : state.dataIPShortCut->rNumericArgs(5)));
9138 : }
9139 :
9140 9 : if ((state.dataIPShortCut->rNumericArgs(6) < 0.0) || (state.dataIPShortCut->rNumericArgs(6) > 1.0)) {
9141 0 : ErrorsFound = true;
9142 0 : ShowSevereError(state,
9143 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9144 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(6) + " has been found.");
9145 0 : ShowContinueError(state,
9146 0 : format("{} must be >= 0 or <= 1, entered value = {:.2R}",
9147 0 : state.dataIPShortCut->cNumericFieldNames(6),
9148 0 : state.dataIPShortCut->rNumericArgs(6)));
9149 : }
9150 :
9151 9 : if ((state.dataIPShortCut->rNumericArgs(7) < 0.0) || (state.dataIPShortCut->rNumericArgs(7) > 1.0)) {
9152 0 : ErrorsFound = true;
9153 0 : ShowSevereError(state,
9154 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9155 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(7) + " has been found.");
9156 0 : ShowContinueError(state,
9157 0 : format("{} must be >=0 or <=1, entered {:.2R}",
9158 0 : state.dataIPShortCut->cNumericFieldNames(7),
9159 0 : state.dataIPShortCut->rNumericArgs(7)));
9160 : }
9161 :
9162 9 : if ((state.dataIPShortCut->rNumericArgs(8) < 0.0) || (state.dataIPShortCut->rNumericArgs(8) > 1.0)) {
9163 0 : ErrorsFound = true;
9164 0 : ShowSevereError(state,
9165 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9166 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(8) + " has been found.");
9167 0 : ShowContinueError(state,
9168 0 : format("{} must be >=0 or <=1, entered value = {:.2R}",
9169 0 : state.dataIPShortCut->cNumericFieldNames(8),
9170 0 : state.dataIPShortCut->rNumericArgs(8)));
9171 : }
9172 :
9173 9 : if ((state.dataIPShortCut->rNumericArgs(9) < 0.0) || (state.dataIPShortCut->rNumericArgs(9) > 1.0)) {
9174 0 : ErrorsFound = true;
9175 0 : ShowSevereError(state,
9176 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9177 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(9) + " has been found.");
9178 0 : ShowContinueError(state,
9179 0 : format("{} must be >=0 or <=1, entered value = {:.2R}",
9180 0 : state.dataIPShortCut->cNumericFieldNames(9),
9181 0 : state.dataIPShortCut->rNumericArgs(9)));
9182 : }
9183 :
9184 9 : if ((state.dataIPShortCut->rNumericArgs(10) < 0.0) || (state.dataIPShortCut->rNumericArgs(10) > 1.0)) {
9185 0 : ErrorsFound = true;
9186 0 : ShowSevereError(state,
9187 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9188 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(10) + " has been found.");
9189 0 : ShowContinueError(state,
9190 0 : format("{} must be >=0 or <=1, entered value = {:.2R}",
9191 0 : state.dataIPShortCut->cNumericFieldNames(10),
9192 0 : state.dataIPShortCut->rNumericArgs(10)));
9193 : }
9194 :
9195 9 : if (BITF_TEST_ANY(BITF(state.dataHeatBal->ComplexShade(Loop).LayerType),
9196 : BITF(TARCOGParams::TARCOGLayerType::VENETBLIND_HORIZ) | BITF(TARCOGParams::TARCOGLayerType::VENETBLIND_HORIZ))) {
9197 2 : if (state.dataIPShortCut->rNumericArgs(11) <= 0.0) {
9198 0 : ErrorsFound = true;
9199 0 : ShowSevereError(state,
9200 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9201 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(11) + " has been found.");
9202 0 : ShowContinueError(state,
9203 0 : format("{} must be >0, entered value = {:.2R}",
9204 0 : state.dataIPShortCut->cNumericFieldNames(11),
9205 0 : state.dataIPShortCut->rNumericArgs(11)));
9206 : }
9207 :
9208 2 : if (state.dataIPShortCut->rNumericArgs(12) <= 0.0) {
9209 0 : ErrorsFound = true;
9210 0 : ShowSevereError(state,
9211 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9212 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(12) + " has been found.");
9213 0 : ShowContinueError(state,
9214 0 : format("{} must be >0, entered value = {:.2R}",
9215 0 : state.dataIPShortCut->cNumericFieldNames(12),
9216 0 : state.dataIPShortCut->rNumericArgs(12)));
9217 : }
9218 :
9219 2 : if (state.dataIPShortCut->rNumericArgs(13) <= 0.0) {
9220 0 : ErrorsFound = true;
9221 0 : ShowSevereError(state,
9222 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9223 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(13) + " has been found.");
9224 0 : ShowContinueError(state,
9225 0 : format("{} must be >0, entered value = {:.2R}",
9226 0 : state.dataIPShortCut->cNumericFieldNames(13),
9227 0 : state.dataIPShortCut->rNumericArgs(13)));
9228 : }
9229 :
9230 2 : if ((state.dataIPShortCut->rNumericArgs(14) < -90.0) || (state.dataIPShortCut->rNumericArgs(14) > 90.0)) {
9231 0 : ErrorsFound = true;
9232 0 : ShowSevereError(state,
9233 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9234 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(14) + " has been found.");
9235 0 : ShowContinueError(state,
9236 0 : format("{} must be >=-90 and <=90, entered value = {:.2R}",
9237 0 : state.dataIPShortCut->cNumericFieldNames(14),
9238 0 : state.dataIPShortCut->rNumericArgs(14)));
9239 : }
9240 :
9241 2 : if (state.dataIPShortCut->rNumericArgs(15) <= 0.0) {
9242 0 : ErrorsFound = true;
9243 0 : ShowSevereError(state,
9244 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9245 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(15) + " has been found.");
9246 0 : ShowContinueError(state,
9247 0 : format("{} must be >0, entered value = {:.2R}",
9248 0 : state.dataIPShortCut->cNumericFieldNames(15),
9249 0 : state.dataIPShortCut->rNumericArgs(15)));
9250 : }
9251 :
9252 4 : if ((state.dataIPShortCut->rNumericArgs(16) < 0.0) ||
9253 2 : ((state.dataIPShortCut->rNumericArgs(16) > 0.0) &&
9254 0 : (state.dataIPShortCut->rNumericArgs(16) < (state.dataIPShortCut->rNumericArgs(11) / 2)))) {
9255 0 : ErrorsFound = true;
9256 0 : ShowSevereError(state,
9257 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9258 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(16) + " has been found.");
9259 0 : ShowContinueError(state,
9260 0 : format("{} must be =0 or greater than SlatWidth/2, entered value = {:.2R}",
9261 0 : state.dataIPShortCut->cNumericFieldNames(16),
9262 0 : state.dataIPShortCut->rNumericArgs(16)));
9263 : }
9264 : }
9265 :
9266 9 : if (ErrorsFound) ShowFatalError(state, "Error in complex fenestration material input.");
9267 : }
9268 10 : }
9269 :
9270 10 : void SetupComplexFenestrationStateInput(EnergyPlusData &state,
9271 : int &ConstrNum, // num of construction items thus far
9272 : bool &ErrorsFound)
9273 : {
9274 :
9275 : // SUBROUTINE INFORMATION:
9276 : // AUTHOR B. Griffith
9277 : // DATE WRITTEN June 2010
9278 : // MODIFIED January 2012 (Simon Vidanovic)
9279 : // MODIFIED May 2012 (Simon Vidanovic)
9280 : // RE-ENGINEERED na
9281 :
9282 : // PURPOSE OF THIS SUBROUTINE:
9283 : // get input for complex fenestration construction
9284 :
9285 : // METHODOLOGY EMPLOYED:
9286 : // usual GetInput processing. Matrix input from MatrixDataManager
9287 :
9288 : // Using/Aliasing
9289 : using namespace MatrixDataManager;
9290 : using namespace DataBSDFWindow;
9291 :
9292 : // SUBROUTINE PARAMETER DEFINITIONS:
9293 10 : constexpr const char *RoutineName("SetupComlexFenestrationStateInput: ");
9294 :
9295 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9296 : // The following moved to DataBSDFWindow module:
9297 : // INTEGER :: TotComplexFenStates ! Number of complex fenestration construction definitions
9298 : int I; // do loop index
9299 : int Loop; // do loop counter
9300 : int NumAlphas; // Number of Alphas for each GetObjectItem call
9301 : int NumNumbers; // Number of Numbers for each GetObjectItem call
9302 : int TotalArgs; // Number of fields for each GetObjectItem call
9303 : int IOStatus; // Used in GetObjectItem
9304 : int iMatGlass; // number of glass layers
9305 : int NumRows; // temporary size of matrix
9306 : int NumCols; // temporary size of matrix
9307 : int NBasis; // temporary number of elements in basis
9308 : int Layer; // loop counter for material layers
9309 : int AlphaIndex;
9310 : int ThermalModelNum; // number of thermal model parameters object
9311 : int NumOfTotalLayers; // total number of layers in the construction
9312 : int NumOfOpticalLayers; // number of optical layers in the construction (excluding gasses and gas mixtures)
9313 : int currentOpticalLayer; // current optical layer number. This is important since optical structures should
9314 : // be loaded only with optical layers
9315 :
9316 : // When reading Construction:ComplexFenestrationState, there is a call of GetMatrix2D which also uses same
9317 : // variables from DataIPShortCuts. Since this can cause some errors in reading, it is important
9318 : // to declare local variables for reading Construction:ComplexFenestrationState object(s)
9319 20 : Array1D_string locAlphaFieldNames;
9320 20 : Array1D_string locNumericFieldNames;
9321 20 : Array1D_bool locNumericFieldBlanks;
9322 20 : Array1D_bool locAlphaFieldBlanks;
9323 20 : Array1D_string locAlphaArgs;
9324 20 : Array1D<Real64> locNumericArgs;
9325 20 : std::string locCurrentModuleObject;
9326 10 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
9327 : // Reading WindowThermalModel:Params
9328 10 : cCurrentModuleObject = "WindowThermalModel:Params";
9329 10 : state.dataBSDFWindow->TotThermalModels = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
9330 10 : state.dataHeatBal->WindowThermalModel.allocate(state.dataBSDFWindow->TotThermalModels);
9331 :
9332 24 : for (Loop = 1; Loop <= state.dataBSDFWindow->TotThermalModels; ++Loop) {
9333 84 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
9334 : cCurrentModuleObject,
9335 : Loop,
9336 14 : state.dataIPShortCut->cAlphaArgs,
9337 : NumAlphas,
9338 14 : state.dataIPShortCut->rNumericArgs,
9339 : NumNumbers,
9340 : IOStatus,
9341 14 : state.dataIPShortCut->lNumericFieldBlanks,
9342 : _,
9343 14 : state.dataIPShortCut->cAlphaFieldNames,
9344 14 : state.dataIPShortCut->cNumericFieldNames);
9345 14 : if (UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound)) continue;
9346 :
9347 14 : state.dataHeatBal->WindowThermalModel(Loop).Name = state.dataIPShortCut->cAlphaArgs(1);
9348 :
9349 14 : state.dataHeatBal->WindowThermalModel(Loop).SDScalar = state.dataIPShortCut->rNumericArgs(1);
9350 14 : if ((state.dataIPShortCut->rNumericArgs(1) < 0.0) || (state.dataIPShortCut->rNumericArgs(1) > 1.0)) {
9351 0 : ErrorsFound = true;
9352 0 : ShowSevereError(state,
9353 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9354 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(1) + " has been found.");
9355 0 : ShowContinueError(state,
9356 0 : format("{} should be >= 0.0 and <= 1.0, entered value = {:.2R}",
9357 0 : state.dataIPShortCut->cNumericFieldNames(1),
9358 0 : state.dataIPShortCut->rNumericArgs(1)));
9359 : }
9360 :
9361 : {
9362 28 : auto const SELECT_CASE_var(state.dataIPShortCut->cAlphaArgs(2));
9363 14 : if (SELECT_CASE_var == "ISO15099") {
9364 14 : state.dataHeatBal->WindowThermalModel(Loop).CalculationStandard = TARCOGGassesParams::Stdrd::ISO15099;
9365 0 : } else if (SELECT_CASE_var == "EN673DECLARED") {
9366 0 : state.dataHeatBal->WindowThermalModel(Loop).CalculationStandard = TARCOGGassesParams::Stdrd::EN673;
9367 0 : } else if (SELECT_CASE_var == "EN673DESIGN") {
9368 0 : state.dataHeatBal->WindowThermalModel(Loop).CalculationStandard = TARCOGGassesParams::Stdrd::EN673Design;
9369 : } else {
9370 0 : ErrorsFound = true;
9371 0 : ShowSevereError(state,
9372 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9373 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(2) + " has been found.");
9374 0 : ShowContinueError(state,
9375 0 : state.dataIPShortCut->cAlphaFieldNames(2) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(2) +
9376 : "\" should be ISO15099, EN673Declared or EN673Design.");
9377 : }
9378 : }
9379 :
9380 : {
9381 28 : auto const SELECT_CASE_var(state.dataIPShortCut->cAlphaArgs(3));
9382 14 : if (SELECT_CASE_var == "ISO15099") {
9383 14 : state.dataHeatBal->WindowThermalModel(Loop).ThermalModel = TARCOGParams::TARCOGThermalModel::ISO15099;
9384 0 : } else if (SELECT_CASE_var == "SCALEDCAVITYWIDTH") {
9385 0 : state.dataHeatBal->WindowThermalModel(Loop).ThermalModel = TARCOGParams::TARCOGThermalModel::SCW;
9386 0 : } else if (SELECT_CASE_var == "CONVECTIVESCALARMODEL_NOSDTHICKNESS") {
9387 0 : state.dataHeatBal->WindowThermalModel(Loop).ThermalModel = TARCOGParams::TARCOGThermalModel::CSM;
9388 0 : } else if (SELECT_CASE_var == "CONVECTIVESCALARMODEL_WITHSDTHICKNESS") {
9389 0 : state.dataHeatBal->WindowThermalModel(Loop).ThermalModel = TARCOGParams::TARCOGThermalModel::CSM_WithSDThickness;
9390 : } else {
9391 0 : ErrorsFound = true;
9392 0 : ShowSevereError(state,
9393 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9394 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(3) + " has been found.");
9395 0 : ShowContinueError(state,
9396 0 : state.dataIPShortCut->cAlphaFieldNames(3) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(3) +
9397 : "\" should be ISO15099, ScaledCavityWidth, ConvectiveScalarModel_NoSDThickness or "
9398 : "ConvectiveScalarModel_WithSDThickness.");
9399 : }
9400 : }
9401 :
9402 : {
9403 28 : auto const SELECT_CASE_var(state.dataIPShortCut->cAlphaArgs(4));
9404 14 : if (SELECT_CASE_var == "NODEFLECTION") {
9405 12 : state.dataHeatBal->WindowThermalModel(Loop).DeflectionModel = TARCOGParams::DeflectionCalculation::NONE;
9406 2 : } else if (SELECT_CASE_var == "TEMPERATUREANDPRESSUREINPUT") {
9407 1 : state.dataHeatBal->WindowThermalModel(Loop).DeflectionModel = TARCOGParams::DeflectionCalculation::TEMPERATURE;
9408 1 : } else if (SELECT_CASE_var == "MEASUREDDEFLECTION") {
9409 1 : state.dataHeatBal->WindowThermalModel(Loop).DeflectionModel = TARCOGParams::DeflectionCalculation::GAP_WIDTHS;
9410 : } else {
9411 0 : ErrorsFound = true;
9412 0 : ShowSevereError(state,
9413 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9414 0 : ", object. Illegal value for " + state.dataIPShortCut->cAlphaFieldNames(4) + " has been found.");
9415 0 : ShowContinueError(state,
9416 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " entered value = \"" + state.dataIPShortCut->cAlphaArgs(4) +
9417 : "\" should be NoDeflection, TemperatureAndPressureInput or MeasuredDeflection.");
9418 : }
9419 : }
9420 :
9421 14 : if (state.dataHeatBal->WindowThermalModel(Loop).DeflectionModel == TARCOGParams::DeflectionCalculation::TEMPERATURE) {
9422 1 : state.dataHeatBal->WindowThermalModel(Loop).VacuumPressureLimit = state.dataIPShortCut->rNumericArgs(2);
9423 1 : if (state.dataIPShortCut->rNumericArgs(2) <= 0.0) {
9424 0 : ErrorsFound = true;
9425 0 : ShowSevereError(state,
9426 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9427 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(2) + " has been found.");
9428 0 : ShowContinueError(state,
9429 0 : format("{} must be > 0, entered value = {:.2R}",
9430 0 : state.dataIPShortCut->cNumericFieldNames(2),
9431 0 : state.dataIPShortCut->rNumericArgs(2)));
9432 : }
9433 :
9434 1 : state.dataHeatBal->WindowThermalModel(Loop).InitialTemperature = state.dataIPShortCut->rNumericArgs(3);
9435 1 : if (state.dataIPShortCut->rNumericArgs(3) <= 0.0) {
9436 0 : ErrorsFound = true;
9437 0 : ShowSevereError(state,
9438 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9439 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(3) + " has been found.");
9440 0 : ShowContinueError(state,
9441 0 : format("{} must be > 0, entered value = {:.2R}",
9442 0 : state.dataIPShortCut->cNumericFieldNames(3),
9443 0 : state.dataIPShortCut->rNumericArgs(3)));
9444 : }
9445 :
9446 1 : state.dataHeatBal->WindowThermalModel(Loop).InitialPressure = state.dataIPShortCut->rNumericArgs(4);
9447 1 : if (state.dataIPShortCut->rNumericArgs(4) <= 0.0) {
9448 0 : ErrorsFound = true;
9449 0 : ShowSevereError(state,
9450 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
9451 0 : ", object. Illegal value for " + state.dataIPShortCut->cNumericFieldNames(4) + " has been found.");
9452 0 : ShowContinueError(state,
9453 0 : format("{} must be > 0, entered value = {:.2R}",
9454 0 : state.dataIPShortCut->cNumericFieldNames(4),
9455 0 : state.dataIPShortCut->rNumericArgs(4)));
9456 : }
9457 : }
9458 :
9459 : } // DO Loop = 1, TotThermalModels
9460 :
9461 : // Reading Construction:ComplexFenestrationState
9462 10 : locCurrentModuleObject = "Construction:ComplexFenestrationState";
9463 10 : state.dataBSDFWindow->TotComplexFenStates = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, locCurrentModuleObject);
9464 :
9465 10 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, locCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
9466 10 : if (!allocated(locAlphaFieldNames)) locAlphaFieldNames.allocate(NumAlphas);
9467 10 : if (!allocated(locNumericFieldNames)) locNumericFieldNames.allocate(NumNumbers);
9468 10 : if (!allocated(locNumericFieldBlanks)) locNumericFieldBlanks.allocate(NumNumbers);
9469 10 : if (!allocated(locAlphaFieldBlanks)) locAlphaFieldBlanks.allocate(NumAlphas);
9470 10 : if (!allocated(locAlphaArgs)) locAlphaArgs.allocate(NumAlphas);
9471 10 : if (!allocated(locNumericArgs)) locNumericArgs.allocate(NumNumbers);
9472 :
9473 10 : state.dataBSDFWindow->FirstBSDF = ConstrNum + 1; // Location of first BSDF construction input (They will be consecutive)
9474 24 : for (Loop = 1; Loop <= state.dataBSDFWindow->TotComplexFenStates; ++Loop) {
9475 14 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
9476 : locCurrentModuleObject,
9477 : Loop,
9478 : locAlphaArgs,
9479 : NumAlphas,
9480 : locNumericArgs,
9481 : NumNumbers,
9482 : IOStatus,
9483 : locNumericFieldBlanks,
9484 : _,
9485 : locAlphaFieldNames,
9486 : locNumericFieldNames);
9487 42 : if (GlobalNames::VerifyUniqueInterObjectName(state,
9488 14 : state.dataHeatBalMgr->UniqueConstructNames,
9489 14 : locAlphaArgs(1),
9490 14 : state.dataHeatBalMgr->CurrentModuleObject,
9491 14 : locAlphaFieldNames(1),
9492 : ErrorsFound)) {
9493 0 : continue;
9494 : }
9495 14 : ++ConstrNum;
9496 : // Glass layer counter
9497 14 : iMatGlass = 0;
9498 : // Simon TODO: This is to be confirmed. If this is just initial value, then we might want to make better guess
9499 14 : state.dataHeatBal->NominalRforNominalUCalculation(ConstrNum) = 0.1;
9500 : // Simon TODO: If I do not put this, then it is considered that surface is NOT window
9501 14 : state.dataConstruction->Construct(ConstrNum).TransDiff = 0.1; // This is a place holder to flag
9502 : // the construction as a window until
9503 : // the correct value is entered in WindowComplexManager
9504 :
9505 : // Now override the deraults as appropriate
9506 14 : state.dataConstruction->Construct(ConstrNum).Name = locAlphaArgs(1);
9507 :
9508 : // ALLOCATE(Construct(ConstrNum)%BSDFInput)
9509 :
9510 : // Construct(ConstrNum)%BSDFInput%ThermalConstruction = ThConstNum
9511 :
9512 : {
9513 28 : auto const SELECT_CASE_var(locAlphaArgs(2)); // Basis Type Keyword
9514 14 : if (SELECT_CASE_var == "LBNLWINDOW") {
9515 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisType = DataBSDFWindow::Basis::WINDOW;
9516 0 : } else if (SELECT_CASE_var == "USERDEFINED") {
9517 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisType = DataBSDFWindow::Basis::Custom;
9518 : } else {
9519 : // throw error
9520 0 : ErrorsFound = true;
9521 0 : ShowSevereError(state,
9522 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + locAlphaArgs(1) + ", object. Illegal value for " +
9523 0 : locAlphaFieldNames(2) + " has been found.");
9524 0 : ShowContinueError(state,
9525 0 : locAlphaFieldNames(2) + " entered value=\"" + locAlphaArgs(2) + "\" should be LBNLWindow or UserDefined.");
9526 : }
9527 : }
9528 :
9529 : {
9530 28 : auto const SELECT_CASE_var(locAlphaArgs(3)); // Basis Symmetry Keyword
9531 14 : if (SELECT_CASE_var == "AXISYMMETRIC") {
9532 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisSymmetryType = DataBSDFWindow::BasisSymmetry::Axisymmetric;
9533 14 : } else if (SELECT_CASE_var == "NONE") {
9534 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisSymmetryType = DataBSDFWindow::BasisSymmetry::None;
9535 : } else {
9536 : // throw error
9537 0 : ErrorsFound = true;
9538 0 : ShowSevereError(state,
9539 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + locAlphaArgs(1) + ", object. Illegal value for " +
9540 0 : locAlphaFieldNames(3) + " has been found.");
9541 0 : ShowContinueError(state, locAlphaFieldNames(3) + " entered value = \"" + locAlphaArgs(3) + "\" should be Axisymmetric or None.");
9542 : }
9543 : }
9544 :
9545 : // Simon: Assign thermal model number
9546 14 : ThermalModelNum = UtilityRoutines::FindItemInList(locAlphaArgs(4), state.dataHeatBal->WindowThermalModel);
9547 14 : if (ThermalModelNum == 0) {
9548 0 : ShowSevereError(state,
9549 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + locAlphaArgs(1) + ", object. Illegal value for " +
9550 0 : locAlphaFieldNames(4) + " has been found.");
9551 0 : ShowContinueError(state,
9552 0 : locAlphaFieldNames(4) + " entered value = \"" + locAlphaArgs(4) +
9553 : "\" no corresponding thermal model (WindowThermalModel:Params) found in the input file.");
9554 : } else {
9555 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.ThermalModel = ThermalModelNum;
9556 : }
9557 :
9558 : // ***************************************************************************************
9559 : // Basis matrix
9560 : // ***************************************************************************************
9561 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisMatIndex = MatrixIndex(state, locAlphaArgs(5));
9562 14 : Get2DMatrixDimensions(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisMatIndex, NumRows, NumCols);
9563 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisMatNrows = NumRows;
9564 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisMatNcols = NumCols;
9565 :
9566 14 : if (NumCols != 2 && NumCols != 1) {
9567 0 : ErrorsFound = true;
9568 0 : ShowSevereError(state,
9569 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + locAlphaArgs(1) + ", object. Illegal value for " +
9570 0 : locAlphaFieldNames(5) + " has been found.");
9571 0 : ShowContinueError(state,
9572 0 : locAlphaFieldNames(5) + " entered value=\"" + locAlphaArgs(5) +
9573 : "\" invalid matrix dimensions. Basis matrix dimension can only be 2 x 1.");
9574 : }
9575 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisMat.allocate(NumCols, NumRows);
9576 28 : Get2DMatrix(state,
9577 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisMatIndex,
9578 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisMat);
9579 14 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisType == DataBSDFWindow::Basis::WINDOW)
9580 28 : CalculateBasisLength(state,
9581 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput,
9582 : ConstrNum,
9583 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.NBasis);
9584 :
9585 : // determine number of layers and optical layers
9586 14 : NumOfTotalLayers = (NumAlphas - 9) / 3;
9587 14 : state.dataConstruction->Construct(ConstrNum).TotLayers = NumOfTotalLayers;
9588 :
9589 14 : NumOfOpticalLayers = NumOfTotalLayers / 2 + 1;
9590 :
9591 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.NumLayers = NumOfOpticalLayers;
9592 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer.allocate(NumOfOpticalLayers);
9593 :
9594 : // check for incomplete field set
9595 14 : if (mod((NumAlphas - 9), 3) != 0) {
9596 : // throw warning if incomplete field set
9597 0 : ErrorsFound = true;
9598 0 : ShowSevereError(
9599 0 : state, std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) + ", object. Incomplete field set found.");
9600 0 : ShowContinueError(state, locAlphaArgs(1) + " is missing some of the layers or/and gaps.");
9601 : }
9602 :
9603 14 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisSymmetryType == DataBSDFWindow::BasisSymmetry::None) {
9604 : // Non-Symmetric basis
9605 :
9606 14 : NBasis = state.dataConstruction->Construct(ConstrNum).BSDFInput.NBasis;
9607 :
9608 : // *******************************************************************************
9609 : // Solar front transmittance
9610 : // *******************************************************************************
9611 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransIndex = MatrixIndex(state, locAlphaArgs(6));
9612 14 : Get2DMatrixDimensions(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransIndex, NumRows, NumCols);
9613 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransNrows = NumRows;
9614 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransNcols = NumCols;
9615 :
9616 14 : if (NumRows != NBasis) {
9617 0 : ErrorsFound = true;
9618 0 : ShowSevereError(state,
9619 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9620 : ", object. Illegal matrix size has been found.");
9621 0 : ShowContinueError(
9622 : state,
9623 0 : "Solar front transmittance matrix \"" + locAlphaArgs(6) +
9624 0 : "\" is not the same size as it is defined by basis definition. Basis size is defined by Matrix:TwoDimension = \"" +
9625 0 : locAlphaArgs(5) + "\".");
9626 : }
9627 :
9628 14 : if (NumRows != NumCols) {
9629 0 : ErrorsFound = true;
9630 0 : ShowSevereError(state,
9631 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9632 : "\", object. Invalid BSDF matrix dimensions.");
9633 0 : ShowContinueError(state,
9634 0 : "Solar front transmittance matrix \"" + locAlphaArgs(6) + "\" must have the same number of rows and columns.");
9635 : }
9636 :
9637 14 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.BasisType == DataBSDFWindow::Basis::Custom) {
9638 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.NBasis = NumRows; // For custom basis, no rows in transmittance
9639 : // matrix defines the basis length
9640 : }
9641 :
9642 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTrans.allocate(NumCols, NumRows);
9643 14 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransIndex == 0) {
9644 0 : ErrorsFound = true;
9645 0 : ShowSevereError(state,
9646 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9647 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
9648 0 : ShowContinueError(state,
9649 0 : "Solar front transmittance Matrix:TwoDimension = \"" + locAlphaArgs(6) + "\" is missing from the input file.");
9650 : } else {
9651 28 : Get2DMatrix(state,
9652 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransIndex,
9653 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTrans);
9654 : }
9655 :
9656 : // *******************************************************************************
9657 : // Solar back reflectance
9658 : // *******************************************************************************
9659 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflIndex = MatrixIndex(state, locAlphaArgs(7));
9660 14 : Get2DMatrixDimensions(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflIndex, NumRows, NumCols);
9661 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflNrows = NumRows;
9662 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflNcols = NumCols;
9663 :
9664 14 : if (NumRows != NBasis) {
9665 0 : ErrorsFound = true;
9666 0 : ShowSevereError(state,
9667 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9668 : ", object. Illegal matrix size has been found.");
9669 0 : ShowContinueError(
9670 : state,
9671 0 : "Solar back reflectance matrix \"" + locAlphaArgs(7) +
9672 0 : "\" is not the same size as it is defined by basis definition. Basis size is defined by Matrix:TwoDimension = \"" +
9673 0 : locAlphaArgs(5) + "\".");
9674 : }
9675 :
9676 14 : if (NumRows != NumCols) {
9677 0 : ErrorsFound = true;
9678 0 : ShowSevereError(state,
9679 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9680 : "\", object. Invalid BSDF matrix dimensions.");
9681 0 : ShowContinueError(state,
9682 0 : "Solar bakc reflectance matrix \"" + locAlphaArgs(7) + "\" must have the same number of rows and columns.");
9683 : }
9684 :
9685 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkRefl.allocate(NumCols, NumRows);
9686 14 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflIndex == 0) {
9687 0 : ErrorsFound = true;
9688 0 : ShowSevereError(state,
9689 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9690 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
9691 0 : ShowContinueError(state,
9692 0 : "Solar back reflectance Matrix:TwoDimension = \"" + locAlphaArgs(7) + "\" is missing from the input file.");
9693 : } else {
9694 28 : Get2DMatrix(state,
9695 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflIndex,
9696 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkRefl);
9697 : }
9698 :
9699 : // *******************************************************************************
9700 : // Visible front transmittance
9701 : // *******************************************************************************
9702 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransIndex = MatrixIndex(state, locAlphaArgs(8));
9703 14 : Get2DMatrixDimensions(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransIndex, NumRows, NumCols);
9704 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransNrows = NumRows;
9705 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransNcols = NumCols;
9706 :
9707 14 : if (NumRows != NBasis) {
9708 0 : ErrorsFound = true;
9709 0 : ShowSevereError(state,
9710 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9711 : ", object. Illegal matrix size has been found.");
9712 0 : ShowContinueError(
9713 : state,
9714 0 : "Visible front transmittance matrix \"" + locAlphaArgs(8) +
9715 0 : "\" is not the same size as it is defined by basis definition. Basis size is defined by Matrix:TwoDimension = \"" +
9716 0 : locAlphaArgs(5) + "\".");
9717 : }
9718 :
9719 14 : if (NumRows != NumCols) {
9720 0 : ErrorsFound = true;
9721 0 : ShowSevereError(state,
9722 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9723 : "\", object. Invalid BSDF matrix dimensions.");
9724 0 : ShowContinueError(
9725 0 : state, "Visible front transmittance matrix \"" + locAlphaArgs(8) + "\" must have the same number of rows and columns.");
9726 : }
9727 :
9728 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTrans.allocate(NumCols, NumRows);
9729 14 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransIndex == 0) {
9730 0 : ErrorsFound = true;
9731 0 : ShowSevereError(state,
9732 0 : std::string{RoutineName} + cCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9733 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
9734 0 : ShowContinueError(
9735 0 : state, "Visible front transmittance Matrix:TwoDimension = \"" + locAlphaArgs(8) + "\" is missing from the input file.");
9736 : } else {
9737 28 : Get2DMatrix(state,
9738 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransIndex,
9739 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTrans);
9740 : }
9741 :
9742 : // *******************************************************************************
9743 : // Visible back reflectance
9744 : // *******************************************************************************
9745 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflIndex = MatrixIndex(state, locAlphaArgs(9));
9746 14 : Get2DMatrixDimensions(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflIndex, NumRows, NumCols);
9747 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflNrows = NumRows;
9748 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflNcols = NumCols;
9749 :
9750 14 : if (NumRows != NBasis) {
9751 0 : ErrorsFound = true;
9752 0 : ShowSevereError(state,
9753 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9754 : ", object. Illegal matrix size has been found.");
9755 0 : ShowContinueError(
9756 : state,
9757 0 : "Visible back reflectance matrix \"" + locAlphaArgs(9) +
9758 0 : "\" is not the same size as it is defined by basis definition. Basis size is defined by Matrix:TwoDimension = \"" +
9759 0 : locAlphaArgs(5) + "\".");
9760 : }
9761 :
9762 14 : if (NumRows != NumCols) {
9763 0 : ErrorsFound = true;
9764 0 : ShowSevereError(state,
9765 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9766 : "\", object. Invalid BSDF matrix dimensions.");
9767 0 : ShowContinueError(state, "Visible back reflectance \"" + locAlphaArgs(9) + "\" must have the same number of rows and columns.");
9768 : }
9769 :
9770 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkRefl.allocate(NumCols, NumRows);
9771 14 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflIndex == 0) {
9772 0 : ErrorsFound = true;
9773 0 : ShowSevereError(state,
9774 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9775 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
9776 0 : ShowContinueError(state,
9777 0 : "Visble back reflectance Matrix:TwoDimension = \"" + locAlphaArgs(9) + "\" is missing from the input file.");
9778 : } else {
9779 28 : Get2DMatrix(state,
9780 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflIndex,
9781 14 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkRefl);
9782 : }
9783 :
9784 : // ALLOCATE(Construct(ConstrNum)%BSDFInput%Layer(NumOfOpticalLayers))
9785 76 : for (Layer = 1; Layer <= state.dataConstruction->Construct(ConstrNum).TotLayers; ++Layer) {
9786 62 : AlphaIndex = 9 + (Layer * 3) - 2;
9787 62 : currentOpticalLayer = int(Layer / 2) + 1;
9788 : // Material info is contained in the thermal construct
9789 62 : state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer) =
9790 62 : UtilityRoutines::FindItemInList(locAlphaArgs(AlphaIndex), state.dataMaterial->Material);
9791 :
9792 : // Simon: Load only if optical layer
9793 62 : if (mod(Layer, 2) != 0) {
9794 38 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).MaterialIndex =
9795 38 : state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer);
9796 :
9797 38 : ++AlphaIndex;
9798 : // *******************************************************************************
9799 : // Front absorptance matrix
9800 : // *******************************************************************************
9801 38 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbsIndex =
9802 38 : MatrixIndex(state, locAlphaArgs(AlphaIndex));
9803 38 : Get2DMatrixDimensions(
9804 38 : state, state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbsIndex, NumRows, NumCols);
9805 :
9806 38 : if (NumRows != 1) {
9807 0 : ErrorsFound = true;
9808 0 : ShowSevereError(state,
9809 0 : std::string{RoutineName} + locCurrentModuleObject + " = \"" + locAlphaArgs(1) +
9810 : "\", object. Incorrect matrix dimension.");
9811 0 : ShowContinueError(state,
9812 0 : format("Front absorbtance Matrix:TwoDimension = \"{}\" for layer {} must have only one row.",
9813 : locAlphaArgs(AlphaIndex),
9814 0 : currentOpticalLayer));
9815 : }
9816 :
9817 38 : if (NumCols != NBasis) {
9818 0 : ErrorsFound = true;
9819 0 : ShowSevereError(state,
9820 0 : std::string{RoutineName} + locCurrentModuleObject + " = \"" + locAlphaArgs(1) +
9821 : "\", object. Incorrect matrix dimension.");
9822 0 : ShowContinueError(state,
9823 0 : format("Front absorbtance Matrix:TwoDimension = \"{}\" for layer {} must have same number of columns "
9824 : "as it is defined by basis matrix.",
9825 : locAlphaArgs(AlphaIndex),
9826 0 : currentOpticalLayer));
9827 0 : ShowContinueError(
9828 : state,
9829 0 : format("Matrix has {} number of columns, while basis definition specifies {} number of columns.", NumCols, NBasis));
9830 : }
9831 :
9832 38 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).AbsNcols = NumCols;
9833 38 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbs.allocate(NumCols, NumRows);
9834 38 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbsIndex == 0) {
9835 0 : ErrorsFound = true;
9836 0 : ShowSevereError(state,
9837 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9838 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
9839 0 : ShowContinueError(state,
9840 0 : format("Front absorbtance Matrix:TwoDimension = \"{}\" for layer {} is missing from the input file.",
9841 : locAlphaArgs(AlphaIndex),
9842 0 : currentOpticalLayer));
9843 : } else {
9844 76 : Get2DMatrix(state,
9845 38 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbsIndex,
9846 38 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbs);
9847 : }
9848 :
9849 38 : ++AlphaIndex;
9850 : // *******************************************************************************
9851 : // Back absorptance matrix
9852 : // *******************************************************************************
9853 38 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbsIndex =
9854 38 : MatrixIndex(state, locAlphaArgs(AlphaIndex));
9855 38 : Get2DMatrixDimensions(
9856 38 : state, state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbsIndex, NumRows, NumCols);
9857 :
9858 38 : if (NumRows != 1) {
9859 0 : ErrorsFound = true;
9860 0 : ShowSevereError(state,
9861 0 : std::string{RoutineName} + locCurrentModuleObject + " = \"" + locAlphaArgs(1) +
9862 : "\", object. Incorrect matrix dimension.");
9863 0 : ShowContinueError(state,
9864 0 : format("Back absorbtance Matrix:TwoDimension = \"{}\" for layer {} must have only one row.",
9865 : locAlphaArgs(AlphaIndex),
9866 0 : currentOpticalLayer));
9867 : }
9868 :
9869 38 : if (NumCols != NBasis) {
9870 0 : ErrorsFound = true;
9871 0 : ShowSevereError(state,
9872 0 : std::string{RoutineName} + locCurrentModuleObject + " = \"" + locAlphaArgs(1) +
9873 : "\", object. Incorrect matrix dimension.");
9874 0 : ShowContinueError(state,
9875 0 : format("Back absorbtance Matrix:TwoDimension = \"{}\" for layer {} must have same number of columns as "
9876 : "it is defined by basis matrix.",
9877 : locAlphaArgs(AlphaIndex),
9878 0 : currentOpticalLayer));
9879 0 : ShowContinueError(
9880 : state,
9881 0 : format("Matrix has {} number of columns, while basis definition specifies {} number of columns.", NumCols, NBasis));
9882 : }
9883 :
9884 38 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbs.allocate(NumCols, NumRows);
9885 38 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbsIndex == 0) {
9886 0 : ErrorsFound = true;
9887 0 : ShowSevereError(state,
9888 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9889 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
9890 0 : ShowContinueError(state,
9891 0 : format("Back absorbtance Matrix:TwoDimension = \"{}\" for layer {} is missing from the input file.",
9892 : locAlphaArgs(AlphaIndex),
9893 0 : currentOpticalLayer));
9894 : } else {
9895 76 : Get2DMatrix(state,
9896 38 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbsIndex,
9897 38 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbs);
9898 : }
9899 : } // if (Mod(Layer, 2) <> 0) then
9900 : }
9901 : } else {
9902 : // Axisymmetric basis
9903 0 : NBasis = state.dataConstruction->Construct(ConstrNum).BSDFInput.NBasis; // Basis length has already been calculated
9904 0 : state.dataBSDFWindow->BSDFTempMtrx.allocate(NBasis, 1);
9905 :
9906 : // *******************************************************************************
9907 : // Solar front transmittance
9908 : // *******************************************************************************
9909 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransIndex = MatrixIndex(state, locAlphaArgs(6));
9910 0 : Get2DMatrixDimensions(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransIndex, NumRows, NumCols);
9911 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransNrows = NBasis;
9912 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransNcols = NBasis;
9913 :
9914 0 : if (NumRows != NBasis) {
9915 0 : ErrorsFound = true;
9916 0 : ShowSevereError(state,
9917 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9918 : ", object. Illegal matrix size has been found.");
9919 0 : ShowContinueError(
9920 : state,
9921 0 : "Solar front transmittance matrix \"" + locAlphaArgs(6) +
9922 0 : "\" is not the same size as it is defined by basis definition. Basis size is defined by Matrix:TwoDimension = \"" +
9923 0 : locAlphaArgs(5) + "\".");
9924 : }
9925 :
9926 0 : if (NumRows != NumCols) {
9927 0 : ErrorsFound = true;
9928 0 : ShowSevereError(state,
9929 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9930 : "\", object. Invalid BSDF matrix dimensions.");
9931 0 : ShowContinueError(state,
9932 0 : "Solar front transmittance matrix \"" + locAlphaArgs(6) + "\" must have the same number of rows and columns.");
9933 : }
9934 :
9935 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTrans.allocate(NBasis, NBasis);
9936 0 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransIndex == 0) {
9937 0 : ErrorsFound = true;
9938 0 : ShowSevereError(state,
9939 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9940 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
9941 0 : ShowContinueError(state,
9942 0 : "Solar front transmittance Matrix:TwoDimension = \"" + locAlphaArgs(6) + "\" is missing from the input file.");
9943 : } else {
9944 0 : Get2DMatrix(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTransIndex, state.dataBSDFWindow->BSDFTempMtrx);
9945 :
9946 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTrans = 0.0;
9947 0 : for (I = 1; I <= NBasis; ++I) {
9948 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolFrtTrans(I, I) = state.dataBSDFWindow->BSDFTempMtrx(I, 1);
9949 : }
9950 : }
9951 :
9952 : // *******************************************************************************
9953 : // Solar back reflectance
9954 : // *******************************************************************************
9955 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflIndex = MatrixIndex(state, locAlphaArgs(7));
9956 0 : Get2DMatrixDimensions(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflIndex, NumRows, NumCols);
9957 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflNrows = NBasis;
9958 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflNcols = NBasis;
9959 :
9960 0 : if (NumRows != NBasis) {
9961 0 : ErrorsFound = true;
9962 0 : ShowSevereError(state,
9963 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9964 : ", object. Illegal matrix size has been found.");
9965 0 : ShowContinueError(
9966 : state,
9967 0 : "Solar back reflectance matrix \"" + locAlphaArgs(7) +
9968 0 : "\" is not the same size as it is defined by basis definition. Basis size is defined by Matrix:TwoDimension = \"" +
9969 0 : locAlphaArgs(5) + "\".");
9970 : }
9971 :
9972 0 : if (NumRows != NumCols) {
9973 0 : ErrorsFound = true;
9974 0 : ShowSevereError(state,
9975 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9976 : "\", object. Invalid BSDF matrix dimensions.");
9977 0 : ShowContinueError(state,
9978 0 : "Solar back reflectance matrix \"" + locAlphaArgs(7) + "\" must have the same number of rows and columns.");
9979 : }
9980 :
9981 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkRefl.allocate(NBasis, NBasis);
9982 0 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflIndex == 0) {
9983 0 : ErrorsFound = true;
9984 0 : ShowSevereError(state,
9985 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
9986 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
9987 0 : ShowContinueError(state,
9988 0 : "Solar back reflectance Matrix:TwoDimension = \"" + locAlphaArgs(7) + "\" is missing from the input file.");
9989 : } else {
9990 0 : Get2DMatrix(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkReflIndex, state.dataBSDFWindow->BSDFTempMtrx);
9991 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkRefl = 0.0;
9992 0 : for (I = 1; I <= NBasis; ++I) {
9993 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.SolBkRefl(I, I) = state.dataBSDFWindow->BSDFTempMtrx(I, 1);
9994 : }
9995 : }
9996 :
9997 : // *******************************************************************************
9998 : // Visible front transmittance
9999 : // *******************************************************************************
10000 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransIndex = MatrixIndex(state, locAlphaArgs(8));
10001 0 : Get2DMatrixDimensions(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransIndex, NumRows, NumCols);
10002 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransNrows = NBasis;
10003 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransNcols = NBasis;
10004 :
10005 0 : if (NumRows != NBasis) {
10006 0 : ErrorsFound = true;
10007 0 : ShowSevereError(state,
10008 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
10009 : ", object. Illegal matrix size has been found.");
10010 0 : ShowContinueError(
10011 : state,
10012 0 : "Visible front transmittance matrix \"" + locAlphaArgs(8) +
10013 0 : "\" is not the same size as it is defined by basis definition. Basis size is defined by Matrix:TwoDimension = \"" +
10014 0 : locAlphaArgs(5) + "\".");
10015 : }
10016 :
10017 0 : if (NumRows != NumCols) {
10018 0 : ErrorsFound = true;
10019 0 : ShowSevereError(state,
10020 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
10021 : "\", object. Invalid BSDF matrix dimensions.");
10022 0 : ShowContinueError(
10023 0 : state, "Visible front transmittance matrix \"" + locAlphaArgs(8) + "\" must have the same number of rows and columns.");
10024 : }
10025 :
10026 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTrans.allocate(NBasis, NBasis);
10027 0 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransIndex == 0) {
10028 0 : ErrorsFound = true;
10029 0 : ShowSevereError(state,
10030 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
10031 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
10032 0 : ShowContinueError(
10033 0 : state, "Visible front transmittance Matrix:TwoDimension = \"" + locAlphaArgs(8) + "\" is missing from the input file.");
10034 : } else {
10035 0 : Get2DMatrix(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTransIndex, state.dataBSDFWindow->BSDFTempMtrx);
10036 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTrans = 0.0;
10037 0 : for (I = 1; I <= NBasis; ++I) {
10038 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisFrtTrans(I, I) = state.dataBSDFWindow->BSDFTempMtrx(I, 1);
10039 : }
10040 : }
10041 :
10042 : // *******************************************************************************
10043 : // Visible back reflectance
10044 : // *******************************************************************************
10045 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflIndex = MatrixIndex(state, locAlphaArgs(9));
10046 0 : Get2DMatrixDimensions(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflIndex, NumRows, NumCols);
10047 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflNrows = NBasis;
10048 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflNcols = NBasis;
10049 :
10050 0 : if (NumRows != NBasis) {
10051 0 : ErrorsFound = true;
10052 0 : ShowSevereError(state,
10053 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
10054 : ", object. Illegal matrix size has been found.");
10055 0 : ShowContinueError(
10056 : state,
10057 0 : "Visible back reflectance matrix \"" + locAlphaArgs(9) +
10058 0 : "\" is not the same size as it is defined by basis definition. Basis size is defined by Matrix:TwoDimension = \"" +
10059 0 : locAlphaArgs(5) + "\".");
10060 : }
10061 :
10062 0 : if (NumRows != NumCols) {
10063 0 : ErrorsFound = true;
10064 0 : ShowSevereError(state,
10065 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
10066 : "\", object. Invalid BSDF matrix dimensions.");
10067 0 : ShowContinueError(state,
10068 0 : "Visible back reflectance matrix \"" + locAlphaArgs(9) + "\" must have the same number of rows and columns.");
10069 : }
10070 :
10071 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkRefl.allocate(NBasis, NBasis);
10072 0 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflIndex == 0) {
10073 0 : ErrorsFound = true;
10074 0 : ShowSevereError(state,
10075 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
10076 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
10077 0 : ShowContinueError(state,
10078 0 : "Visible back reflectance Matrix:TwoDimension = \"" + locAlphaArgs(9) + "\" is missing from the input file.");
10079 : } else {
10080 0 : Get2DMatrix(state, state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkReflIndex, state.dataBSDFWindow->BSDFTempMtrx);
10081 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkRefl = 0.0;
10082 0 : for (I = 1; I <= NBasis; ++I) {
10083 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.VisBkRefl(I, I) = state.dataBSDFWindow->BSDFTempMtrx(I, 1);
10084 : }
10085 : }
10086 :
10087 : // determine number of layers
10088 : // Construct(ConstrNum)%TotLayers = (NumAlphas - 9)/3
10089 :
10090 : // check for incomplete field set
10091 : // IF (Mod((NumAlphas - 9), 3) /= 0) Then
10092 : // throw warning if incomplete field set
10093 : // CALL ShowWarningError(state, 'Construction:ComplexFenestrationState: Axisymmetric properties have incomplete field &
10094 : // & set')
10095 : // ENDIF
10096 :
10097 : // ALLOCATE(Construct(ConstrNum)%BSDFInput%Layer(NumOfOpticalLayers))
10098 0 : for (Layer = 1; Layer <= state.dataConstruction->Construct(ConstrNum).TotLayers; ++Layer) {
10099 0 : AlphaIndex = 9 + (Layer * 3) - 2;
10100 0 : currentOpticalLayer = int(Layer / 2) + 1;
10101 :
10102 0 : state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer) =
10103 0 : UtilityRoutines::FindItemInList(locAlphaArgs(AlphaIndex), state.dataMaterial->Material);
10104 :
10105 0 : if (mod(Layer, 2) != 0) {
10106 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).MaterialIndex =
10107 0 : state.dataConstruction->Construct(ConstrNum).LayerPoint(Layer);
10108 :
10109 : // *******************************************************************************
10110 : // Front absorptance matrix
10111 : // *******************************************************************************
10112 0 : ++AlphaIndex;
10113 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbsIndex =
10114 0 : MatrixIndex(state, locAlphaArgs(AlphaIndex));
10115 0 : Get2DMatrixDimensions(
10116 0 : state, state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbsIndex, NumRows, NumCols);
10117 :
10118 0 : if (NumRows != 1) {
10119 0 : ErrorsFound = true;
10120 0 : ShowSevereError(state,
10121 0 : std::string{RoutineName} + locCurrentModuleObject + " = \"" + locAlphaArgs(1) +
10122 : "\", object. Incorrect matrix dimension.");
10123 0 : ShowContinueError(state,
10124 0 : format("Front absorbtance Matrix:TwoDimension = \"{}\" for layer {} must have only one row.",
10125 : locAlphaArgs(AlphaIndex),
10126 0 : currentOpticalLayer));
10127 : }
10128 :
10129 0 : if (NumCols != NBasis) {
10130 0 : ErrorsFound = true;
10131 0 : ShowSevereError(state,
10132 0 : std::string{RoutineName} + locCurrentModuleObject + " = \"" + locAlphaArgs(1) +
10133 : "\", object. Incorrect matrix dimension.");
10134 0 : ShowContinueError(state,
10135 0 : format("Front absorbtance Matrix:TwoDimension = \"{}\" for layer {} must have same number of columns "
10136 : "as it is defined by basis matrix.",
10137 : locAlphaArgs(AlphaIndex),
10138 0 : currentOpticalLayer));
10139 0 : ShowContinueError(
10140 : state,
10141 0 : format("Matrix has {} number of columns, while basis definition specifies {} number of columns.", NumCols, NBasis));
10142 : }
10143 :
10144 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).AbsNcols = NumCols;
10145 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbs.allocate(NumCols, NumRows);
10146 :
10147 0 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbsIndex == 0) {
10148 0 : ErrorsFound = true;
10149 0 : ShowSevereError(state,
10150 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
10151 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
10152 0 : ShowContinueError(state,
10153 0 : format("Front absorbtance Matrix:TwoDimension = \"{}\" for layer {} is missing from the input file.",
10154 : locAlphaArgs(AlphaIndex),
10155 0 : currentOpticalLayer));
10156 : } else {
10157 0 : Get2DMatrix(state,
10158 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbsIndex,
10159 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).FrtAbs);
10160 : }
10161 :
10162 : // *******************************************************************************
10163 : // Back absorptance matrix
10164 : // *******************************************************************************
10165 0 : ++AlphaIndex;
10166 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbsIndex =
10167 0 : MatrixIndex(state, locAlphaArgs(AlphaIndex));
10168 0 : Get2DMatrixDimensions(
10169 0 : state, state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbsIndex, NumRows, NumCols);
10170 :
10171 0 : if (NumRows != 1) {
10172 0 : ErrorsFound = true;
10173 0 : ShowSevereError(state,
10174 0 : std::string{RoutineName} + locCurrentModuleObject + " = \"" + locAlphaArgs(1) +
10175 : "\", object. Incorrect matrix dimension.");
10176 0 : ShowContinueError(state,
10177 0 : format("Back absorbtance Matrix:TwoDimension = \"{}\" for layer {} must have only one row.",
10178 : locAlphaArgs(AlphaIndex),
10179 0 : currentOpticalLayer));
10180 : }
10181 :
10182 0 : if (NumCols != NBasis) {
10183 0 : ErrorsFound = true;
10184 0 : ShowSevereError(state,
10185 0 : std::string{RoutineName} + locCurrentModuleObject + " = \"" + locAlphaArgs(1) +
10186 : "\", object. Incorrect matrix dimension.");
10187 0 : ShowContinueError(state,
10188 0 : format("Back absorbtance Matrix:TwoDimension = \"{}\" for layer {} must have same number of columns as "
10189 : "it is defined by basis matrix.",
10190 : locAlphaArgs(AlphaIndex),
10191 0 : currentOpticalLayer));
10192 0 : ShowContinueError(
10193 : state,
10194 0 : format("Matrix has {} number of columns, while basis definition specifies {} number of columns.", NumCols, NBasis));
10195 : }
10196 :
10197 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbs.allocate(NumCols, NumRows);
10198 :
10199 0 : if (state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbsIndex == 0) {
10200 0 : ErrorsFound = true;
10201 0 : ShowSevereError(state,
10202 0 : std::string{RoutineName} + locCurrentModuleObject + "=\"" + locAlphaArgs(1) +
10203 : ", object. Referenced Matrix:TwoDimension is missing from the input file.");
10204 0 : ShowContinueError(state,
10205 0 : format("Back absorbtance Matrix:TwoDimension = \"{}\" for layer {} is missing from the input file.",
10206 : locAlphaArgs(AlphaIndex),
10207 0 : currentOpticalLayer));
10208 : } else {
10209 0 : Get2DMatrix(state,
10210 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbsIndex,
10211 0 : state.dataConstruction->Construct(ConstrNum).BSDFInput.Layer(currentOpticalLayer).BkAbs);
10212 : }
10213 : } // if (Mod(Layer, 2) <> 0) then
10214 : }
10215 :
10216 0 : state.dataBSDFWindow->BSDFTempMtrx.deallocate();
10217 : }
10218 14 : state.dataConstruction->Construct(ConstrNum).TypeIsWindow = true;
10219 14 : state.dataConstruction->Construct(ConstrNum).WindowTypeBSDF = true;
10220 : }
10221 :
10222 : // Do not forget to deallocate localy allocated variables
10223 10 : if (allocated(locAlphaFieldNames)) locAlphaFieldNames.deallocate();
10224 10 : if (allocated(locNumericFieldNames)) locNumericFieldNames.deallocate();
10225 10 : if (allocated(locNumericFieldBlanks)) locNumericFieldBlanks.deallocate();
10226 10 : if (allocated(locAlphaFieldBlanks)) locAlphaFieldBlanks.deallocate();
10227 10 : if (allocated(locAlphaArgs)) locAlphaArgs.deallocate();
10228 10 : if (allocated(locNumericArgs)) locNumericArgs.deallocate();
10229 :
10230 10 : if (ErrorsFound) ShowFatalError(state, "Error in complex fenestration input.");
10231 10 : }
10232 :
10233 759 : void InitConductionTransferFunctions(EnergyPlusData &state)
10234 : {
10235 759 : bool ErrorsFound(false); // Flag for input error condition
10236 759 : bool DoCTFErrorReport(false);
10237 6576 : for (auto &construction : state.dataConstruction->Construct) {
10238 5817 : construction.calculateTransferFunction(state, ErrorsFound, DoCTFErrorReport);
10239 5817 : if (construction.NumHistories > 1) {
10240 76 : state.dataHeatBal->SimpleCTFOnly = false;
10241 : }
10242 5817 : if (construction.NumCTFTerms > state.dataHeatBal->MaxCTFTerms) {
10243 1234 : state.dataHeatBal->MaxCTFTerms = construction.NumCTFTerms;
10244 : }
10245 : }
10246 759 : if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
10247 31 : state.dataHeatBal->SimpleCTFOnly = false;
10248 : }
10249 :
10250 : bool InitCTFDoReport;
10251 759 : General::ScanForReports(state, "Constructions", InitCTFDoReport, "Constructions");
10252 759 : if (InitCTFDoReport || DoCTFErrorReport) {
10253 294 : print(state.files.eio,
10254 : "! <Construction CTF>,Construction Name,Index,#Layers,#CTFs,Time Step {{hours}},ThermalConductance "
10255 294 : "{{w/m2-K}},OuterThermalAbsorptance,InnerThermalAbsorptance,OuterSolarAbsorptance,InnerSolarAbsorptance,Roughness\n");
10256 294 : print(state.files.eio,
10257 : "! <Material CTF Summary>,Material Name,Thickness {{m}},Conductivity {{w/m-K}},Density {{kg/m3}},Specific Heat "
10258 294 : "{{J/kg-K}},ThermalResistance {{m2-K/w}}\n");
10259 294 : print(state.files.eio, "! <Material:Air>,Material Name,ThermalResistance {{m2-K/w}}\n");
10260 294 : print(state.files.eio, "! <CTF>,Time,Outside,Cross,Inside,Flux (except final one)\n");
10261 :
10262 294 : int cCounter = 0; // just used to keep construction index in output report
10263 3170 : for (auto &construction : state.dataConstruction->Construct) {
10264 2876 : cCounter++;
10265 2876 : if (!construction.IsUsedCTF) continue;
10266 1819 : construction.reportTransferFunction(state, cCounter);
10267 : }
10268 : }
10269 :
10270 759 : if (ErrorsFound) {
10271 0 : ShowFatalError(state, "Program terminated for reasons listed (InitConductionTransferFunctions)");
10272 : }
10273 759 : }
10274 :
10275 : } // namespace HeatBalanceManager
10276 :
10277 2313 : } // namespace EnergyPlus
|