From 71257e5a5a1c40955b59e365c88261f0a81cf687 Mon Sep 17 00:00:00 2001 From: amirroth Date: Tue, 24 Dec 2024 16:25:13 -0500 Subject: [PATCH] std::array for window incident angles --- src/EnergyPlus/Construction.cc | 34 +- src/EnergyPlus/Construction.hh | 34 +- src/EnergyPlus/DElightManagerF.cc | 12 +- src/EnergyPlus/General.hh | 9 +- src/EnergyPlus/HeatBalanceManager.cc | 146 +++--- src/EnergyPlus/SurfaceGeometry.cc | 32 +- src/EnergyPlus/WindowManager.cc | 449 +++++++++++------- src/EnergyPlus/WindowManager.hh | 23 +- .../unit/HeatBalanceSurfaceManager.unit.cc | 7 +- tst/EnergyPlus/unit/SolarShading.unit.cc | 4 +- 10 files changed, 438 insertions(+), 312 deletions(-) diff --git a/src/EnergyPlus/Construction.cc b/src/EnergyPlus/Construction.cc index 267e9f56ed5..ba748b49c83 100644 --- a/src/EnergyPlus/Construction.cc +++ b/src/EnergyPlus/Construction.cc @@ -2025,18 +2025,6 @@ void ConstructionProps::setArraysBasedOnMaxSolidWinLayers(EnergyPlusData &state) this->rbBareVisCoef.allocate(state.dataHeatBal->MaxSolidWinLayers); this->afBareSolCoef.allocate(state.dataHeatBal->MaxSolidWinLayers); this->abBareSolCoef.allocate(state.dataHeatBal->MaxSolidWinLayers); - for (int Layer = 1; Layer <= state.dataHeatBal->MaxSolidWinLayers; ++Layer) { - this->AbsBeamCoef(Layer).allocate(DataSurfaces::MaxPolyCoeff); - this->AbsBeamBackCoef(Layer).allocate(DataSurfaces::MaxPolyCoeff); - this->tBareSolCoef(Layer).allocate(DataSurfaces::MaxPolyCoeff); - this->tBareVisCoef(Layer).allocate(DataSurfaces::MaxPolyCoeff); - this->rfBareSolCoef(Layer).allocate(DataSurfaces::MaxPolyCoeff); - this->rfBareVisCoef(Layer).allocate(DataSurfaces::MaxPolyCoeff); - this->rbBareSolCoef(Layer).allocate(DataSurfaces::MaxPolyCoeff); - this->rbBareVisCoef(Layer).allocate(DataSurfaces::MaxPolyCoeff); - this->afBareSolCoef(Layer).allocate(DataSurfaces::MaxPolyCoeff); - this->abBareSolCoef(Layer).allocate(DataSurfaces::MaxPolyCoeff); - } for (int Layer = 1; Layer <= state.dataHeatBal->MaxSolidWinLayers; ++Layer) { this->AbsDiff(Layer) = 0.0; @@ -2053,18 +2041,16 @@ void ConstructionProps::setArraysBasedOnMaxSolidWinLayers(EnergyPlusData &state) } } for (int Layer = 1; Layer <= state.dataHeatBal->MaxSolidWinLayers; ++Layer) { - for (int Index = 1; Index <= DataSurfaces::MaxPolyCoeff; ++Index) { - this->AbsBeamCoef(Layer)(Index) = 0.0; - this->AbsBeamBackCoef(Layer)(Index) = 0.0; - this->tBareSolCoef(Layer)(Index) = 0.0; - this->tBareVisCoef(Layer)(Index) = 0.0; - this->rfBareSolCoef(Layer)(Index) = 0.0; - this->rfBareVisCoef(Layer)(Index) = 0.0; - this->rbBareSolCoef(Layer)(Index) = 0.0; - this->rbBareVisCoef(Layer)(Index) = 0.0; - this->afBareSolCoef(Layer)(Index) = 0.0; - this->abBareSolCoef(Layer)(Index) = 0.0; - } + std::fill(this->AbsBeamCoef(Layer).begin(), this->AbsBeamCoef(Layer).end(), 0.0); + std::fill(this->AbsBeamBackCoef(Layer).begin(), this->AbsBeamBackCoef(Layer).end(), 0.0); + std::fill(this->tBareSolCoef(Layer).begin(), this->tBareSolCoef(Layer).end(), 0.0); + std::fill(this->tBareVisCoef(Layer).begin(), this->tBareVisCoef(Layer).end(), 0.0); + std::fill(this->rfBareSolCoef(Layer).begin(), this->rfBareSolCoef(Layer).end(), 0.0); + std::fill(this->rfBareVisCoef(Layer).begin(), this->rfBareVisCoef(Layer).end(), 0.0); + std::fill(this->rbBareSolCoef(Layer).begin(), this->rbBareSolCoef(Layer).end(), 0.0); + std::fill(this->rbBareVisCoef(Layer).begin(), this->rbBareVisCoef(Layer).end(), 0.0); + std::fill(this->afBareSolCoef(Layer).begin(), this->afBareSolCoef(Layer).end(), 0.0); + std::fill(this->abBareSolCoef(Layer).begin(), this->abBareSolCoef(Layer).end(), 0.0); } } diff --git a/src/EnergyPlus/Construction.hh b/src/EnergyPlus/Construction.hh index 1c95c7b513a..9b8fe438e84 100644 --- a/src/EnergyPlus/Construction.hh +++ b/src/EnergyPlus/Construction.hh @@ -216,10 +216,10 @@ namespace Construction { Real64 AbsDiffShade = 0.0; // Diffuse solar absorptance for shade Real64 AbsDiffBackShade = 0.0; // Diffuse back solar absorptance for shade Real64 ShadeAbsorpThermal = 0.0; // Diffuse back thermal absorptance of shade - Array1D> AbsBeamCoef; // Coefficients of incidence-angle polynomial for solar + Array1D> AbsBeamCoef; // Coefficients of incidence-angle polynomial for solar // absorptance for each solid glazing layer - Array1D> AbsBeamBackCoef; // As for AbsBeamCoef but for back-incident solar - Array1D AbsBeamShadeCoef; // Coefficients of incidence-angle polynomial for solar + Array1D> AbsBeamBackCoef; // As for AbsBeamCoef but for back-incident solar + std::array AbsBeamShadeCoef; // Coefficients of incidence-angle polynomial for solar // absorptance of shade Real64 TransDiff = 0.0; // Diffuse solar transmittance, bare glass or shade on Real64 TransDiffVis; // Diffuse visible transmittance, bare glass or shade on @@ -227,21 +227,21 @@ namespace Construction { Real64 ReflectSolDiffFront = 0.0; // Diffuse front solar reflectance, bare glass or shade on Real64 ReflectVisDiffBack = 0.0; // Diffuse back visible reflectance, bare glass or shade on Real64 ReflectVisDiffFront = 0.0; // Diffuse front visible reflectance, bare glass or shade on - Array1D TransSolBeamCoef; // Coeffs of incidence-angle polynomial for beam sol trans, + std::array TransSolBeamCoef; // Coeffs of incidence-angle polynomial for beam sol trans, // bare glass or shade on - Array1D TransVisBeamCoef; // Coeffs of incidence-angle polynomial for beam vis trans, + std::array TransVisBeamCoef; // Coeffs of incidence-angle polynomial for beam vis trans, // bare glass or shade on - Array1D ReflSolBeamFrontCoef; // Coeffs of incidence-angle polynomial for beam sol front refl, + std::array ReflSolBeamFrontCoef; // Coeffs of incidence-angle polynomial for beam sol front refl, // bare glass or shade on - Array1D ReflSolBeamBackCoef; // Like ReflSolBeamFrontCoef, but for back-incident beam solar - Array1D> tBareSolCoef; // Isolated glass solar transmittance coeffs of inc. angle polynomial - Array1D> tBareVisCoef; // Isolated glass visible transmittance coeffs of inc. angle polynomial - Array1D> rfBareSolCoef; // Isolated glass front solar reflectance coeffs of inc. angle polynomial - Array1D> rfBareVisCoef; // Isolated glass front visible reflectance coeffs of inc. angle polynomial - Array1D> rbBareSolCoef; // Isolated glass back solar reflectance coeffs of inc. angle polynomial - Array1D> rbBareVisCoef; // Isolated glass back visible reflectance coeffs of inc. angle polynomial - Array1D> afBareSolCoef; // Isolated glass front solar absorptance coeffs of inc. angle polynomial - Array1D> abBareSolCoef; // Isolated glass back solar absorptance coeffs of inc. angle polynomial + std::array ReflSolBeamBackCoef; // Like ReflSolBeamFrontCoef, but for back-incident beam solar + Array1D> tBareSolCoef; // Isolated glass solar transmittance coeffs of inc. angle polynomial + Array1D> tBareVisCoef; // Isolated glass visible transmittance coeffs of inc. angle polynomial + Array1D> rfBareSolCoef; // Isolated glass front solar reflectance coeffs of inc. angle polynomial + Array1D> rfBareVisCoef; // Isolated glass front visible reflectance coeffs of inc. angle polynomial + Array1D> rbBareSolCoef; // Isolated glass back solar reflectance coeffs of inc. angle polynomial + Array1D> rbBareVisCoef; // Isolated glass back visible reflectance coeffs of inc. angle polynomial + Array1D> afBareSolCoef; // Isolated glass front solar absorptance coeffs of inc. angle polynomial + Array1D> abBareSolCoef; // Isolated glass back solar absorptance coeffs of inc. angle polynomial Array1D tBareSolDiff; // Isolated glass diffuse solar transmittance Array1D tBareVisDiff; // Isolated glass diffuse visible transmittance Array1D rfBareSolDiff; // Isolated glass diffuse solar front reflectance @@ -325,8 +325,8 @@ namespace Construction { // Default Constructor ConstructionProps() - : LayerPoint(MaxLayersInConstruct, 0), AbsBeamShadeCoef(6, 0.0), TransDiffVis(0.0), TransSolBeamCoef(6, 0.0), TransVisBeamCoef(6, 0.0), - ReflSolBeamFrontCoef(6, 0.0), ReflSolBeamBackCoef(6, 0.0), tBareSolDiff(5, 0.0), tBareVisDiff(5, 0.0), rfBareSolDiff(5, 0.0), + : LayerPoint(MaxLayersInConstruct, 0), TransDiffVis(0.0), + tBareSolDiff(5, 0.0), tBareVisDiff(5, 0.0), rfBareSolDiff(5, 0.0), rfBareVisDiff(5, 0.0), rbBareSolDiff(5, 0.0), rbBareVisDiff(5, 0.0), afBareSolDiff(5, 0.0), abBareSolDiff(5, 0.0), AbsDiffFrontEQL(DataWindowEquivalentLayer::CFSMAXNL, 0.0), AbsDiffBackEQL(DataWindowEquivalentLayer::CFSMAXNL, 0.0) { diff --git a/src/EnergyPlus/DElightManagerF.cc b/src/EnergyPlus/DElightManagerF.cc index 1be42160c7e..4b73aa71e0a 100644 --- a/src/EnergyPlus/DElightManagerF.cc +++ b/src/EnergyPlus/DElightManagerF.cc @@ -687,12 +687,12 @@ namespace DElightManagerF { iWndoConstIndexes(iconst) + 10000, state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransDiffVis, state.dataConstruction->Construct(iWndoConstIndexes(iconst)).ReflectVisDiffBack, - state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef(1), - state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef(2), - state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef(3), - state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef(4), - state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef(5), - state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef(6)); + state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef[0], + state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef[1], + state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef[2], + state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef[3], + state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef[4], + state.dataConstruction->Construct(iWndoConstIndexes(iconst)).TransVisBeamCoef[5]); } // Glass Type loop diff --git a/src/EnergyPlus/General.hh b/src/EnergyPlus/General.hh index 31f26cdf9f4..11afea846c1 100644 --- a/src/EnergyPlus/General.hh +++ b/src/EnergyPlus/General.hh @@ -82,6 +82,13 @@ namespace General { Real64 X_0, // 1st bound of interval that contains the solution Real64 X_1); // 2nd bound of interval that contains the solution + constexpr Real64 POLYF(Real64 const X, // Cosine of angle of incidence + std::array const &A // Polynomial coefficients + ) + { + return (X < 0.0 || X > 1.0) ? 0.0 : (X * (A[0] + X * (A[1] + X * (A[2] + X * (A[3] + X * (A[4] + X * A[5])))))); + } + constexpr Real64 POLYF(Real64 const X, // Cosine of angle of incidence Array1D const &A // Polynomial coefficients ) @@ -92,7 +99,7 @@ namespace General { return X * (A(1) + X * (A(2) + X * (A(3) + X * (A(4) + X * (A(5) + X * A(6)))))); } } - + void MovingAvg(Array1D &DataIn, int NumItemsInAvg); void ProcessDateString(EnergyPlusData &state, diff --git a/src/EnergyPlus/HeatBalanceManager.cc b/src/EnergyPlus/HeatBalanceManager.cc index a4c2d6ceed3..8e01a55501f 100644 --- a/src/EnergyPlus/HeatBalanceManager.cc +++ b/src/EnergyPlus/HeatBalanceManager.cc @@ -3628,21 +3628,27 @@ namespace HeatBalanceManager { Array1D SCCenter(2); // Center of glass shading coefficient for glazing system Array1D SHGCCenter(2); // Center of glass solar heat gain coefficient for glazing system Array1D TVisCenter(2); // Center of glass visible transmittance for glazing system - Array1D Tsol(11); // Solar transmittance vs incidence angle; diffuse trans. - Array2D AbsSol(11, 5); // Solar absorptance vs inc. angle in each glass layer - Array1D Rfsol(11); // Front solar reflectance vs inc. angle - Array1D Rbsol(11); // Back solar reflectance vs inc. angle - Array1D Tvis(11); // Visible transmittance vs inc. angle - Array1D Rfvis(11); // Front visible reflectance vs inc. angle - Array1D Rbvis(11); // Back visible reflectance vs inc. angle - Array1D CosPhiIndepVar(10); // Cosine of incidence angle from 0 to 90 deg in 10 deg increments - int IPhi; // Incidence angle counter - Real64 Phi; // Incidence angle (deg) - Array1D CosPhi(10); // Cosine of incidence angle - Array1D tsolFit(10); // Fitted solar transmittance vs incidence angle - Array1D tvisFit(10); // Fitted visible transmittance vs incidence angle - Array1D rfsolFit(10); // Fitted solar front reflectance vs incidence angle - Array2D solabsFit(5, 10); // Fitted solar absorptance vs incidence angle for each glass layer + Array1D TsolTemp(Window::numPhis+1); // Solar transmittance vs incidence angle; diffuse trans. + std::array Tsol; + Array2D AbsSolTemp(Window::maxGlassLayers, Window::numPhis+1); // Solar absorptance vs inc. angle in each glass layer + Array1D> AbsSol(Window::maxGlassLayers); // Solar absorptance vs inc. angle in each glass layer + Array1D RfsolTemp(Window::numPhis+1); // Front solar reflectance vs inc. angle + std::array Rfsol; + Array1D RbsolTemp(Window::numPhis+1); // Back solar reflectance vs inc. angle + std::array Rbsol; + Array1D TvisTemp(Window::numPhis+1); // Visible transmittance vs inc. angle + std::array Tvis; + Array1D RfvisTemp(Window::numPhis+1); // Front visible reflectance vs inc. angle + std::array Rfvis; + Array1D RbvisTemp(Window::numPhis+1); // Back visible reflectance vs inc. angle + std::array Rbvis; + + // std::array CosPhiIndepVar; // Cosine of incidence angle from 0 to 90 deg in 10 deg increments + // std::array CosPhi; // Cosine of incidence angle + std::array tsolFit; // Fitted solar transmittance vs incidence angle + std::array tvisFit; // Fitted visible transmittance vs incidence angle + std::array rfsolFit; // Fitted solar front reflectance vs incidence angle + Array1D> solabsFit(Window::maxGlassLayers); // Fitted solar absorptance vs incidence angle for each glass layer Array1D_string DividerType(2); // Divider type: DividedLite or Suspended Real64 FrameWidth; Real64 MullionWidth; @@ -4135,16 +4141,16 @@ namespace HeatBalanceManager { ++FileLineCount; // Pre-calculate constants - for (IPhi = 1; IPhi <= 10; ++IPhi) { - CosPhiIndepVar(IPhi) = std::cos((IPhi - 1) * 10.0 * Constant::DegToRadians); - } + // for (int iPhi = 0; iPhi < 10; ++iPhi) { + // CosPhiIndepVar[iPhi] = std::cos(iPhi * 10.0 * Constant::DegToRad); + // } - // Pre-calculate constants - for (IPhi = 1; IPhi <= 10; ++IPhi) { - Phi = double(IPhi - 1) * 10.0; - CosPhi(IPhi) = std::cos(Phi * Constant::DegToRadians); - if (std::abs(CosPhi(IPhi)) < 0.0001) CosPhi(IPhi) = 0.0; - } + // Pre-calculate constants // Why do we need both of these? + // for (int iPhi = 0; iPhi < Window::numPhis; ++iPhi) { + // Real64 Phi = double(iPhi) * 10.0; + // CosPhi[iPhi] = std::cos(Phi * Constant::DegToRad); + // if (std::abs(CosPhi[iPhi]) < 0.0001) CosPhi[iPhi] = 0.0; + // } for (IGlSys = 1; IGlSys <= NGlSys; ++IGlSys) { ConstrNum = state.dataHeatBal->TotConstructs - NGlSys + IGlSys; @@ -4186,7 +4192,7 @@ namespace HeatBalanceManager { thisConstruct.AbsDiffShade = 0.0; thisConstruct.AbsDiffBackShade = 0.0; thisConstruct.ShadeAbsorpThermal = 0.0; - thisConstruct.AbsBeamShadeCoef = 0.0; + std::fill(thisConstruct.AbsBeamShadeCoef.begin(), thisConstruct.AbsBeamShadeCoef.end(), 0.0); thisConstruct.AbsDiffIn = 0.0; thisConstruct.AbsDiffOut = 0.0; thisConstruct.TransDiff = 0.0; @@ -4195,20 +4201,18 @@ namespace HeatBalanceManager { thisConstruct.ReflectSolDiffFront = 0.0; thisConstruct.ReflectVisDiffBack = 0.0; thisConstruct.ReflectVisDiffFront = 0.0; - thisConstruct.TransSolBeamCoef = 0.0; - thisConstruct.TransVisBeamCoef = 0.0; - thisConstruct.ReflSolBeamFrontCoef = 0.0; - thisConstruct.ReflSolBeamBackCoef = 0.0; + std::fill(thisConstruct.TransSolBeamCoef.begin(), thisConstruct.TransSolBeamCoef.end(), 0.0); + std::fill(thisConstruct.TransVisBeamCoef.begin(), thisConstruct.TransVisBeamCoef.end(), 0.0); + std::fill(thisConstruct.ReflSolBeamFrontCoef.begin(), thisConstruct.ReflSolBeamFrontCoef.end(), 0.0); + std::fill(thisConstruct.ReflSolBeamBackCoef.begin(), thisConstruct.ReflSolBeamBackCoef.end(), 0.0); thisConstruct.W5FrameDivider = 0; thisConstruct.TotLayers = NGlass(IGlSys) + NGaps(IGlSys); thisConstruct.TotGlassLayers = NGlass(IGlSys); thisConstruct.TotSolidLayers = NGlass(IGlSys); for (int Layer = 1; Layer <= state.dataHeatBal->MaxSolidWinLayers; ++Layer) { - for (int index = 1; index <= DataSurfaces::MaxPolyCoeff; ++index) { - thisConstruct.AbsBeamCoef(Layer)(index) = 0.0; - thisConstruct.AbsBeamBackCoef(Layer)(index) = 0.0; - } + std::fill(thisConstruct.AbsBeamCoef(Layer).begin(), thisConstruct.AbsBeamCoef(Layer).end(), 0.0); + std::fill(thisConstruct.AbsBeamBackCoef(Layer).begin(), thisConstruct.AbsBeamBackCoef(Layer).end(), 0.0); } for (IGlass = 1; IGlass <= NGlass(IGlSys); ++IGlass) { @@ -4242,25 +4246,26 @@ namespace HeatBalanceManager { NextLine = W5DataFile.readLine(); if (NextLine.eof) goto Label1000; ++FileLineCount; - if (!readItem(NextLine.data.substr(5), Tsol)) { + if (!readItem(NextLine.data.substr(5), TsolTemp)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of TSol values."); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount, NextLine.data.substr(0, 100))); ErrorsFound = true; - } else if (any_lt(Tsol, 0.0) || any_gt(Tsol, 1.0)) { + } else if (any_lt(TsolTemp, 0.0) || any_gt(TsolTemp, 1.0)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of TSol values. (out of range [0,1])"); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount, NextLine.data.substr(0, 100))); ErrorsFound = true; } + for (IGlass = 1; IGlass <= NGlass(IGlSys); ++IGlass) { NextLine = W5DataFile.readLine(); ++FileLineCount; - if (!readItem(NextLine.data.substr(5), AbsSol(_, IGlass))) { + if (!readItem(NextLine.data.substr(5), AbsSolTemp(IGlass, _))) { ShowSevereError(state, format("HeatBalanceManager: SearchWindow5DataFile: Error in Read of AbsSol values. For Glass={}", IGlass)); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount, NextLine.data.substr(0, 100))); ErrorsFound = true; - } else if (any_lt(AbsSol(_, IGlass), 0.0) || any_gt(AbsSol(_, IGlass), 1.0)) { + } else if (any_lt(AbsSolTemp(IGlass, _), 0.0) || any_gt(AbsSolTemp(IGlass, _), 1.0)) { ShowSevereError( state, format("HeatBalanceManager: SearchWindow5DataFile: Error in Read of AbsSol values. (out of range [0,1]) For Glass={}", @@ -4275,48 +4280,48 @@ namespace HeatBalanceManager { DataLine(ILine) = NextLine.data; } - if (!readItem(DataLine(1).substr(5), Rfsol)) { + if (!readItem(DataLine(1).substr(5), RfsolTemp)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of RfSol values."); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 1, DataLine(1).substr(0, 100))); ErrorsFound = true; - } else if (any_lt(Rfsol, 0.0) || any_gt(Rfsol, 1.0)) { + } else if (any_lt(RfsolTemp, 0.0) || any_gt(RfsolTemp, 1.0)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of RfSol values. (out of range [0,1])"); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 1, DataLine(1).substr(0, 100))); ErrorsFound = true; } - if (!readItem(DataLine(2).substr(5), Rbsol)) { + if (!readItem(DataLine(2).substr(5), RbsolTemp)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of RbSol values."); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 2, DataLine(2).substr(0, 100))); ErrorsFound = true; - } else if (any_lt(Rbsol, 0.0) || any_gt(Rbsol, 1.0)) { + } else if (any_lt(RbsolTemp, 0.0) || any_gt(RbsolTemp, 1.0)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of RbSol values. (out of range [0,1])"); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 2, DataLine(2).substr(0, 100))); ErrorsFound = true; } - if (!readItem(DataLine(3).substr(5), Tvis)) { + if (!readItem(DataLine(3).substr(5), TvisTemp)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Tvis values."); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 3, DataLine(3).substr(0, 100))); ErrorsFound = true; - } else if (any_lt(Tvis, 0.0) || any_gt(Tvis, 1.0)) { + } else if (any_lt(TvisTemp, 0.0) || any_gt(TvisTemp, 1.0)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Tvis values. (out of range [0,1])"); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 3, DataLine(3).substr(0, 100))); ErrorsFound = true; } - if (!readItem(DataLine(4).substr(5), Rfvis)) { + if (!readItem(DataLine(4).substr(5), RfvisTemp)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Rfvis values."); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 4, DataLine(4).substr(0, 100))); ErrorsFound = true; - } else if (any_lt(Rfvis, 0.0) || any_gt(Rfvis, 1.0)) { + } else if (any_lt(RfvisTemp, 0.0) || any_gt(RfvisTemp, 1.0)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Rfvis values. (out of range [0,1])"); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 4, DataLine(4).substr(0, 100))); ErrorsFound = true; } - if (!readItem(DataLine(5).substr(5), Rbvis)) { + if (!readItem(DataLine(5).substr(5), RbvisTemp)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Rbvis values."); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 5, DataLine(5).substr(0, 100))); ErrorsFound = true; - } else if (any_lt(Rbvis, 0.0) || any_gt(Rbvis, 1.0)) { + } else if (any_lt(RbvisTemp, 0.0) || any_gt(RbvisTemp, 1.0)) { ShowSevereError(state, "HeatBalanceManager: SearchWindow5DataFile: Error in Read of Rbvis values. (out of range [0,1])"); ShowContinueError(state, format("Line (~{}) in error (first 100 characters)={}", FileLineCount + 5, DataLine(5).substr(0, 100))); ErrorsFound = true; @@ -4330,28 +4335,43 @@ namespace HeatBalanceManager { "of above errors", DesiredConstructionName)); + for (int iPhi = 0; iPhi < Window::numPhis; ++iPhi) { + Tsol[iPhi] = TsolTemp(iPhi+1); + Tvis[iPhi] = TvisTemp(iPhi+1); + Rfsol[iPhi] = RfsolTemp(iPhi+1); + Rbsol[iPhi] = RbsolTemp(iPhi+1); + Rfvis[iPhi] = RfvisTemp(iPhi+1); + Rbvis[iPhi] = RbvisTemp(iPhi+1); + } + + for (IGlass = 1; IGlass <= NGlass(IGlSys); ++IGlass) { + for (int iPhi = 0; iPhi < Window::numPhis; ++iPhi) { + AbsSol(IGlass)[iPhi] = AbsSolTemp(IGlass, iPhi+1); + } + } + // Hemis - thisConstruct.TransDiff = Tsol(11); - thisConstruct.TransDiffVis = Tvis(11); - thisConstruct.ReflectSolDiffFront = Rfsol(11); - thisConstruct.ReflectSolDiffBack = Rbsol(11); - thisConstruct.ReflectVisDiffFront = Rfvis(11); - thisConstruct.ReflectVisDiffBack = Rbvis(11); - - Window::W5LsqFit(CosPhiIndepVar, Tsol, 6, 1, 10, thisConstruct.TransSolBeamCoef); - Window::W5LsqFit(CosPhiIndepVar, Tvis, 6, 1, 10, thisConstruct.TransVisBeamCoef); - Window::W5LsqFit(CosPhiIndepVar, Rfsol, 6, 1, 10, thisConstruct.ReflSolBeamFrontCoef); + thisConstruct.TransDiff = TsolTemp(11); + thisConstruct.TransDiffVis = TvisTemp(11); + thisConstruct.ReflectSolDiffFront = RfsolTemp(11); + thisConstruct.ReflectSolDiffBack = RbsolTemp(11); + thisConstruct.ReflectVisDiffFront = RfvisTemp(11); + thisConstruct.ReflectVisDiffBack = RbvisTemp(11); + + Window::W5LsqFit(Window::cosPhis, Tsol, thisConstruct.TransSolBeamCoef); + Window::W5LsqFit(Window::cosPhis, Tvis, thisConstruct.TransVisBeamCoef); + Window::W5LsqFit(Window::cosPhis, Rfsol, thisConstruct.ReflSolBeamFrontCoef); for (IGlass = 1; IGlass <= NGlass(IGlSys); ++IGlass) { - Window::W5LsqFit(CosPhiIndepVar, AbsSol(_, IGlass), 6, 1, 10, thisConstruct.AbsBeamCoef(IGlass)); + Window::W5LsqFit(Window::cosPhis, AbsSol(IGlass), thisConstruct.AbsBeamCoef(IGlass)); } // For comparing fitted vs. input distribution in incidence angle - for (IPhi = 1; IPhi <= 10; ++IPhi) { - tsolFit(IPhi) = POLYF(CosPhi(IPhi), thisConstruct.TransSolBeamCoef); - tvisFit(IPhi) = POLYF(CosPhi(IPhi), thisConstruct.TransVisBeamCoef); - rfsolFit(IPhi) = POLYF(CosPhi(IPhi), thisConstruct.ReflSolBeamFrontCoef); + for (int iPhi = 0; iPhi < Window::numPhis; ++iPhi) { + tsolFit[iPhi] = POLYF(Window::cosPhis[iPhi], thisConstruct.TransSolBeamCoef); + tvisFit[iPhi] = POLYF(Window::cosPhis[iPhi], thisConstruct.TransVisBeamCoef); + rfsolFit[iPhi] = POLYF(Window::cosPhis[iPhi], thisConstruct.ReflSolBeamFrontCoef); for (IGlass = 1; IGlass <= NGlass(IGlSys); ++IGlass) { - solabsFit(IGlass, IPhi) = POLYF(CosPhi(IPhi), thisConstruct.AbsBeamCoef(IGlass)); + solabsFit(IGlass)[iPhi] = POLYF(Window::cosPhis[iPhi], thisConstruct.AbsBeamCoef(IGlass)); } } // end diff --git a/src/EnergyPlus/SurfaceGeometry.cc b/src/EnergyPlus/SurfaceGeometry.cc index faf30f55f0c..64d87f2c11c 100644 --- a/src/EnergyPlus/SurfaceGeometry.cc +++ b/src/EnergyPlus/SurfaceGeometry.cc @@ -13273,17 +13273,17 @@ namespace SurfaceGeometry { thisConstructNewSh.AbsDiffShade = 0.0; thisConstructNewSh.AbsDiffBackShade = 0.0; thisConstructNewSh.ShadeAbsorpThermal = 0.0; - thisConstructNewSh.AbsBeamShadeCoef = 0.0; + std::fill(thisConstructNewSh.AbsBeamShadeCoef.begin(), thisConstructNewSh.AbsBeamShadeCoef.end(), 0.0); thisConstructNewSh.TransDiff = 0.0; thisConstructNewSh.TransDiffVis = 0.0; thisConstructNewSh.ReflectSolDiffBack = 0.0; thisConstructNewSh.ReflectSolDiffFront = 0.0; thisConstructNewSh.ReflectVisDiffBack = 0.0; thisConstructNewSh.ReflectVisDiffFront = 0.0; - thisConstructNewSh.TransSolBeamCoef = 0.0; - thisConstructNewSh.TransVisBeamCoef = 0.0; - thisConstructNewSh.ReflSolBeamFrontCoef = 0.0; - thisConstructNewSh.ReflSolBeamBackCoef = 0.0; + std::fill(thisConstructNewSh.TransSolBeamCoef.begin(), thisConstructNewSh.TransSolBeamCoef.end(), 0.0); + std::fill(thisConstructNewSh.TransVisBeamCoef.begin(), thisConstructNewSh.TransVisBeamCoef.end(), 0.0); + std::fill(thisConstructNewSh.ReflSolBeamFrontCoef.begin(), thisConstructNewSh.ReflSolBeamFrontCoef.end(), 0.0); + std::fill(thisConstructNewSh.ReflSolBeamBackCoef.begin(), thisConstructNewSh.ReflSolBeamBackCoef.end(), 0.0); thisConstructNewSh.W5FrameDivider = 0; thisConstructNewSh.FromWindow5DataFile = false; @@ -13295,10 +13295,8 @@ namespace SurfaceGeometry { thisConstructNewSh.IsUsed = true; for (int Layer = 1; Layer <= state.dataHeatBal->MaxSolidWinLayers; ++Layer) { - for (int index = 1; index <= DataSurfaces::MaxPolyCoeff; ++index) { - thisConstructNewSh.AbsBeamCoef(Layer)(index) = 0.0; - thisConstructNewSh.AbsBeamBackCoef(Layer)(index) = 0.0; - } + std::fill(thisConstructNewSh.AbsBeamCoef(Layer).begin(), thisConstructNewSh.AbsBeamCoef(Layer).end(), 0.0); + std::fill(thisConstructNewSh.AbsBeamBackCoef(Layer).begin(), thisConstructNewSh.AbsBeamBackCoef(Layer).end(), 0.0); } } } @@ -13475,17 +13473,17 @@ namespace SurfaceGeometry { thisConstruct.AbsDiffShade = 0.0; thisConstruct.AbsDiffBackShade = 0.0; thisConstruct.ShadeAbsorpThermal = 0.0; - thisConstruct.AbsBeamShadeCoef = 0.0; + std::fill(thisConstruct.AbsBeamShadeCoef.begin(), thisConstruct.AbsBeamShadeCoef.end(), 0.0); thisConstruct.TransDiff = 0.0; thisConstruct.TransDiffVis = 0.0; thisConstruct.ReflectSolDiffBack = 0.0; thisConstruct.ReflectSolDiffFront = 0.0; thisConstruct.ReflectVisDiffBack = 0.0; thisConstruct.ReflectVisDiffFront = 0.0; - thisConstruct.TransSolBeamCoef = 0.0; - thisConstruct.TransVisBeamCoef = 0.0; - thisConstruct.ReflSolBeamFrontCoef = 0.0; - thisConstruct.ReflSolBeamBackCoef = 0.0; + std::fill(thisConstruct.TransSolBeamCoef.begin(), thisConstruct.TransSolBeamCoef.end(), 0.0); + std::fill(thisConstruct.TransVisBeamCoef.begin(), thisConstruct.TransVisBeamCoef.end(), 0.0); + std::fill(thisConstruct.ReflSolBeamFrontCoef.begin(), thisConstruct.ReflSolBeamFrontCoef.end(), 0.0); + std::fill(thisConstruct.ReflSolBeamBackCoef.begin(), thisConstruct.ReflSolBeamBackCoef.end(), 0.0); thisConstruct.W5FrameDivider = 0; thisConstruct.FromWindow5DataFile = false; thisConstruct.W5FileMullionWidth = 0.0; @@ -13493,10 +13491,8 @@ namespace SurfaceGeometry { thisConstruct.W5FileGlazingSysWidth = 0.0; thisConstruct.W5FileGlazingSysHeight = 0.0; for (int Layer = 1; Layer <= state.dataHeatBal->MaxSolidWinLayers; ++Layer) { - for (int index = 1; index <= DataSurfaces::MaxPolyCoeff; ++index) { - thisConstruct.AbsBeamCoef(Layer)(index) = 0.0; - thisConstruct.AbsBeamBackCoef(Layer)(index) = 0.0; - } + std::fill(thisConstruct.AbsBeamCoef(Layer).begin(), thisConstruct.AbsBeamCoef(Layer).end(), 0.0); + std::fill(thisConstruct.AbsBeamBackCoef(Layer).begin(), thisConstruct.AbsBeamBackCoef(Layer).end(), 0.0); } } return (newConstruct); diff --git a/src/EnergyPlus/WindowManager.cc b/src/EnergyPlus/WindowManager.cc index 47ac924d445..bb4f4763f79 100644 --- a/src/EnergyPlus/WindowManager.cc +++ b/src/EnergyPlus/WindowManager.cc @@ -203,49 +203,49 @@ namespace Window { // Glazing system layer solar absorptance for each glass layer Array1D solabsDiff(maxGlassLayers); // Glazing system solar absorptance for a layer at each incidence angle - Array1D solabsPhiLay(maxIncidentAngles); + std::array solabsPhiLay; // Glazing system solar transmittance from fit at each incidence angle - Array1D tsolPhiFit(maxIncidentAngles); + std::array tsolPhiFit; // Glazing system visible transmittance from fit at each incidence angle - Array1D tvisPhiFit(maxIncidentAngles); + std::array tvisPhiFit; // Isolated glass solar transmittance for each incidence angle - Array2D tBareSolPhi(maxGlassLayers, maxIncidentAngles); + Array1D> tBareSolPhi(maxGlassLayers); Real64 t1; // = tBareSolPhi(,1)(,2) Real64 t2; // Isolated glass visible transmittance for each incidence angle - Array2D tBareVisPhi(maxGlassLayers, maxIncidentAngles); + Array1D> tBareVisPhi(maxGlassLayers); Real64 t1v; // = tBareVisPhi(,1)(,2) Real64 t2v; // Isolated glass front solar reflectance for each incidence angle - Array2D rfBareSolPhi(maxGlassLayers, maxIncidentAngles); + Array1D> rfBareSolPhi(maxGlassLayers); // Isolated glass front visible reflectance for each incidence angle - Array2D rfBareVisPhi(maxGlassLayers, maxIncidentAngles); + Array1D> rfBareVisPhi(maxGlassLayers); // Isolated glass back solar reflectance for each incidence angle - Array2D rbBareSolPhi(maxGlassLayers, maxIncidentAngles); + Array1D> rbBareSolPhi(maxGlassLayers); // Isolated glass back visible reflectance for each incidence angle - Array2D rbBareVisPhi(maxGlassLayers, maxIncidentAngles); + Array1D> rbBareVisPhi(maxGlassLayers); // Isolated glass front solar absorptance for each incidence angle - Array2D afBareSolPhi(maxGlassLayers, maxIncidentAngles); + Array1D> afBareSolPhi(maxGlassLayers); Real64 af1; // = afBareSolPhi(,1)(,2) Real64 af2; Real64 rbmf2; // Isolated glass #2 front beam reflectance // Isolated glass back solar absorptance for each incidence angle - Array2D abBareSolPhi(maxGlassLayers, maxIncidentAngles); + Array1D> abBareSolPhi(maxGlassLayers); // Glazing system solar absorptance for each angle of incidence - Array2D solabsPhi(maxGlassLayers, maxIncidentAngles); + Array1D> solabsPhi(maxGlassLayers); // Glazing system back solar absorptance for each angle of incidence - Array2D solabsBackPhi(maxGlassLayers, maxIncidentAngles); + Array1D> solabsBackPhi(maxGlassLayers); // Glazing system interior shade solar absorptance for each angle of incidence - Array1D solabsShadePhi(maxIncidentAngles); + std::array solabsShadePhi; // These need to stay as Array1D for a little longer because changing them spreads into many source files - Array1D tsolPhi(maxIncidentAngles); // Glazing system solar transmittance for each angle of incidence - Array1D rfsolPhi(maxIncidentAngles); // Glazing system solar front reflectance for each angle of incidence - Array1D rbsolPhi(maxIncidentAngles); // Glazing system solar back reflectance for each angle of incidence - Array1D tvisPhi(maxIncidentAngles); // Glazing system visible transmittance for each angle of incidence - Array1D rfvisPhi(maxIncidentAngles); // Glazing system visible front reflectance for each angle of incidence - Array1D rbvisPhi(maxIncidentAngles); // Glazing system visible back reflectance for each angle of incidence - Array1D CosPhiIndepVar(maxIncidentAngles); // Cos of incidence angles at 10-deg increments for curve fits + std::array tsolPhi; // Glazing system solar transmittance for each angle of incidence + std::array rfsolPhi; // Glazing system solar front reflectance for each angle of incidence + std::array rbsolPhi; // Glazing system solar back reflectance for each angle of incidence + std::array tvisPhi; // Glazing system visible transmittance for each angle of incidence + std::array rfvisPhi; // Glazing system visible front reflectance for each angle of incidence + std::array rbvisPhi; // Glazing system visible back reflectance for each angle of incidence + // std::array CosPhiIndepVar; // Cos of incidence angles at 10-deg increments for curve fits Real64 ab1; // = abBareSolPhi(,1)(,2) Real64 ab2; @@ -280,8 +280,8 @@ namespace Window { Real64 RhoGlIR; // IR reflectance of inside face of inside glass int NGlass; // Number of glass layers in a construction int LayPtr; // Material number corresponding to LayNum - Real64 Phi; // Incidence angle (deg) - Real64 CosPhi; // Cosine of incidence angle + // Real64 Phi; // Incidence angle (deg) + // Real64 CosPhi; // Cosine of incidence angle Real64 tsolDiff; // Glazing system diffuse solar transmittance Real64 tvisDiff; // Glazing system diffuse visible transmittance int IGlassBack; // Glass layer number counted from back of window @@ -363,9 +363,10 @@ namespace Window { if (thisConstruct.WindowTypeEQL) continue; // skip Equivalent Layer Fenestration // handling of optical properties - for (int IPhi = 1; IPhi <= 10; ++IPhi) { - CosPhiIndepVar(IPhi) = std::cos((IPhi - 1) * 10.0 * Constant::DegToRadians); - } + constexpr int TotalIPhi = 10; + // for (int iPhi = 0; iPhi < TotalIPhi; ++iPhi) { + // CosPhiIndepVar[iPhi] = std::cos(iPhi * 10.0 * Constant::DegToRad); + // } TotLay = thisConstruct.TotLayers; @@ -496,7 +497,6 @@ namespace Window { lquasi = false; AllGlassIsSpectralAverage = true; - int constexpr TotalIPhi = 10; wm->LayerNum = {0}; // Loop over glass layers in the construction @@ -642,14 +642,14 @@ namespace Window { } } // End of loop over glass layers in the construction for front calculation - if (TotalIPhi > maxIncidentAngles) { + if (TotalIPhi > numPhis) { ShowSevereError(state, format("WindowManage::InitGlassOpticalCalculations = {}, Invalid maximum value of common incident angles = {}.", thisConstruct.Name, TotalIPhi)); ShowContinueError( state, - format("The maximum number of incident angles for each construct is {}. Please rearrange the dataset.", maxIncidentAngles)); + format("The maximum number of incident angles for each construct is {}. Please rearrange the dataset.", numPhis)); ShowFatalError(state, "Errors found getting inputs. Previous error(s) cause program termination."); } @@ -657,11 +657,11 @@ namespace Window { // Get glass layer properties, then glazing system properties (which include the // effect of inter-reflection among glass layers) at each incidence angle. - for (int IPhi = 1; IPhi <= TotalIPhi; ++IPhi) { + for (int iPhi = 0; iPhi < TotalIPhi; ++iPhi) { // 10 degree increment for incident angle is only value for a construction without a layer = SpectralAndAngle - Phi = double(IPhi - 1) * 10.0; - CosPhi = std::cos(Phi * Constant::DegToRadians); - if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0; + // Real64 Phi = double(iPhi) * 10.0; + // Real64 CosPhi = std::cos(Phi * Constant::DegToRadians); + // if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0; // For each wavelength, get glass layer properties at this angle of incidence // from properties at normal incidence @@ -671,7 +671,7 @@ namespace Window { assert(matGlass != nullptr); if (matGlass->windowOpticalData != Window::OpticalDataModel::SpectralAndAngle) { for (int ILam = 1; ILam <= numpt[IGlass - 1]; ++ILam) { - TransAndReflAtPhi(CosPhi, + TransAndReflAtPhi(cosPhis[iPhi], t[IGlass - 1][ILam - 1], rff[IGlass - 1][ILam - 1], rbb[IGlass - 1][ILam - 1], @@ -686,23 +686,23 @@ namespace Window { for (int ILam = 1; ILam <= (int)wm->wle.size(); ++ILam) { Real64 lam = wm->wle[ILam - 1]; wlt[IGlass - 1][ILam - 1] = lam; - tPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngTransDataPtr, Phi, lam); - rfPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngFRefleDataPtr, Phi, lam); - rbPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngBRefleDataPtr, Phi, lam); + tPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngTransDataPtr, iPhi * 10.0, lam); + rfPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngFRefleDataPtr, iPhi * 10.0, lam); + rbPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngBRefleDataPtr, iPhi * 10.0, lam); } } // For use with between-glass shade/blind, save angular properties of isolated glass // for case that all glass layers were input with spectral-average properties // only used by between-glass shades or blinds if (AllGlassIsSpectralAverage) { - tBareSolPhi(IGlass, IPhi) = tPhi[IGlass - 1][0]; - tBareVisPhi(IGlass, IPhi) = tPhi[IGlass - 1][1]; - rfBareSolPhi(IGlass, IPhi) = rfPhi[IGlass - 1][0]; - rfBareVisPhi(IGlass, IPhi) = rfPhi[IGlass - 1][1]; - rbBareSolPhi(IGlass, IPhi) = rbPhi[IGlass - 1][0]; - rbBareVisPhi(IGlass, IPhi) = rbPhi[IGlass - 1][1]; - afBareSolPhi(IGlass, IPhi) = max(0.0, 1.0 - (tBareSolPhi(IGlass, IPhi) + rfBareSolPhi(IGlass, IPhi))); - abBareSolPhi(IGlass, IPhi) = max(0.0, 1.0 - (tBareSolPhi(IGlass, IPhi) + rbBareSolPhi(IGlass, IPhi))); + tBareSolPhi(IGlass)[iPhi] = tPhi[IGlass - 1][0]; + tBareVisPhi(IGlass)[iPhi] = tPhi[IGlass - 1][1]; + rfBareSolPhi(IGlass)[iPhi] = rfPhi[IGlass - 1][0]; + rfBareVisPhi(IGlass)[iPhi] = rfPhi[IGlass - 1][1]; + rbBareSolPhi(IGlass)[iPhi] = rbPhi[IGlass - 1][0]; + rbBareVisPhi(IGlass)[iPhi] = rbPhi[IGlass - 1][1]; + afBareSolPhi(IGlass)[iPhi] = max(0.0, 1.0 - (tBareSolPhi(IGlass)[iPhi] + rfBareSolPhi(IGlass)[iPhi])); + abBareSolPhi(IGlass)[iPhi] = max(0.0, 1.0 - (tBareSolPhi(IGlass)[iPhi] + rbBareSolPhi(IGlass)[iPhi])); } } @@ -721,15 +721,15 @@ namespace Window { // Get solar properties of system by integrating over solar irradiance spectrum. // For now it is assumed that the exterior and interior irradiance spectra are the same. - tsolPhi(IPhi) = solarSpectrumAverage(state, stPhi); - rfsolPhi(IPhi) = solarSpectrumAverage(state, srfPhi); - rbsolPhi(IPhi) = solarSpectrumAverage(state, srbPhi); + tsolPhi[iPhi] = solarSpectrumAverage(state, stPhi); + rfsolPhi[iPhi] = solarSpectrumAverage(state, srfPhi); + rbsolPhi[iPhi] = solarSpectrumAverage(state, srbPhi); for (int IGlass = 1; IGlass <= NGlass; ++IGlass) { for (int ILam = 1; ILam <= nume; ++ILam) { sabsPhi(ILam) = saPhi(IGlass, ILam); } - solabsPhi(IGlass, IPhi) = solarSpectrumAverage(state, sabsPhi); + solabsPhi(IGlass)[iPhi] = solarSpectrumAverage(state, sabsPhi); } // Get visible properties of system by integrating over solar irradiance @@ -740,23 +740,23 @@ namespace Window { // without spectral data, as indicated by the argument "2". if (lquasi) SystemSpectralPropertiesAtPhi(state, 2, NGlass, 0.37, 0.78, numpt, wlt, tPhi, rfPhi, rbPhi, stPhi, srfPhi, srbPhi, saPhi); - tvisPhi(IPhi) = visibleSpectrumAverage(state, stPhi); - rfvisPhi(IPhi) = visibleSpectrumAverage(state, srfPhi); - rbvisPhi(IPhi) = visibleSpectrumAverage(state, srbPhi); + tvisPhi[iPhi] = visibleSpectrumAverage(state, stPhi); + rfvisPhi[iPhi] = visibleSpectrumAverage(state, srfPhi); + rbvisPhi[iPhi] = visibleSpectrumAverage(state, srbPhi); } // End of loop over incidence angles for front calculation // only used by between-glass shades or blinds if (AllGlassIsSpectralAverage) { for (int IGlass = 1; IGlass <= NGlass; ++IGlass) { - W5LsqFit(CosPhiIndepVar, tBareSolPhi(IGlass, _), 6, 1, TotalIPhi, thisConstruct.tBareSolCoef(IGlass)); - W5LsqFit(CosPhiIndepVar, tBareVisPhi(IGlass, _), 6, 1, TotalIPhi, thisConstruct.tBareVisCoef(IGlass)); - W5LsqFit(CosPhiIndepVar, rfBareSolPhi(IGlass, _), 6, 1, TotalIPhi, thisConstruct.rfBareSolCoef(IGlass)); - W5LsqFit(CosPhiIndepVar, rfBareVisPhi(IGlass, _), 6, 1, TotalIPhi, thisConstruct.rfBareVisCoef(IGlass)); - W5LsqFit(CosPhiIndepVar, rbBareSolPhi(IGlass, _), 6, 1, TotalIPhi, thisConstruct.rbBareSolCoef(IGlass)); - W5LsqFit(CosPhiIndepVar, rbBareVisPhi(IGlass, _), 6, 1, TotalIPhi, thisConstruct.rbBareVisCoef(IGlass)); - W5LsqFit(CosPhiIndepVar, afBareSolPhi(IGlass, _), 6, 1, TotalIPhi, thisConstruct.afBareSolCoef(IGlass)); - W5LsqFit(CosPhiIndepVar, abBareSolPhi(IGlass, _), 6, 1, TotalIPhi, thisConstruct.abBareSolCoef(IGlass)); + W5LsqFit(cosPhis, tBareSolPhi(IGlass), thisConstruct.tBareSolCoef(IGlass)); + W5LsqFit(cosPhis, tBareVisPhi(IGlass), thisConstruct.tBareVisCoef(IGlass)); + W5LsqFit(cosPhis, rfBareSolPhi(IGlass), thisConstruct.rfBareSolCoef(IGlass)); + W5LsqFit(cosPhis, rfBareVisPhi(IGlass), thisConstruct.rfBareVisCoef(IGlass)); + W5LsqFit(cosPhis, rbBareSolPhi(IGlass), thisConstruct.rbBareSolCoef(IGlass)); + W5LsqFit(cosPhis, rbBareVisPhi(IGlass), thisConstruct.rbBareVisCoef(IGlass)); + W5LsqFit(cosPhis, afBareSolPhi(IGlass), thisConstruct.afBareSolCoef(IGlass)); + W5LsqFit(cosPhis, abBareSolPhi(IGlass), thisConstruct.abBareSolCoef(IGlass)); } } @@ -770,7 +770,7 @@ namespace Window { thisConstruct.TransDiff = tsolDiff; thisConstruct.TransDiffVis = tvisDiff; for (int IGlass = 1; IGlass <= NGlass; ++IGlass) { - solabsPhiLay({1, TotalIPhi}) = solabsPhi(IGlass, {1, TotalIPhi}); + solabsPhiLay = solabsPhi(IGlass); // Is this a deep copy? solabsDiff(IGlass) = DiffuseAverage(solabsPhiLay); thisConstruct.AbsDiff(IGlass) = solabsDiff(IGlass); @@ -778,12 +778,12 @@ namespace Window { // all glass layers were input with spectral-average properties // only used by between-glass shades or blinds if (AllGlassIsSpectralAverage) { - thisConstruct.tBareSolDiff(IGlass) = DiffuseAverage(tBareSolPhi(IGlass, {1, TotalIPhi})); - thisConstruct.tBareVisDiff(IGlass) = DiffuseAverage(tBareVisPhi(IGlass, {1, TotalIPhi})); - thisConstruct.rfBareSolDiff(IGlass) = DiffuseAverage(rfBareSolPhi(IGlass, {1, TotalIPhi})); - thisConstruct.rfBareVisDiff(IGlass) = DiffuseAverage(rfBareVisPhi(IGlass, {1, TotalIPhi})); - thisConstruct.rbBareSolDiff(IGlass) = DiffuseAverage(rbBareSolPhi(IGlass, {1, TotalIPhi})); - thisConstruct.rbBareVisDiff(IGlass) = DiffuseAverage(rbBareVisPhi(IGlass, {1, TotalIPhi})); + thisConstruct.tBareSolDiff(IGlass) = DiffuseAverage(tBareSolPhi(IGlass)); + thisConstruct.tBareVisDiff(IGlass) = DiffuseAverage(tBareVisPhi(IGlass)); + thisConstruct.rfBareSolDiff(IGlass) = DiffuseAverage(rfBareSolPhi(IGlass)); + thisConstruct.rfBareVisDiff(IGlass) = DiffuseAverage(rfBareVisPhi(IGlass)); + thisConstruct.rbBareSolDiff(IGlass) = DiffuseAverage(rbBareSolPhi(IGlass)); + thisConstruct.rbBareVisDiff(IGlass) = DiffuseAverage(rbBareVisPhi(IGlass)); thisConstruct.afBareSolDiff(IGlass) = max(0.0, 1.0 - (thisConstruct.tBareSolDiff(IGlass) + thisConstruct.rfBareSolDiff(IGlass))); thisConstruct.abBareSolDiff(IGlass) = max(0.0, 1.0 - (thisConstruct.tBareSolDiff(IGlass) + thisConstruct.rbBareSolDiff(IGlass))); } @@ -858,10 +858,10 @@ namespace Window { // The glazing system properties include the effect of inter-reflection among glass layers, // but exclude the effect of a shade or blind if present in the construction. // When a construction has a layer = SpectralAndAngle, the 10 degree increment will be overridden. - for (int IPhi = 1; IPhi <= TotalIPhi; ++IPhi) { - Phi = double(IPhi - 1) * 10.0; - CosPhi = std::cos(Phi * Constant::DegToRadians); - if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0; + for (int iPhi = 0; iPhi < TotalIPhi; ++iPhi) { + // Real64 Phi = double(iPhi) * 10.0; + // Real64 CosPhi = std::cos(Phi * Constant::DegToRad); + // if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0; // For each wavelength, get glass layer properties at this angle of incidence // from properties at normal incidence @@ -872,7 +872,7 @@ namespace Window { if (matGlass->windowOpticalData != Window::OpticalDataModel::SpectralAndAngle) { for (int ILam = 1; ILam <= numpt[IGlass - 1]; ++ILam) { - TransAndReflAtPhi(CosPhi, + TransAndReflAtPhi(cosPhis[iPhi], t[IGlass - 1][ILam - 1], rff[IGlass - 1][ILam - 1], rbb[IGlass - 1][ILam - 1], @@ -888,9 +888,9 @@ namespace Window { for (int ILam = 1; ILam <= (int)wm->wle.size(); ++ILam) { Real64 lam = wm->wle[ILam - 1]; wlt[IGlass - 1][ILam - 1] = lam; - tPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngTransDataPtr, Phi, lam); - rfPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngFRefleDataPtr, Phi, lam); - rbPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngBRefleDataPtr, Phi, lam); + tPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngTransDataPtr, iPhi * dPhiDeg, lam); + rfPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngFRefleDataPtr, iPhi * dPhiDeg, lam); + rbPhi[IGlass - 1][ILam - 1] = Curve::CurveValue(state, matGlass->GlassSpecAngBRefleDataPtr, iPhi * dPhiDeg, lam); } } } @@ -912,14 +912,14 @@ namespace Window { for (int j = 1; j <= nume; ++j) { sabsPhi(j) = saPhi(IGlass, j); } - solabsBackPhi(IGlass, IPhi) = solarSpectrumAverage(state, sabsPhi); + solabsBackPhi(IGlass)[iPhi] = solarSpectrumAverage(state, sabsPhi); } } // End of loop over incidence angles for back calculation for (int IGlass = 1; IGlass <= NGlass; ++IGlass) { IGlassBack = NGlass - IGlass + 1; - thisConstruct.AbsDiffBack(IGlass) = DiffuseAverage(solabsBackPhi(IGlassBack, {1, 10})); + thisConstruct.AbsDiffBack(IGlass) = DiffuseAverage(solabsBackPhi(IGlassBack)); } //----------------------------------------------------------------------- @@ -957,13 +957,13 @@ namespace Window { ShadeReflFacVis = 1.0 / (1.0 - ShadeReflVis * constr.ReflectVisDiffBack); // Front incident solar, beam, interior shade - for (int IPhi = 1; IPhi <= 10; ++IPhi) { + for (int iPhi = 0; iPhi < TotalIPhi; ++iPhi) { for (int IGlass = 1; IGlass <= NGlass; ++IGlass) { - solabsPhi(IGlass, IPhi) += tsolPhi(IPhi) * ShadeRefl * ShadeReflFac * constr.AbsDiffBack(IGlass); + solabsPhi(IGlass)[iPhi] += tsolPhi[iPhi] * ShadeRefl * ShadeReflFac * constr.AbsDiffBack(IGlass); } - solabsShadePhi(IPhi) = tsolPhi(IPhi) * ShadeReflFac * ShadeAbs; - tsolPhi(IPhi) *= ShadeReflFac * ShadeTrans; - tvisPhi(IPhi) *= ShadeReflFacVis * ShadeTransVis; + solabsShadePhi[iPhi] = tsolPhi[iPhi] * ShadeReflFac * ShadeAbs; + tsolPhi[iPhi] *= ShadeReflFac * ShadeTrans; + tvisPhi[iPhi] *= ShadeReflFacVis * ShadeTransVis; } // Front incident solar, diffuse, interior shade @@ -1006,13 +1006,13 @@ namespace Window { ShadeReflFac = 1.0 / (1.0 - ShadeRefl * constr.ReflectSolDiffFront); ShadeReflFacVis = 1.0 / (1.0 - ShadeReflVis * constr.ReflectVisDiffFront); - for (int IPhi = 1; IPhi <= 10; ++IPhi) { + for (int iPhi = 0; iPhi < TotalIPhi; ++iPhi) { for (int IGlass = 1; IGlass <= NGlass; ++IGlass) { - solabsPhi(IGlass, IPhi) = ShadeTrans * solabsDiff(IGlass) * ShadeReflFac; + solabsPhi(IGlass)[iPhi] = ShadeTrans * solabsDiff(IGlass) * ShadeReflFac; } - tsolPhi(IPhi) = ShadeTrans * ShadeReflFac * tsolDiff; - tvisPhi(IPhi) = ShadeTransVis * ShadeReflFacVis * tvisDiff; - solabsShadePhi(IPhi) = ShadeAbs * (1.0 + ShadeTrans * ShadeReflFac * constr.ReflectSolDiffFront); + tsolPhi[iPhi] = ShadeTrans * ShadeReflFac * tsolDiff; + tvisPhi[iPhi] = ShadeTransVis * ShadeReflFacVis * tvisDiff; + solabsShadePhi[iPhi] = ShadeAbs * (1.0 + ShadeTrans * ShadeReflFac * constr.ReflectSolDiffFront); } // Front incident solar, diffuse, exterior shade/screen/blind @@ -1074,16 +1074,16 @@ namespace Window { // Front incident solar, beam, between-glass shade, NGlass = 2 - for (int IPhi = 1; IPhi <= 10; ++IPhi) { - t1 = tBareSolPhi(1, IPhi); - t1v = tBareVisPhi(1, IPhi); - af1 = afBareSolPhi(1, IPhi); - ab1 = abBareSolPhi(1, IPhi); - tsolPhi(IPhi) = t1 * (tsh + rsh * rb1 * tsh + tsh * rf2 * rsh) * td2; - tvisPhi(IPhi) = t1v * (tshv + rshv * rb1v * tshv + tshv * rf2v * rshv) * td2v; - solabsShadePhi(IPhi) = t1 * (ash + rsh * rb1 + tsh * rf2) * ash; - solabsPhi(1, IPhi) = af1 + t1 * (rsh + rsh * rb1 * rsh + tsh * rf2 * tsh) * abd1; - solabsPhi(2, IPhi) = t1 * (tsh + rsh * rb1 * tsh + tsh * rf2 * rsh) * afd2; + for (int iPhi = 0; iPhi < TotalIPhi; ++iPhi) { + t1 = tBareSolPhi(1)[iPhi]; + t1v = tBareVisPhi(1)[iPhi]; + af1 = afBareSolPhi(1)[iPhi]; + ab1 = abBareSolPhi(1)[iPhi]; + tsolPhi[iPhi] = t1 * (tsh + rsh * rb1 * tsh + tsh * rf2 * rsh) * td2; + tvisPhi[iPhi] = t1v * (tshv + rshv * rb1v * tshv + tshv * rf2v * rshv) * td2v; + solabsShadePhi[iPhi] = t1 * (ash + rsh * rb1 + tsh * rf2) * ash; + solabsPhi(1)[iPhi] = af1 + t1 * (rsh + rsh * rb1 * rsh + tsh * rf2 * tsh) * abd1; + solabsPhi(2)[iPhi] = t1 * (tsh + rsh * rb1 * tsh + tsh * rf2 * rsh) * afd2; } // End of loop over incidence angles // Front incident solar, diffuse, between-glass shade, NGlass = 2 @@ -1117,23 +1117,23 @@ namespace Window { // Front incident solar, beam, between-glass shade, NGlass = 3 - for (int IPhi = 1; IPhi <= 10; ++IPhi) { - t1 = tBareSolPhi(1, IPhi); - t1v = tBareVisPhi(1, IPhi); - t2 = tBareSolPhi(2, IPhi); - t2v = tBareVisPhi(2, IPhi); - af1 = afBareSolPhi(1, IPhi); - af2 = afBareSolPhi(2, IPhi); - ab1 = abBareSolPhi(1, IPhi); - ab2 = abBareSolPhi(2, IPhi); + for (int iPhi = 0; iPhi < TotalIPhi; ++iPhi) { + t1 = tBareSolPhi(1)[iPhi]; + t1v = tBareVisPhi(1)[iPhi]; + t2 = tBareSolPhi(2)[iPhi]; + t2v = tBareVisPhi(2)[iPhi]; + af1 = afBareSolPhi(1)[iPhi]; + af2 = afBareSolPhi(2)[iPhi]; + ab1 = abBareSolPhi(1)[iPhi]; + ab2 = abBareSolPhi(2)[iPhi]; rbmf2 = max(0.0, 1.0 - (t2 + af2)); - tsolPhi(IPhi) = t1 * t2 * (tsh + tsh * rf3 * rsh + rsh * td2 * rb1 * td2 * tsh + rsh * rb2 * tsh) * td3; - tvisPhi(IPhi) = t1v * t2v * (tshv + tshv * rf3v * rshv + rshv * td2v * rb1v * td2v * tshv + rshv * rb2v * tshv) * td3v; - solabsShadePhi(IPhi) = t1 * t2 * (1 + rsh * td2 * rb1 * td2 + rsh * rb2) * ash; - solabsPhi(1, IPhi) = af1 + rbmf2 * ab1 + t1 * t2 * rsh * (1 + rf3 * tsh + rb2 * rsh + td2 * rb1 * td2 * rsh) * td2 * abd1; - solabsPhi(2, IPhi) = t1 * af2 + t1 * t2 * ((rsh + tsh * rf3 * tsh + rsh * rb2 * rsh) * abd2 + rsh * td2 * rb1 * afd2); - solabsPhi(3, IPhi) = t1 * t2 * (tsh + rsh * (rb2 * tsh + td2 * rb2 * td2 * tsh + rf3 * rsh)) * afd3; + tsolPhi[iPhi] = t1 * t2 * (tsh + tsh * rf3 * rsh + rsh * td2 * rb1 * td2 * tsh + rsh * rb2 * tsh) * td3; + tvisPhi[iPhi] = t1v * t2v * (tshv + tshv * rf3v * rshv + rshv * td2v * rb1v * td2v * tshv + rshv * rb2v * tshv) * td3v; + solabsShadePhi[iPhi] = t1 * t2 * (1 + rsh * td2 * rb1 * td2 + rsh * rb2) * ash; + solabsPhi(1)[iPhi] = af1 + rbmf2 * ab1 + t1 * t2 * rsh * (1 + rf3 * tsh + rb2 * rsh + td2 * rb1 * td2 * rsh) * td2 * abd1; + solabsPhi(2)[iPhi] = t1 * af2 + t1 * t2 * ((rsh + tsh * rf3 * tsh + rsh * rb2 * rsh) * abd2 + rsh * td2 * rb1 * afd2); + solabsPhi(3)[iPhi] = t1 * t2 * (tsh + rsh * (rb2 * tsh + td2 * rb2 * td2 * tsh + rf3 * rsh)) * afd3; } // End of loop over incidence angle // Front incident solar, diffuse, between-glass shade, NGlass = 3 @@ -1438,44 +1438,38 @@ namespace Window { // visible transmittance as polynomials in cosine of incidence angle if (!BlindOn && !ScreenOn) { // Bare glass or shade on - W5LsqFit(CosPhiIndepVar, tsolPhi, 6, 1, TotalIPhi, thisConstruct.TransSolBeamCoef); - W5LsqFit(CosPhiIndepVar, rfsolPhi, 6, 1, TotalIPhi, thisConstruct.ReflSolBeamFrontCoef); - W5LsqFit(CosPhiIndepVar, rbsolPhi, 6, 1, TotalIPhi, thisConstruct.ReflSolBeamBackCoef); - W5LsqFit(CosPhiIndepVar, tvisPhi, 6, 1, TotalIPhi, thisConstruct.TransVisBeamCoef); - Array1D DepVarCurveFit(TotalIPhi); - Array1D CoeffsCurveFit(6); + W5LsqFit(cosPhis, tsolPhi, thisConstruct.TransSolBeamCoef); + W5LsqFit(cosPhis, rfsolPhi, thisConstruct.ReflSolBeamFrontCoef); + W5LsqFit(cosPhis, rbsolPhi, thisConstruct.ReflSolBeamBackCoef); + W5LsqFit(cosPhis, tvisPhi, thisConstruct.TransVisBeamCoef); for (int IGlass = 1; IGlass <= NGlass; ++IGlass) { // Front absorptance coefficients for glass layers - DepVarCurveFit = solabsPhi(IGlass, {1, TotalIPhi}); - W5LsqFit(CosPhiIndepVar, DepVarCurveFit, 6, 1, TotalIPhi, CoeffsCurveFit); - thisConstruct.AbsBeamCoef(IGlass) = CoeffsCurveFit; + W5LsqFit(cosPhis, solabsPhi(IGlass), thisConstruct.AbsBeamCoef(IGlass)); + // Back absorptance coefficients for glass layers IGlassBack = NGlass - IGlass + 1; - DepVarCurveFit = solabsBackPhi(IGlassBack, {1, TotalIPhi}); - W5LsqFit(CosPhiIndepVar, DepVarCurveFit, 6, 1, TotalIPhi, CoeffsCurveFit); - thisConstruct.AbsBeamBackCoef(IGlass) = CoeffsCurveFit; + W5LsqFit(cosPhis, solabsBackPhi(IGlassBack), thisConstruct.AbsBeamBackCoef(IGlass)); } // To check goodness of fit //Tuned - for (int IPhi = 1; IPhi <= TotalIPhi; ++IPhi) { - tsolPhiFit(IPhi) = 0.0; - tvisPhiFit(IPhi) = 0.0; - - Phi = double(IPhi - 1) * 10.0; - CosPhi = std::cos(Phi * Constant::DegToRadians); - if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0; - Real64 cos_pow(1.0); - for (int CoefNum = 1; CoefNum <= 6; ++CoefNum) { - cos_pow *= CosPhi; - tsolPhiFit(IPhi) += thisConstruct.TransSolBeamCoef(CoefNum) * cos_pow; - tvisPhiFit(IPhi) += thisConstruct.TransVisBeamCoef(CoefNum) * cos_pow; + for (int iPhi = 0; iPhi < TotalIPhi; ++iPhi) { + tsolPhiFit[iPhi] = 0.0; + tvisPhiFit[iPhi] = 0.0; + + // Real64 Phi = double(iPhi) * 10.0; + // Real64 CosPhi = std::cos(Phi * Constant::DegToRad); + // if (std::abs(CosPhi) < 0.0001) CosPhi = 0.0; + + for (int CoefNum = 0; CoefNum < DataSurfaces::MaxPolyCoeff; ++CoefNum) { + tsolPhiFit[iPhi] += thisConstruct.TransSolBeamCoef[CoefNum] * cosPhis[iPhi]; + tvisPhiFit[iPhi] += thisConstruct.TransVisBeamCoef[CoefNum] * cosPhis[iPhi]; } } } - if (ShadeOn) W5LsqFit(CosPhiIndepVar, solabsShadePhi, 6, 1, TotalIPhi, thisConstruct.AbsBeamShadeCoef); + if (ShadeOn) W5LsqFit(cosPhis, solabsShadePhi, thisConstruct.AbsBeamShadeCoef); } // End of loop over constructions @@ -1604,28 +1598,28 @@ namespace Window { auto &s_mat = state.dataMaterial; auto &s_surf = state.dataSurface; - for (int ConstrNum = 1; ConstrNum <= state.dataHeatBal->TotConstructs; ++ConstrNum) { - auto &thisConstruct = state.dataConstruction->Construct(ConstrNum); - if (thisConstruct.FromWindow5DataFile) continue; - if (thisConstruct.WindowTypeBSDF) continue; - thisConstruct.TransDiff = 0.0; - thisConstruct.TransDiffVis = 0.0; - thisConstruct.AbsDiffBackShade = 0.0; - thisConstruct.ShadeAbsorpThermal = 0.0; - thisConstruct.ReflectSolDiffBack = 0.0; - thisConstruct.ReflectSolDiffFront = 0.0; - thisConstruct.ReflectVisDiffFront = 0.0; - thisConstruct.AbsBeamShadeCoef = 0.0; - thisConstruct.TransSolBeamCoef = 0.0; - thisConstruct.ReflSolBeamFrontCoef = 0.0; - thisConstruct.ReflSolBeamBackCoef = 0.0; - thisConstruct.TransVisBeamCoef = 0.0; - thisConstruct.AbsDiff = 0.0; - thisConstruct.AbsDiffBack = 0.0; + for (auto &constr : state.dataConstruction->Construct) { + if (constr.FromWindow5DataFile) continue; + if (constr.WindowTypeBSDF) continue; + constr.TransDiff = 0.0; + constr.TransDiffVis = 0.0; + constr.AbsDiffBackShade = 0.0; + constr.ShadeAbsorpThermal = 0.0; + constr.ReflectSolDiffBack = 0.0; + constr.ReflectSolDiffFront = 0.0; + constr.ReflectVisDiffFront = 0.0; + + std::fill(constr.AbsBeamShadeCoef.begin(), constr.AbsBeamShadeCoef.end(), 0.0); + std::fill(constr.TransSolBeamCoef.begin(), constr.TransSolBeamCoef.end(), 0.0); + std::fill(constr.ReflSolBeamFrontCoef.begin(), constr.ReflSolBeamFrontCoef.end(), 0.0); + std::fill(constr.ReflSolBeamBackCoef.begin(), constr.ReflSolBeamBackCoef.begin(), 0.0); + std::fill(constr.TransVisBeamCoef.begin(), constr.TransVisBeamCoef.end(), 0.0); + constr.AbsDiff = 0.0; + constr.AbsDiffBack = 0.0; for (int Layer = 1; Layer <= state.dataHeatBal->MaxSolidWinLayers; ++Layer) { - for (int index = 1; index <= DataSurfaces::MaxPolyCoeff; ++index) { - state.dataConstruction->Construct(state.dataHeatBal->TotConstructs).AbsBeamCoef(Layer)(index) = 0.0; - state.dataConstruction->Construct(state.dataHeatBal->TotConstructs).AbsBeamBackCoef(Layer)(index) = 0.0; + for (int index = 0; index < DataSurfaces::MaxPolyCoeff; ++index) { + state.dataConstruction->Construct(state.dataHeatBal->TotConstructs).AbsBeamCoef(Layer)[index] = 0.0; + state.dataConstruction->Construct(state.dataHeatBal->TotConstructs).AbsBeamBackCoef(Layer)[index] = 0.0; } } } @@ -5452,7 +5446,7 @@ namespace Window { } // InterpolateBetweenFourValues() //************************************************************************** - +#ifdef GET_OUT void W5LsqFit(Array1S const IndepVar, // Independent variables Array1S const DepVar, // Dependent variables int const N, // Order of polynomial @@ -5538,7 +5532,87 @@ namespace Window { --L; } } // W5LsqFit() +#endif // GET_OUT + + void W5LsqFit(std::array const &ivars, // Independent variables + std::array const &dvars, // Dependent variables + std::array &coeffs // Polynomial coefficients from fit + ) + { + + // SUBROUTINE INFORMATION: + // AUTHOR George Walton + // DATE WRITTEN April 1976 + // MODIFIED November 1999 F.Winkelmann + // RE-ENGINEERED na + // PURPOSE OF THIS SUBROUTINE: + // Does least squares fit for coefficients of a polynomial + // that gives a window property, such as transmittance, as a function of + // the cosine of the angle of incidence. The polynomial is of the + // form C1*X + C2*X**2 + C3*X**3 + ... +CN*X**N, where N <= 6. + // Adapted from BLAST subroutine LSQFIT. + + std::array, DataSurfaces::MaxPolyCoeff> A; // Least squares derivative matrix + std::array B; // Least squares derivative vector + std::array, DataSurfaces::MaxPolyCoeff> D; // Powers of independent variable + + // Set up least squares matrix + for (int M = 0; M < numPhis; ++M) { + D[0][M] = ivars[M]; + } + + for (int i = 1; i < DataSurfaces::MaxPolyCoeff; ++i) { + for (int M = 0; M < numPhis; ++M) { + D[i][M] = D[i - 1][M] * ivars[M]; + } + } + + for (int i = 0; i < DataSurfaces::MaxPolyCoeff; ++i) { + Real64 SUM = 0.0; + for (int M = 0; M < numPhis; ++M) { + SUM += dvars[M] * D[i][M]; + } + B[i] = SUM; + for (int j = 0; j < DataSurfaces::MaxPolyCoeff; ++j) { + Real64 SUM2 = 0.0; + for (int M = 0; M < numPhis; ++M) { + SUM2 += D[i][M] * D[j][M]; + } + A[j][i] = SUM2; + A[i][j] = SUM2; + } + } + + // Solve the simultaneous equations using Gauss elimination + int order1 = DataSurfaces::MaxPolyCoeff - 1; + for (int K = 0; K < order1; ++K) { + int KP1 = K + 1; + for (int i = KP1; i < DataSurfaces::MaxPolyCoeff; ++i) { + Real64 ACON = A[K][i] / A[K][K]; + B[i] -= B[K] * ACON; + for (int j = K; j < DataSurfaces::MaxPolyCoeff; ++j) { + A[j][i] -= A[j][K] * ACON; + } + } + } + + // Perform back substitution + coeffs[DataSurfaces::MaxPolyCoeff-1] = B[DataSurfaces::MaxPolyCoeff-1] / A[DataSurfaces::MaxPolyCoeff-1][DataSurfaces::MaxPolyCoeff-1]; + int LP1 = DataSurfaces::MaxPolyCoeff - 1; + int L = DataSurfaces::MaxPolyCoeff - 2; + + while (L >= 0) { + Real64 SUM = 0.0; + for (int j = LP1; j < DataSurfaces::MaxPolyCoeff; ++j) { + SUM += A[j][L] * coeffs[j]; + } + coeffs[L] = (B[L] - SUM) / A[L][L]; + LP1 = L; + --L; + } + } // W5LsqFit() + //******************************************************************************** void W5LsqFit2(Array1A const IndepVar, // Independent variables @@ -5634,7 +5708,7 @@ namespace Window { } // W5LsqFit2() //*********************************************************************** - +#ifdef GET_OUT Real64 DiffuseAverage(Array1S const PropertyValue) // Property value at angles of incidence { @@ -5661,18 +5735,50 @@ namespace Window { // SUBROUTINE ARGUMENT DEFINITIONS: // 0,10,20,...,80,90 degrees - Real64 const DPhiR(10.0 * Constant::DegToRadians); // Half of 10-deg incidence angle increment (radians) - DiffuseAverage = 0.0; for (int IPhi = 1; IPhi <= 9; ++IPhi) { DiffuseAverage += - 0.5 * DPhiR * (PropertyValue(IPhi) * std::sin(2.0 * (IPhi - 1) * DPhiR) + PropertyValue(IPhi + 1) * std::sin(2.0 * IPhi * DPhiR)); + 0.5 * DPhiR * (PropertyValue(IPhi) * std::sin(2.0 * (IPhi - 1) * dPhiRad) + PropertyValue(IPhi + 1) * std::sin(2.0 * IPhi * dPhiRad)); } if (DiffuseAverage < 0.0) DiffuseAverage = 0.0; return DiffuseAverage; } // DiffuseAverage() +#endif // GET_OUT + + Real64 DiffuseAverage(std::array const &props) // Property value at angles of incidence + { + + // FUNCTION INFORMATION: + // AUTHOR Fred Winkelmann + // DATE WRITTEN November 1999 + // MODIFIED na + // RE-ENGINEERED na + // PURPOSE OF THIS FUNCTION: + // Calculate value of property, such as transmittance, for hemispherical + // diffuse radiation from property values at angles of incidence from + // 0 to 90 degrees in 10 degree increments. + + // METHODOLOGY EMPLOYED: + // By Simpson's rule, evaluates the integral from 0 to 90 deg of + // 2*PropertyValue(phi)*cos(phi)*sin(phi)*dphi (which is same as + // PropertyValue(phi)*sin(2*phi)*dphi) + + // Locals + // SUBROUTINE ARGUMENT DEFINITIONS: + // 0,10,20,...,80,90 degrees + + constexpr Real64 dPhiR = dPhiDeg * Constant::DegToRad; // Half of 10-deg incidence angle increment (radians) + + Real64 avg = 0.0; + for (int iPhi = 0; iPhi < numPhis - 1; ++iPhi) { + avg += 0.5 * dPhiR * (props[iPhi] * std::sin(2.0 * iPhi * dPhiR) + props[iPhi + 1] * std::sin(2.0 * (iPhi + 1) * dPhiR)); + } + + return (avg < 0.0) ? 0.0 : avg; + } // DiffuseAverage() + //************************************************************************************* void CalcWinFrameAndDividerTemps(EnergyPlusData &state, @@ -7673,7 +7779,6 @@ namespace Window { c.dim(15); p.dim(16); - Array1D fEdgeSource(10); // Slat edge correction factor vs source elevation Array1D fEdgeA(2); // Average slat edge correction factor for upper and lower quadrants // seen by window blind Array1D j(6); // Slat section radiosity vector @@ -7766,7 +7871,6 @@ namespace Window { } // Irradiances - for (int k = 1; k <= 6; ++k) { G(k) = 0.0; for (int m = 1; m <= 6; ++m) { @@ -7776,13 +7880,16 @@ namespace Window { } // Slat edge correction factor + std::array fEdgeSource; // Slat edge correction factor vs source elevation + Real64 const phib = b_el; // Elevation of slat normal vector (radians) - Real64 constexpr delphis = Constant::PiOvr2 / 10.0; // Angle increment for integration over source distribution (radians) + Real64 constexpr delphis = Constant::PiOvr2 / 10.0; // Angle increment for integration over source distribution (radians) // This is a bug, the delta is 10.0, PiOvr2/10.0 is 9.0. + for (int IUpDown = 1; IUpDown <= 2; ++IUpDown) { - for (int Iphis = 1; Iphis <= 10; ++Iphis) { - Real64 phis = -(Iphis - 0.5) * delphis; // Source elevation (radians) - if (IUpDown == 2) phis = (Iphis - 0.5) * delphis; - fEdgeSource(Iphis) = 0.0; + for (int iPhi = 0; iPhi < numPhis; ++iPhi) { + Real64 phis = -((double)iPhi + 0.5) * delphis; // Source elevation (radians) + if (IUpDown == 2) phis = ((double)iPhi + 0.5) * delphis; + fEdgeSource[iPhi] = 0.0; Real64 fEdge1 = 0.0; Real64 gamma = phib - phis; if (std::abs(std::sin(gamma)) > 0.01) { @@ -7791,7 +7898,7 @@ namespace Window { fEdge1 = matBlind->SlatThickness * std::abs(std::sin(gamma)) / ((matBlind->SlatSeparation + matBlind->SlatThickness / std::abs(std::sin(phib))) * std::cos(phis)); } - fEdgeSource(Iphis) = min(1.0, std::abs(fEdge1)); + fEdgeSource[iPhi] = min(1.0, std::abs(fEdge1)); } } fEdgeA(IUpDown) = DiffuseAverage(fEdgeSource); diff --git a/src/EnergyPlus/WindowManager.hh b/src/EnergyPlus/WindowManager.hh index 730049a628d..68fd287d7c7 100644 --- a/src/EnergyPlus/WindowManager.hh +++ b/src/EnergyPlus/WindowManager.hh @@ -52,7 +52,6 @@ #include #include #include -#include // EnergyPlus Headers #include @@ -75,9 +74,16 @@ namespace Window { int constexpr maxGlassLayers = 5; int constexpr maxGapLayers = 5; - int constexpr maxIncidentAngles = 20; int constexpr maxSpectralDataElements = 800; // Maximum number in Spectral Data arrays. + int constexpr numPhis = 10; + Real64 constexpr dPhiDeg = 10.0; + Real64 constexpr dPhiRad = dPhiDeg * Constant::DegToRad; + + constexpr std::array cosPhis = + {1.0, 0.98480775301220802, 0.93969262078590842, 0.86602540378443871, 0.76604444311897812, + 0.64278760968653936, 0.50000000000000011, 0.34202014332566882, 0.17364817766693041, 6.123233995736766E-17}; + class CWindowModel; class CWindowOpticalModel; class CWindowConstructionsSimplified; @@ -277,14 +283,12 @@ namespace Window { Real64 InterpolateBetweenFourValues( Real64 X, Real64 Y, Real64 X1, Real64 X2, Real64 Y1, Real64 Y2, Real64 Fx1y1, Real64 Fx1y2, Real64 Fx2y1, Real64 Fx2y2); - void W5LsqFit(Array1S IndepVar, // Independent variables - Array1S DepVar, // Dependent variables - int N, // Order of polynomial - int N1, // First and last data points used - int N2, - Array1S CoeffsCurve // Polynomial coeffients from fit + void W5LsqFit(std::array const &ivars, // Independent variables + std::array const &dvars, // Dependent variables + std::array &coeffs // Polynomial coeffients from fit ); +#ifdef GET_OUT void W5LsqFit2(Array1A IndepVar, // Independent variables Array1A DepVar, // Dependent variables int N, // Order of polynomial @@ -294,6 +298,9 @@ namespace Window { ); Real64 DiffuseAverage(Array1S PropertyValue); // Property value at angles of incidence +#endif // GET_OUT + + Real64 DiffuseAverage(std::array const &props); // Property value at angles of incidence Real64 DiffuseAverageProfAngGnd(Array1S Property); // Property value vs. profile angle diff --git a/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc b/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc index dbb84bbd90a..9d39f32e09b 100644 --- a/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc +++ b/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc @@ -4909,10 +4909,13 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_IncSolarMultiplier) int ConstrNum = 1; state->dataSurface->Surface(SurfNum).Construction = ConstrNum; + auto &constr = state->dataConstruction->Construct(ConstrNum); + state->dataSurface->SurfActiveConstruction(SurfNum) = state->dataSurface->Surface(SurfNum).Construction; state->dataConstruction->Construct(ConstrNum).TransDiff = 0.1; - state->dataConstruction->Construct(ConstrNum).TransSolBeamCoef = 0.1; - state->dataConstruction->Construct(ConstrNum).TransSolBeamCoef = 0.2; + // Why is this being written and immediately overwritten? + std::fill(constr.TransSolBeamCoef.begin(), constr.TransSolBeamCoef.end(), 0.1); + std::fill(constr.TransSolBeamCoef.begin(), constr.TransSolBeamCoef.end(), 0.2); state->dataSurface->SurfaceWindow.allocate(totSurf); state->dataSurface->SurfaceWindow(SurfNum).OutProjSLFracMult[state->dataGlobal->HourOfDay] = 999.0; diff --git a/tst/EnergyPlus/unit/SolarShading.unit.cc b/tst/EnergyPlus/unit/SolarShading.unit.cc index 23d8830f682..26d993ae1e8 100644 --- a/tst/EnergyPlus/unit/SolarShading.unit.cc +++ b/tst/EnergyPlus/unit/SolarShading.unit.cc @@ -5223,7 +5223,7 @@ TEST_F(EnergyPlusFixture, SolarShadingTest_CalcBeamSolarOnWinRevealSurface) construct1.LayerPoint(1) = 1; construct1.Name = "Construction1"; construct1.TotGlassLayers = 1; - construct1.TransSolBeamCoef(1) = 0.9; + construct1.TransSolBeamCoef[0] = 0.9; auto &s_mat = state->dataMaterial; @@ -5250,7 +5250,7 @@ TEST_F(EnergyPlusFixture, SolarShadingTest_CalcBeamSolarOnWinRevealSurface) state->dataHeatBal->SurfSunlitFracWithoutReveal(state->dataGlobal->HourOfDay, state->dataGlobal->TimeStep, 2) = 1.0; Window::W5InitGlassParameters(*state); - construct1.TransSolBeamCoef(1) = 0.9; + construct1.TransSolBeamCoef[0] = 0.9; state->dataSurface->SurfWinTanProfileAngVert(1) = 10.0; state->dataSurface->SurfWinTanProfileAngVert(2) = 10.0; state->dataSurface->SurfWinTanProfileAngHor(1) = 10.0;