diff --git a/src/EnergyPlus/HeatBalanceManager.cc b/src/EnergyPlus/HeatBalanceManager.cc index b47090233c9..b879276ca3b 100644 --- a/src/EnergyPlus/HeatBalanceManager.cc +++ b/src/EnergyPlus/HeatBalanceManager.cc @@ -1362,7 +1362,7 @@ namespace HeatBalanceManager { auto const SELECT_CASE_var(AlphaName(1)); if ((SELECT_CASE_var == "REGULAFALSI")) { HVACSystemRootFinding.HVACSystemRootSolver = DataHVACGlobals::HVACSystemRootSolverAlgorithm::RegulaFalsi; - } else if (SELECT_CASE_var == "BiSECTION") { + } else if (SELECT_CASE_var == "BISECTION") { HVACSystemRootFinding.HVACSystemRootSolver = DataHVACGlobals::HVACSystemRootSolverAlgorithm::Bisection; } else if (SELECT_CASE_var == "BISECTIONTHENREGULAFALSI") { HVACSystemRootFinding.HVACSystemRootSolver = DataHVACGlobals::HVACSystemRootSolverAlgorithm::BisectionThenRegulaFalsi; diff --git a/src/EnergyPlus/MixedAir.cc b/src/EnergyPlus/MixedAir.cc index 9ecf5e6afeb..7c9aa8b23bf 100644 --- a/src/EnergyPlus/MixedAir.cc +++ b/src/EnergyPlus/MixedAir.cc @@ -93,6 +93,7 @@ #include #include #include +#include #include #include #include @@ -458,7 +459,7 @@ namespace MixedAir { OACoolCoil, OAHX); } - // now simulate again propogate current temps back through OA system + // now simulate again propigate current temps back through OA system for (CompNum = 1; CompNum <= OutsideAirSys(OASysNum).NumComponents; ++CompNum) { CompType = OutsideAirSys(OASysNum).ComponentType(CompNum); CompName = OutsideAirSys(OASysNum).ComponentName(CompNum); @@ -599,8 +600,6 @@ namespace MixedAir { using HVACDXSystem::SimDXCoolingSystem; using HVACHXAssistedCoolingCoil::HXAssistedCoil; using HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil; - using PhotovoltaicThermalCollectors::CalledFromOutsideAirSystem; - using PhotovoltaicThermalCollectors::SimPVTcollectors; using SimAirServingZones::SolveWaterCoilController; using SteamCoils::SimulateSteamCoilComponents; using TranspiredCollector::SimTranspiredCollector; @@ -831,7 +830,10 @@ namespace MixedAir { // Air-based Photovoltaic-thermal flat plate collector } else if (SELECT_CASE_var == PVT_AirBased) { // 'SolarCollector:FlatPlate:PhotovoltaicThermal' if (Sim) { - SimPVTcollectors(CompIndex, FirstHVACIteration, CalledFromOutsideAirSystem, CompName); + if (CompIndex == 0) { + CompIndex = PhotovoltaicThermalCollectors::getPVTindexFromName(CompName); + } + PhotovoltaicThermalCollectors::simPVTfromOASys(CompIndex, FirstHVACIteration); } // Evaporative Cooler Types diff --git a/src/EnergyPlus/PhotovoltaicThermalCollectors.cc b/src/EnergyPlus/PhotovoltaicThermalCollectors.cc index 36d045df15f..2807fe7bdb9 100644 --- a/src/EnergyPlus/PhotovoltaicThermalCollectors.cc +++ b/src/EnergyPlus/PhotovoltaicThermalCollectors.cc @@ -55,8 +55,6 @@ // EnergyPlus Headers #include #include -#include -#include #include #include #include @@ -64,7 +62,6 @@ #include #include #include -#include #include #include #include @@ -74,8 +71,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -99,139 +96,64 @@ namespace PhotovoltaicThermalCollectors { // METHODOLOGY EMPLOYED: // The approach is to have one PVT structure that works with different models. - // the PVT modle reuses photovoltaic modeling in Photovoltaics.cc for electricity generation. + // the PVT model reuses photovoltaic modeling in Photovoltaics.cc for electricity generation. // the electric load center and "generator" is all accessed thru PV objects and models. // this module is for the thermal portion of PVT. // the first model is a "simple" or "ideal" model useful for sizing, early design, or policy analyses // Simple PV/T model just converts incoming solar to electricity and temperature rise of a working fluid. - // REFERENCES: - - // OTHER NOTES: - // na - - // Using/Aliasing - using namespace DataPrecisionGlobals; - using namespace DataGlobals; - using DataSurfaces::Surface; - using DataSurfaces::SurfaceClass_Detached_B; - using DataSurfaces::SurfaceClass_Detached_F; - using DataSurfaces::SurfaceClass_Shading; - using DataSurfaces::SurfSunlitArea; - using DataSurfaces::SurfSunlitFrac; - using DataSurfaces::TotSurfaces; - using namespace DataPhotovoltaics; - - // Data - // MODULE PARAMETER DEFINITIONS: int const SimplePVTmodel(1001); - int const LayerByLayerPVTmodel(1002); - - int const ScheduledThermEffic(15); // mode for thermal efficiency is to use schedule - int const FixedThermEffic(16); // mode for thermal efficiency is to use fixed value - - int const LiquidWorkingFluid(1); - int const AirWorkingFluid(2); - - int const CalledFromPlantLoopEquipMgr(101); - int const CalledFromOutsideAirSystem(102); Real64 const SimplePVTWaterSizeFactor(1.905e-5); // [ m3/s/m2 ] average of collectors in SolarCollectors.idf - static std::string const BlankString; static bool GetInputFlag(true); // First time, input is "gotten" - // DERIVED TYPE DEFINITIONS: - - // MODULE VARIABLE DECLARATIONS: - Array1D_bool CheckEquipName; - int NumPVT(0); // count of all types of PVT in input file - int NumSimplePVTPerform(0); // count of simple PVT performance objects in input file + int NumPVT(0); // count of all types of PVT in input file - // SUBROUTINE SPECIFICATIONS FOR MODULE: - // Driver/Manager Routines - - // Utility routines for module - // these would be public such as: - // PUBLIC GetPVTIncidentSolarForInternalPVLayer - // PUBLIC GetPVTCellTemp - - // Object Data Array1D PVT; - // Functions - - void SimPVTcollectors(int &PVTnum, // index to PVT array. - bool const FirstHVACIteration, - int const CalledFrom, - Optional_string_const PVTName, - Optional_bool_const InitLoopEquip) + void clear_state() { + GetInputFlag = true; + NumPVT = 0; + PVT.deallocate(); + } - // SUBROUTINE INFORMATION: - // AUTHOR - // DATE WRITTEN - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // - - // Using/Aliasing - using General::TrimSigDigits; - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - + PlantComponent *PVTCollectorStruct::factory(std::string const &objectName) + { if (GetInputFlag) { GetPVTcollectorsInput(); GetInputFlag = false; } - if (present(PVTName)) { - if (PVTnum == 0) { - PVTnum = UtilityRoutines::FindItemInList(PVTName, PVT); - if (PVTnum == 0) { - ShowFatalError("SimPVTcollectors: Unit not found=" + PVTName()); - } - } else { - if (PVTnum > NumPVT || PVTnum < 1) { - ShowFatalError("SimPVTcollectors: Invalid PVT index passed = " + TrimSigDigits(PVTnum) + - ", Number of PVT units=" + TrimSigDigits(NumPVT) + ", Entered Unit name=" + PVTName()); - } - if (CheckEquipName(PVTnum)) { - if (PVTName != PVT(PVTnum).Name) { - ShowFatalError("SimPVTcollectors: Invalid PVT index passed = " + TrimSigDigits(PVTnum) + ", Unit name=" + PVTName() + - ", stored name for that index=" + PVT(PVTnum).Name); - } - CheckEquipName(PVTnum) = false; - } - } - } else { - if (PVTnum > NumPVT || PVTnum < 1) { - ShowFatalError("SimPVTcollectors: Invalid PVT index passed = " + TrimSigDigits(PVTnum) + - ", Number of PVT units=" + TrimSigDigits(NumPVT) + ", Entered Unit name=" + PVTName()); - } - } // compName present - - if (present(InitLoopEquip)) { - if (InitLoopEquip) { - InitPVTcollectors(PVTnum, FirstHVACIteration); - SizePVT(PVTnum); - return; + for (auto &thisComp : PVT) { + if (thisComp.Name == objectName) { + return &thisComp; } } - // check where called from and what type of collector this is, return if not right for calling order for speed - if ((PVT(PVTnum).WorkingFluidType == AirWorkingFluid) && (CalledFrom == CalledFromPlantLoopEquipMgr)) return; - if ((PVT(PVTnum).WorkingFluidType == LiquidWorkingFluid) && (CalledFrom == CalledFromOutsideAirSystem)) return; - - InitPVTcollectors(PVTnum, FirstHVACIteration); + // If we didn't find it, fatal + ShowFatalError("Solar Thermal Collector Factory: Error getting inputs for object named: " + objectName); + // Shut up the compiler + return nullptr; + } - ControlPVTcollector(PVTnum); + void PVTCollectorStruct::onInitLoopEquip(const PlantLocation &EP_UNUSED(calledFromLocation)) + { + this->initialize(true); + this->size(); + } - CalcPVTcollectors(PVTnum); + void PVTCollectorStruct::simulate(const PlantLocation &EP_UNUSED(calledFromLocation), + bool const FirstHVACIteration, + Real64 &EP_UNUSED(CurLoad), + bool const EP_UNUSED(RunFlag)) + { - UpdatePVTcollectors(PVTnum); + this->initialize(FirstHVACIteration); + this->control(); + this->calculate(); + this->update(); } void GetPVTcollectorsInput() @@ -246,287 +168,283 @@ namespace PhotovoltaicThermalCollectors { // PURPOSE OF THIS SUBROUTINE: // Get input for PVT objects - // METHODOLOGY EMPLOYED: - // usual E+ methods - - // Using/Aliasing - using namespace DataIPShortCuts; - using namespace DataHeatBalance; - using namespace DataLoopNode; - using BranchNodeConnections::TestCompSet; - using DataEnvironment::StdRhoAir; - using DataSizing::AutoSize; - using General::RoundSigDigits; - using NodeInputManager::GetOnlySingleNode; - using PlantUtilities::RegisterPlantCompDesignFlow; - using ReportSizingManager::ReportSizingOutput; - using ScheduleManager::GetScheduleIndex; - using namespace DataPlant; // DSU - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int Item; // Item to be "gotten" - int NumAlphas; // Number of Alphas for each GetObjectItem call - int NumNumbers; // Number of Numbers for each GetObjectItem call - int IOStatus; // Used in GetObjectItem - static bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine - int SurfNum; // local use only - int ThisParamObj; + int Item; // Item to be "gotten" + int NumAlphas; // Number of Alphas for each GetObjectItem call + int NumNumbers; // Number of Numbers for each GetObjectItem call + int IOStatus; // Used in GetObjectItem + bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine // Object Data Array1D tmpSimplePVTperf; // first load the performance object info into temporary structure - cCurrentModuleObject = "SolarCollectorPerformance:PhotovoltaicThermal:Simple"; - NumSimplePVTPerform = inputProcessor->getNumObjectsFound(cCurrentModuleObject); + DataIPShortCuts::cCurrentModuleObject = "SolarCollectorPerformance:PhotovoltaicThermal:Simple"; + int NumSimplePVTPerform = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); if (NumSimplePVTPerform > 0) { tmpSimplePVTperf.allocate(NumSimplePVTPerform); for (Item = 1; Item <= NumSimplePVTPerform; ++Item) { - inputProcessor->getObjectItem(cCurrentModuleObject, + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, Item, - cAlphaArgs, + DataIPShortCuts::cAlphaArgs, NumAlphas, - rNumericArgs, + DataIPShortCuts::rNumericArgs, NumNumbers, IOStatus, _, - lAlphaFieldBlanks, - cAlphaFieldNames, - cNumericFieldNames); - if (UtilityRoutines::IsNameEmpty(cAlphaArgs(1), cCurrentModuleObject, ErrorsFound)) continue; - - tmpSimplePVTperf(Item).Name = cAlphaArgs(1); - if (UtilityRoutines::SameString(cAlphaArgs(2), "Fixed")) { - tmpSimplePVTperf(Item).ThermEfficMode = FixedThermEffic; - } else if (UtilityRoutines::SameString(cAlphaArgs(2), "Scheduled")) { - tmpSimplePVTperf(Item).ThermEfficMode = ScheduledThermEffic; + DataIPShortCuts::lAlphaFieldBlanks, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + if (UtilityRoutines::IsNameEmpty(DataIPShortCuts::cAlphaArgs(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound)) continue; + + tmpSimplePVTperf(Item).Name = DataIPShortCuts::cAlphaArgs(1); + if (UtilityRoutines::SameString(DataIPShortCuts::cAlphaArgs(2), "Fixed")) { + tmpSimplePVTperf(Item).ThermEfficMode = ThermEfficEnum::FIXED; + } else if (UtilityRoutines::SameString(DataIPShortCuts::cAlphaArgs(2), "Scheduled")) { + tmpSimplePVTperf(Item).ThermEfficMode = ThermEfficEnum::SCHEDULED; } else { - ShowSevereError("Invalid " + cAlphaFieldNames(2) + " = " + cAlphaArgs(2)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(2) + " = " + DataIPShortCuts::cAlphaArgs(2)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } - tmpSimplePVTperf(Item).ThermalActiveFract = rNumericArgs(1); - tmpSimplePVTperf(Item).ThermEffic = rNumericArgs(2); + tmpSimplePVTperf(Item).ThermalActiveFract = DataIPShortCuts::rNumericArgs(1); + tmpSimplePVTperf(Item).ThermEffic = DataIPShortCuts::rNumericArgs(2); - tmpSimplePVTperf(Item).ThermEffSchedNum = GetScheduleIndex(cAlphaArgs(3)); - if ((tmpSimplePVTperf(Item).ThermEffSchedNum == 0) && (tmpSimplePVTperf(Item).ThermEfficMode == ScheduledThermEffic)) { - ShowSevereError("Invalid " + cAlphaFieldNames(3) + " = " + cAlphaArgs(3)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + cAlphaArgs(1)); + tmpSimplePVTperf(Item).ThermEffSchedNum = ScheduleManager::GetScheduleIndex(DataIPShortCuts::cAlphaArgs(3)); + if ((tmpSimplePVTperf(Item).ThermEffSchedNum == 0) && (tmpSimplePVTperf(Item).ThermEfficMode == ThermEfficEnum::SCHEDULED)) { + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(3) + " = " + DataIPShortCuts::cAlphaArgs(3)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } - tmpSimplePVTperf(Item).SurfEmissivity = rNumericArgs(3); + tmpSimplePVTperf(Item).SurfEmissivity = DataIPShortCuts::rNumericArgs(3); } } // NumSimplePVTPerform > 0 // now get main PVT objects - cCurrentModuleObject = "SolarCollector:FlatPlate:PhotovoltaicThermal"; - NumPVT = inputProcessor->getNumObjectsFound(cCurrentModuleObject); + DataIPShortCuts::cCurrentModuleObject = "SolarCollector:FlatPlate:PhotovoltaicThermal"; + NumPVT = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); PVT.allocate(NumPVT); - CheckEquipName.dimension(NumPVT, true); for (Item = 1; Item <= NumPVT; ++Item) { - inputProcessor->getObjectItem(cCurrentModuleObject, + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, Item, - cAlphaArgs, + DataIPShortCuts::cAlphaArgs, NumAlphas, - rNumericArgs, + DataIPShortCuts::rNumericArgs, NumNumbers, IOStatus, _, - lAlphaFieldBlanks, - cAlphaFieldNames, - cNumericFieldNames); - if (UtilityRoutines::IsNameEmpty(cAlphaArgs(1), cCurrentModuleObject, ErrorsFound)) continue; + DataIPShortCuts::lAlphaFieldBlanks, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + if (UtilityRoutines::IsNameEmpty(DataIPShortCuts::cAlphaArgs(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound)) continue; - PVT(Item).Name = cAlphaArgs(1); - PVT(Item).TypeNum = TypeOf_PVTSolarCollectorFlatPlate; // DSU, assigned in DataPlant + PVT(Item).Name = DataIPShortCuts::cAlphaArgs(1); + PVT(Item).TypeNum = DataPlant::TypeOf_PVTSolarCollectorFlatPlate; - PVT(Item).SurfNum = UtilityRoutines::FindItemInList(cAlphaArgs(2), Surface); + PVT(Item).SurfNum = UtilityRoutines::FindItemInList(DataIPShortCuts::cAlphaArgs(2), DataSurfaces::Surface); // check surface if (PVT(Item).SurfNum == 0) { - if (lAlphaFieldBlanks(2)) { - ShowSevereError("Invalid " + cAlphaFieldNames(2) + " = " + cAlphaArgs(2)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + cAlphaArgs(1)); + if (DataIPShortCuts::lAlphaFieldBlanks(2)) { + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(2) + " = " + DataIPShortCuts::cAlphaArgs(2)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1)); ShowContinueError("Surface name cannot be blank."); } else { - ShowSevereError("Invalid " + cAlphaFieldNames(2) + " = " + cAlphaArgs(2)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(2) + " = " + DataIPShortCuts::cAlphaArgs(2)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1)); ShowContinueError("Surface was not found."); } ErrorsFound = true; } else { - // ! Found one -- make sure has right parameters for PVT - SurfNum = PVT(Item).SurfNum; - if (!Surface(PVT(Item).SurfNum).ExtSolar) { - ShowSevereError("Invalid " + cAlphaFieldNames(2) + " = " + cAlphaArgs(2)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + cAlphaArgs(1)); + if (!DataSurfaces::Surface(PVT(Item).SurfNum).ExtSolar) { + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(2) + " = " + DataIPShortCuts::cAlphaArgs(2)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1)); ShowContinueError("Surface must be exposed to solar."); ErrorsFound = true; } // check surface orientation, warn if upside down - if ((Surface(SurfNum).Tilt < -95.0) || (Surface(SurfNum).Tilt > 95.0)) { - ShowWarningError("Suspected input problem with " + cAlphaFieldNames(2) + " = " + cAlphaArgs(2)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + cAlphaArgs(1)); + if ((DataSurfaces::Surface(PVT(Item).SurfNum).Tilt < -95.0) || (DataSurfaces::Surface(PVT(Item).SurfNum).Tilt > 95.0)) { + ShowWarningError("Suspected input problem with " + DataIPShortCuts::cAlphaFieldNames(2) + " = " + DataIPShortCuts::cAlphaArgs(2)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1)); ShowContinueError("Surface used for solar collector faces down"); - ShowContinueError("Surface tilt angle (degrees from ground outward normal) = " + RoundSigDigits(Surface(SurfNum).Tilt, 2)); + ShowContinueError("Surface tilt angle (degrees from ground outward normal) = " + + General::RoundSigDigits(DataSurfaces::Surface(PVT(Item).SurfNum).Tilt, 2)); } } // check surface - if (lAlphaFieldBlanks(3)) { - ShowSevereError("Invalid " + cAlphaFieldNames(3) + " = " + cAlphaArgs(3)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + cAlphaArgs(1)); - ShowContinueError(cAlphaFieldNames(3) + ", name cannot be blank."); + if (DataIPShortCuts::lAlphaFieldBlanks(3)) { + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(3) + " = " + DataIPShortCuts::cAlphaArgs(3)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1)); + ShowContinueError(DataIPShortCuts::cAlphaFieldNames(3) + ", name cannot be blank."); ErrorsFound = true; } else { - PVT(Item).PVTModelName = cAlphaArgs(3); - ThisParamObj = UtilityRoutines::FindItemInList(PVT(Item).PVTModelName, tmpSimplePVTperf); + PVT(Item).PVTModelName = DataIPShortCuts::cAlphaArgs(3); + int ThisParamObj = UtilityRoutines::FindItemInList(PVT(Item).PVTModelName, tmpSimplePVTperf); if (ThisParamObj > 0) { PVT(Item).Simple = tmpSimplePVTperf(ThisParamObj); // entire structure assigned // do one-time setups on input data - PVT(Item).AreaCol = Surface(PVT(Item).SurfNum).Area * PVT(Item).Simple.ThermalActiveFract; + PVT(Item).AreaCol = DataSurfaces::Surface(PVT(Item).SurfNum).Area * PVT(Item).Simple.ThermalActiveFract; PVT(Item).PVTModelType = SimplePVTmodel; } else { - ShowSevereError("Invalid " + cAlphaFieldNames(3) + " = " + cAlphaArgs(3)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + cAlphaArgs(1)); - ShowContinueError(cAlphaFieldNames(3) + ", was not found."); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(3) + " = " + DataIPShortCuts::cAlphaArgs(3)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1)); + ShowContinueError(DataIPShortCuts::cAlphaFieldNames(3) + ", was not found."); ErrorsFound = true; } } - if (allocated(PVarray)) { // then PV input gotten... but don't expect this to be true. - PVT(Item).PVnum = UtilityRoutines::FindItemInList(cAlphaArgs(4), PVarray); + if (allocated(DataPhotovoltaics::PVarray)) { // then PV input gotten... but don't expect this to be true. + PVT(Item).PVnum = UtilityRoutines::FindItemInList(DataIPShortCuts::cAlphaArgs(4), DataPhotovoltaics::PVarray); // check PV if (PVT(Item).PVnum == 0) { - ShowSevereError("Invalid " + cAlphaFieldNames(4) + " = " + cAlphaArgs(4)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(4) + " = " + DataIPShortCuts::cAlphaArgs(4)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } else { - PVT(Item).PVname = cAlphaArgs(4); + PVT(Item).PVname = DataIPShortCuts::cAlphaArgs(4); PVT(Item).PVfound = true; } } else { // no PV or not yet gotten. - PVT(Item).PVname = cAlphaArgs(4); + PVT(Item).PVname = DataIPShortCuts::cAlphaArgs(4); PVT(Item).PVfound = false; } - if (UtilityRoutines::SameString(cAlphaArgs(5), "Water")) { - PVT(Item).WorkingFluidType = LiquidWorkingFluid; - } else if (UtilityRoutines::SameString(cAlphaArgs(5), "Air")) { - PVT(Item).WorkingFluidType = AirWorkingFluid; + if (UtilityRoutines::SameString(DataIPShortCuts::cAlphaArgs(5), "Water")) { + PVT(Item).WorkingFluidType = WorkingFluidEnum::LIQUID; + } else if (UtilityRoutines::SameString(DataIPShortCuts::cAlphaArgs(5), "Air")) { + PVT(Item).WorkingFluidType = WorkingFluidEnum::AIR; } else { - if (lAlphaFieldBlanks(5)) { - ShowSevereError("Invalid " + cAlphaFieldNames(5) + " = " + cAlphaArgs(5)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + cAlphaArgs(1)); - ShowContinueError(cAlphaFieldNames(5) + " field cannot be blank."); + if (DataIPShortCuts::lAlphaFieldBlanks(5)) { + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(5) + " = " + DataIPShortCuts::cAlphaArgs(5)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1)); + ShowContinueError(DataIPShortCuts::cAlphaFieldNames(5) + " field cannot be blank."); } else { - ShowSevereError("Invalid " + cAlphaFieldNames(5) + " = " + cAlphaArgs(5)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(5) + " = " + DataIPShortCuts::cAlphaArgs(5)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1)); } ErrorsFound = true; } - if (PVT(Item).WorkingFluidType == LiquidWorkingFluid) { - PVT(Item).PlantInletNodeNum = GetOnlySingleNode( - cAlphaArgs(6), ErrorsFound, cCurrentModuleObject, cAlphaArgs(1), NodeType_Water, NodeConnectionType_Inlet, 1, ObjectIsNotParent); - PVT(Item).PlantOutletNodeNum = GetOnlySingleNode( - cAlphaArgs(7), ErrorsFound, cCurrentModuleObject, cAlphaArgs(1), NodeType_Water, NodeConnectionType_Outlet, 1, ObjectIsNotParent); - - TestCompSet(cCurrentModuleObject, cAlphaArgs(1), cAlphaArgs(6), cAlphaArgs(7), "Water Nodes"); - - PVT(Item).WLoopSideNum = DemandSupply_No; + if (PVT(Item).WorkingFluidType == WorkingFluidEnum::LIQUID) { + PVT(Item).PlantInletNodeNum = NodeInputManager::GetOnlySingleNode(DataIPShortCuts::cAlphaArgs(6), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + DataIPShortCuts::cAlphaArgs(1), + DataLoopNode::NodeType_Water, + DataLoopNode::NodeConnectionType_Inlet, + 1, + DataLoopNode::ObjectIsNotParent); + PVT(Item).PlantOutletNodeNum = NodeInputManager::GetOnlySingleNode(DataIPShortCuts::cAlphaArgs(7), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + DataIPShortCuts::cAlphaArgs(1), + DataLoopNode::NodeType_Water, + DataLoopNode::NodeConnectionType_Outlet, + 1, + DataLoopNode::ObjectIsNotParent); + + BranchNodeConnections::TestCompSet(DataIPShortCuts::cCurrentModuleObject, + DataIPShortCuts::cAlphaArgs(1), + DataIPShortCuts::cAlphaArgs(6), + DataIPShortCuts::cAlphaArgs(7), + "Water Nodes"); + + PVT(Item).WLoopSideNum = DataPlant::DemandSupply_No; } - if (PVT(Item).WorkingFluidType == AirWorkingFluid) { - PVT(Item).HVACInletNodeNum = GetOnlySingleNode( - cAlphaArgs(8), ErrorsFound, cCurrentModuleObject, cAlphaArgs(1), NodeType_Air, NodeConnectionType_Inlet, 1, ObjectIsNotParent); - PVT(Item).HVACOutletNodeNum = GetOnlySingleNode( - cAlphaArgs(9), ErrorsFound, cCurrentModuleObject, cAlphaArgs(1), NodeType_Air, NodeConnectionType_Outlet, 1, ObjectIsNotParent); - - TestCompSet(cCurrentModuleObject, cAlphaArgs(1), cAlphaArgs(8), cAlphaArgs(9), "Air Nodes"); + if (PVT(Item).WorkingFluidType == WorkingFluidEnum::AIR) { + PVT(Item).HVACInletNodeNum = NodeInputManager::GetOnlySingleNode(DataIPShortCuts::cAlphaArgs(8), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + DataIPShortCuts::cAlphaArgs(1), + DataLoopNode::NodeType_Air, + DataLoopNode::NodeConnectionType_Inlet, + 1, + DataLoopNode::ObjectIsNotParent); + PVT(Item).HVACOutletNodeNum = NodeInputManager::GetOnlySingleNode(DataIPShortCuts::cAlphaArgs(9), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + DataIPShortCuts::cAlphaArgs(1), + DataLoopNode::NodeType_Air, + DataLoopNode::NodeConnectionType_Outlet, + 1, + DataLoopNode::ObjectIsNotParent); + + BranchNodeConnections::TestCompSet(DataIPShortCuts::cCurrentModuleObject, + DataIPShortCuts::cAlphaArgs(1), + DataIPShortCuts::cAlphaArgs(8), + DataIPShortCuts::cAlphaArgs(9), + "Air Nodes"); } - PVT(Item).DesignVolFlowRate = rNumericArgs(1); + PVT(Item).DesignVolFlowRate = DataIPShortCuts::rNumericArgs(1); PVT(Item).SizingInit = true; - if (PVT(Item).DesignVolFlowRate == AutoSize) { + if (PVT(Item).DesignVolFlowRate == DataSizing::AutoSize) { PVT(Item).DesignVolFlowRateWasAutoSized = true; } - if (PVT(Item).DesignVolFlowRate != AutoSize) { + if (PVT(Item).DesignVolFlowRate != DataSizing::AutoSize) { - if (PVT(Item).WorkingFluidType == LiquidWorkingFluid) { - RegisterPlantCompDesignFlow(PVT(Item).PlantInletNodeNum, PVT(Item).DesignVolFlowRate); - } else if (PVT(Item).WorkingFluidType == AirWorkingFluid) { - PVT(Item).MaxMassFlowRate = PVT(Item).DesignVolFlowRate * StdRhoAir; + if (PVT(Item).WorkingFluidType == WorkingFluidEnum::LIQUID) { + PlantUtilities::RegisterPlantCompDesignFlow(PVT(Item).PlantInletNodeNum, PVT(Item).DesignVolFlowRate); + } else if (PVT(Item).WorkingFluidType == WorkingFluidEnum::AIR) { + PVT(Item).MaxMassFlowRate = PVT(Item).DesignVolFlowRate * DataEnvironment::StdRhoAir; } PVT(Item).SizingInit = false; } } - for (Item = 1; Item <= NumPVT; ++Item) { - // electrical production reporting under generator:photovoltaic.... - // only thermal side reported here, + if (ErrorsFound) { + ShowFatalError("Errors found in processing input for photovoltaic thermal collectors"); + } - SetupOutputVariable( - "Generator Produced Thermal Rate", OutputProcessor::Unit::W, PVT(Item).Report.ThermPower, "System", "Average", PVT(Item).Name); - if (PVT(Item).WorkingFluidType == LiquidWorkingFluid) { - SetupOutputVariable("Generator Produced Thermal Energy", - OutputProcessor::Unit::J, - PVT(Item).Report.ThermEnergy, - "System", - "Sum", - PVT(Item).Name, - _, - "SolarWater", - "HeatProduced", - _, - "Plant"); - } else if (PVT(Item).WorkingFluidType == AirWorkingFluid) { - SetupOutputVariable("Generator Produced Thermal Energy", - OutputProcessor::Unit::J, - PVT(Item).Report.ThermEnergy, - "System", - "Sum", - PVT(Item).Name, - _, - "SolarAir", - "HeatProduced", - _, - "System"); - SetupOutputVariable("Generator PVT Fluid Bypass Status", - OutputProcessor::Unit::None, - PVT(Item).Report.BypassStatus, - "System", - "Average", - PVT(Item).Name); - } + if (allocated(tmpSimplePVTperf)) tmpSimplePVTperf.deallocate(); + } - SetupOutputVariable("Generator PVT Fluid Inlet Temperature", - OutputProcessor::Unit::C, - PVT(Item).Report.TinletWorkFluid, - "System", - "Average", - PVT(Item).Name); - SetupOutputVariable("Generator PVT Fluid Outlet Temperature", - OutputProcessor::Unit::C, - PVT(Item).Report.ToutletWorkFluid, + void PVTCollectorStruct::setupReportVars() + { + SetupOutputVariable("Generator Produced Thermal Rate", OutputProcessor::Unit::W, this->Report.ThermPower, "System", "Average", this->Name); + + if (this->WorkingFluidType == WorkingFluidEnum::LIQUID) { + SetupOutputVariable("Generator Produced Thermal Energy", + OutputProcessor::Unit::J, + this->Report.ThermEnergy, "System", - "Average", - PVT(Item).Name); - SetupOutputVariable("Generator PVT Fluid Mass Flow Rate", - OutputProcessor::Unit::kg_s, - PVT(Item).Report.MdotWorkFluid, + "Sum", + this->Name, + _, + "SolarWater", + "HeatProduced", + _, + "Plant"); + + } else if (this->WorkingFluidType == WorkingFluidEnum::AIR) { + SetupOutputVariable("Generator Produced Thermal Energy", + OutputProcessor::Unit::J, + this->Report.ThermEnergy, "System", - "Average", - PVT(Item).Name); - } + "Sum", + this->Name, + _, + "SolarAir", + "HeatProduced", + _, + "System"); - if (ErrorsFound) { - ShowFatalError("Errors found in processing input for photovoltaic thermal collectors"); + SetupOutputVariable( + "Generator PVT Fluid Bypass Status", OutputProcessor::Unit::None, this->Report.BypassStatus, "System", "Average", this->Name); } - if (allocated(tmpSimplePVTperf)) tmpSimplePVTperf.deallocate(); + SetupOutputVariable( + "Generator PVT Fluid Inlet Temperature", OutputProcessor::Unit::C, this->Report.TinletWorkFluid, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator PVT Fluid Outlet Temperature", OutputProcessor::Unit::C, this->Report.ToutletWorkFluid, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator PVT Fluid Mass Flow Rate", OutputProcessor::Unit::kg_s, this->Report.MdotWorkFluid, "System", "Average", this->Name); } - void InitPVTcollectors(int const PVTnum, bool const FirstHVACIteration) + void PVTCollectorStruct::initialize(bool const FirstHVACIteration) { // SUBROUTINE INFORMATION: @@ -538,99 +456,57 @@ namespace PhotovoltaicThermalCollectors { // PURPOSE OF THIS SUBROUTINE: // init for PVT - // Using/Aliasing - using DataGlobals::AnyEnergyManagementSystemInModel; - using DataGlobals::SysSizingCalc; - using DataHeatBalance::QRadSWOutIncident; - using DataHVACGlobals::DoSetPointTest; - using DataHVACGlobals::SetPointErrorFlag; - using DataLoopNode::Node; - using DataLoopNode::SensedNodeFlagValue; - using DataPlant::PlantLoop; - using EMSManager::CheckIfNodeSetPointManagedByEMS; - using EMSManager::iTemperatureSetPoint; - using FluidProperties::GetDensityGlycol; - using General::RoundSigDigits; - using PlantUtilities::InitComponentNodes; - using PlantUtilities::RegisterPlantCompDesignFlow; - using PlantUtilities::ScanPlantLoopsForObject; - using PlantUtilities::SetComponentFlowRate; - - // SUBROUTINE PARAMETER DEFINITIONS: static std::string const RoutineName("InitPVTcollectors"); - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int InletNode; - int OutletNode; - int PVTindex; - int SurfNum; - static bool ErrorsFound(false); - static bool MySetPointCheckFlag(true); - static bool MyOneTimeFlag(true); // one time flag - static Array1D_bool SetLoopIndexFlag; // get loop number flag - bool errFlag; - Real64 rho; // local fluid density kg/s - // Do the one time initializations - if (MyOneTimeFlag) { - SetLoopIndexFlag.dimension(NumPVT, true); - MyOneTimeFlag = false; + if (this->MyOneTimeFlag) { + this->setupReportVars(); + this->MyOneTimeFlag = false; } - if (SetLoopIndexFlag(PVTnum)) { - if (allocated(PlantLoop) && (PVT(PVTnum).PlantInletNodeNum > 0)) { - errFlag = false; - ScanPlantLoopsForObject(PVT(PVTnum).Name, - PVT(PVTnum).TypeNum, - PVT(PVTnum).WLoopNum, - PVT(PVTnum).WLoopSideNum, - PVT(PVTnum).WLoopBranchNum, - PVT(PVTnum).WLoopCompNum, - errFlag, - _, - _, - _, - _, - _); + if (this->SetLoopIndexFlag) { + if (allocated(DataPlant::PlantLoop) && (this->PlantInletNodeNum > 0)) { + bool errFlag = false; + PlantUtilities::ScanPlantLoopsForObject( + this->Name, this->TypeNum, this->WLoopNum, this->WLoopSideNum, this->WLoopBranchNum, this->WLoopCompNum, errFlag, _, _, _, _, _); if (errFlag) { ShowFatalError("InitPVTcollectors: Program terminated for previous conditions."); } - SetLoopIndexFlag(PVTnum) = false; + this->SetLoopIndexFlag = false; } } - // finish set up of PV, becaues PV get-input follows PVT's get input. - if (!PVT(PVTnum).PVfound) { - if (allocated(PVarray)) { - PVT(PVTnum).PVnum = UtilityRoutines::FindItemInList(PVT(PVTnum).PVname, PVarray); - if (PVT(PVTnum).PVnum == 0) { - ShowSevereError("Invalid name for photovoltaic generator = " + PVT(PVTnum).PVname); - ShowContinueError("Entered in flat plate photovoltaic-thermal collector = " + PVT(PVTnum).Name); - ErrorsFound = true; + // finish set up of PV, because PV get-input follows PVT's get input. + if (!this->PVfound) { + if (allocated(DataPhotovoltaics::PVarray)) { + this->PVnum = UtilityRoutines::FindItemInList(this->PVname, DataPhotovoltaics::PVarray); + if (this->PVnum == 0) { + ShowSevereError("Invalid name for photovoltaic generator = " + this->PVname); + ShowContinueError("Entered in flat plate photovoltaic-thermal collector = " + this->Name); } else { - PVT(PVTnum).PVfound = true; + this->PVfound = true; } } else { - if ((!BeginEnvrnFlag) && (!FirstHVACIteration)) { + if ((!DataGlobals::BeginEnvrnFlag) && (!FirstHVACIteration)) { ShowSevereError("Photovoltaic generators are missing for Photovoltaic Thermal modeling"); - ShowContinueError("Needed for flat plate photovoltaic-thermal collector = " + PVT(PVTnum).Name); - ErrorsFound = true; + ShowContinueError("Needed for flat plate photovoltaic-thermal collector = " + this->Name); } } } - if (!SysSizingCalc && MySetPointCheckFlag && DoSetPointTest) { - for (PVTindex = 1; PVTindex <= NumPVT; ++PVTindex) { - if (PVT(PVTindex).WorkingFluidType == AirWorkingFluid) { - if (Node(PVT(PVTindex).HVACOutletNodeNum).TempSetPoint == SensedNodeFlagValue) { - if (!AnyEnergyManagementSystemInModel) { + if (!DataGlobals::SysSizingCalc && this->MySetPointCheckFlag && DataHVACGlobals::DoSetPointTest) { + for (int PVTindex = 1; PVTindex <= NumPVT; ++PVTindex) { + if (PVT(PVTindex).WorkingFluidType == WorkingFluidEnum::AIR) { + if (DataLoopNode::Node(PVT(PVTindex).HVACOutletNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue) { + if (!DataGlobals::AnyEnergyManagementSystemInModel) { ShowSevereError("Missing temperature setpoint for PVT outlet node "); ShowContinueError("Add a setpoint manager to outlet node of PVT named " + PVT(PVTindex).Name); - SetPointErrorFlag = true; + DataHVACGlobals::SetPointErrorFlag = true; } else { // need call to EMS to check node - CheckIfNodeSetPointManagedByEMS(PVT(PVTindex).HVACOutletNodeNum, iTemperatureSetPoint, SetPointErrorFlag); - if (SetPointErrorFlag) { + EMSManager::CheckIfNodeSetPointManagedByEMS( + PVT(PVTindex).HVACOutletNodeNum, EMSManager::iTemperatureSetPoint, DataHVACGlobals::SetPointErrorFlag); + if (DataHVACGlobals::SetPointErrorFlag) { ShowSevereError("Missing temperature setpoint for PVT outlet node "); ShowContinueError("Add a setpoint manager to outlet node of PVT named " + PVT(PVTindex).Name); ShowContinueError(" or use an EMS actuator to establish a setpoint at the outlet node of PVT"); @@ -639,104 +515,99 @@ namespace PhotovoltaicThermalCollectors { } } } - MySetPointCheckFlag = false; + this->MySetPointCheckFlag = false; } - if (!SysSizingCalc && PVT(PVTnum).SizingInit && (PVT(PVTnum).WorkingFluidType == AirWorkingFluid)) { - SizePVT(PVTnum); + if (!DataGlobals::SysSizingCalc && this->SizingInit && (this->WorkingFluidType == WorkingFluidEnum::AIR)) { + this->size(); } + int InletNode = 0; + int OutletNode = 0; + { - auto const SELECT_CASE_var(PVT(PVTnum).WorkingFluidType); - if (SELECT_CASE_var == LiquidWorkingFluid) { - InletNode = PVT(PVTnum).PlantInletNodeNum; - OutletNode = PVT(PVTnum).PlantOutletNodeNum; - } else if (SELECT_CASE_var == AirWorkingFluid) { - InletNode = PVT(PVTnum).HVACInletNodeNum; - OutletNode = PVT(PVTnum).HVACOutletNodeNum; + auto const SELECT_CASE_var(this->WorkingFluidType); + if (SELECT_CASE_var == WorkingFluidEnum::LIQUID) { + InletNode = this->PlantInletNodeNum; + OutletNode = this->PlantOutletNodeNum; + } else if (SELECT_CASE_var == WorkingFluidEnum::AIR) { + InletNode = this->HVACInletNodeNum; + OutletNode = this->HVACOutletNodeNum; + } else { + assert(false); } } - if (BeginEnvrnFlag && PVT(PVTnum).EnvrnInit) { - - PVT(PVTnum).MassFlowRate = 0.0; - PVT(PVTnum).BypassDamperOff = true; - PVT(PVTnum).CoolingUseful = false; - PVT(PVTnum).HeatingUseful = false; - PVT(PVTnum).Simple.LastCollectorTemp = 0.0; - PVT(PVTnum).Simple.CollectorTemp = 0.0; - PVT(PVTnum).Report.ThermEfficiency = 0.0; - PVT(PVTnum).Report.ThermPower = 0.0; - PVT(PVTnum).Report.ThermHeatGain = 0.0; - PVT(PVTnum).Report.ThermHeatLoss = 0.0; - PVT(PVTnum).Report.ThermEnergy = 0.0; - PVT(PVTnum).Report.MdotWorkFluid = 0.0; - PVT(PVTnum).Report.TinletWorkFluid = 0.0; - PVT(PVTnum).Report.ToutletWorkFluid = 0.0; - PVT(PVTnum).Report.BypassStatus = 0.0; + if (DataGlobals::BeginEnvrnFlag && this->EnvrnInit) { + + this->MassFlowRate = 0.0; + this->BypassDamperOff = true; + this->CoolingUseful = false; + this->HeatingUseful = false; + this->Simple.LastCollectorTemp = 0.0; + this->Simple.CollectorTemp = 0.0; + this->Report.ThermEfficiency = 0.0; + this->Report.ThermPower = 0.0; + this->Report.ThermHeatGain = 0.0; + this->Report.ThermHeatLoss = 0.0; + this->Report.ThermEnergy = 0.0; + this->Report.MdotWorkFluid = 0.0; + this->Report.TinletWorkFluid = 0.0; + this->Report.ToutletWorkFluid = 0.0; + this->Report.BypassStatus = 0.0; { - auto const SELECT_CASE_var(PVT(PVTnum).WorkingFluidType); + auto const SELECT_CASE_var(this->WorkingFluidType); - if (SELECT_CASE_var == LiquidWorkingFluid) { + if (SELECT_CASE_var == WorkingFluidEnum::LIQUID) { - rho = GetDensityGlycol(PlantLoop(PVT(PVTnum).WLoopNum).FluidName, - DataGlobals::HWInitConvTemp, - PlantLoop(PVT(PVTnum).WLoopNum).FluidIndex, - RoutineName); + Real64 rho = FluidProperties::GetDensityGlycol(DataPlant::PlantLoop(this->WLoopNum).FluidName, + DataGlobals::HWInitConvTemp, + DataPlant::PlantLoop(this->WLoopNum).FluidIndex, + RoutineName); - PVT(PVTnum).MaxMassFlowRate = PVT(PVTnum).DesignVolFlowRate * rho; + this->MaxMassFlowRate = this->DesignVolFlowRate * rho; - InitComponentNodes(0.0, - PVT(PVTnum).MaxMassFlowRate, - InletNode, - OutletNode, - PVT(PVTnum).WLoopNum, - PVT(PVTnum).WLoopSideNum, - PVT(PVTnum).WLoopBranchNum, - PVT(PVTnum).WLoopCompNum); + PlantUtilities::InitComponentNodes(0.0, + this->MaxMassFlowRate, + InletNode, + OutletNode, + this->WLoopNum, + this->WLoopSideNum, + this->WLoopBranchNum, + this->WLoopCompNum); - PVT(PVTnum).Simple.LastCollectorTemp = 23.0; + this->Simple.LastCollectorTemp = 23.0; - } else if (SELECT_CASE_var == AirWorkingFluid) { - PVT(PVTnum).Simple.LastCollectorTemp = 23.0; + } else if (SELECT_CASE_var == WorkingFluidEnum::AIR) { + this->Simple.LastCollectorTemp = 23.0; } } - PVT(PVTnum).EnvrnInit = false; + this->EnvrnInit = false; } - if (!BeginEnvrnFlag) PVT(PVTnum).EnvrnInit = true; + if (!DataGlobals::BeginEnvrnFlag) this->EnvrnInit = true; { - auto const SELECT_CASE_var(PVT(PVTnum).WorkingFluidType); - - if (SELECT_CASE_var == LiquidWorkingFluid) { - // heating only right now, so control flow requests based on incident solar - SurfNum = PVT(PVTnum).SurfNum; - if (QRadSWOutIncident(SurfNum) > MinIrradiance) { - // IF (FirstHVACIteration) THEN - PVT(PVTnum).MassFlowRate = PVT(PVTnum).MaxMassFlowRate; // DSU - // ENDIF + auto const SELECT_CASE_var(this->WorkingFluidType); + + if (SELECT_CASE_var == WorkingFluidEnum::LIQUID) { + // heating only right now, so control flow requests based on incident solar; + if (DataHeatBalance::QRadSWOutIncident(this->SurfNum) > DataPhotovoltaics::MinIrradiance) { + this->MassFlowRate = this->MaxMassFlowRate; } else { - // IF (FirstHVACIteration) THEN - PVT(PVTnum).MassFlowRate = 0.0; // DSU - // ENDIF + this->MassFlowRate = 0.0; } - // Should we declare a mass flow rate variable in the data structure instead of using node(outlet)%MassFlowRate ? DSU - SetComponentFlowRate(PVT(PVTnum).MassFlowRate, - InletNode, - OutletNode, - PVT(PVTnum).WLoopNum, - PVT(PVTnum).WLoopSideNum, - PVT(PVTnum).WLoopBranchNum, - PVT(PVTnum).WLoopCompNum); // DSU | DSU - } else if (SELECT_CASE_var == AirWorkingFluid) { - PVT(PVTnum).MassFlowRate = Node(InletNode).MassFlowRate; + + PlantUtilities::SetComponentFlowRate( + this->MassFlowRate, InletNode, OutletNode, this->WLoopNum, this->WLoopSideNum, this->WLoopBranchNum, this->WLoopCompNum); + } else if (SELECT_CASE_var == WorkingFluidEnum::AIR) { + this->MassFlowRate = DataLoopNode::Node(InletNode).MassFlowRate; } } } - void SizePVT(int const PVTnum) + void PVTCollectorStruct::size() { // SUBROUTINE INFORMATION: @@ -752,133 +623,85 @@ namespace PhotovoltaicThermalCollectors { // METHODOLOGY EMPLOYED: // Obtains hot water flow rate from the plant sizing array. - // REFERENCES: - // na - - // Using/Aliasing - using namespace DataSizing; - using DataHVACGlobals::Cooling; - using DataHVACGlobals::Heating; - using DataHVACGlobals::Main; - using DataHVACGlobals::Other; - using DataHVACGlobals::SmallWaterVolFlow; - using DataPlant::DemandSide; - using DataPlant::PlantLoop; - using DataPlant::SupplySide; - using PlantUtilities::RegisterPlantCompDesignFlow; - using ReportSizingManager::ReportSizingOutput; - using namespace OutputReportPredefined; - using DataEnvironment::StdRhoAir; - using DataLoopNode::Node; - using DataPlant::PlantFinalSizesOkayToReport; - using DataPlant::PlantFirstSizesOkayToFinalize; - using DataPlant::PlantFirstSizesOkayToReport; - using General::RoundSigDigits; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS - // na - - // DERIVED TYPE DEFINITIONS - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int PltSizNum; // Plant Sizing index corresponding to CurLoopNum - bool ErrorsFound; // If errors detected in input - // unused1208 CHARACTER(len=MaxNameLength) :: equipName ! Name of boiler object - Real64 DesVolFlow; - Real64 DesMassFlow; - bool HardSizeNoDesRun; // Indicator to hardsize and no sizing run - bool SizingDesRunThisAirSys; // true if a particular air system had a Sizing:System object and system sizing done - Real64 DesignVolFlowRateDes; // Autosize design volume flow for reporting - Real64 DesignVolFlowRateUser; // Hardsize design volume flow for reporting - - if (SysSizingRunDone || ZoneSizingRunDone) { - HardSizeNoDesRun = false; - } else { - HardSizeNoDesRun = true; - } - if (CurSysNum > 0) { - CheckThisAirSystemForSizing(CurSysNum, SizingDesRunThisAirSys); + bool SizingDesRunThisAirSys; // true if a particular air system had a Sizing:System object and system sizing done + + // Indicator to hardsize and no sizing run + bool HardSizeNoDesRun = !(DataSizing::SysSizingRunDone || DataSizing::ZoneSizingRunDone); + + if (DataSizing::CurSysNum > 0) { + CheckThisAirSystemForSizing(DataSizing::CurSysNum, SizingDesRunThisAirSys); } else { SizingDesRunThisAirSys = false; } - DesignVolFlowRateDes = 0.0; - DesignVolFlowRateUser = 0.0; - PltSizNum = 0; - ErrorsFound = false; + Real64 DesignVolFlowRateDes = 0.0; // Autosize design volume flow for reporting + int PltSizNum = 0; // Plant Sizing index corresponding to CurLoopNum + bool ErrorsFound = false; - if (PVT(PVTnum).WorkingFluidType == LiquidWorkingFluid) { + if (this->WorkingFluidType == WorkingFluidEnum::LIQUID) { - if (!allocated(PlantSizData)) return; - if (!allocated(PlantLoop)) return; + if (!allocated(DataSizing::PlantSizData)) return; + if (!allocated(DataPlant::PlantLoop)) return; - if (PVT(PVTnum).WLoopNum > 0) { - PltSizNum = PlantLoop(PVT(PVTnum).WLoopNum).PlantSizNum; + if (this->WLoopNum > 0) { + PltSizNum = DataPlant::PlantLoop(this->WLoopNum).PlantSizNum; } - if (PVT(PVTnum).WLoopSideNum == SupplySide) { + if (this->WLoopSideNum == DataPlant::SupplySide) { if (PltSizNum > 0) { - if (PlantSizData(PltSizNum).DesVolFlowRate >= SmallWaterVolFlow) { - DesVolFlow = PlantSizData(PltSizNum).DesVolFlowRate; + if (DataSizing::PlantSizData(PltSizNum).DesVolFlowRate >= DataHVACGlobals::SmallWaterVolFlow) { + DesignVolFlowRateDes = DataSizing::PlantSizData(PltSizNum).DesVolFlowRate; } else { - DesVolFlow = 0.0; + DesignVolFlowRateDes = 0.0; } - DesignVolFlowRateDes = DesVolFlow; } else { - if (PVT(PVTnum).DesignVolFlowRateWasAutoSized) { - if (PlantFirstSizesOkayToFinalize) { + if (this->DesignVolFlowRateWasAutoSized) { + if (DataPlant::PlantFirstSizesOkayToFinalize) { ShowSevereError("Autosizing of PVT solar collector design flow rate requires a Sizing:Plant object"); - ShowContinueError("Occurs in PVT object=" + PVT(PVTnum).Name); + ShowContinueError("Occurs in PVT object=" + this->Name); ErrorsFound = true; } } else { // Hardsized - if (PlantFinalSizesOkayToReport && PVT(PVTnum).DesignVolFlowRate > 0.0) { - ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", - PVT(PVTnum).Name, - "User-Specified Design Flow Rate [m3/s]", - PVT(PVTnum).DesignVolFlowRate); + if (DataPlant::PlantFinalSizesOkayToReport && this->DesignVolFlowRate > 0.0) { + ReportSizingManager::ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", + this->Name, + "User-Specified Design Flow Rate [m3/s]", + this->DesignVolFlowRate); } } } - } else if (PVT(PVTnum).WLoopSideNum == DemandSide) { - DesignVolFlowRateDes = PVT(PVTnum).AreaCol * SimplePVTWaterSizeFactor; + } else if (this->WLoopSideNum == DataPlant::DemandSide) { + DesignVolFlowRateDes = this->AreaCol * SimplePVTWaterSizeFactor; } - if (PVT(PVTnum).DesignVolFlowRateWasAutoSized) { - PVT(PVTnum).DesignVolFlowRate = DesignVolFlowRateDes; - if (PlantFinalSizesOkayToReport) { - ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", - PVT(PVTnum).Name, - "Design Size Design Flow Rate [m3/s]", - DesignVolFlowRateDes); + if (this->DesignVolFlowRateWasAutoSized) { + this->DesignVolFlowRate = DesignVolFlowRateDes; + if (DataPlant::PlantFinalSizesOkayToReport) { + ReportSizingManager::ReportSizingOutput( + "SolarCollector:FlatPlate:PhotovoltaicThermal", this->Name, "Design Size Design Flow Rate [m3/s]", DesignVolFlowRateDes); } - if (PlantFirstSizesOkayToReport) { - ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", - PVT(PVTnum).Name, - "Initial Design Size Design Flow Rate [m3/s]", - DesignVolFlowRateDes); + if (DataPlant::PlantFirstSizesOkayToReport) { + ReportSizingManager::ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", + this->Name, + "Initial Design Size Design Flow Rate [m3/s]", + DesignVolFlowRateDes); } - RegisterPlantCompDesignFlow(PVT(PVTnum).PlantInletNodeNum, PVT(PVTnum).DesignVolFlowRate); + PlantUtilities::RegisterPlantCompDesignFlow(this->PlantInletNodeNum, this->DesignVolFlowRate); } else { // Hardsized with sizing data - if (PVT(PVTnum).DesignVolFlowRate > 0.0 && DesignVolFlowRateDes > 0.0 && PlantFinalSizesOkayToReport) { - DesignVolFlowRateUser = PVT(PVTnum).DesignVolFlowRate; - ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", - PVT(PVTnum).Name, - "Design Size Design Flow Rate [m3/s]", - DesignVolFlowRateDes, - "User-Specified Design Flow Rate [m3/s]", - DesignVolFlowRateUser); - if (DisplayExtraWarnings) { - if ((std::abs(DesignVolFlowRateDes - DesignVolFlowRateUser) / DesignVolFlowRateUser) > AutoVsHardSizingThreshold) { - ShowMessage("SizeSolarCollector: Potential issue with equipment sizing for " + PVT(PVTnum).Name); - ShowContinueError("User-Specified Design Flow Rate of " + RoundSigDigits(DesignVolFlowRateUser, 5) + " [W]"); - ShowContinueError("differs from Design Size Design Flow Rate of " + RoundSigDigits(DesignVolFlowRateDes, 5) + " [W]"); + if (this->DesignVolFlowRate > 0.0 && DesignVolFlowRateDes > 0.0 && DataPlant::PlantFinalSizesOkayToReport) { + Real64 DesignVolFlowRateUser = this->DesignVolFlowRate; + ReportSizingManager::ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", + this->Name, + "Design Size Design Flow Rate [m3/s]", + DesignVolFlowRateDes, + "User-Specified Design Flow Rate [m3/s]", + DesignVolFlowRateUser); + if (DataGlobals::DisplayExtraWarnings) { + if ((std::abs(DesignVolFlowRateDes - DesignVolFlowRateUser) / DesignVolFlowRateUser) > + DataSizing::AutoVsHardSizingThreshold) { + ShowMessage("SizeSolarCollector: Potential issue with equipment sizing for " + this->Name); + ShowContinueError("User-Specified Design Flow Rate of " + General::RoundSigDigits(DesignVolFlowRateUser, 5) + " [W]"); + ShowContinueError("differs from Design Size Design Flow Rate of " + General::RoundSigDigits(DesignVolFlowRateDes, 5) + + " [W]"); ShowContinueError("This may, or may not, indicate mismatched component sizes."); ShowContinueError("Verify that the value entered is intended and is consistent with other components."); } @@ -887,64 +710,63 @@ namespace PhotovoltaicThermalCollectors { } } // plant component - if (PVT(PVTnum).WorkingFluidType == AirWorkingFluid) { + if (this->WorkingFluidType == WorkingFluidEnum::AIR) { - if (CurSysNum > 0) { - if (!PVT(PVTnum).DesignVolFlowRateWasAutoSized && !SizingDesRunThisAirSys) { // Simulation continue + if (DataSizing::CurSysNum > 0) { + if (!this->DesignVolFlowRateWasAutoSized && !SizingDesRunThisAirSys) { // Simulation continue HardSizeNoDesRun = true; - if (PVT(PVTnum).DesignVolFlowRate > 0.0) { - ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", - PVT(PVTnum).Name, - "User-Specified Design Flow Rate [m3/s]", - PVT(PVTnum).DesignVolFlowRate); + if (this->DesignVolFlowRate > 0.0) { + ReportSizingManager::ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", + this->Name, + "User-Specified Design Flow Rate [m3/s]", + this->DesignVolFlowRate); } } else { - CheckSysSizing("SolarCollector:FlatPlate:PhotovoltaicThermal", PVT(PVTnum).Name); - if (CurOASysNum > 0) { - DesVolFlow = FinalSysSizing(CurSysNum).DesOutAirVolFlow; + CheckSysSizing("SolarCollector:FlatPlate:PhotovoltaicThermal", this->Name); + if (DataSizing::CurOASysNum > 0) { + DesignVolFlowRateDes = DataSizing::FinalSysSizing(DataSizing::CurSysNum).DesOutAirVolFlow; } else { { - auto const SELECT_CASE_var(CurDuctType); - if (SELECT_CASE_var == Main) { - DesVolFlow = FinalSysSizing(CurSysNum).SysAirMinFlowRat * FinalSysSizing(CurSysNum).DesMainVolFlow; - } else if (SELECT_CASE_var == Cooling) { - DesVolFlow = FinalSysSizing(CurSysNum).SysAirMinFlowRat * FinalSysSizing(CurSysNum).DesCoolVolFlow; - } else if (SELECT_CASE_var == Heating) { - DesVolFlow = FinalSysSizing(CurSysNum).DesHeatVolFlow; - } else if (SELECT_CASE_var == Other) { - DesVolFlow = FinalSysSizing(CurSysNum).DesMainVolFlow; + auto const SELECT_CASE_var(DataSizing::CurDuctType); + if (SELECT_CASE_var == DataHVACGlobals::Main) { + DesignVolFlowRateDes = DataSizing::FinalSysSizing(DataSizing::CurSysNum).SysAirMinFlowRat * + DataSizing::FinalSysSizing(DataSizing::CurSysNum).DesMainVolFlow; + } else if (SELECT_CASE_var == DataHVACGlobals::Cooling) { + DesignVolFlowRateDes = DataSizing::FinalSysSizing(DataSizing::CurSysNum).SysAirMinFlowRat * + DataSizing::FinalSysSizing(DataSizing::CurSysNum).DesCoolVolFlow; + } else if (SELECT_CASE_var == DataHVACGlobals::Heating) { + DesignVolFlowRateDes = DataSizing::FinalSysSizing(DataSizing::CurSysNum).DesHeatVolFlow; } else { - DesVolFlow = FinalSysSizing(CurSysNum).DesMainVolFlow; + DesignVolFlowRateDes = DataSizing::FinalSysSizing(DataSizing::CurSysNum).DesMainVolFlow; } } } - DesMassFlow = StdRhoAir * DesVolFlow; - DesignVolFlowRateDes = DesVolFlow; - PVT(PVTnum).MaxMassFlowRate = DesMassFlow; + Real64 DesMassFlow = DataEnvironment::StdRhoAir * DesignVolFlowRateDes; + this->MaxMassFlowRate = DesMassFlow; } if (!HardSizeNoDesRun) { - if (PVT(PVTnum).DesignVolFlowRateWasAutoSized) { - PVT(PVTnum).DesignVolFlowRate = DesignVolFlowRateDes; - ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", - PVT(PVTnum).Name, - "Design Size Design Flow Rate [m3/s]", - DesignVolFlowRateDes); - PVT(PVTnum).SizingInit = false; + if (this->DesignVolFlowRateWasAutoSized) { + this->DesignVolFlowRate = DesignVolFlowRateDes; + ReportSizingManager::ReportSizingOutput( + "SolarCollector:FlatPlate:PhotovoltaicThermal", this->Name, "Design Size Design Flow Rate [m3/s]", DesignVolFlowRateDes); + this->SizingInit = false; } else { - if (PVT(PVTnum).DesignVolFlowRate > 0.0 && DesignVolFlowRateDes > 0.0) { - DesignVolFlowRateUser = PVT(PVTnum).DesignVolFlowRate; - ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", - PVT(PVTnum).Name, - "Design Size Design Flow Rate [m3/s]", - DesignVolFlowRateDes, - "User-Specified Design Flow Rate [m3/s]", - DesignVolFlowRateUser); - if (DisplayExtraWarnings) { - if ((std::abs(DesignVolFlowRateDes - DesignVolFlowRateUser) / DesignVolFlowRateUser) > AutoVsHardSizingThreshold) { - ShowMessage("SizeSolarCollector: Potential issue with equipment sizing for " + PVT(PVTnum).Name); - ShowContinueError("User-Specified Design Flow Rate of " + RoundSigDigits(DesignVolFlowRateUser, 5) + " [W]"); - ShowContinueError("differs from Design Size Design Flow Rate of " + RoundSigDigits(DesignVolFlowRateDes, 5) + + if (this->DesignVolFlowRate > 0.0 && DesignVolFlowRateDes > 0.0) { + Real64 DesignVolFlowRateUser = this->DesignVolFlowRate; + ReportSizingManager::ReportSizingOutput("SolarCollector:FlatPlate:PhotovoltaicThermal", + this->Name, + "Design Size Design Flow Rate [m3/s]", + DesignVolFlowRateDes, + "User-Specified Design Flow Rate [m3/s]", + DesignVolFlowRateUser); + if (DataGlobals::DisplayExtraWarnings) { + if ((std::abs(DesignVolFlowRateDes - DesignVolFlowRateUser) / DesignVolFlowRateUser) > + DataSizing::AutoVsHardSizingThreshold) { + ShowMessage("SizeSolarCollector: Potential issue with equipment sizing for " + this->Name); + ShowContinueError("User-Specified Design Flow Rate of " + General::RoundSigDigits(DesignVolFlowRateUser, 5) + " [W]"); + ShowContinueError("differs from Design Size Design Flow Rate of " + + General::RoundSigDigits(DesignVolFlowRateDes, 5) + " [W]"); ShowContinueError("This may, or may not, indicate mismatched component sizes."); ShowContinueError("Verify that the value entered is intended and is consistent with other components."); } @@ -952,7 +774,7 @@ namespace PhotovoltaicThermalCollectors { } } } - } else if (CurZoneEqNum > 0) { + } else if (DataSizing::CurZoneEqNum > 0) { // PVT is not currently for zone equipment, should not come here. } } @@ -962,7 +784,7 @@ namespace PhotovoltaicThermalCollectors { } } - void ControlPVTcollector(int const PVTnum) + void PVTCollectorStruct::control() { // SUBROUTINE INFORMATION: @@ -977,98 +799,51 @@ namespace PhotovoltaicThermalCollectors { // METHODOLOGY EMPLOYED: // decide if PVT should be in cooling or heat mode and if it should be bypassed or not - // REFERENCES: - // na - - // Using/Aliasing - using DataHeatBalance::QRadSWOutIncident; - using DataLoopNode::Node; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na + if (this->WorkingFluidType == WorkingFluidEnum::AIR) { - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - static int SurfNum(0); - // INTEGER :: PlantLoopNum = 0 - // REAL(r64) :: mdot = 0.0D0 - - SurfNum = PVT(PVTnum).SurfNum; - - if (PVT(PVTnum).WorkingFluidType == AirWorkingFluid) { - - if (PVT(PVTnum).PVTModelType == SimplePVTmodel) { - if (QRadSWOutIncident(SurfNum) > MinIrradiance) { + if (this->PVTModelType == SimplePVTmodel) { + if (DataHeatBalance::QRadSWOutIncident(this->SurfNum) > DataPhotovoltaics::MinIrradiance) { // is heating wanted? // Outlet node is required to have a setpoint. - if (Node(PVT(PVTnum).HVACOutletNodeNum).TempSetPoint > Node(PVT(PVTnum).HVACInletNodeNum).Temp) { - PVT(PVTnum).HeatingUseful = true; - PVT(PVTnum).CoolingUseful = false; - PVT(PVTnum).BypassDamperOff = true; + if (DataLoopNode::Node(this->HVACOutletNodeNum).TempSetPoint > DataLoopNode::Node(this->HVACInletNodeNum).Temp) { + this->HeatingUseful = true; + this->CoolingUseful = false; + this->BypassDamperOff = true; } else { - PVT(PVTnum).HeatingUseful = false; - PVT(PVTnum).CoolingUseful = true; - PVT(PVTnum).BypassDamperOff = false; + this->HeatingUseful = false; + this->CoolingUseful = true; + this->BypassDamperOff = false; } } else { // is cooling wanted? - if (Node(PVT(PVTnum).HVACOutletNodeNum).TempSetPoint < Node(PVT(PVTnum).HVACInletNodeNum).Temp) { - PVT(PVTnum).CoolingUseful = true; - PVT(PVTnum).HeatingUseful = false; - PVT(PVTnum).BypassDamperOff = true; + if (DataLoopNode::Node(this->HVACOutletNodeNum).TempSetPoint < DataLoopNode::Node(this->HVACInletNodeNum).Temp) { + this->CoolingUseful = true; + this->HeatingUseful = false; + this->BypassDamperOff = true; } else { - PVT(PVTnum).CoolingUseful = false; - PVT(PVTnum).HeatingUseful = true; - PVT(PVTnum).BypassDamperOff = false; + this->CoolingUseful = false; + this->HeatingUseful = true; + this->BypassDamperOff = false; } } } - } else if (PVT(PVTnum).WorkingFluidType == LiquidWorkingFluid) { - // PlantLoopNum = PVT(PVTNum)%PlantLoopNum - // mdot = Node(PVT(PVTNum)%PlantInletNodeNum)%MassFlowRate - // If (.NOT. Allocated(PlantReport)) RETURN ! this can happen early before plant is setup - if (PVT(PVTnum).PVTModelType == SimplePVTmodel) { - if (QRadSWOutIncident(SurfNum) > MinIrradiance) { + } else if (this->WorkingFluidType == WorkingFluidEnum::LIQUID) { + if (this->PVTModelType == SimplePVTmodel) { + if (DataHeatBalance::QRadSWOutIncident(this->SurfNum) > DataPhotovoltaics::MinIrradiance) { // is heating wanted? - - // IF (mdot > 0.0D0) THEN - // If (PlantReport(PlantLoopNum)%HeatingDemand > 0.0) THEN - PVT(PVTnum).HeatingUseful = true; - // PVT(PVTnum)%CoolingUseful = .FALSE. - PVT(PVTnum).BypassDamperOff = true; - // ELSE - // PVT(PVTnum)%HeatingUseful = .FALSE. - // PVT(PVTnum)%CoolingUseful = .TRUE. - // PVT(PVTnum)%BypassDamperOff = .FALSE. - // ENDIF - + this->HeatingUseful = true; + this->BypassDamperOff = true; } else { // is cooling wanted? - // IF (mdot > 0.0D0) THEN - // If (PlantReport(PlantLoopNum)%CoolingDemand > 0.0) THEN - // PVT(PVTnum)%CoolingUseful = .TRUE. - // PVT(PVTnum)%HeatingUseful = .FALSE. - // PVT(PVTnum)%BypassDamperOff = .TRUE. - // ELSE - PVT(PVTnum).CoolingUseful = false; - // PVT(PVTnum)%HeatingUseful = .TRUE. - PVT(PVTnum).BypassDamperOff = false; - // ENDIF + this->CoolingUseful = false; + this->BypassDamperOff = false; } } } } - void CalcPVTcollectors(int const PVTnum) + void PVTCollectorStruct::calculate() { // SUBROUTINE INFORMATION: @@ -1083,119 +858,69 @@ namespace PhotovoltaicThermalCollectors { // METHODOLOGY EMPLOYED: // Current model is "simple" fixed efficiency and simple night sky balance for cooling - // REFERENCES: - // na - - // Using/Aliasing - using ConvectionCoefficients::InitExteriorConvectionCoeff; - using DataEnvironment::OutBaroPress; - using DataEnvironment::OutDryBulbTemp; - using DataEnvironment::SkyTemp; - using DataGlobals::SecInHour; - using DataHeatBalance::QRadSWOutIncident; - using DataHeatBalance::VerySmooth; - using DataHVACGlobals::TimeStepSys; - using DataLoopNode::Node; - using Psychrometrics::CPHW; - using Psychrometrics::PsyCpAirFnWTdb; - using Psychrometrics::PsyTdpFnTdbTwbPb; - using Psychrometrics::PsyTwbFnTdbWPb; - using ScheduleManager::GetCurrentScheduleValue; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: static std::string const RoutineName("CalcPVTcollectors"); - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - - static int InletNode(0); - static int OutletNode(0); - static Real64 Eff(0.0); - static int SurfNum(0); - static int RoughSurf(0); - static Real64 HcExt(0.0); - static Real64 HrSky(0.0); - static Real64 HrGround(0.0); - static Real64 HrAir(0.0); - static Real64 Tcollector(0.0); - static Real64 mdot(0.0); - static Real64 Tinlet(0.0); - static Real64 Winlet(0.0); - static Real64 CpInlet(0.0); - static Real64 PotentialOutletTemp(0.0); - static Real64 BypassFraction(0.0); - static Real64 PotentialHeatGain(0.0); - static Real64 WetBulbInlet(0.0); - static Real64 DewPointInlet(0.0); - - // flow - SurfNum = PVT(PVTnum).SurfNum; - RoughSurf = VerySmooth; + int InletNode(0); { - auto const SELECT_CASE_var(PVT(PVTnum).WorkingFluidType); - if (SELECT_CASE_var == LiquidWorkingFluid) { - InletNode = PVT(PVTnum).PlantInletNodeNum; - OutletNode = PVT(PVTnum).PlantOutletNodeNum; - } else if (SELECT_CASE_var == AirWorkingFluid) { - InletNode = PVT(PVTnum).HVACInletNodeNum; - OutletNode = PVT(PVTnum).HVACOutletNodeNum; + auto const SELECT_CASE_var(this->WorkingFluidType); + if (SELECT_CASE_var == WorkingFluidEnum::LIQUID) { + InletNode = this->PlantInletNodeNum; + } else if (SELECT_CASE_var == WorkingFluidEnum::AIR) { + InletNode = this->HVACInletNodeNum; } } - mdot = PVT(PVTnum).MassFlowRate; - Tinlet = Node(InletNode).Temp; + Real64 mdot = this->MassFlowRate; + Real64 Tinlet = DataLoopNode::Node(InletNode).Temp; + + if (this->PVTModelType == SimplePVTmodel) { + + Real64 BypassFraction(0.0); + Real64 PotentialOutletTemp(0.0); - if (PVT(PVTnum).PVTModelType == SimplePVTmodel) { + if (this->HeatingUseful && this->BypassDamperOff && (mdot > 0.0)) { - if (PVT(PVTnum).HeatingUseful && PVT(PVTnum).BypassDamperOff && (mdot > 0.0)) { + Real64 Eff(0.0); { - auto const SELECT_CASE_var(PVT(PVTnum).Simple.ThermEfficMode); + auto const SELECT_CASE_var(this->Simple.ThermEfficMode); - if (SELECT_CASE_var == FixedThermEffic) { - Eff = PVT(PVTnum).Simple.ThermEffic; - } else if (SELECT_CASE_var == ScheduledThermEffic) { - Eff = GetCurrentScheduleValue(PVT(PVTnum).Simple.ThermEffSchedNum); - PVT(PVTnum).Simple.ThermEffic = Eff; + if (SELECT_CASE_var == ThermEfficEnum::FIXED) { + Eff = this->Simple.ThermEffic; + } else if (SELECT_CASE_var == ThermEfficEnum::SCHEDULED) { + Eff = ScheduleManager::GetCurrentScheduleValue(this->Simple.ThermEffSchedNum); + this->Simple.ThermEffic = Eff; } } - PotentialHeatGain = QRadSWOutIncident(SurfNum) * Eff * PVT(PVTnum).AreaCol; + Real64 PotentialHeatGain = DataHeatBalance::QRadSWOutIncident(this->SurfNum) * Eff * this->AreaCol; - if (PVT(PVTnum).WorkingFluidType == AirWorkingFluid) { - Winlet = Node(InletNode).HumRat; - CpInlet = PsyCpAirFnWTdb(Winlet, Tinlet); + if (this->WorkingFluidType == WorkingFluidEnum::AIR) { + Real64 Winlet = DataLoopNode::Node(InletNode).HumRat; + Real64 CpInlet = Psychrometrics::PsyCpAirFnWTdb(Winlet, Tinlet); if (mdot * CpInlet > 0.0) { PotentialOutletTemp = Tinlet + PotentialHeatGain / (mdot * CpInlet); } else { PotentialOutletTemp = Tinlet; } // now compare heating potential to setpoint and figure bypass fraction - if (PotentialOutletTemp > Node(PVT(PVTnum).HVACOutletNodeNum).TempSetPoint) { // need to modulate + if (PotentialOutletTemp > DataLoopNode::Node(this->HVACOutletNodeNum).TempSetPoint) { // need to modulate if (Tinlet != PotentialOutletTemp) { BypassFraction = - (Node(PVT(PVTnum).HVACOutletNodeNum).TempSetPoint - PotentialOutletTemp) / (Tinlet - PotentialOutletTemp); + (DataLoopNode::Node(this->HVACOutletNodeNum).TempSetPoint - PotentialOutletTemp) / (Tinlet - PotentialOutletTemp); } else { BypassFraction = 0.0; } BypassFraction = max(0.0, BypassFraction); - PotentialOutletTemp = Node(PVT(PVTnum).HVACOutletNodeNum).TempSetPoint; - PotentialHeatGain = mdot * PsyCpAirFnWTdb(Winlet, Tinlet) * (PotentialOutletTemp - Tinlet); + PotentialOutletTemp = DataLoopNode::Node(this->HVACOutletNodeNum).TempSetPoint; + PotentialHeatGain = mdot * Psychrometrics::PsyCpAirFnWTdb(Winlet, Tinlet) * (PotentialOutletTemp - Tinlet); } else { BypassFraction = 0.0; } - } else if (PVT(PVTnum).WorkingFluidType == LiquidWorkingFluid) { - CpInlet = CPHW(Tinlet); + } else if (this->WorkingFluidType == WorkingFluidEnum::LIQUID) { + Real64 CpInlet = Psychrometrics::CPHW(Tinlet); if (mdot * CpInlet != 0.0) { // protect divide by zero PotentialOutletTemp = Tinlet + PotentialHeatGain / (mdot * CpInlet); } else { @@ -1204,40 +929,57 @@ namespace PhotovoltaicThermalCollectors { BypassFraction = 0.0; } - PVT(PVTnum).Report.ThermEfficiency = Eff; - PVT(PVTnum).Report.ThermHeatGain = PotentialHeatGain; - PVT(PVTnum).Report.ThermPower = PVT(PVTnum).Report.ThermHeatGain; - PVT(PVTnum).Report.ThermEnergy = PVT(PVTnum).Report.ThermPower * TimeStepSys * SecInHour; - PVT(PVTnum).Report.ThermHeatLoss = 0.0; - PVT(PVTnum).Report.TinletWorkFluid = Tinlet; - PVT(PVTnum).Report.MdotWorkFluid = mdot; - PVT(PVTnum).Report.ToutletWorkFluid = PotentialOutletTemp; - PVT(PVTnum).Report.BypassStatus = BypassFraction; - - } else if (PVT(PVTnum).CoolingUseful && PVT(PVTnum).BypassDamperOff && (mdot > 0.0)) { + this->Report.ThermEfficiency = Eff; + this->Report.ThermHeatGain = PotentialHeatGain; + this->Report.ThermPower = this->Report.ThermHeatGain; + this->Report.ThermEnergy = this->Report.ThermPower * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + this->Report.ThermHeatLoss = 0.0; + this->Report.TinletWorkFluid = Tinlet; + this->Report.MdotWorkFluid = mdot; + this->Report.ToutletWorkFluid = PotentialOutletTemp; + this->Report.BypassStatus = BypassFraction; + + } else if (this->CoolingUseful && this->BypassDamperOff && (mdot > 0.0)) { // calculate cooling using energy balance - InitExteriorConvectionCoeff( - SurfNum, 0.0, RoughSurf, PVT(PVTnum).Simple.SurfEmissivity, PVT(PVTnum).Simple.LastCollectorTemp, HcExt, HrSky, HrGround, HrAir); - - if (PVT(PVTnum).WorkingFluidType == AirWorkingFluid) { - Winlet = Node(InletNode).HumRat; - CpInlet = PsyCpAirFnWTdb(Winlet, Tinlet); - WetBulbInlet = PsyTwbFnTdbWPb(Tinlet, Winlet, OutBaroPress, RoutineName); - DewPointInlet = PsyTdpFnTdbTwbPb(Tinlet, WetBulbInlet, OutBaroPress, RoutineName); - } else if (PVT(PVTnum).WorkingFluidType == LiquidWorkingFluid) { - CpInlet = CPHW(Tinlet); + Real64 HrGround(0.0); + Real64 HrAir(0.0); + Real64 HcExt(0.0); + Real64 HrSky(0.0); + + ConvectionCoefficients::InitExteriorConvectionCoeff(this->SurfNum, + 0.0, + DataHeatBalance::VerySmooth, + this->Simple.SurfEmissivity, + this->Simple.LastCollectorTemp, + HcExt, + HrSky, + HrGround, + HrAir); + + Real64 WetBulbInlet(0.0); + Real64 DewPointInlet(0.0); + Real64 CpInlet(0.0); + + if (this->WorkingFluidType == WorkingFluidEnum::AIR) { + Real64 Winlet = DataLoopNode::Node(InletNode).HumRat; + CpInlet = Psychrometrics::PsyCpAirFnWTdb(Winlet, Tinlet); + WetBulbInlet = Psychrometrics::PsyTwbFnTdbWPb(Tinlet, Winlet, DataEnvironment::OutBaroPress, RoutineName); + DewPointInlet = Psychrometrics::PsyTdpFnTdbTwbPb(Tinlet, WetBulbInlet, DataEnvironment::OutBaroPress, RoutineName); + } else if (this->WorkingFluidType == WorkingFluidEnum::LIQUID) { + CpInlet = Psychrometrics::CPHW(Tinlet); } - Tcollector = (2.0 * mdot * CpInlet * Tinlet + - PVT(PVTnum).AreaCol * (HrGround * OutDryBulbTemp + HrSky * SkyTemp + HrAir * Surface(SurfNum).OutDryBulbTemp + - HcExt * Surface(SurfNum).OutDryBulbTemp)) / - (2.0 * mdot * CpInlet + PVT(PVTnum).AreaCol * (HrGround + HrSky + HrAir + HcExt)); + Real64 Tcollector = + (2.0 * mdot * CpInlet * Tinlet + this->AreaCol * (HrGround * DataEnvironment::OutDryBulbTemp + HrSky * DataEnvironment::SkyTemp + + HrAir * DataSurfaces::Surface(this->SurfNum).OutDryBulbTemp + + HcExt * DataSurfaces::Surface(this->SurfNum).OutDryBulbTemp)) / + (2.0 * mdot * CpInlet + this->AreaCol * (HrGround + HrSky + HrAir + HcExt)); PotentialOutletTemp = 2.0 * Tcollector - Tinlet; - PVT(PVTnum).Report.ToutletWorkFluid = PotentialOutletTemp; + this->Report.ToutletWorkFluid = PotentialOutletTemp; // trap for air not being cooled below its wetbulb. - if (PVT(PVTnum).WorkingFluidType == AirWorkingFluid) { + if (this->WorkingFluidType == WorkingFluidEnum::AIR) { if (PotentialOutletTemp < DewPointInlet) { // water removal would be needed.. not going to allow that for now. limit cooling to dew point and model bypass if (Tinlet != PotentialOutletTemp) { @@ -1250,44 +992,32 @@ namespace PhotovoltaicThermalCollectors { } } - PVT(PVTnum).Report.MdotWorkFluid = mdot; - PVT(PVTnum).Report.TinletWorkFluid = Tinlet; - PVT(PVTnum).Report.ToutletWorkFluid = PotentialOutletTemp; - PVT(PVTnum).Report.ThermHeatLoss = mdot * CpInlet * (Tinlet - PVT(PVTnum).Report.ToutletWorkFluid); - PVT(PVTnum).Report.ThermHeatGain = 0.0; - PVT(PVTnum).Report.ThermPower = -1.0 * PVT(PVTnum).Report.ThermHeatLoss; - PVT(PVTnum).Report.ThermEnergy = PVT(PVTnum).Report.ThermPower * TimeStepSys * SecInHour; - PVT(PVTnum).Report.ThermEfficiency = 0.0; - PVT(PVTnum).Simple.LastCollectorTemp = Tcollector; - PVT(PVTnum).Report.BypassStatus = 0.0; - - } else if (!PVT(PVTnum).BypassDamperOff) { // bypassed, zero things out - - PVT(PVTnum).Report.TinletWorkFluid = Tinlet; - PVT(PVTnum).Report.ToutletWorkFluid = Tinlet; - PVT(PVTnum).Report.ThermHeatLoss = 0.0; - PVT(PVTnum).Report.ThermHeatGain = 0.0; - PVT(PVTnum).Report.ThermPower = 0.0; - PVT(PVTnum).Report.ThermEfficiency = 0.0; - PVT(PVTnum).Report.ThermEnergy = 0.0; - PVT(PVTnum).Report.BypassStatus = 1.0; - PVT(PVTnum).Report.MdotWorkFluid = mdot; + this->Report.MdotWorkFluid = mdot; + this->Report.TinletWorkFluid = Tinlet; + this->Report.ToutletWorkFluid = PotentialOutletTemp; + this->Report.ThermHeatLoss = mdot * CpInlet * (Tinlet - this->Report.ToutletWorkFluid); + this->Report.ThermHeatGain = 0.0; + this->Report.ThermPower = -1.0 * this->Report.ThermHeatLoss; + this->Report.ThermEnergy = this->Report.ThermPower * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + this->Report.ThermEfficiency = 0.0; + this->Simple.LastCollectorTemp = Tcollector; + this->Report.BypassStatus = BypassFraction; } else { - PVT(PVTnum).Report.TinletWorkFluid = Tinlet; - PVT(PVTnum).Report.ToutletWorkFluid = Tinlet; - PVT(PVTnum).Report.ThermHeatLoss = 0.0; - PVT(PVTnum).Report.ThermHeatGain = 0.0; - PVT(PVTnum).Report.ThermPower = 0.0; - PVT(PVTnum).Report.ThermEfficiency = 0.0; - PVT(PVTnum).Report.ThermEnergy = 0.0; - PVT(PVTnum).Report.BypassStatus = 1.0; - PVT(PVTnum).Report.MdotWorkFluid = mdot; + this->Report.TinletWorkFluid = Tinlet; + this->Report.ToutletWorkFluid = Tinlet; + this->Report.ThermHeatLoss = 0.0; + this->Report.ThermHeatGain = 0.0; + this->Report.ThermPower = 0.0; + this->Report.ThermEfficiency = 0.0; + this->Report.ThermEnergy = 0.0; + this->Report.BypassStatus = 1.0; + this->Report.MdotWorkFluid = mdot; } } } - void UpdatePVTcollectors(int const PVTnum) + void PVTCollectorStruct::update() { // SUBROUTINE INFORMATION: @@ -1296,69 +1026,41 @@ namespace PhotovoltaicThermalCollectors { // MODIFIED na // RE-ENGINEERED na - // PURPOSE OF THIS SUBROUTINE: - // - - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // Using/Aliasing - using DataLoopNode::Node; - using PlantUtilities::SafeCopyPlantNode; - using Psychrometrics::PsyHFnTdbW; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: int InletNode; int OutletNode; { - auto const SELECT_CASE_var(PVT(PVTnum).WorkingFluidType); - if (SELECT_CASE_var == LiquidWorkingFluid) { - InletNode = PVT(PVTnum).PlantInletNodeNum; - OutletNode = PVT(PVTnum).PlantOutletNodeNum; + auto const SELECT_CASE_var(this->WorkingFluidType); + if (SELECT_CASE_var == WorkingFluidEnum::LIQUID) { + InletNode = this->PlantInletNodeNum; + OutletNode = this->PlantOutletNodeNum; - SafeCopyPlantNode(InletNode, OutletNode); - Node(OutletNode).Temp = PVT(PVTnum).Report.ToutletWorkFluid; + PlantUtilities::SafeCopyPlantNode(InletNode, OutletNode); + DataLoopNode::Node(OutletNode).Temp = this->Report.ToutletWorkFluid; - } else if (SELECT_CASE_var == AirWorkingFluid) { - InletNode = PVT(PVTnum).HVACInletNodeNum; - OutletNode = PVT(PVTnum).HVACOutletNodeNum; + } else if (SELECT_CASE_var == WorkingFluidEnum::AIR) { + InletNode = this->HVACInletNodeNum; + OutletNode = this->HVACOutletNodeNum; // Set the outlet nodes for properties that just pass through & not used - Node(OutletNode).Quality = Node(InletNode).Quality; - Node(OutletNode).Press = Node(InletNode).Press; - Node(OutletNode).MassFlowRate = Node(InletNode).MassFlowRate; - Node(OutletNode).MassFlowRateMin = Node(InletNode).MassFlowRateMin; - Node(OutletNode).MassFlowRateMax = Node(InletNode).MassFlowRateMax; - Node(OutletNode).MassFlowRateMinAvail = Node(InletNode).MassFlowRateMinAvail; - Node(OutletNode).MassFlowRateMaxAvail = Node(InletNode).MassFlowRateMaxAvail; + DataLoopNode::Node(OutletNode).Quality = DataLoopNode::Node(InletNode).Quality; + DataLoopNode::Node(OutletNode).Press = DataLoopNode::Node(InletNode).Press; + DataLoopNode::Node(OutletNode).MassFlowRate = DataLoopNode::Node(InletNode).MassFlowRate; + DataLoopNode::Node(OutletNode).MassFlowRateMin = DataLoopNode::Node(InletNode).MassFlowRateMin; + DataLoopNode::Node(OutletNode).MassFlowRateMax = DataLoopNode::Node(InletNode).MassFlowRateMax; + DataLoopNode::Node(OutletNode).MassFlowRateMinAvail = DataLoopNode::Node(InletNode).MassFlowRateMinAvail; + DataLoopNode::Node(OutletNode).MassFlowRateMaxAvail = DataLoopNode::Node(InletNode).MassFlowRateMaxAvail; // Set outlet node variables that are possibly changed - Node(OutletNode).Temp = PVT(PVTnum).Report.ToutletWorkFluid; - Node(OutletNode).HumRat = Node(InletNode).HumRat; // assumes dewpoint bound on cooling .... - Node(OutletNode).Enthalpy = PsyHFnTdbW(PVT(PVTnum).Report.ToutletWorkFluid, Node(OutletNode).HumRat); + DataLoopNode::Node(OutletNode).Temp = this->Report.ToutletWorkFluid; + DataLoopNode::Node(OutletNode).HumRat = DataLoopNode::Node(InletNode).HumRat; // assumes dewpoint bound on cooling .... + DataLoopNode::Node(OutletNode).Enthalpy = + Psychrometrics::PsyHFnTdbW(this->Report.ToutletWorkFluid, DataLoopNode::Node(OutletNode).HumRat); } } } - void GetPVTThermalPowerProduction(int const PVindex, // index of PV generator (not PVT collector) - Real64 &ThermalPower, - Real64 &ThermalEnergy) + void GetPVTThermalPowerProduction(int const PVindex, Real64 &ThermalPower, Real64 &ThermalEnergy) { // SUBROUTINE INFORMATION: @@ -1367,35 +1069,10 @@ namespace PhotovoltaicThermalCollectors { // MODIFIED na // RE-ENGINEERED na - // PURPOSE OF THIS SUBROUTINE: - // - - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - static int PVTnum(0); - static int loop(0); + int PVTnum(0); // first find PVT index that is associated with this PV generator - for (loop = 1; loop <= NumPVT; ++loop) { + for (int loop = 1; loop <= NumPVT; ++loop) { if (!PVT(loop).PVfound) continue; if (PVT(loop).PVnum == PVindex) { // we found it PVTnum = loop; @@ -1411,9 +1088,7 @@ namespace PhotovoltaicThermalCollectors { } } - int GetAirInletNodeNum(std::string const &PVTName, - bool &ErrorsFound - ) + int GetAirInletNodeNum(std::string const &PVTName, bool &ErrorsFound) { // FUNCTION INFORMATION: // AUTHOR Lixing Gu @@ -1425,10 +1100,7 @@ namespace PhotovoltaicThermalCollectors { // This function looks up the given PVT and returns the air inlet node number. // If incorrect PVT name is given, ErrorsFound is returned as true and node number as zero. - // Return value int NodeNum; // node number returned - - // FUNCTION LOCAL VARIABLE DECLARATIONS: int WhichPVT; if (GetInputFlag) { @@ -1447,9 +1119,7 @@ namespace PhotovoltaicThermalCollectors { return NodeNum; } - int GetAirOutletNodeNum(std::string const &PVTName, - bool &ErrorsFound - ) + int GetAirOutletNodeNum(std::string const &PVTName, bool &ErrorsFound) { // FUNCTION INFORMATION: // AUTHOR Lixing Gu @@ -1461,10 +1131,7 @@ namespace PhotovoltaicThermalCollectors { // This function looks up the given PVT and returns the air outlet node number. // If incorrect PVT name is given, ErrorsFound is returned as true and node number as zero. - // Return value int NodeNum; // node number returned - - // FUNCTION LOCAL VARIABLE DECLARATIONS: int WhichPVT; if (GetInputFlag) { @@ -1484,8 +1151,33 @@ namespace PhotovoltaicThermalCollectors { return NodeNum; } - //===================== Utility/Other routines for module. - // Insert as appropriate + int getPVTindexFromName(std::string const &objectName) + { + if (GetInputFlag) { + GetPVTcollectorsInput(); + GetInputFlag = false; + } + + for (auto it = PVT.begin(); it != PVT.end(); ++it) { + if (it->Name == objectName) { + return static_cast(std::distance(PVT.begin(), it) + 1); + } + } + + // If we didn't find it, fatal + ShowFatalError("Solar Thermal Collector GetIndexFromName: Error getting inputs for object named: " + objectName); + assert(false); + return 0; // Shutup compiler + } + + void simPVTfromOASys(int const index, bool const FirstHVACIteration) + { + PlantLocation dummyLoc(0, 0, 0, 0); + Real64 dummyCurLoad(0.0); + bool dummyRunFlag(true); + + PVT(index).simulate(dummyLoc, FirstHVACIteration, dummyCurLoad, dummyRunFlag); + } } // namespace PhotovoltaicThermalCollectors diff --git a/src/EnergyPlus/PhotovoltaicThermalCollectors.hh b/src/EnergyPlus/PhotovoltaicThermalCollectors.hh index ac7cbf945bb..80ee6456f93 100644 --- a/src/EnergyPlus/PhotovoltaicThermalCollectors.hh +++ b/src/EnergyPlus/PhotovoltaicThermalCollectors.hh @@ -50,67 +50,42 @@ // ObjexxFCL Headers #include -#include // EnergyPlus Headers -#include -#include +#include namespace EnergyPlus { namespace PhotovoltaicThermalCollectors { - // Using/Aliasing - - // Data - // MODULE PARAMETER DEFINITIONS: - extern int const SimplePVTmodel; - extern int const LayerByLayerPVTmodel; - - extern int const ScheduledThermEffic; // mode for thermal efficiency is to use schedule - extern int const FixedThermEffic; // mode for thermal efficiency is to use fixed value - - extern int const LiquidWorkingFluid; - extern int const AirWorkingFluid; - - extern int const CalledFromPlantLoopEquipMgr; - extern int const CalledFromOutsideAirSystem; - - extern Real64 const SimplePVTWaterSizeFactor; // [ m3/s/m2 ] average of collectors in SolarCollectors.idf - - // DERIVED TYPE DEFINITIONS: - - // MODULE VARIABLE DECLARATIONS: - extern Array1D_bool CheckEquipName; - extern int NumPVT; // count of all types of PVT in input file - extern int NumSimplePVTPerform; // count of simple PVT performance objects in input file - - // SUBROUTINE SPECIFICATIONS FOR MODULE: - // Driver/Manager Routines - - // Utility routines for module - // these would be public such as: - // PUBLIC GetPVTIncidentSolarForInternalPVLayer - // PUBLIC GetPVTCellTemp + enum struct WorkingFluidEnum + { + LIQUID, + AIR + }; - // Types + enum struct ThermEfficEnum + { + SCHEDULED, + FIXED + }; struct SimplePVTModelStruct { // Members std::string Name; - Real64 ThermalActiveFract; // fraction of surface area with active thermal collection - int ThermEfficMode; // setting for how therm effic is determined - Real64 ThermEffic; // fixed or current Therm efficiency - int ThermEffSchedNum; // pointer to schedule for therm effic (if any) - Real64 SurfEmissivity; // surface emittance in long wave IR - Real64 LastCollectorTemp; // store previous temperature - Real64 CollectorTemp; // average solar collector temp. + Real64 ThermalActiveFract; // fraction of surface area with active thermal collection + ThermEfficEnum ThermEfficMode; // setting for how therm effic is determined + Real64 ThermEffic; // fixed or current Therm efficiency + int ThermEffSchedNum; // pointer to schedule for therm effic (if any) + Real64 SurfEmissivity; // surface emittance in long wave IR + Real64 LastCollectorTemp; // store previous temperature + Real64 CollectorTemp; // average solar collector temp. // Default Constructor SimplePVTModelStruct() - : ThermalActiveFract(0.0), ThermEfficMode(0), ThermEffic(0.0), ThermEffSchedNum(0), SurfEmissivity(0.0), LastCollectorTemp(0.0), - CollectorTemp(0.0) + : ThermalActiveFract(0.0), ThermEfficMode(ThermEfficEnum::FIXED), ThermEffic(0.0), ThermEffSchedNum(0), SurfEmissivity(0.0), + LastCollectorTemp(0.0), CollectorTemp(0.0) { } }; @@ -136,28 +111,25 @@ namespace PhotovoltaicThermalCollectors { } }; - struct PVTCollectorStruct + struct PVTCollectorStruct : PlantComponent { // Members - // input - std::string Name; // Name of PVT collector - int TypeNum; // Plant Side Connection: 'TypeOf_Num' assigned in DataPlant !DSU - int WLoopNum; // Water plant loop index number !DSU - int WLoopSideNum; // Water plant loop side index !DSU - int WLoopBranchNum; // Water plant loop branch index !DSU - int WLoopCompNum; // Water plant loop component index !DSU - bool EnvrnInit; // manage begin environmen inits - bool SizingInit; // manage when sizing is complete - std::string PVTModelName; // Name of PVT performance object - int PVTModelType; // model type indicator, only simple avail now - int SurfNum; // surface index - std::string PVname; // named Generator:Photovoltaic object - int PVnum; // PV index - bool PVfound; // init, need to delay get input until PV gotten - // INTEGER :: PlantLoopNum = 0 ! needed for sizing and control - // INTEGER :: PlantLoopSide = 0 ! needed for sizing, demand vs. supply sided + std::string Name; // Name of PVT collector + int TypeNum; // Plant Side Connection: 'TypeOf_Num' assigned in DataPlant + int WLoopNum; // Water plant loop index number + int WLoopSideNum; // Water plant loop side index + int WLoopBranchNum; // Water plant loop branch index + int WLoopCompNum; // Water plant loop component index + bool EnvrnInit; // manage begin environment inits + bool SizingInit; // manage when sizing is complete + std::string PVTModelName; // Name of PVT performance object + int PVTModelType; // model type indicator, only simple avail now + int SurfNum; // surface index + std::string PVname; // named Generator:Photovoltaic object + int PVnum; // PV index + bool PVfound; // init, need to delay get input until PV gotten SimplePVTModelStruct Simple; // performance data structure. - int WorkingFluidType; + WorkingFluidEnum WorkingFluidType; int PlantInletNodeNum; int PlantOutletNodeNum; int HVACInletNodeNum; @@ -165,59 +137,60 @@ namespace PhotovoltaicThermalCollectors { Real64 DesignVolFlowRate; bool DesignVolFlowRateWasAutoSized; // true if design volume flow rate was autosize on input Real64 MaxMassFlowRate; - Real64 MassFlowRate; // DSU + Real64 MassFlowRate; Real64 AreaCol; bool BypassDamperOff; bool CoolingUseful; bool HeatingUseful; PVTReportStruct Report; + bool MySetPointCheckFlag; + bool MyOneTimeFlag; + bool SetLoopIndexFlag; // Default Constructor PVTCollectorStruct() - : WLoopNum(0), WLoopSideNum(0), WLoopBranchNum(0), WLoopCompNum(0), EnvrnInit(true), SizingInit(true), PVTModelType(0), SurfNum(0), - PVnum(0), PVfound(false), WorkingFluidType(0), PlantInletNodeNum(0), PlantOutletNodeNum(0), HVACInletNodeNum(0), HVACOutletNodeNum(0), - DesignVolFlowRate(0.0), DesignVolFlowRateWasAutoSized(false), MaxMassFlowRate(0.0), MassFlowRate(0.0), AreaCol(0.0), - BypassDamperOff(true), CoolingUseful(false), HeatingUseful(false) + : TypeNum(0), WLoopNum(0), WLoopSideNum(0), WLoopBranchNum(0), WLoopCompNum(0), EnvrnInit(true), SizingInit(true), PVTModelType(0), + SurfNum(0), PVnum(0), PVfound(false), WorkingFluidType(WorkingFluidEnum::LIQUID), PlantInletNodeNum(0), PlantOutletNodeNum(0), + HVACInletNodeNum(0), HVACOutletNodeNum(0), DesignVolFlowRate(0.0), DesignVolFlowRateWasAutoSized(false), MaxMassFlowRate(0.0), + MassFlowRate(0.0), AreaCol(0.0), BypassDamperOff(true), CoolingUseful(false), HeatingUseful(false), MySetPointCheckFlag(true), + MyOneTimeFlag(true), SetLoopIndexFlag(true) { } - }; - // Object Data - extern Array1D PVT; + static PlantComponent *factory(std::string const &objectName); - // Functions + void onInitLoopEquip(const PlantLocation &calledFromLocation) override; - void SimPVTcollectors(int &PVTnum, // index to PVT array. - bool const FirstHVACIteration, - int const CalledFrom, - Optional_string_const PVTName = _, - Optional_bool_const InitLoopEquip = _); + void simulate(const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag) override; - void GetPVTcollectorsInput(); + void setupReportVars(); + + void initialize(bool FirstHVACIteration); + + void size(); - void InitPVTcollectors(int const PVTnum, bool const FirstHVACIteration); + void control(); - void SizePVT(int const PVTnum); + void calculate(); - void ControlPVTcollector(int const PVTnum); + void update(); + }; + + extern Array1D PVT; + + void clear_state(); + + void GetPVTcollectorsInput(); - void CalcPVTcollectors(int const PVTnum); + void simPVTfromOASys(int index, bool FirstHVACIteration); - void UpdatePVTcollectors(int const PVTnum); + int getPVTindexFromName(std::string const &name); - void GetPVTThermalPowerProduction(int const PVindex, // index of PV generator (not PVT collector) - Real64 &ThermalPower, - Real64 &ThermalEnergy); - int GetAirInletNodeNum(std::string const &PVTName, - bool &ErrorsFound - ); + void GetPVTThermalPowerProduction(int PVindex, Real64 &ThermalPower, Real64 &ThermalEnergy); - int GetAirOutletNodeNum(std::string const &PVTName, - bool &ErrorsFound - ); + int GetAirInletNodeNum(std::string const &PVTName, bool &ErrorsFound); - //===================== Utility/Other routines for module. - // Insert as appropriate + int GetAirOutletNodeNum(std::string const &PVTName, bool &ErrorsFound); } // namespace PhotovoltaicThermalCollectors diff --git a/src/EnergyPlus/Plant/PlantManager.cc b/src/EnergyPlus/Plant/PlantManager.cc index a2382c2a751..6e0076879a3 100644 --- a/src/EnergyPlus/Plant/PlantManager.cc +++ b/src/EnergyPlus/Plant/PlantManager.cc @@ -89,6 +89,7 @@ #include #include #include +#include #include #include #include @@ -1342,6 +1343,7 @@ namespace EnergyPlus { } else if (LoopSideNum == SupplySide) { this_comp.CurOpSchemeType = UnknownStatusOpSchemeType; } + this_comp.compPtr = PhotovoltaicThermalCollectors::PVTCollectorStruct::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "CentralHeatPumpSystem")) { this_comp.TypeOf_Num = TypeOf_CentralGroundSourceHeatPump; this_comp.GeneralEquipType = GenEquipTypes_CentralHeatPumpSystem; diff --git a/src/EnergyPlus/PlantLoopEquip.cc b/src/EnergyPlus/PlantLoopEquip.cc index 9beb73ad02d..c7d423ba5c3 100644 --- a/src/EnergyPlus/PlantLoopEquip.cc +++ b/src/EnergyPlus/PlantLoopEquip.cc @@ -190,8 +190,6 @@ namespace PlantLoopEquip { using BaseboardRadiator::UpdateBaseboardPlantConnection; using HVACVariableRefrigerantFlow::SimVRFCondenserPlant; using HWBaseboardRadiator::UpdateHWBaseboardPlantConnection; - using PhotovoltaicThermalCollectors::CalledFromPlantLoopEquipMgr; - using PhotovoltaicThermalCollectors::SimPVTcollectors; using RefrigeratedCase::SimRefrigCondenser; using SteamBaseboardRadiator::UpdateSteamBaseboardPlantConnection; using WaterCoils::UpdateWaterToAirCoilPlantConnection; @@ -867,17 +865,9 @@ namespace PlantLoopEquip { sim_component.compPtr->simulate(sim_component_location, FirstHVACIteration, CurLoad, RunFlag); - if (InitLoopEquip) { - sim_component.CompNum = EquipNum; - } - } else if (EquipTypeNum == TypeOf_PVTSolarCollectorFlatPlate) { - SimPVTcollectors(EquipNum, FirstHVACIteration, CalledFromPlantLoopEquipMgr, sim_component.Name, InitLoopEquip); - - if (InitLoopEquip) { - sim_component.CompNum = EquipNum; - } + sim_component.compPtr->simulate(sim_component_location, FirstHVACIteration, CurLoad, RunFlag); } else { ShowSevereError("SimPlantEquip: Invalid Solar Collector Type=" + sim_component.TypeOf); diff --git a/src/EnergyPlus/UnitarySystem.cc b/src/EnergyPlus/UnitarySystem.cc index 056d0cb8a29..8a2536845c0 100644 --- a/src/EnergyPlus/UnitarySystem.cc +++ b/src/EnergyPlus/UnitarySystem.cc @@ -4242,9 +4242,6 @@ namespace UnitarySystems { thisSys.m_CoolingCoilType_Num = DataHVACGlobals::Coil_CoolingWaterToAirHPVSEquationFit; } else if (UtilityRoutines::SameString(loc_coolingCoilType, "Coil:Cooling:DX:SingleSpeed")) { thisSys.m_CoolingCoilType_Num = DataHVACGlobals::CoilDX_CoolingSingleSpeed; - if (DataGlobals::DoCoilDirectSolutions) { - DXCoils::DisableLatentDegradation(thisSys.m_CoolingCoilIndex); - } } else if (UtilityRoutines::SameString(loc_coolingCoilType, "Coil:Cooling:DX:TwoSpeed")) { thisSys.m_CoolingCoilType_Num = DataHVACGlobals::CoilDX_CoolingTwoSpeed; } else if (UtilityRoutines::SameString(loc_coolingCoilType, "Coil:UserDefined")) { @@ -4273,6 +4270,9 @@ namespace UnitarySystems { ShowContinueError("Occurs in " + cCurrentModuleObject + " = " + thisObjectName); errorsFound = true; } + if (DataGlobals::DoCoilDirectSolutions && thisSys.m_CoolingCoilType_Num == DataHVACGlobals::CoilDX_CoolingSingleSpeed) { + DXCoils::DisableLatentDegradation(thisSys.m_CoolingCoilIndex); + } thisSys.m_CoolingCoilAvailSchPtr = DXCoils::GetDXCoilAvailSchPtr(loc_coolingCoilType, loc_m_CoolingCoilName, errFlag); diff --git a/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc b/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc index 158e1741d48..dd93d95c71c 100644 --- a/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc +++ b/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc @@ -59,8 +59,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -71,9 +71,8 @@ #include #include #include -#include #include -#include +#include #include #include #include @@ -84,10 +83,10 @@ #include #include #include -#include +#include #include #include -#include +#include #include #include #include @@ -112,11 +111,12 @@ #include #include #include -#include +#include #include #include #include #include +#include #include #include #include @@ -130,8 +130,18 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #include #include #include @@ -142,16 +152,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include @@ -171,9 +171,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -191,6 +191,7 @@ #include #include #include +#include #include #include #include @@ -211,6 +212,7 @@ #include #include #include +#include #include #include #include @@ -304,27 +306,29 @@ void EnergyPlusFixture::TearDown() void EnergyPlusFixture::clear_all_states() { // A to Z order + AirflowNetwork::clear_state(); AirflowNetworkBalanceManager::clear_state(); BaseboardElectric::clear_state(); BaseboardRadiator::clear_state(); Boilers::clear_state(); BoilerSteam::clear_state(); BranchInputManager::clear_state(); - CoolingPanelSimple::clear_state(); ChillerAbsorption::clear_state(); ChillerElectricEIR::clear_state(); ChillerExhaustAbsorption::clear_state(); ChillerGasAbsorption::clear_state(); ChillerIndirectAbsorption::clear_state(); + clearCoilSelectionReportObj(); // ReportCoilSelection + clearFacilityElectricPowerServiceObject(); CondenserLoopTowers::clear_state(); + CoolingPanelSimple::clear_state(); CoolTower::clear_state(); CrossVentMgr::clear_state(); - CurveManager::clear_state(); CTElectricGenerator::clear_state(); - AirflowNetwork::clear_state(); + CurveManager::clear_state(); DataAirLoop::clear_state(); - DataBranchAirLoopPlant::clear_state(); DataAirSystems::clear_state(); + DataBranchAirLoopPlant::clear_state(); DataBranchNodeConnections::clear_state(); DataContaminantBalance::clear_state(); DataConvergParams::clear_state(); @@ -362,11 +366,12 @@ void EnergyPlusFixture::clear_all_states() DirectAirManager::clear_state(); DualDuct::clear_state(); DXCoils::clear_state(); - clearFacilityElectricPowerServiceObject(); EarthTube::clear_state(); EconomicLifeCycleCost::clear_state(); EconomicTariff::clear_state(); + EIRWaterToWaterHeatPumps::EIRWaterToWaterHeatPump::clear_state(); EMSManager::clear_state(); + EnergyPlus::inputProcessor->clear_state(); EvaporativeCoolers::clear_state(); EvaporativeFluidCoolers::clear_state(); ExteriorEnergyUse::clear_state(); @@ -384,18 +389,18 @@ void EnergyPlusFixture::clear_all_states() HeatBalanceManager::clear_state(); HeatBalanceSurfaceManager::clear_state(); HeatBalFiniteDiffManager::clear_state(); - HeatPumpWaterToWaterSimple::GshpSpecs::clear_state(); + HeatingCoils::clear_state(); HeatPumpWaterToWaterCOOLING::clear_state(); HeatPumpWaterToWaterHEATING::clear_state(); + HeatPumpWaterToWaterSimple::GshpSpecs::clear_state(); HeatRecovery::clear_state(); - HeatingCoils::clear_state(); HighTempRadiantSystem::clear_state(); Humidifiers::clear_state(); HVACControllers::clear_state(); HVACDXHeatPumpSystem::clear_state(); HVACDXSystem::clear_state(); - HVACHXAssistedCoolingCoil::clear_state(); HVACFan::clearHVACFanObjects(); + HVACHXAssistedCoolingCoil::clear_state(); HVACManager::clear_state(); HVACSingleDuctInduc::clear_state(); HVACStandAloneERV::clear_state(); @@ -403,7 +408,6 @@ void EnergyPlusFixture::clear_all_states() HVACVariableRefrigerantFlow::clear_state(); HybridModel::clear_state(); HysteresisPhaseChange::clear_state(); - EnergyPlus::inputProcessor->clear_state(); IceThermalStorage::clear_state(); IntegratedHeatPump::clear_state(); InternalHeatGains::clear_state(); @@ -420,8 +424,9 @@ void EnergyPlusFixture::clear_all_states() OutputReportTabularAnnual::clear_state(); OutsideEnergySources::clear_state(); PackagedTerminalHeatPump::clear_state(); - Pipes::clear_state(); + PhotovoltaicThermalCollectors::clear_state(); PipeHeatTransfer::clear_state(); + Pipes::clear_state(); PlantCentralGSHP::clear_state(); PlantChillers::clear_state(); PlantCondLoopOperation::clear_state(); @@ -429,9 +434,9 @@ void EnergyPlusFixture::clear_all_states() PlantLoopSolver::clear_state(); PlantManager::clear_state(); PlantPipingSystemsManager::clear_state(); + PlantPipingSystemsManager::clear_state(); PlantPressureSystem::clear_state(); PlantUtilities::clear_state(); - PlantPipingSystemsManager::clear_state(); PlantValves::clear_state(); PollutionModule::clear_state(); PoweredInductionUnits::clear_state(); @@ -439,7 +444,7 @@ void EnergyPlusFixture::clear_all_states() Pumps::clear_state(); PurchasedAirManager::clear_state(); PVWatts::clear_state(); - clearCoilSelectionReportObj(); // ReportCoilSelection + ResultsFramework::clear_state(); ReturnAirPathManager::clear_state(); RoomAirModelAirflowNetwork::clear_state(); RoomAirModelManager::clear_state(); @@ -455,8 +460,8 @@ void EnergyPlusFixture::clear_all_states() SplitterComponent::clear_state(); SteamCoils::clear_state(); SurfaceGeometry::clear_state(); - SystemAvailabilityManager::clear_state(); SwimmingPool::clear_state(); + SystemAvailabilityManager::clear_state(); ThermalComfort::clear_state(); UnitarySystems::clear_state(); UnitHeater::clear_state(); @@ -467,7 +472,6 @@ void EnergyPlusFixture::clear_all_states() WaterCoils::clear_state(); WaterThermalTanks::clear_state(); WaterToAirHeatPumpSimple::clear_state(); - EIRWaterToWaterHeatPumps::EIRWaterToWaterHeatPump::clear_state(); WaterUse::clear_state(); WeatherManager::clear_state(); WindowAC::clear_state(); @@ -480,7 +484,6 @@ void EnergyPlusFixture::clear_all_states() ZoneEquipmentManager::clear_state(); ZonePlenum::clear_state(); ZoneTempPredictorCorrector::clear_state(); - ResultsFramework::clear_state(); } std::string EnergyPlusFixture::delimited_string(std::vector const &strings, std::string const &delimiter) diff --git a/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.hh b/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.hh index 7d0ab82206f..30d6eecaa03 100644 --- a/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.hh +++ b/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.hh @@ -148,7 +148,7 @@ protected: } // This function creates a string based on a vector of string inputs that is delimited by DataStringGlobals::NL by default, but any - // delimiter can be passed in to this funciton. This allows for cross platform output string comparisons. + // delimiter can be passed in to this function. This allows for cross platform output string comparisons. std::string delimited_string(std::vector const &strings, std::string const &delimiter = DataStringGlobals::NL); // This function reads all the lines in the supplied filePath. It puts each line into the vector. diff --git a/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc b/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc index 69c8b80a20f..b75b97297c1 100644 --- a/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc +++ b/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc @@ -2019,5 +2019,38 @@ TEST_F(EnergyPlusFixture, HeatBalanceManager_UpdateWindowFaceTempsNonBSDFWin) EXPECT_NEAR(FenLaySurfTempBack(1,3),ZeroResult,0.0001); } - + +TEST_F(EnergyPlusFixture, HeatBalanceManager_HVACSystemRootFindingAlgorithmBisectionInputTest) +{ + // Test eio output for HVACSystemRootFindingAlgorithm + + std::string const idf_objects = delimited_string({ + "Version,9.2;", + "Building,", + "My Building, !- Name", + "30., !- North Axis{ deg }", + "City, !- Terrain", + "0.04, !- Loads Convergence Tolerance Value", + "0.4, !- Temperature Convergence Tolerance Value{ deltaC }", + "FullExterior, !- Solar Distribution", + "25, !- Maximum Number of Warmup Days", + "6; !- Minimum Number of Warmup Days", + "ZoneAirMassFlowConservation,", + "No, !- Adjust Zone Mixing For Zone Air Mass Flow Balance", + "None, !- Infiltration Balancing Method", + "; !- Infiltration Balancing Zones", + " HVACSystemRootFindingAlgorithm,", + " Bisection;!- Algorithm", + + }); + + ASSERT_TRUE(process_idf(idf_objects)); + + bool ErrorsFound(false); // If errors detected in input + ErrorsFound = false; + GetProjectControlData(ErrorsFound); // returns ErrorsFound false + EXPECT_FALSE(ErrorsFound); + EXPECT_EQ(DataHVACGlobals::HVACSystemRootFinding.Algorithm, "BISECTION"); +} + } // namespace EnergyPlus diff --git a/tst/EnergyPlus/unit/UnitarySystem.unit.cc b/tst/EnergyPlus/unit/UnitarySystem.unit.cc index a2c47cddd8d..efb529c7b0e 100644 --- a/tst/EnergyPlus/unit/UnitarySystem.unit.cc +++ b/tst/EnergyPlus/unit/UnitarySystem.unit.cc @@ -11441,3 +11441,232 @@ TEST_F( ZoneUnitarySysTest, UnitarySystemModel_getUnitarySystemInputDataTest ) EXPECT_EQ("MULTISPEED PERFORMANCE", thisSys->m_DesignSpecMultispeedHPName ); // checks design_specification_multispeed_object_name value } +TEST_F(EnergyPlusFixture, UnitarySystemModel_GetInputwithTradeOff) +{ + // Test #7601 + bool ErrorsFound(false); + bool FirstHVACIteration(false); + + std::string const idf_objects = delimited_string({ + "Zone,", + " EAST ZONE, !- Name", + " 0, !- Direction of Relative North{ deg }", + " 0, !- X Origin{ m }", + " 0, !- Y Origin{ m }", + " 0, !- Z Origin{ m }", + " 1, !- Type", + " 1, !- Multiplier", + " autocalculate, !- Ceiling Height{ m }", + " autocalculate; !- Volume{ m3 }", + " ", + "ZoneHVAC:EquipmentConnections,", + "EAST ZONE, !- Zone Name", + " Zone2Equipment, !- Zone Conditioning Equipment List Name", + " Zone 2 Inlet Node, !- Zone Air Inlet Node or NodeList Name", + " Zone Exhaust Node, !- Zone Air Exhaust Node or NodeList Name", + " Zone 2 Node, !- Zone Air Node Name", + " Zone 2 Outlet Node; !- Zone Return Air Node Name", + " ", + "ZoneHVAC:EquipmentList,", + " Zone2Equipment, !- Name", + " SequentialLoad, !- Load Distribution Scheme", + " AirLoopHVAC:UnitarySystem, !- Zone Equipment 1 Object Type", + " Unitary System Model, !- Zone Equipment 1 Name", + " 1, !- Zone Equipment 1 Cooling Sequence", + " 1, !- Zone Equipment 1 Heating or No - Load Sequence", + " , !- Zone Equipment 1 Sequential Cooling Fraction", + " ; !- Zone Equipment 1 Sequential Heating Fraction", + " ", + "AirLoopHVAC:UnitarySystem,", + " Unitary System Model, !- Name", + " Load, !- Control Type", + " East Zone, !- Controlling Zone or Thermostat Location", + " None, !- Dehumidification Control Type", + " FanAndCoilAvailSched, !- Availability Schedule Name", + " Zone Exhaust Node, !- Air Inlet Node Name", + " Zone 2 Inlet Node, !- Air Outlet Node Name", + " Fan:OnOff, !- Supply Fan Object Type", + " Supply Fan 1, !- Supply Fan Name", + " BlowThrough, !- Fan Placement", + " ContinuousFanSchedule, !- Supply Air Fan Operating Mode Schedule Name", + " Coil:Heating:Fuel, !- Heating Coil Object Type", + " Furnace Heating Coil 1, !- Heating Coil Name", + " , !- DX Heating Coil Sizing Ratio", + " Coil:Cooling:DX:SingleSpeed, !- Cooling Coil Object Type", + " Furnace ACDXCoil 1, !- Cooling Coil Name", + " , !- Use DOAS DX Cooling Coil", + " , !- DOAS DX Cooling Coil Leaving Minimum Air Temperature{ C }", + " , !- Latent Load Control", + " Coil:Heating:Fuel, !- Supplemental Heating Coil Object Type", + " Humidistat Reheat Coil 1, !- Supplemental Heating Coil Name", + " SupplyAirFlowRate, !- Supply Air Flow Rate Method During Cooling Operation", + " 1.6, !- Supply Air Flow Rate During Cooling Operation{ m3/s }", + " , !- Supply Air Flow Rate Per Floor Area During Cooling Operation{ m3/s-m2 }", + " , !- Fraction of Autosized Design Cooling Supply Air Flow Rate", + " , !- Design Supply Air Flow Rate Per Unit of Capacity During Cooling Operation{ m3/s-W }", + " SupplyAirFlowRate, !- Supply air Flow Rate Method During Heating Operation", + " 1.6, !- Supply Air Flow Rate During Heating Operation{ m3/s }", + " , !- Supply Air Flow Rate Per Floor Area during Heating Operation{ m3/s-m2 }", + " , !- Fraction of Autosized Design Heating Supply Air Flow Rate", + " , !- Design Supply Air Flow Rate Per Unit of Capacity During Heating Operation{ m3/s-W }", + " SupplyAirFlowRate, !- Supply Air Flow Rate Method When No Cooling or Heating is Required", + " 1.6, !- Supply Air Flow Rate When No Cooling or Heating is Required{ m3/s }", + " , !- Supply Air Flow Rate Per Floor Area When No Cooling or Heating is Required{ m3/s-m2 }", + " , !- Fraction of Autosized Design Cooling Supply Air Flow Rate", + " , !- Fraction of Autosized Design Heating Supply Air Flow Rate", + " , !- Design Supply Air Flow Rate Per Unit of Capacity During Cooling Operation{ m3/s-W }", + " , !- Design Supply Air Flow Rate Per Unit of Capacity During Heating Operation{ m3/s-W }", + " 80; !- Maximum Supply Air Temperature{ C }", + " ", + "Fan:OnOff,", + " Supply Fan 1, !- Name", + " FanAndCoilAvailSched, !- Availability Schedule Name", + " 0.7, !- Fan Total Efficiency", + " 600.0, !- Pressure Rise{ Pa }", + " 1.6, !- Maximum Flow Rate{ m3 / s }", + " 0.9, !- Motor Efficiency", + " 1.0, !- Motor In Airstream Fraction", + " Zone Exhaust Node, !- Air Inlet Node Name", + " DX Cooling Coil Air Inlet Node; !- Air Outlet Node Name", + " ", + "Coil:Cooling:DX:SingleSpeed,", + " Furnace ACDXCoil 1, !- Name", + " FanAndCoilAvailSched, !- Availability Schedule Name", + " 32000, !- Gross Rated Total Cooling Capacity {W}", + " 0.75, !- Gross Rated Sensible Heat Ratio", + " 3.0, !- Gross Rated Cooling COP {W/W}", + " 1.6, !- Rated Air Flow Rate {m3/s}", + " , !- Rated Evaporator Fan Power Per Volume Flow Rate {W/(m3/s)}", + " DX Cooling Coil Air Inlet Node, !- Air Inlet Node Name", + " Heating Coil Air Inlet Node, !- Air Outlet Node Name", + " WindACCoolCapFT, !- Total Cooling Capacity Function of Temperature Curve Name", + " WindACCoolCapFFF, !- Total Cooling Capacity Function of Flow Fraction Curve Name", + " WindACEIRFT, !- Energy Input Ratio Function of Temperature Curve Name", + " WindACEIRFFF, !- Energy Input Ratio Function of Flow Fraction Curve Name", + " WindACPLFFPLR, !- Part Load Fraction Correlation Curve Name", + " , !- Minimum Outdoor Dry-Bulb Temperature for Compressor Operation {C}", + " 1000, !- Nominal Time for Condensate Removal to Begin {s}", + " 0.4, !- Ratio of Initial Moisture Evaporation Rate and Steady State Latent Capacity {dimensionless}", + " 4, !- Maximum Cycling Rate {cycles/hr}", + " 45; !- Latent Capacity Time Constant {s}", + " ", + "Coil:Heating:Fuel,", + " Furnace Heating Coil 1, !- Name", + " FanAndCoilAvailSched, !- Availability Schedule Name", + " Gas, !- Fuel Type", + " 0.8, !- Gas Burner Efficiency", + " 32000, !- Nominal Capacity{ W }", + " Heating Coil Air Inlet Node, !- Air Inlet Node Name", + " Reheat Coil Air Inlet Node; !- Air Outlet Node Name", + " ", + "Coil:Heating:Fuel,", + " Humidistat Reheat Coil 1, !- Name", + " FanAndCoilAvailSched, !- Availability Schedule Name", + " Gas, !- Fuel Type", + " 0.8, !- Gas Burner Efficiency", + " 32000, !- Nominal Capacity{ W }", + " Reheat Coil Air Inlet Node, !- Air Inlet Node Name", + " Zone 2 Inlet Node; !- Air Outlet Node Name", + " ", + "ScheduleTypeLimits,", + " Any Number; !- Name", + " ", + "Schedule:Compact,", + " FanAndCoilAvailSched, !- Name", + " Any Number, !- Schedule Type Limits Name", + " Through: 12/31, !- Field 1", + " For: AllDays, !- Field 2", + " Until: 24:00, 1.0; !- Field 3", + " ", + "Schedule:Compact,", + " ContinuousFanSchedule, !- Name", + " Any Number, !- Schedule Type Limits Name", + " Through: 12/31, !- Field 1", + " For: AllDays, !- Field 2", + " Until: 24:00, 1.0; !- Field 3", + " ", + "Curve:Quadratic,", + " WindACCoolCapFFF, !- Name", + " 0.8, !- Coefficient1 Constant", + " 0.2, !- Coefficient2 x", + " 0.0, !- Coefficient3 x**2", + " 0.5, !- Minimum Value of x", + " 1.5; !- Maximum Value of x", + " ", + "Curve:Quadratic,", + " WindACEIRFFF, !- Name", + " 1.1552, !- Coefficient1 Constant", + " -0.1808, !- Coefficient2 x", + " 0.0256, !- Coefficient3 x**2", + " 0.5, !- Minimum Value of x", + " 1.5; !- Maximum Value of x", + " ", + "Curve:Quadratic,", + " WindACPLFFPLR, !- Name", + " 0.85, !- Coefficient1 Constant", + " 0.15, !- Coefficient2 x", + " 0.0, !- Coefficient3 x**2", + " 0.0, !- Minimum Value of x", + " 1.0; !- Maximum Value of x", + " ", + "Curve:Biquadratic,", + " WindACCoolCapFT, !- Name", + " 0.942587793, !- Coefficient1 Constant", + " 0.009543347, !- Coefficient2 x", + " 0.000683770, !- Coefficient3 x**2", + " -0.011042676, !- Coefficient4 y", + " 0.000005249, !- Coefficient5 y**2", + " -0.000009720, !- Coefficient6 x*y", + " 12.77778, !- Minimum Value of x", + " 23.88889, !- Maximum Value of x", + " 18.0, !- Minimum Value of y", + " 46.11111, !- Maximum Value of y", + " , !- Minimum Curve Output", + " , !- Maximum Curve Output", + " Temperature, !- Input Unit Type for X", + " Temperature, !- Input Unit Type for Y", + " Dimensionless; !- Output Unit Type", + " ", + "Curve:Biquadratic,", + " WindACEIRFT, !- Name", + " 0.342414409, !- Coefficient1 Constant", + " 0.034885008, !- Coefficient2 x", + " -0.000623700, !- Coefficient3 x**2", + " 0.004977216, !- Coefficient4 y", + " 0.000437951, !- Coefficient5 y**2", + " -0.000728028, !- Coefficient6 x*y", + " 12.77778, !- Minimum Value of x", + " 23.88889, !- Maximum Value of x", + " 18.0, !- Minimum Value of y", + " 46.11111, !- Maximum Value of y", + " , !- Minimum Curve Output", + " , !- Maximum Curve Output", + " Temperature, !- Input Unit Type for X", + " Temperature, !- Input Unit Type for Y", + " Dimensionless; !- Output Unit Type", + }); + + ASSERT_TRUE(process_idf(idf_objects)); // read idf objects + + HeatBalanceManager::GetZoneData(ErrorsFound); // read zone data + EXPECT_FALSE(ErrorsFound); // expect no errors + + DataZoneEquipment::GetZoneEquipmentData1(); // read zone equipment configuration and list objects + + DataSizing::ZoneEqSizing.allocate(1); + DataZoneEquipment::ZoneEquipList(1).EquipIndex.allocate(1); + DataZoneEquipment::ZoneEquipList(1).EquipIndex(1) = 1; // initialize equipment index for ZoneHVAC + + UnitarySys mySys; + std::string compName = "UNITARY SYSTEM MODEL"; + bool zoneEquipment = true; + int compTypeOfNum = DataHVACGlobals::UnitarySys_AnyCoilType; + FirstHVACIteration = true; + UnitarySys *thisSys; + thisSys = mySys.factory(compTypeOfNum, compName, zoneEquipment, 0); + + DataGlobals::DoCoilDirectSolutions = true; + DataZoneEquipment::ZoneEquipInputsFilled = true; // indicate zone data is available + thisSys->getUnitarySystemInputData(compName, zoneEquipment, 0, ErrorsFound); // get UnitarySystem input from object above + EXPECT_FALSE(ErrorsFound); // expect no errors +}