diff --git a/src/EnergyPlus/BaseboardRadiator.cc b/src/EnergyPlus/BaseboardRadiator.cc index 1655fc11ee3..97ebe1f1a89 100644 --- a/src/EnergyPlus/BaseboardRadiator.cc +++ b/src/EnergyPlus/BaseboardRadiator.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/BoilerSteam.cc b/src/EnergyPlus/BoilerSteam.cc index 088005aa691..48f291100b5 100644 --- a/src/EnergyPlus/BoilerSteam.cc +++ b/src/EnergyPlus/BoilerSteam.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/Boilers.cc b/src/EnergyPlus/Boilers.cc index c6a0069e753..c42ae8165f2 100644 --- a/src/EnergyPlus/Boilers.cc +++ b/src/EnergyPlus/Boilers.cc @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/CMakeLists.txt b/src/EnergyPlus/CMakeLists.txt index 9413fb7ca03..4480a8d09f7 100644 --- a/src/EnergyPlus/CMakeLists.txt +++ b/src/EnergyPlus/CMakeLists.txt @@ -128,8 +128,6 @@ SET( SRC DataOutputs.hh DataPhotovoltaics.cc DataPhotovoltaics.hh - DataPlant.cc - DataPlant.hh DataPrecisionGlobals.cc DataPrecisionGlobals.hh DataReportingFlags.cc @@ -398,22 +396,26 @@ SET( SRC Pipes.cc Pipes.hh Plant/CallingOrder.hh + Plant/DataPlant.cc + Plant/DataPlant.hh Plant/Enums.hh Plant/EquipAndOperations.hh Plant/LoopSidePumpInformation.hh Plant/PlantAvailManager.hh Plant/PlantConvergencePoint.hh - Plant/LoopSideReportVars.hh Plant/MeterData.hh Plant/ReportBranchData.hh Plant/ReportCompData.hh Plant/ReportLoopData.hh - Plant/ReportVars.hh + Plant/Branch.cc Plant/Branch.hh + Plant/Component.cc Plant/Component.hh Plant/ConnectedLoopData.hh Plant/Connection.hh + Plant/Loop.cc Plant/Loop.hh + Plant/LoopSide.cc Plant/LoopSide.hh Plant/MixerData.hh Plant/SplitterData.hh @@ -432,10 +434,6 @@ SET( SRC PlantLoadProfile.cc PlantLoadProfile.hh Plant/PlantLocation.hh - PlantLoopEquip.cc - PlantLoopEquip.hh - Plant/PlantLoopSolver.cc - Plant/PlantLoopSolver.hh Plant/PlantManager.cc Plant/PlantManager.hh PlantPipingSystemsManager.cc diff --git a/src/EnergyPlus/CTElectricGenerator.cc b/src/EnergyPlus/CTElectricGenerator.cc index ffab4adadc3..4758a41d29a 100644 --- a/src/EnergyPlus/CTElectricGenerator.cc +++ b/src/EnergyPlus/CTElectricGenerator.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/ChilledCeilingPanelSimple.cc b/src/EnergyPlus/ChilledCeilingPanelSimple.cc index f166ae4514e..d104f8846e6 100644 --- a/src/EnergyPlus/ChilledCeilingPanelSimple.cc +++ b/src/EnergyPlus/ChilledCeilingPanelSimple.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/ChillerAbsorption.cc b/src/EnergyPlus/ChillerAbsorption.cc index fd59a2b9332..2af1b0aec23 100644 --- a/src/EnergyPlus/ChillerAbsorption.cc +++ b/src/EnergyPlus/ChillerAbsorption.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/ChillerElectricEIR.cc b/src/EnergyPlus/ChillerElectricEIR.cc index baf53d479db..4df0e98a006 100644 --- a/src/EnergyPlus/ChillerElectricEIR.cc +++ b/src/EnergyPlus/ChillerElectricEIR.cc @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/ChillerExhaustAbsorption.cc b/src/EnergyPlus/ChillerExhaustAbsorption.cc index 2f9e8209033..8b60e724e57 100644 --- a/src/EnergyPlus/ChillerExhaustAbsorption.cc +++ b/src/EnergyPlus/ChillerExhaustAbsorption.cc @@ -58,13 +58,11 @@ #include #include #include -//#include #include #include #include #include -#include -//#include +#include #include #include #include diff --git a/src/EnergyPlus/ChillerGasAbsorption.cc b/src/EnergyPlus/ChillerGasAbsorption.cc index 06d6f1f0332..6b6549535e6 100644 --- a/src/EnergyPlus/ChillerGasAbsorption.cc +++ b/src/EnergyPlus/ChillerGasAbsorption.cc @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/ChillerIndirectAbsorption.cc b/src/EnergyPlus/ChillerIndirectAbsorption.cc index 7842f9bdfd2..e4a61644785 100644 --- a/src/EnergyPlus/ChillerIndirectAbsorption.cc +++ b/src/EnergyPlus/ChillerIndirectAbsorption.cc @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/ChillerReformulatedEIR.cc b/src/EnergyPlus/ChillerReformulatedEIR.cc index 41e3fa7e56c..e4c843c7bd2 100644 --- a/src/EnergyPlus/ChillerReformulatedEIR.cc +++ b/src/EnergyPlus/ChillerReformulatedEIR.cc @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/CondenserLoopTowers.cc b/src/EnergyPlus/CondenserLoopTowers.cc index 340ca9e11db..8427245cec4 100644 --- a/src/EnergyPlus/CondenserLoopTowers.cc +++ b/src/EnergyPlus/CondenserLoopTowers.cc @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/DataAirSystems.hh b/src/EnergyPlus/DataAirSystems.hh index fcba0f29131..006e43577d7 100644 --- a/src/EnergyPlus/DataAirSystems.hh +++ b/src/EnergyPlus/DataAirSystems.hh @@ -53,8 +53,8 @@ // EnergyPlus Headers #include +#include #include -#include #include namespace EnergyPlus { diff --git a/src/EnergyPlus/DesiccantDehumidifiers.cc b/src/EnergyPlus/DesiccantDehumidifiers.cc index c2353aba595..bcaaaa3052d 100644 --- a/src/EnergyPlus/DesiccantDehumidifiers.cc +++ b/src/EnergyPlus/DesiccantDehumidifiers.cc @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/ElectricPowerServiceManager.cc b/src/EnergyPlus/ElectricPowerServiceManager.cc index 9fc44b88dcf..5a5095b0d15 100644 --- a/src/EnergyPlus/ElectricPowerServiceManager.cc +++ b/src/EnergyPlus/ElectricPowerServiceManager.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/EvaporativeFluidCoolers.cc b/src/EnergyPlus/EvaporativeFluidCoolers.cc index afd81a949d8..adc8d76786d 100644 --- a/src/EnergyPlus/EvaporativeFluidCoolers.cc +++ b/src/EnergyPlus/EvaporativeFluidCoolers.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/FanCoilUnits.cc b/src/EnergyPlus/FanCoilUnits.cc index e13ffb9b27b..2e6041d8526 100644 --- a/src/EnergyPlus/FanCoilUnits.cc +++ b/src/EnergyPlus/FanCoilUnits.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/FluidCoolers.cc b/src/EnergyPlus/FluidCoolers.cc index 1110a217ee2..9611f304701 100644 --- a/src/EnergyPlus/FluidCoolers.cc +++ b/src/EnergyPlus/FluidCoolers.cc @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/FuelCellElectricGenerator.cc b/src/EnergyPlus/FuelCellElectricGenerator.cc index 58db5ce6e8f..2e656889939 100644 --- a/src/EnergyPlus/FuelCellElectricGenerator.cc +++ b/src/EnergyPlus/FuelCellElectricGenerator.cc @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/GeneratorDynamicsManager.cc b/src/EnergyPlus/GeneratorDynamicsManager.cc index f1abb578f43..093937d8d9c 100644 --- a/src/EnergyPlus/GeneratorDynamicsManager.cc +++ b/src/EnergyPlus/GeneratorDynamicsManager.cc @@ -59,7 +59,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/GroundHeatExchangers.cc b/src/EnergyPlus/GroundHeatExchangers.cc index 8503da353bd..953addc25ff 100644 --- a/src/EnergyPlus/GroundHeatExchangers.cc +++ b/src/EnergyPlus/GroundHeatExchangers.cc @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HVACControllers.cc b/src/EnergyPlus/HVACControllers.cc index 6559dbe0aa8..58a657aaea2 100644 --- a/src/EnergyPlus/HVACControllers.cc +++ b/src/EnergyPlus/HVACControllers.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HVACCooledBeam.cc b/src/EnergyPlus/HVACCooledBeam.cc index 7196aabf468..513e3e5c4ea 100644 --- a/src/EnergyPlus/HVACCooledBeam.cc +++ b/src/EnergyPlus/HVACCooledBeam.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HVACFourPipeBeam.cc b/src/EnergyPlus/HVACFourPipeBeam.cc index e8e209f7b7c..1113d682d78 100644 --- a/src/EnergyPlus/HVACFourPipeBeam.cc +++ b/src/EnergyPlus/HVACFourPipeBeam.cc @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HVACInterfaceManager.cc b/src/EnergyPlus/HVACInterfaceManager.cc index 7f757ec845f..8385109bc89 100644 --- a/src/EnergyPlus/HVACInterfaceManager.cc +++ b/src/EnergyPlus/HVACInterfaceManager.cc @@ -59,7 +59,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HVACManager.cc b/src/EnergyPlus/HVACManager.cc index c098611a60b..b3c9bc5da54 100644 --- a/src/EnergyPlus/HVACManager.cc +++ b/src/EnergyPlus/HVACManager.cc @@ -71,7 +71,7 @@ #include #include #include -#include +#include #include #include #include @@ -80,7 +80,6 @@ #include #include #include -//#include #include #include #include @@ -105,7 +104,6 @@ #include #include #include -//#include #include #include #include diff --git a/src/EnergyPlus/HVACMultiSpeedHeatPump.cc b/src/EnergyPlus/HVACMultiSpeedHeatPump.cc index fe30c9ed841..2014ddd5561 100644 --- a/src/EnergyPlus/HVACMultiSpeedHeatPump.cc +++ b/src/EnergyPlus/HVACMultiSpeedHeatPump.cc @@ -65,7 +65,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HVACSingleDuctInduc.cc b/src/EnergyPlus/HVACSingleDuctInduc.cc index fa02480b2f5..04f277e722d 100644 --- a/src/EnergyPlus/HVACSingleDuctInduc.cc +++ b/src/EnergyPlus/HVACSingleDuctInduc.cc @@ -59,7 +59,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HVACSizingSimulationManager.cc b/src/EnergyPlus/HVACSizingSimulationManager.cc index ba52dd32948..b389faa710e 100644 --- a/src/EnergyPlus/HVACSizingSimulationManager.cc +++ b/src/EnergyPlus/HVACSizingSimulationManager.cc @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include #include @@ -131,7 +131,6 @@ void HVACSizingSimulationManager::CreateNewCoincidentPlantAnalysisObject(std::st void HVACSizingSimulationManager::SetupSizingAnalyses() { using DataLoopNode::Node; - using DataPlant::PlantReport; using DataSizing::CondenserLoop; using DataSizing::CoolingLoop; using DataSizing::HeatingLoop; @@ -143,9 +142,9 @@ void HVACSizingSimulationManager::SetupSizingAnalyses() P.supplyInletNodeFlow_LogIndex = sizingLogger.SetupVariableSizingLog(Node(P.supplySideInletNodeNum).MassFlowRate, P.numTimeStepsInAvg); P.supplyInletNodeTemp_LogIndex = sizingLogger.SetupVariableSizingLog(Node(P.supplySideInletNodeNum).Temp, P.numTimeStepsInAvg); if (PlantSizData(P.plantSizingIndex).LoopType == HeatingLoop || PlantSizData(P.plantSizingIndex).LoopType == SteamLoop) { - P.loopDemand_LogIndex = sizingLogger.SetupVariableSizingLog(PlantReport(P.plantLoopIndex).HeatingDemand, P.numTimeStepsInAvg); + P.loopDemand_LogIndex = sizingLogger.SetupVariableSizingLog(DataPlant::PlantLoop(P.plantLoopIndex).HeatingDemand, P.numTimeStepsInAvg); } else if (PlantSizData(P.plantSizingIndex).LoopType == CoolingLoop || PlantSizData(P.plantSizingIndex).LoopType == CondenserLoop) { - P.loopDemand_LogIndex = sizingLogger.SetupVariableSizingLog(PlantReport(P.plantLoopIndex).CoolingDemand, P.numTimeStepsInAvg); + P.loopDemand_LogIndex = sizingLogger.SetupVariableSizingLog(DataPlant::PlantLoop(P.plantLoopIndex).CoolingDemand, P.numTimeStepsInAvg); } } } diff --git a/src/EnergyPlus/HVACSizingSimulationManager.hh b/src/EnergyPlus/HVACSizingSimulationManager.hh index dd32b8944c2..e21a28e1c25 100644 --- a/src/EnergyPlus/HVACSizingSimulationManager.hh +++ b/src/EnergyPlus/HVACSizingSimulationManager.hh @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HVACUnitaryBypassVAV.cc b/src/EnergyPlus/HVACUnitaryBypassVAV.cc index f496b9f9cea..8a229a0e5e4 100644 --- a/src/EnergyPlus/HVACUnitaryBypassVAV.cc +++ b/src/EnergyPlus/HVACUnitaryBypassVAV.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 9645f1854d2..910507e3b11 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -68,7 +68,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HWBaseboardRadiator.cc b/src/EnergyPlus/HWBaseboardRadiator.cc index 556ee3fa215..fcedeaf6008 100644 --- a/src/EnergyPlus/HWBaseboardRadiator.cc +++ b/src/EnergyPlus/HWBaseboardRadiator.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HeatPumpWaterToWaterCOOLING.cc b/src/EnergyPlus/HeatPumpWaterToWaterCOOLING.cc index 96194c643cb..b4089839aa5 100644 --- a/src/EnergyPlus/HeatPumpWaterToWaterCOOLING.cc +++ b/src/EnergyPlus/HeatPumpWaterToWaterCOOLING.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HeatPumpWaterToWaterHEATING.cc b/src/EnergyPlus/HeatPumpWaterToWaterHEATING.cc index ae32f538a79..c428f9a9ad4 100644 --- a/src/EnergyPlus/HeatPumpWaterToWaterHEATING.cc +++ b/src/EnergyPlus/HeatPumpWaterToWaterHEATING.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/HeatPumpWaterToWaterSimple.cc b/src/EnergyPlus/HeatPumpWaterToWaterSimple.cc index 8b9f285dd80..2ca14b08732 100644 --- a/src/EnergyPlus/HeatPumpWaterToWaterSimple.cc +++ b/src/EnergyPlus/HeatPumpWaterToWaterSimple.cc @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/ICEngineElectricGenerator.cc b/src/EnergyPlus/ICEngineElectricGenerator.cc index e3ffbe21b0c..f0ffa54740f 100644 --- a/src/EnergyPlus/ICEngineElectricGenerator.cc +++ b/src/EnergyPlus/ICEngineElectricGenerator.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/IceThermalStorage.cc b/src/EnergyPlus/IceThermalStorage.cc index c0907ad6a68..2995e75d1a8 100644 --- a/src/EnergyPlus/IceThermalStorage.cc +++ b/src/EnergyPlus/IceThermalStorage.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/IntegratedHeatPump.cc b/src/EnergyPlus/IntegratedHeatPump.cc index cc20f83a03f..f1db6476179 100644 --- a/src/EnergyPlus/IntegratedHeatPump.cc +++ b/src/EnergyPlus/IntegratedHeatPump.cc @@ -53,7 +53,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/LowTempRadiantSystem.cc b/src/EnergyPlus/LowTempRadiantSystem.cc index 0f92694abd8..9ff0a6e8731 100644 --- a/src/EnergyPlus/LowTempRadiantSystem.cc +++ b/src/EnergyPlus/LowTempRadiantSystem.cc @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/MicroCHPElectricGenerator.cc b/src/EnergyPlus/MicroCHPElectricGenerator.cc index 904c35cd4f0..6be85c1ea6a 100644 --- a/src/EnergyPlus/MicroCHPElectricGenerator.cc +++ b/src/EnergyPlus/MicroCHPElectricGenerator.cc @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/MicroturbineElectricGenerator.cc b/src/EnergyPlus/MicroturbineElectricGenerator.cc index 491c461fa39..e2b578cd76c 100644 --- a/src/EnergyPlus/MicroturbineElectricGenerator.cc +++ b/src/EnergyPlus/MicroturbineElectricGenerator.cc @@ -59,7 +59,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/OutdoorAirUnit.cc b/src/EnergyPlus/OutdoorAirUnit.cc index b325d02f241..c6a5fb39ad2 100644 --- a/src/EnergyPlus/OutdoorAirUnit.cc +++ b/src/EnergyPlus/OutdoorAirUnit.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/OutsideEnergySources.cc b/src/EnergyPlus/OutsideEnergySources.cc index 116acc08fdf..262d214ca63 100644 --- a/src/EnergyPlus/OutsideEnergySources.cc +++ b/src/EnergyPlus/OutsideEnergySources.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PackagedTerminalHeatPump.cc b/src/EnergyPlus/PackagedTerminalHeatPump.cc index 6e82bddccef..9aed39f9860 100644 --- a/src/EnergyPlus/PackagedTerminalHeatPump.cc +++ b/src/EnergyPlus/PackagedTerminalHeatPump.cc @@ -65,7 +65,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PackagedThermalStorageCoil.cc b/src/EnergyPlus/PackagedThermalStorageCoil.cc index 44b184a340e..2a2d5664f5e 100644 --- a/src/EnergyPlus/PackagedThermalStorageCoil.cc +++ b/src/EnergyPlus/PackagedThermalStorageCoil.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PhotovoltaicThermalCollectors.cc b/src/EnergyPlus/PhotovoltaicThermalCollectors.cc index 8293291a09b..89e5880f22b 100644 --- a/src/EnergyPlus/PhotovoltaicThermalCollectors.cc +++ b/src/EnergyPlus/PhotovoltaicThermalCollectors.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PipeHeatTransfer.cc b/src/EnergyPlus/PipeHeatTransfer.cc index 72d340c9663..f84d6a01716 100644 --- a/src/EnergyPlus/PipeHeatTransfer.cc +++ b/src/EnergyPlus/PipeHeatTransfer.cc @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/Pipes.cc b/src/EnergyPlus/Pipes.cc index 2881d20a477..5a81c2a7cc1 100644 --- a/src/EnergyPlus/Pipes.cc +++ b/src/EnergyPlus/Pipes.cc @@ -53,7 +53,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/Plant/ReportVars.hh b/src/EnergyPlus/Plant/Branch.cc similarity index 58% rename from src/EnergyPlus/Plant/ReportVars.hh rename to src/EnergyPlus/Plant/Branch.cc index 1fe938a3604..6f204a9c843 100644 --- a/src/EnergyPlus/Plant/ReportVars.hh +++ b/src/EnergyPlus/Plant/Branch.cc @@ -45,40 +45,57 @@ // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -#ifndef PlantReportingReportVars_hh_INCLUDED -#define PlantReportingReportVars_hh_INCLUDED - -#include +#include +#include +#include +#include namespace EnergyPlus { namespace DataPlant { - struct ReportVars - { - // Members - // Whole loop descriptions - Real64 CoolingDemand; // Plant Loop Cooling Demand, W - Real64 HeatingDemand; // Plant Loop Heating Demand[W] - Real64 DemandNotDispatched; // Plant Loop Demand that was not distributed [W] - Real64 UnmetDemand; // Plant Loop Unmet Demand [W] - // Loop side data - Array1D LoopSide; - Real64 BypassFrac; // Debug Variable - Real64 InletNodeFlowrate; // Debug Variable - Real64 InletNodeTemperature; // Debug Variable - Real64 OutletNodeFlowrate; // Debug Variable - Real64 OutletNodeTemperature; // Debug Variable - int LastLoopSideSimulated; + Real64 BranchData::DetermineBranchFlowRequest() { + + // SUBROUTINE INFORMATION: + // AUTHOR Edwin Lee + // DATE WRITTEN September 2010 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS SUBROUTINE: + // This routine will analyze the given branch and determine the representative + // flow request. + + // METHODOLOGY EMPLOYED: + // Several possibilities are available. In any case, the request is constrained to within + // branch outlet min/max avail. This assumes that the component flow routines will properly + // propagate the min/max avail down the branch. + // Some possibilities for flow request are: + // 1) take the outlet flow rate -- assumes that the last component wins + // 2) take the inlet flow rate request -- assumes that the request is propogated up and is good + // 3) take the maximum request + // 4) move down the loop and take the maximum "non-load-range-based" request within min/max avail bounds + // This assumes that load range based should not request flow for load-rejection purposes, and we + // should only "respond" to other component types. - // Default Constructor - ReportVars() - : CoolingDemand(0.0), HeatingDemand(0.0), DemandNotDispatched(0.0), UnmetDemand(0.0), LoopSide(2), BypassFrac(0.0), - InletNodeFlowrate(0.0), InletNodeTemperature(0.0), OutletNodeFlowrate(0.0), OutletNodeTemperature(0.0), LastLoopSideSimulated(0) - { + int const BranchInletNodeNum = this->NodeNumIn; + int const BranchOutletNodeNum = this->NodeNumOut; + Real64 OverallFlowRequest = 0.0; + + if (this->ControlType != DataBranchAirLoopPlant::ControlType_SeriesActive) { + OverallFlowRequest = DataLoopNode::Node(BranchInletNodeNum).MassFlowRateRequest; + } else { // is series active, so take largest request of all the component inlet nodes + for (int CompCounter = 1; CompCounter <= this->TotalComponents; ++CompCounter) { + int const CompInletNode = this->Comp(CompCounter).NodeNumIn; + OverallFlowRequest = max(OverallFlowRequest, DataLoopNode::Node(CompInletNode).MassFlowRateRequest); + } } - }; -} // namespace DataPlant -} // namespace EnergyPlus + //~ Now use a worker to bound the value to outlet min/max avail + OverallFlowRequest = PlantUtilities::BoundValueToNodeMinMaxAvail(OverallFlowRequest, BranchOutletNodeNum); + + return OverallFlowRequest; + + } -#endif +} +} diff --git a/src/EnergyPlus/Plant/Branch.hh b/src/EnergyPlus/Plant/Branch.hh index cbab62c25a9..28e180c203b 100644 --- a/src/EnergyPlus/Plant/Branch.hh +++ b/src/EnergyPlus/Plant/Branch.hh @@ -99,6 +99,8 @@ namespace DataPlant { } return load; } + + Real64 DetermineBranchFlowRequest(); }; } // namespace DataPlant diff --git a/src/EnergyPlus/PlantLoopEquip.cc b/src/EnergyPlus/Plant/Component.cc similarity index 78% rename from src/EnergyPlus/PlantLoopEquip.cc rename to src/EnergyPlus/Plant/Component.cc index 37e6fc85cb9..1af589831e9 100644 --- a/src/EnergyPlus/PlantLoopEquip.cc +++ b/src/EnergyPlus/Plant/Component.cc @@ -45,33 +45,28 @@ // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -// C++ Headers -#include - -// EnergyPlus Headers -#include -#include -#include +#include +#include namespace EnergyPlus { +namespace DataPlant { -namespace PlantLoopEquip { - - // MODULE INFORMATION: - // AUTHOR Sankaranarayanan K P - // DATE WRITTEN July 2005 - // MODIFIED na - // RE-ENGINEERED na + bool CompData::isPump() { + if (this->TypeOf_Num == DataPlant::TypeOf_PumpConstantSpeed) { + return true; + } else if (this->TypeOf_Num == DataPlant::TypeOf_PumpVariableSpeed) { + return true; + } else if (this->TypeOf_Num == DataPlant::TypeOf_PumpBankConstantSpeed) { + return true; + } else if (this->TypeOf_Num == DataPlant::TypeOf_PumpBankVariableSpeed) { + return true; + } else if (this->TypeOf_Num == DataPlant::TypeOf_PumpCondensate) { + return true; + } + return false; + } - void SimPlantEquip(int const LoopNum, // loop counter - int const LoopSideNum, // loop counter - int const BranchNum, - int const Num, - bool const FirstHVACIteration, // TRUE if First iteration of simulation - bool &InitLoopEquip, - bool const GetCompSizFac // Tells component routine to return the component sizing fraction - ) - { + void CompData::simulate(bool const FirstHVACIteration, bool &InitLoopEquip, bool const GetCompSizFac) { // SUBROUTINE INFORMATION: // AUTHOR Dan Fisher @@ -116,18 +111,16 @@ namespace PlantLoopEquip { // If you add a module or new equipment type, you must set up this structure. // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - EnergyPlus::PlantLocation sim_component_location(LoopNum, LoopSideNum, BranchNum, Num); - auto &sim_component(DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(Num)); - static std::vector compsToSimAfterInitLoopEquip = {DataPlant::TypeOf_Pipe, DataPlant::TypeOf_PipeSteam, DataPlant::TypeOf_SolarCollectorICS, DataPlant::TypeOf_SolarCollectorFlatPlate}; - if (sim_component.compPtr != nullptr) { + static std::vector compsToSimAfterInitLoopEquip = { + DataPlant::TypeOf_Pipe, DataPlant::TypeOf_PipeSteam, DataPlant::TypeOf_SolarCollectorICS, DataPlant::TypeOf_SolarCollectorFlatPlate}; + if (this->compPtr != nullptr) { if (InitLoopEquip) { - sim_component.compPtr->onInitLoopEquip(sim_component_location); - sim_component.compPtr->getDesignCapacities( - sim_component_location, sim_component.MaxLoad, sim_component.MinLoad, sim_component.OptLoad); - sim_component.compPtr->getDesignTemperatures(sim_component.TempDesCondIn, sim_component.TempDesEvapOut); + this->compPtr->onInitLoopEquip(this->location); + this->compPtr->getDesignCapacities(this->location, this->MaxLoad, this->MinLoad, this->OptLoad); + this->compPtr->getDesignTemperatures(this->TempDesCondIn, this->TempDesEvapOut); if (GetCompSizFac) { - sim_component.compPtr->getSizingFactor(sim_component.SizFac); + this->compPtr->getSizingFactor(this->SizFac); } // KLUGEY HACK ALERT!!! @@ -139,15 +132,14 @@ namespace PlantLoopEquip { // I anticipate the list of components that fall through to be very small, so that is the check I will do. // If std::find returns the .end() iterator, that means it didn't find it in the list, which means it's not one of the ones to fall // through, so RETURN - if (std::find(compsToSimAfterInitLoopEquip.begin(), compsToSimAfterInitLoopEquip.end(), sim_component.TypeOf_Num) == + if (std::find(compsToSimAfterInitLoopEquip.begin(), compsToSimAfterInitLoopEquip.end(), this->TypeOf_Num) == compsToSimAfterInitLoopEquip.end()) { return; } } - sim_component.compPtr->simulate(sim_component_location, FirstHVACIteration, sim_component.MyLoad, sim_component.ON); + this->compPtr->simulate(this->location, FirstHVACIteration, this->MyLoad, this->ON); } } -} // namespace PlantLoopEquip - -} // namespace EnergyPlus +} +} diff --git a/src/EnergyPlus/Plant/Component.hh b/src/EnergyPlus/Plant/Component.hh index 68af05f66e3..a6a70b42d11 100644 --- a/src/EnergyPlus/Plant/Component.hh +++ b/src/EnergyPlus/Plant/Component.hh @@ -51,6 +51,7 @@ #include #include #include +#include namespace EnergyPlus { namespace DataPlant { @@ -60,7 +61,6 @@ namespace DataPlant { // Members std::string TypeOf; // The 'keyWord' identifying component type int TypeOf_Num; // Reference the "TypeOf" parameters in DataPlant - int GeneralEquipType; // General Equipment Type (e.g. Chillers, Pumps, etc) std::string Name; // Component name int CompNum; // Component ID number int FlowCtrl; // flow control for splitter/mixer (ACTIVE/PASSIVE/BYPASS) @@ -96,10 +96,11 @@ namespace DataPlant { Real64 TempDesCondIn; Real64 TempDesEvapOut; PlantComponent *compPtr; + EnergyPlus::PlantLocation location; // Default Constructor CompData() - : TypeOf_Num(0), GeneralEquipType(0), CompNum(0), FlowCtrl(0), FlowPriority(LoopFlowStatus_Unknown), ON(false), Available(false), + : TypeOf_Num(0), CompNum(0), FlowCtrl(0), FlowPriority(LoopFlowStatus_Unknown), ON(false), Available(false), NodeNumIn(0), NodeNumOut(0), MyLoad(0.0), MaxLoad(0.0), MinLoad(0.0), OptLoad(0.0), SizFac(0.0), CurOpSchemeType(UnknownStatusOpSchemeType), NumOpSchemes(0), CurCompLevelOpNum(0), EquipDemand(0.0), EMSLoadOverrideOn(false), EMSLoadOverrideValue(0.0), HowLoadServed(HowMet_Unknown), MinOutletTemp(0.0), MaxOutletTemp(0.0), FreeCoolCntrlShutDown(false), @@ -107,6 +108,10 @@ namespace DataPlant { TempDesEvapOut(0.0), compPtr(nullptr) { } + + void simulate(bool FirstHVACIteration, bool &InitLoopEquip, bool GetCompSizFac); + + bool isPump(); }; } // namespace DataPlant } // namespace EnergyPlus diff --git a/src/EnergyPlus/DataPlant.cc b/src/EnergyPlus/Plant/DataPlant.cc similarity index 89% rename from src/EnergyPlus/DataPlant.cc rename to src/EnergyPlus/Plant/DataPlant.cc index c47abf8454c..e3429423ec1 100644 --- a/src/EnergyPlus/DataPlant.cc +++ b/src/EnergyPlus/Plant/DataPlant.cc @@ -49,24 +49,14 @@ #include // EnergyPlus Headers -#include -#include +#include #include -#include -#include #include -#include namespace EnergyPlus { namespace DataPlant { - // MODULE INFORMATION: - // AUTHOR Plant code authors? - // DATE WRITTEN - // MODIFIED na - // RE-ENGINEERED na - // PURPOSE OF THIS MODULE: // This data-only module contains the structures for various parts of the Plant and // Condenser Loops. @@ -113,11 +103,6 @@ namespace DataPlant { int const DemandSide(1); int const SupplySide(2); - // Parameters for economizer - int const Integrated(1); - int const NonIntegrated(2); - int const None(3); - // Parameters for tolerance Real64 const LoopDemandTol(0.1); // minimum significant loop cooling or heating demand Real64 const DeltaTempTol(0.0001); // minimum significant loop temperature difference @@ -456,65 +441,11 @@ namespace DataPlant { int const TypeOf_HeatPumpEIRCooling(95); int const TypeOf_HeatPumpEIRHeating(96); - // Parameters for General Equipment Types - int const NumGeneralEquipTypes(23); - Array1D_string const GeneralEquipTypes(NumGeneralEquipTypes, - {"BOILER", - "CHILLER", - "COOLINGTOWER", - "GENERATOR", - "HEATEXCHANGER", - "HEATPUMP", - "PIPE", - "PUMP", - "DISTRICT", - "THERMALSTORAGE", - "TEMPERINGVALVE", - "WATERHEATER", - "WATERUSE", - "DEMANDCOIL", - "SOLARCOLLECTOR", - "LOADPROFILE", - "FLUIDCOOLER", - "EVAPORATIVEFLUIDCOOLER", - "GROUNDHEATEXCHANGER", - "ZONEHVACDEMAND", - "REFRIGERATION", - "PLANTCOMPONENT", - "CENTRALHEATPUMPSYSTEM"}); - - int const GenEquipTypes_Boiler(1); - int const GenEquipTypes_Chiller(2); - int const GenEquipTypes_CoolingTower(3); - int const GenEquipTypes_Generator(4); - int const GenEquipTypes_HeatExchanger(5); - int const GenEquipTypes_HeatPump(6); - int const GenEquipTypes_Pipe(7); - int const GenEquipTypes_Pump(8); - int const GenEquipTypes_Purchased(9); - int const GenEquipTypes_ThermalStorage(10); - int const GenEquipTypes_Valve(11); - int const GenEquipTypes_WaterThermalTank(12); - int const GenEquipTypes_WaterUse(13); - int const GenEquipTypes_DemandCoil(14); - int const GenEquipTypes_SolarCollector(15); - int const GenEquipTypes_LoadProfile(16); - int const GenEquipTypes_FluidCooler(17); - int const GenEquipTypes_EvapFluidCooler(18); - int const GenEquipTypes_GroundHeatExchanger(19); - int const GenEquipTypes_ZoneHVACDemand(20); - int const GenEquipTypes_Refrigeration(21); - int const GenEquipTypes_PlantComponent(22); - int const GenEquipTypes_CentralHeatPumpSystem(23); - Array1D const ConvergenceHistoryARR(DataPlant::NumConvergenceHistoryTerms, {0.0, -1.0, -2.0, -3.0, -4.0}); Real64 const sum_ConvergenceHistoryARR(sum(ConvergenceHistoryARR)); Real64 const square_sum_ConvergenceHistoryARR(pow_2(sum_ConvergenceHistoryARR)); Real64 const sum_square_ConvergenceHistoryARR(sum(pow(ConvergenceHistoryARR, 2))); - int NumPipes(0); // Total number of pipes - int NumPlantPipes(0); // Total number of plant pipes - int NumCondPipes(0); // Total number of condenser pipes int TotNumLoops(0); // number of plant and condenser loops int TotNumHalfLoops(0); // number of half loops (2 * TotNumLoops) bool PlantFirstSizeCompleted(false); @@ -524,18 +455,12 @@ namespace DataPlant { bool PlantFinalSizesOkayToReport(false); bool AnyEMSPlantOpSchemesInModel(false); - Array1D_int EconBranchNum; // Branch num on which economizer is placed - Array1D_int EconCompNum; // Component num of economizer in the economizer branch - - Array1D_bool LoadChangeDownStream; // sim control flag. - int PlantManageSubIterations(0); // tracks plant iterations to characterize solver int PlantManageHalfLoopCalls(0); // tracks number of half loop calls // Object Data Array1D PlantLoop; Array1D PlantAvailMgr; - Array1D PlantReport; Array1D VentRepPlantSupplySide; Array1D VentRepPlantDemandSide; Array1D VentRepCondSupplySide; @@ -546,9 +471,6 @@ namespace DataPlant { // Needed for unit tests, should not be normally called. void clear_state() { - NumPipes = 0; - NumPlantPipes = 0; - NumCondPipes = 0; TotNumLoops = 0; TotNumHalfLoops = 0; PlantFirstSizeCompleted = false; @@ -557,14 +479,10 @@ namespace DataPlant { PlantFirstSizesOkayToReport = false; PlantFinalSizesOkayToReport = false; AnyEMSPlantOpSchemesInModel = false; - EconBranchNum.deallocate(); - EconCompNum.deallocate(); - LoadChangeDownStream.deallocate(); PlantManageSubIterations = 0; PlantManageHalfLoopCalls = 0; PlantLoop.deallocate(); PlantAvailMgr.deallocate(); - PlantReport.deallocate(); VentRepPlantSupplySide.deallocate(); VentRepPlantDemandSide.deallocate(); VentRepCondSupplySide.deallocate(); diff --git a/src/EnergyPlus/DataPlant.hh b/src/EnergyPlus/Plant/DataPlant.hh similarity index 87% rename from src/EnergyPlus/DataPlant.hh rename to src/EnergyPlus/Plant/DataPlant.hh index 423f72c9472..adfc1895c45 100644 --- a/src/EnergyPlus/DataPlant.hh +++ b/src/EnergyPlus/Plant/DataPlant.hh @@ -62,9 +62,7 @@ #include #include #include -#include #include -#include namespace EnergyPlus { @@ -114,11 +112,6 @@ namespace DataPlant { extern int const DemandSide; extern int const SupplySide; - // Parameters for economizer - extern int const Integrated; - extern int const NonIntegrated; - extern int const None; - // Parameters for tolerance extern Real64 const LoopDemandTol; // minimum significant loop cooling or heating demand extern Real64 const DeltaTempTol; // minimum significant loop temperature difference @@ -250,42 +243,11 @@ namespace DataPlant { extern int const TypeOf_HeatPumpEIRCooling; extern int const TypeOf_HeatPumpEIRHeating; - // Parameters for General Equipment Types - extern int const NumGeneralEquipTypes; - extern Array1D_string const GeneralEquipTypes; - - extern int const GenEquipTypes_Boiler; - extern int const GenEquipTypes_Chiller; - extern int const GenEquipTypes_CoolingTower; - extern int const GenEquipTypes_Generator; - extern int const GenEquipTypes_HeatExchanger; - extern int const GenEquipTypes_HeatPump; - extern int const GenEquipTypes_Pipe; - extern int const GenEquipTypes_Pump; - extern int const GenEquipTypes_Purchased; - extern int const GenEquipTypes_ThermalStorage; - extern int const GenEquipTypes_Valve; - extern int const GenEquipTypes_WaterThermalTank; - extern int const GenEquipTypes_WaterUse; - extern int const GenEquipTypes_DemandCoil; - extern int const GenEquipTypes_SolarCollector; - extern int const GenEquipTypes_LoadProfile; - extern int const GenEquipTypes_FluidCooler; - extern int const GenEquipTypes_EvapFluidCooler; - extern int const GenEquipTypes_GroundHeatExchanger; - extern int const GenEquipTypes_ZoneHVACDemand; - extern int const GenEquipTypes_Refrigeration; - extern int const GenEquipTypes_PlantComponent; - extern int const GenEquipTypes_CentralHeatPumpSystem; - extern Array1D const ConvergenceHistoryARR; extern Real64 const sum_ConvergenceHistoryARR; extern Real64 const square_sum_ConvergenceHistoryARR; extern Real64 const sum_square_ConvergenceHistoryARR; - extern int NumPipes; // Total number of pipes - extern int NumPlantPipes; // Total number of plant pipes - extern int NumCondPipes; // Total number of condenser pipes extern int TotNumLoops; // number of plant and condenser loops extern int TotNumHalfLoops; // number of half loops (2 * TotNumLoops) extern bool PlantFirstSizeCompleted; // true if first-pass sizing is still going on and not finished @@ -296,18 +258,12 @@ namespace DataPlant { extern bool AnyEMSPlantOpSchemesInModel; - extern Array1D_int EconBranchNum; // Branch num on which economizer is placed - extern Array1D_int EconCompNum; // Component num of economizer in the economizer branch - - extern Array1D_bool LoadChangeDownStream; // sim control flag. - extern int PlantManageSubIterations; // tracks plant iterations to characterize solver extern int PlantManageHalfLoopCalls; // tracks number of half loop calls // Object Data extern Array1D PlantLoop; extern Array1D PlantAvailMgr; - extern Array1D PlantReport; extern Array1D VentRepPlantSupplySide; extern Array1D VentRepPlantDemandSide; extern Array1D VentRepCondSupplySide; diff --git a/src/EnergyPlus/Plant/Loop.cc b/src/EnergyPlus/Plant/Loop.cc new file mode 100644 index 00000000000..1c70748cb22 --- /dev/null +++ b/src/EnergyPlus/Plant/Loop.cc @@ -0,0 +1,283 @@ +// EnergyPlus, Copyright (c) 1996-2020, The Board of Trustees of the University of Illinois, +// The Regents of the University of California, through Lawrence Berkeley National Laboratory +// (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge +// National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other +// contributors. All rights reserved. +// +// NOTICE: This Software was developed under funding from the U.S. Department of Energy and the +// U.S. Government consequently retains certain rights. As such, the U.S. Government has been +// granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, +// worldwide license in the Software to reproduce, distribute copies to the public, prepare +// derivative works, and perform publicly and display publicly, and to permit others to do so. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// (1) Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, +// the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific prior +// written permission. +// +// (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form +// without changes from the version obtained under this License, or (ii) Licensee makes a +// reference solely to the software portion of its product, Licensee must refer to the +// software as "EnergyPlus version X" software, where "X" is the version number Licensee +// obtained under this License and may not use a different name for the software. Except as +// specifically required in this Section (4), Licensee shall not use in a company name, a +// product name, in advertising, publicity, or other promotional activities any name, trade +// name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly +// similar designation, without the U.S. Department of Energy's prior written consent. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include +#include +#include +#include +#include +#include + +namespace EnergyPlus { +namespace DataPlant { + + void PlantLoopData::UpdateLoopSideReportVars( + Real64 const OtherSideDemand, // This is the 'other side' demand, based on other side flow + Real64 const LocalRemLoopDemand // Unmet Demand after equipment has been simulated (report variable) + ) { + + // SUBROUTINE INFORMATION: + // AUTHOR Dan Fisher + // DATE WRITTEN July 1998 + // MODIFIED Aug 2010 Edwin Lee -- add per LoopSide variable support + // RE-ENGINEERED na + + // Using/Aliasing + using DataLoopNode::Node; + + this->InletNodeFlowrate = Node(this->LoopSide(DataPlant::SupplySide).NodeNumIn).MassFlowRate; + this->InletNodeTemperature = Node(this->LoopSide(DataPlant::SupplySide).NodeNumIn).Temp; + this->OutletNodeFlowrate = Node(this->LoopSide(DataPlant::SupplySide).NodeNumOut).MassFlowRate; + this->OutletNodeTemperature = Node(this->LoopSide(DataPlant::SupplySide).NodeNumOut).Temp; + + // In the baseline code, only reported supply side demand. so putting in "SupplySide" IF block for now but might expand later + if (OtherSideDemand < 0.0) { + this->CoolingDemand = std::abs(OtherSideDemand); + this->HeatingDemand = 0.0; + this->DemandNotDispatched = -LocalRemLoopDemand; // Setting sign based on old logic for now + } else { + this->HeatingDemand = OtherSideDemand; + this->CoolingDemand = 0.0; + this->DemandNotDispatched = LocalRemLoopDemand; // Setting sign based on old logic for now + } + + this->CalcUnmetPlantDemand(); + } + + + void PlantLoopData::CalcUnmetPlantDemand() { + + // SUBROUTINE INFORMATION: + // AUTHOR Brent Griffith + // DATE WRITTEN June 2011 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS SUBROUTINE: + // determine the magnitude of unmet plant loads after the half loop simulation is done + + // METHODOLOGY EMPLOYED: + // using the loop setpoint node, look at target vs current and + // calculate a demand based on mass flow times specific heat times delta T + + // Using/Aliasing + using DataLoopNode::Node; + using DataLoopNode::NodeType_Steam; + using DataLoopNode::NodeType_Water; + using DataPlant::DualSetPointDeadBand; + using DataPlant::LoopDemandTol; + using DataPlant::SingleSetPoint; + using FluidProperties::GetSatEnthalpyRefrig; + using FluidProperties::GetSpecificHeatGlycol; + + // SUBROUTINE PARAMETER DEFINITIONS: + static std::string const RoutineName("PlantLoopSolver::EvaluateLoopSetPointLoad"); + static std::string const RoutineNameAlt("PlantSupplySide:EvaluateLoopSetPointLoad"); + + //~ General variables + Real64 MassFlowRate; + Real64 TargetTemp; + Real64 LoopSetPointTemperature; + Real64 LoopSetPointTemperatureHi; + Real64 LoopSetPointTemperatureLo; + Real64 LoadToHeatingSetPoint; + Real64 LoadToCoolingSetPoint; + Real64 DeltaTemp; + Real64 Cp; + Real64 EnthalpySteamSatVapor; // Enthalpy of saturated vapor + Real64 EnthalpySteamSatLiquid; // Enthalpy of saturated liquid + Real64 LatentHeatSteam; // Latent heat of steam + Real64 LoadToLoopSetPoint; + + // Initialize + LoadToLoopSetPoint = 0.0; + + // Get temperature at loop setpoint node. + TargetTemp = Node(this->TempSetPointNodeNum).Temp; + MassFlowRate = Node(this->TempSetPointNodeNum).MassFlowRate; + + if (this->FluidType == NodeType_Water) { + + Cp = GetSpecificHeatGlycol(this->FluidName, TargetTemp, this->FluidIndex, RoutineName); + + { + auto const SELECT_CASE_var(this->LoopDemandCalcScheme); + + if (SELECT_CASE_var == SingleSetPoint) { + + // Pick up the loop setpoint temperature + LoopSetPointTemperature = this->LoopSide(DataPlant::SupplySide).TempSetPoint; + // Calculate the delta temperature + DeltaTemp = LoopSetPointTemperature - TargetTemp; + + // Calculate the demand on the loop + LoadToLoopSetPoint = MassFlowRate * Cp * DeltaTemp; + + } else if (SELECT_CASE_var == DualSetPointDeadBand) { + + // Get the range of setpoints + LoopSetPointTemperatureHi = Node(this->TempSetPointNodeNum).TempSetPointHi; + LoopSetPointTemperatureLo = Node(this->TempSetPointNodeNum).TempSetPointLo; + + // Calculate the demand on the loop + if (MassFlowRate > 0.0) { + LoadToHeatingSetPoint = MassFlowRate * Cp * (LoopSetPointTemperatureLo - TargetTemp); + LoadToCoolingSetPoint = MassFlowRate * Cp * (LoopSetPointTemperatureHi - TargetTemp); + // Possible combinations: + // 1 LoadToHeatingSetPoint > 0 & LoadToCoolingSetPoint > 0 --> Heating required + // 2 LoadToHeatingSetPoint < 0 & LoadToCoolingSetPoint < 0 --> Cooling Required + // 3 LoadToHeatingSetPoint <=0 & LoadToCoolingSetPoint >=0 --> Dead Band Operation - includes zero load cases + // 4 LoadToHeatingSetPoint > LoadToCoolingSetPoint --> Not Feasible if LoopSetPointHi >= LoopSetPointLo + if (LoadToHeatingSetPoint > 0.0 && LoadToCoolingSetPoint > 0.0) { + LoadToLoopSetPoint = LoadToHeatingSetPoint; + } else if (LoadToHeatingSetPoint < 0.0 && LoadToCoolingSetPoint < 0.0) { + LoadToLoopSetPoint = LoadToCoolingSetPoint; + } else if (LoadToHeatingSetPoint <= 0.0 && + LoadToCoolingSetPoint >= 0.0) { // deadband includes zero loads + LoadToLoopSetPoint = 0.0; + } + } else { + LoadToLoopSetPoint = 0.0; + } + } + } + + } else if (this->FluidType == NodeType_Steam) { + + Cp = GetSpecificHeatGlycol(this->FluidName, TargetTemp, this->FluidIndex, RoutineName); + + { + auto const SELECT_CASE_var(this->LoopDemandCalcScheme); + + if (SELECT_CASE_var == SingleSetPoint) { + + // Pick up the loop setpoint temperature + LoopSetPointTemperature = this->LoopSide(DataPlant::SupplySide).TempSetPoint; + + // Calculate the delta temperature + DeltaTemp = LoopSetPointTemperature - TargetTemp; + + EnthalpySteamSatVapor = GetSatEnthalpyRefrig(this->FluidName, LoopSetPointTemperature, 1.0, + this->FluidIndex, RoutineNameAlt); + EnthalpySteamSatLiquid = GetSatEnthalpyRefrig(this->FluidName, LoopSetPointTemperature, 0.0, + this->FluidIndex, RoutineNameAlt); + + LatentHeatSteam = EnthalpySteamSatVapor - EnthalpySteamSatLiquid; + + // Calculate the demand on the loop + LoadToLoopSetPoint = MassFlowRate * (Cp * DeltaTemp + LatentHeatSteam); + } + } + + } else { // only have two types, water serves for glycol. + } + + // Trim the demand to zero if it is very small + if (std::abs(LoadToLoopSetPoint) < LoopDemandTol) LoadToLoopSetPoint = 0.0; + + this->UnmetDemand = LoadToLoopSetPoint; + } + + void PlantLoopData::CheckLoopExitNode(bool const FirstHVACIteration) { + + // SUBROUTINE INFORMATION: + // AUTHOR Dan Fisher + // DATE WRITTEN October 1998 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS SUBROUTINE: + // This subroutine sets the temperature + // and mass flow rate of the plant loop supply side exit + // node. As written, the routine calculates the exit + // temperature based on the fraction of loop demand met + // by the plant equipment. This assumes that each piece + // of operating plant equipment produced chilled/hot water + // at the loop setpoint temperature. + + // Using/Aliasing + using DataBranchAirLoopPlant::MassFlowTolerance; + using DataGlobals::WarmupFlag; + using DataLoopNode::Node; + using DataLoopNode::NodeID; + using DataPlant::SupplySide; + using General::RoundSigDigits; + + // SUBROUTINE LOCAL VARIABLE DECLARATIONS: + int LoopInlet; // plant loop inlet node num. + int LoopOutlet; // plant loop outlet node num. + + // set local variables: loop inlet and outlet nodes + auto &supplySide = this->LoopSide(DataPlant::SupplySide); + LoopInlet = supplySide.NodeNumIn; + LoopOutlet = supplySide.NodeNumOut; + // Check continuity invalid...loop pumps now turned on and off + if (!FirstHVACIteration && !WarmupFlag) { + if (std::abs(Node(LoopOutlet).MassFlowRate - Node(LoopInlet).MassFlowRate) > MassFlowTolerance) { + if (this->MFErrIndex == 0) { + ShowWarningError("PlantSupplySide: PlantLoop=\"" + this->Name + + "\", Error (CheckLoopExitNode) -- Mass Flow Rate Calculation. Outlet and Inlet differ by more than tolerance."); + ShowContinueErrorTimeStamp(""); + ShowContinueError("Loop inlet node=" + NodeID(LoopInlet) + ", flowrate=" + + RoundSigDigits(Node(LoopInlet).MassFlowRate, 4) + + " kg/s"); + ShowContinueError("Loop outlet node=" + NodeID(LoopOutlet) + ", flowrate=" + + RoundSigDigits(Node(LoopOutlet).MassFlowRate, 4) + + " kg/s"); + ShowContinueError("This loop might be helped by a bypass."); + } + ShowRecurringWarningErrorAtEnd("PlantSupplySide: PlantLoop=\"" + this->Name + + "\", Error -- Mass Flow Rate Calculation -- continues ** ", + this->MFErrIndex); + } + } + // Reset Max loop flow rate based on pump performance + Node(LoopOutlet).MassFlowRateMax = Node(LoopInlet).MassFlowRateMax; + } + +} +} diff --git a/src/EnergyPlus/Plant/Loop.hh b/src/EnergyPlus/Plant/Loop.hh index 4683f305b56..2129eee93ad 100644 --- a/src/EnergyPlus/Plant/Loop.hh +++ b/src/EnergyPlus/Plant/Loop.hh @@ -49,7 +49,6 @@ #define PlantTopologyLoop_hh_INCLUDED #include -#include namespace EnergyPlus { namespace DataPlant { @@ -93,9 +92,6 @@ namespace DataPlant { int LoopDemandCalcScheme; // Load distribution scheme 1 SingleSetPoint, // 2 DualSetPointwithDeadBand int CommonPipeType; - std::string EconomizerHtExchanger; // DSU review, should move these out of here - std::string EconPlantSideSensedNodeName; // DSU review, should move these out of here - std::string EconCondSideSensedNodeName; // DSU review, should move these out of here int EconPlantSideSensedNodeNum; // DSU review, should move these out of here int EconCondSideSensedNodeNum; // DSU review, should move these out of here int EconPlacement; // DSU review, should move these out of here @@ -109,7 +105,17 @@ namespace DataPlant { Real64 PressureDrop; bool UsePressureForPumpCalcs; Real64 PressureEffectiveK; - PlantLoopSolver::PlantLoopSolverClass loopSolver; + // report variables + Real64 CoolingDemand; // Plant Loop Cooling Demand, W + Real64 HeatingDemand; // Plant Loop Heating Demand[W] + Real64 DemandNotDispatched; // Plant Loop Demand that was not distributed [W] + Real64 UnmetDemand; // Plant Loop Unmet Demand [W] + Real64 BypassFrac; // Debug Variable + Real64 InletNodeFlowrate; // Debug Variable + Real64 InletNodeTemperature; // Debug Variable + Real64 OutletNodeFlowrate; // Debug Variable + Real64 OutletNodeTemperature; // Debug Variable + int LastLoopSideSimulated; // Default Constructor PlantLoopData() @@ -120,10 +126,19 @@ namespace DataPlant { CirculationTime(2.0), Mass(0.0), EMSCtrl(false), EMSValue(0.0), NumOpSchemes(0), LoadDistribution(0), PlantSizNum(0), LoopDemandCalcScheme(0), CommonPipeType(0), EconPlantSideSensedNodeNum(0), EconCondSideSensedNodeNum(0), EconPlacement(0), EconBranch(0), EconComp(0), EconControlTempDiff(0.0), LoopHasConnectionComp(false), TypeOfLoop(0), PressureSimType(1), - HasPressureComponents(false), PressureDrop(0.0), UsePressureForPumpCalcs(false), PressureEffectiveK(0.0) + HasPressureComponents(false), PressureDrop(0.0), UsePressureForPumpCalcs(false), PressureEffectiveK(0.0), + CoolingDemand(0.0), HeatingDemand(0.0), DemandNotDispatched(0.0), UnmetDemand(0.0), BypassFrac(0.0), + InletNodeFlowrate(0.0), InletNodeTemperature(0.0), OutletNodeFlowrate(0.0), OutletNodeTemperature(0.0), LastLoopSideSimulated(0) { - this->loopSolver = PlantLoopSolver::PlantLoopSolverClass(); } + + + void UpdateLoopSideReportVars(Real64 OtherSideDemand, Real64 LocalRemLoopDemand); + + void CheckLoopExitNode(bool FirstHVACIteration); + + void CalcUnmetPlantDemand(); + }; } // namespace DataPlant } // namespace EnergyPlus diff --git a/src/EnergyPlus/Plant/LoopSide.cc b/src/EnergyPlus/Plant/LoopSide.cc new file mode 100644 index 00000000000..4d654f5a818 --- /dev/null +++ b/src/EnergyPlus/Plant/LoopSide.cc @@ -0,0 +1,2311 @@ +// EnergyPlus, Copyright (c) 1996-2020, The Board of Trustees of the University of Illinois, +// The Regents of the University of California, through Lawrence Berkeley National Laboratory +// (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge +// National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other +// contributors. All rights reserved. +// +// NOTICE: This Software was developed under funding from the U.S. Department of Energy and the +// U.S. Government consequently retains certain rights. As such, the U.S. Government has been +// granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, +// worldwide license in the Software to reproduce, distribute copies to the public, prepare +// derivative works, and perform publicly and display publicly, and to permit others to do so. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// (1) Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, +// the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific prior +// written permission. +// +// (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form +// without changes from the version obtained under this License, or (ii) Licensee makes a +// reference solely to the software portion of its product, Licensee must refer to the +// software as "EnergyPlus version X" software, where "X" is the version number Licensee +// obtained under this License and may not use a different name for the software. Except as +// specifically required in this Section (4), Licensee shall not use in a company name, a +// product name, in advertising, publicity, or other promotional activities any name, trade +// name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly +// similar designation, without the U.S. Department of Energy's prior written consent. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace EnergyPlus { +namespace DataPlant { + + static std::string const fluidNameSteam("STEAM"); + + void HalfLoopData::solve(bool const FirstHVACIteration, bool &ReSimOtherSideNeeded) { + + // SUBROUTINE INFORMATION: + // AUTHORS: Dan Fisher, Sankaranarayanan K P, Edwin Lee + // DATE WRITTEN: April 1998 + // MODIFIED June 2005(Work in the Plant Super Manager Module) + // July 2006 + // RE-ENGINEERED July 2010 + + // PURPOSE OF THIS SUBROUTINE: + // SimSupplyFlowSolution is the driver routine for plant loops. It performs + // the following tasks for each half loop (supply or demand side): + // 1. Calculate flow request for half loop + // 2. Predict Loop Flow + // 3. Simulate the inlet branch + // 4. Simulate the parallel branches, distributing load if necessary + // 5. Set flow rates on parallel branches + // 6. Simulate outlet branch and update node and report variables + + // METHODOLOGY EMPLOYED: + // The algorithm operates on a predictor/corrector flow setting method by simulating all available loop components + // based on component requested flow rates, then enforcing continuity on all loop branch flows by calling + // the flow resolver and locking those flows down. Available components are then re-simulated using the + // corrected flow rates. + + auto &thisPlantLoop = DataPlant::PlantLoop(this->myLoopNum); + int ThisSideInletNode = this->NodeNumIn; + + this->InitialDemandToLoopSetPoint = 0.0; + this->CurrentAlterationsToDemand = 0.0; + this->UpdatedDemandToLoopSetPoint = 0.0; + + // The following block is related to validating the flow control paths of the loop side + // Since the control types are scheduled, I think BeginTimeStep should be a decent check frequency + if (DataGlobals::BeginTimeStepFlag && this->OncePerTimeStepOperations) { + + // Initialize loop side controls -- could just be done for one loop since this routine inherently + // loops over all plant/condenser loops. Not sure if the penalty is worth investigating. + PlantCondLoopOperation::InitLoadDistribution(FirstHVACIteration); + + // Now that the op scheme types are updated, do LoopSide validation + this->ValidateFlowControlPaths(); + + // Set the flag to false so we won't do these again this time step + this->OncePerTimeStepOperations = false; + + } else { + + // Set the flag to true so that it is activated for the next time step + this->OncePerTimeStepOperations = true; + } + + // Do pressure system initialize if this is the demand side (therefore once per whole loop) + if (this->myLoopSideNum == DataPlant::DemandSide) { + PlantPressureSystem::SimPressureDropSystem(this->myLoopNum, FirstHVACIteration, DataPlant::PressureCall_Init); + } + + // Turn on any previously disabled branches due to constant speed branch pump issue + this->TurnOnAllLoopSideBranches(); + + // Do the actual simulation here every time + this->DoFlowAndLoadSolutionPass(this->myOtherLoopSideNum, ThisSideInletNode, FirstHVACIteration); + + // On constant speed branch pump loop sides we need to re-simulate + if (this->hasConstSpeedBranchPumps) { + // turn off any pumps connected to unloaded equipment and re-do the flow/load solution pass + this->DisableAnyBranchPumpsConnectedToUnloadedEquipment(); + this->DoFlowAndLoadSolutionPass(this->myOtherLoopSideNum, ThisSideInletNode, FirstHVACIteration); + } + + // A couple things are specific to which LoopSide we are on // TODO: This whole block needs to be moved up to the loop level + if (this->myLoopSideNum == DataPlant::DemandSide) { + + // Pass the loop information via the HVAC interface manager + HVACInterfaceManager::UpdatePlantLoopInterface(this->myLoopNum, + this->myLoopSideNum, + thisPlantLoop.LoopSide(DataPlant::DemandSide).NodeNumOut, + thisPlantLoop.LoopSide(DataPlant::SupplySide).NodeNumIn, + ReSimOtherSideNeeded, + thisPlantLoop.CommonPipeType); + + } else { // LoopSide == SupplySide + + // Update pressure drop reporting, calculate total loop pressure drop for use elsewhere + PlantPressureSystem::SimPressureDropSystem(this->myLoopNum, FirstHVACIteration, DataPlant::PressureCall_Update); + + // Pass the loop information via the HVAC interface manager (only the flow) + HVACInterfaceManager::UpdatePlantLoopInterface(this->myLoopNum, + this->myLoopSideNum, + thisPlantLoop.LoopSide(DataPlant::SupplySide).NodeNumOut, + thisPlantLoop.LoopSide(DataPlant::DemandSide).NodeNumIn, + ReSimOtherSideNeeded, + thisPlantLoop.CommonPipeType); + + // Update the loop outlet node conditions + DataPlant::PlantLoop(this->myLoopNum).CheckLoopExitNode(FirstHVACIteration); // TODO: This is a loop level check, move out + + DataPlant::PlantLoop(this->myLoopNum).UpdateLoopSideReportVars(this->InitialDemandToLoopSetPointSAVED, + this->LoadToLoopSetPointThatWasntMet); + + } + + } + + void HalfLoopData::ValidateFlowControlPaths() + { + + // FUNCTION INFORMATION: + // AUTHOR Edwin Lee + // DATE WRITTEN July 2010 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS FUNCTION: + // This routine will scan all the loop side paths and validate the component topology according + // to current topology rules and regulations. + + // METHODOLOGY EMPLOYED: + // Scan this loop side and begin by scanning the first branch, then follow with the remainder of the flow paths + // - this would be from splitter outlet nodes all the way to the loop side outlet node. + // The current rules are that "other types" of components (as defined below in the references) can be placed along each + // flow path as needed. At this point, any number of "load-range based" components can be placed along the flow + // path. After this, the user is allowed to place another set of any number of "other types" of components. + // The key restriction is that an "other type" of component may not be sandwiched by "load-range based" components. + // This is due to the load range based needing to be simulated all at once along each flow path. + + // REFERENCES: + // "other types" of components: basically not load-range based heat transfer components. This would include: + // - demand based components such as coils + // - component setpoint based operating components + // - heat exchanger components including waterside economizers + // "load-range based" components are heat transfer components which are controlled based on a single load range. + // - currently only one load range based scheme is available at a given time, although other control types + // may be enabled, such as component setpoint. + // Pumps are separate components since the pump heat is not accounted for in the flow path order. + // Improvements during the demand side rewrite has allowed pumps to be placed as -not- the first component on a branch + // Pumps can be placed anywhere, even between load-range based components, since they will not affect loop load + + // RETURN VALUE: + // Returns a control validator flow structure, including a flag for successful or not, then if not successful + // the other values are filled in such as location on the loop where the error occurred and a message error description + + // FUNCTION PARAMETER DEFINITIONS: + int const Parallel(1); + int const Outlet(2); + + //~ Initialze + bool EncounteredLRB = false; + bool EncounteredNonLRBAfterLRB = false; + int const NumParallelPaths = this->TotalBranches - 2; + + // We'll start by stepping through the first branch, which may be the only branch + // If we find a load range based, then trip the flag and just keep moving + // If we only have one branch and all is good, then RETURN early + // If we have parallel branches, then start looping through each flow path to + // decide if it is a valid path. + // If any one path is invalid then all is wrong + int firstBranchIndex = 1; + for (int CompIndex = 1; CompIndex <= this->Branch(firstBranchIndex).TotalComponents; ++CompIndex) { + + auto &this_component(this->Branch(firstBranchIndex).Comp(CompIndex)); + + { + auto const SELECT_CASE_var(this_component.CurOpSchemeType); + + if ((SELECT_CASE_var >= DataPlant::LoadRangeBasedMin) && (SELECT_CASE_var <= DataPlant::LoadRangeBasedMax)) { //~ load range based + if (EncounteredNonLRBAfterLRB) { + // We must have already encountered a LRB, then a non-LRB, and now another LRB, this is bad + ShowSevereError("Plant topology problem on \"" + this->loopSideDescription + "\""); + ShowContinueError("PlaLoad range based components are separated by other control type components."); + ShowContinueError("Load Range Based should be grouped together on each flow path."); + ShowFatalError("Plant topology issue causes program termination"); + } else { + EncounteredLRB = true; + } + + } else if (SELECT_CASE_var == DataPlant::PumpOpSchemeType) { //~ pump + // For now this is just a placeholder, because I think pumps will be available anywhere, + // and they won't affect the load distribution + + } else if (SELECT_CASE_var == DataPlant::NoControlOpSchemeType) { //~ Such as pipes + // For now this is just a placeholder, because these components shouldn't cause a problem anywhere... + + } else if (SELECT_CASE_var == + DataPlant::UnknownStatusOpSchemeType) { //~ Uninitialized, this should be a sufficient place to catch for this on branch 1 + // throw fatal + ShowSevereError("ValidateFlowControlPaths: Uninitialized operation scheme type for component Name: " + this_component.Name); + ShowFatalError("ValidateFlowControlPaths: developer notice, Inlet path validation loop"); + } else { //~ Other control type + if (EncounteredLRB) { + EncounteredNonLRBAfterLRB = true; + } else { + // For now don't do anything, but we'll see... + } + } + } + } + + // Return early if we only needed to do the one branch + if (NumParallelPaths <= 0) return; + + // Now, if we have multiple parallel branches, I think the easiest way is to go all the way from the inlet node + // of each parallel branch to the loop outlet node and check the flow path + // This way we don't have to remember the conditions on each of the parallel branches when we would finally move + // to analyzing the outlet node when all done + // This will reduce allocation on the heap because we will keep from storing that array + // For each parallel path, we will need to check two branches: the parallel branch and the LoopSide outlet branch + for (int PathCounter = 1; PathCounter <= NumParallelPaths; ++PathCounter) { + for (int ParallelOrOutletIndex = Parallel; ParallelOrOutletIndex <= Outlet; ++ParallelOrOutletIndex) { + int BranchIndex; + if (ParallelOrOutletIndex == Parallel) { + // The branch index will be the current pathtype + 1 to add the inlet branch + BranchIndex = PathCounter + 1; + } else { // ParallelOrOutletIndex == Outlet + // The branch index will be the LoopSide outlet node + BranchIndex = this->TotalBranches; + } + + // Now that we have the branch index, let's do the control type check over all the components + for (int CompIndex = 1; CompIndex <= this->Branch(BranchIndex).TotalComponents; ++CompIndex) { + + auto &this_component(this->Branch(BranchIndex).Comp(CompIndex)); + + { + auto const SELECT_CASE_var(this_component.CurOpSchemeType); + + if ((SELECT_CASE_var >= DataPlant::LoadRangeBasedMin) && + (SELECT_CASE_var <= DataPlant::LoadRangeBasedMax)) { //~ load range based + if (EncounteredNonLRBAfterLRB) { + // We must have already encountered a LRB, then a non-LRB, and now another LRB, this is bad + ShowSevereError("Plant topology problem on \"" + this->loopSideDescription + "\""); + ShowContinueError("Load range based components are separated by other control type components."); + ShowContinueError("Load Range Based should be grouped together on each flow path."); + ShowFatalError("Plant topology issue causes program termination"); + } else { + EncounteredLRB = true; + } + + } else if (SELECT_CASE_var == DataPlant::NoControlOpSchemeType) { //~ Such as pipes + // For now this is just a placeholder, because these components shouldn't cause a problem anywhere... + + } else if (SELECT_CASE_var == DataPlant::PumpOpSchemeType) { //~ pump + // For now this is just a placeholder, because I think pumps will be available anywhere, + // and they won't affect the load distribution + + } else if (SELECT_CASE_var == DataPlant::UnknownStatusOpSchemeType) { //~ Uninitialized, this should be sufficient place to catch for this on other branches + // throw fatal error + ShowSevereError("ValidateFlowControlPaths: Uninitialized operation scheme type for component Name: " + + this_component.Name); + ShowFatalError("ValidateFlowControlPaths: developer notice, problem in Parallel path validation loop"); + } else { //~ Other control type + if (EncounteredLRB) { + EncounteredNonLRBAfterLRB = true; + } else { + // For now don't do anything, but we'll see... + } + } + } + + } //~ CompIndex + + } //~ Parallel and Outlet Branches + + } //~ Parallel Paths + } + + bool HalfLoopData::CheckPlantConvergence(bool const FirstHVACIteration) { + + // FUNCTION INFORMATION: + // AUTHOR Edwin Lee + // DATE WRITTEN Summer 2011 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS FUNCTION: + // This routine checks the history values in the convergence arrays of this loop/LoopSide combination + + // METHODOLOGY EMPLOYED: + // On FirstHVAC, we are not converged yet, thus forcing at least two iterations + // Calculate the average of each related variable history (generalized: could be any number of history terms) + // If any of the history terms do not match this average, then at least one value is different, so not converged + // Although this routine appears to check for convergence, it is also used to check for stuck (max iteration) conditions + // in cases where demand side (air loop, for example) equipment is "fighting" with the plant loop + // The result of this routine can help the plant "lock-in" and take action to stop the iteration + + // Using/Aliasing + using namespace DataPlant; + using namespace DataLoopNode; + + // FUNCTION LOCAL VARIABLE DECLARATIONS: + Real64 InletAvgTemp; + Real64 InletAvgMdot; + Real64 OutletAvgTemp; + Real64 OutletAvgMdot; + + if (FirstHVACIteration) { + return false; + } + + InletAvgTemp = sum(this->InletNode.TemperatureHistory) / + size(this->InletNode.TemperatureHistory); + if (any_ne(this->InletNode.TemperatureHistory, InletAvgTemp)) { + return false; + } + + InletAvgMdot = sum(this->InletNode.MassFlowRateHistory) / + size(this->InletNode.MassFlowRateHistory); + if (any_ne(this->InletNode.MassFlowRateHistory, InletAvgMdot)) { + return false; + } + + OutletAvgTemp = sum(this->OutletNode.TemperatureHistory) / + size(this->OutletNode.TemperatureHistory); + if (any_ne(this->OutletNode.TemperatureHistory, OutletAvgTemp)) { + return false; + } + + OutletAvgMdot = sum(this->OutletNode.MassFlowRateHistory) / + size(this->OutletNode.MassFlowRateHistory); + if (any_ne(this->OutletNode.MassFlowRateHistory, OutletAvgMdot)) { + return false; + } + + // If we made it this far, we're good! + return true; + } + + void HalfLoopData::PushBranchFlowCharacteristics(int const BranchNum, + Real64 const ValueToPush, + bool const FirstHVACIteration // TRUE if First HVAC iteration of Time step + ) { + + // SUBROUTINE INFORMATION: + // AUTHOR Edwin Lee + // DATE WRITTEN September 2010 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS SUBROUTINE: + // This routine takes the flow resolved flow rate and pushes it + // down a branch. In the process, if an externally connected + // component (air-water coil for example) is found to have a + // differing flow rate, the air sim flag is tripped to true, but + // the flow resolved flow rate is pushed down the loop to allow + // the plant to finish successfully. + + // METHODOLOGY EMPLOYED: + // Push mass flow rate and max avail down each branch. If the component + // is connected (or could be, for now) to an external loop such as + // an air loop, the current component outlet mass flow is checked + // vs the current resolved mass flow. If the mass flow doesn't match, + // the air sim flag is tripped to true. + + // Currently this routine is only performed for starved branches, when + // the coil is requesting too much flow, more than the plant can provide. + // If this were moved to every call type, including a minimum plant flow, + // you would need to provide a mass flow and min/max avail to push + // down the branch as well. + + // Using/Aliasing + using namespace DataPlant; // Use the entire module to allow all TypeOf's, would be a huge ONLY list + using DataLoopNode::Node; + + // SUBROUTINE LOCAL VARIABLE DECLARATIONS: + int CompCounter; + int BranchInletNode; + int ComponentInletNode; + int ComponentOutletNode; + int ComponentTypeOfNum; + Real64 MassFlowRateFound; + Real64 MassFlow; + bool PlantIsRigid; + + auto &this_branch(this->Branch(BranchNum)); + + BranchInletNode = this_branch.NodeNumIn; + + //~ Possible error handling if needed + if (ValueToPush != Node(BranchInletNode).MassFlowRate) { + // Diagnostic problem, flow resolver isn't calling this routine properly + } + + //~ This section would really be useful more later on if this routine has more logic regarding what to push down the branch + MassFlow = ValueToPush; + // MinAvail = ValueToPush + // MaxAvail = ValueToPush + + PlantIsRigid = this->CheckPlantConvergence(FirstHVACIteration); + + //~ Loop across all component outlet nodes and update their mass flow and max avail + for (CompCounter = 1; CompCounter <= this_branch.TotalComponents; ++CompCounter) { + + auto &this_comp(this_branch.Comp(CompCounter)); + + //~ Pick up some values for convenience + ComponentInletNode = this_comp.NodeNumIn; + ComponentOutletNode = this_comp.NodeNumOut; + MassFlowRateFound = Node(ComponentOutletNode).MassFlowRate; + ComponentTypeOfNum = this_comp.TypeOf_Num; + + //~ Push the values through + Node(ComponentOutletNode).MassFlowRate = MassFlow; + + if (PlantIsRigid) { + Node(ComponentInletNode).MassFlowRateMinAvail = MassFlow; + Node(ComponentInletNode).MassFlowRateMaxAvail = MassFlow; + Node(ComponentOutletNode).MassFlowRateMinAvail = MassFlow; + Node(ComponentOutletNode).MassFlowRateMaxAvail = MassFlow; + } + // Node(ComponentOutletNode)%MassFlowRateMinAvail = MinAvail + // no this is 2-way valve which messes up flow options + // for demand components Node(ComponentOutletNode)%MassFlowRateMaxAvail = MaxAvail + + //~ If this value matches then we are good to move to the next component + if (std::abs(MassFlow - MassFlowRateFound) < CriteriaDelta_MassFlowRate) continue; + //~ Since there is a difference, we have to decide what to do based on the component type: + //~ For plant connections, don't do anything, it SHOULD work itself out + //~ For air connections, trip the LoopSide air flag + //~ Similar for zone, none zone, and electric load center + { + auto const SELECT_CASE_var(ComponentTypeOfNum); + + // possibly air-connected components + if ((SELECT_CASE_var == TypeOf_CoilWaterCooling) || + (SELECT_CASE_var == TypeOf_CoilWaterDetailedFlatCooling) || + (SELECT_CASE_var == TypeOf_CoilWaterSimpleHeating) || + (SELECT_CASE_var == TypeOf_CoilSteamAirHeating) || + (SELECT_CASE_var == TypeOf_CoilWAHPHeatingEquationFit) || + (SELECT_CASE_var == TypeOf_CoilWAHPCoolingEquationFit) || + (SELECT_CASE_var == TypeOf_CoilWAHPHeatingParamEst) || + (SELECT_CASE_var == TypeOf_CoilWAHPCoolingParamEst) || + (SELECT_CASE_var == TypeOf_CoilUserDefined) || + (SELECT_CASE_var == TypeOf_CoilVSWAHPCoolingEquationFit) || + (SELECT_CASE_var == TypeOf_CoilVSWAHPHeatingEquationFit) || + (SELECT_CASE_var == TypeOf_PackagedTESCoolingCoil)) { + + this->SimAirLoopsNeeded = true; + // sometimes these coils are children in ZoneHVAC equipment + // PlantLoop(LoopNum)%LoopSide(LoopSideNum)%SimZoneEquipNeeded= .TRUE. + + } else if ((SELECT_CASE_var == TypeOf_CoolingPanel_Simple) || + (SELECT_CASE_var == TypeOf_Baseboard_Conv_Water) || + (SELECT_CASE_var == TypeOf_Baseboard_Rad_Conv_Steam) || + (SELECT_CASE_var == TypeOf_Baseboard_Rad_Conv_Water) || + (SELECT_CASE_var == TypeOf_LowTempRadiant_VarFlow) || + (SELECT_CASE_var == TypeOf_LowTempRadiant_ConstFlow) || + (SELECT_CASE_var == TypeOf_CooledBeamAirTerminal) || + (SELECT_CASE_var == TypeOf_ZoneHVACAirUserDefined) || + (SELECT_CASE_var == TypeOf_AirTerminalUserDefined) || + (SELECT_CASE_var == TypeOf_FourPipeBeamAirTerminal)) { // zone connected components + + this->SimZoneEquipNeeded = true; + + } else if ((SELECT_CASE_var == TypeOf_Generator_FCExhaust) || + (SELECT_CASE_var == TypeOf_Generator_FCStackCooler) || + (SELECT_CASE_var == TypeOf_Generator_MicroCHP) || + (SELECT_CASE_var == TypeOf_Generator_MicroTurbine) || + (SELECT_CASE_var == TypeOf_Generator_ICEngine) || + (SELECT_CASE_var == TypeOf_Generator_CTurbine)) { // electric center connected components + + this->SimElectLoadCentrNeeded = true; + } + } + } + } + + void HalfLoopData::TurnOnAllLoopSideBranches() { + for (int branchNum = 2; branchNum <= this->TotalBranches - 1; ++branchNum) { + auto &branch = this->Branch(branchNum); + branch.disableOverrideForCSBranchPumping = false; + } + } + + void HalfLoopData::SimulateAllLoopSideBranches(Real64 const ThisLoopSideFlow, bool const FirstHVACIteration, bool &LoopShutDownFlag) + { + + // SUBROUTINE INFORMATION: + // AUTHOR Edwin Lee + // DATE WRITTEN July 2010 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS SUBROUTINE: + // This routine will step through all branch groups (single branch .OR. inlet/parallels/outlet) + // and call the branch group simulation routine. This routine also calls to update the splitter + // and mixer. + + // METHODOLOGY EMPLOYED: + // The number of branch groups is either 1 or 3. 1 would be a single branch half-loop. 3 would + // be the minimum for an inlet/parallels/outlet set. The number of branch groups can then be + // calculated as #BrGrps = 1 + 2*L; where L is zero for single half loop and one for parallel-type set. + // This calculation can be reduced to the logical/integer conversion as shown in the code. + // The simulation then steps through each branch group. If there are parallel branches, the splitter is + // updated on flowlock=0 to pass information through, then after the parallel branches the mixer is always + // updated. The outlet branch "group" is then simulated. + + // SUBROUTINE PARAMETER DEFINITIONS: + int const InletBranchOrOneBranchHalfLoop(1); + int const ParallelBranchSet(2); + int const OutletBranch(3); + + int NumBranchGroups = 1; + if (this->TotalBranches > 1) { + NumBranchGroups = 3; + } + + // reset branch starting component index back to zero before each pass + for (int BranchCounter = 1; BranchCounter <= this->TotalBranches; ++BranchCounter) { + this->Branch(BranchCounter).lastComponentSimulated = 0; + } + + for (int BranchGroup = 1; BranchGroup <= NumBranchGroups; ++BranchGroup) { + + if ((BranchGroup > 1) && (this->TotalBranches == 1)) break; + + switch (BranchGroup) { + case InletBranchOrOneBranchHalfLoop: + this->SimulateLoopSideBranchGroup(1, 1, ThisLoopSideFlow, FirstHVACIteration, LoopShutDownFlag); + break; + case ParallelBranchSet: + this->UpdatePlantSplitter(); + this->SimulateLoopSideBranchGroup(2, this->TotalBranches - 1, ThisLoopSideFlow, FirstHVACIteration, LoopShutDownFlag); + this->UpdatePlantMixer(); + break; + case OutletBranch: + this->SimulateLoopSideBranchGroup(this->TotalBranches, this->TotalBranches, ThisLoopSideFlow, FirstHVACIteration, LoopShutDownFlag); + break; + } + } + } + + void HalfLoopData::AdjustPumpFlowRequestByEMSControls(int const BranchNum, int const CompNum, Real64 &FlowToRequest) { + + // SUBROUTINE INFORMATION: + // AUTHOR Brent Griffith + // DATE WRITTEN April 2012 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS SUBROUTINE: + // modify flow request to pump simulation if EMS is overriding pump component + + // SUBROUTINE LOCAL VARIABLE DECLARATIONS: + auto &this_branch(this->Branch(BranchNum)); + auto &this_comp(this_branch.Comp(CompNum)); + + if ((this->EMSCtrl) && (this->EMSValue <= 0.0)) { + FlowToRequest = 0.0; + return; + } + + if ((this_branch.EMSCtrlOverrideOn) && (this_branch.EMSCtrlOverrideValue <= 0.0)) { + FlowToRequest = 0.0; + return; + } + + if (this_comp.EMSLoadOverrideOn) { + if (this_comp.EMSLoadOverrideValue == 0.0) { + FlowToRequest = 0.0; + } + } + } + + void HalfLoopData::DisableAnyBranchPumpsConnectedToUnloadedEquipment() { + for (int branchNum = 2; branchNum <= this->TotalBranches - 1; ++branchNum) { + auto &branch = this->Branch(branchNum); + Real64 totalDispatchedLoadOnBranch = 0.0; + for (int compNum = 1; compNum <= branch.TotalComponents; ++compNum) { + auto &component = branch.Comp(compNum); + auto &t = component.TypeOf_Num; + if (t == DataPlant::TypeOf_PumpConstantSpeed || t == DataPlant::TypeOf_PumpBankConstantSpeed || + t == DataPlant::TypeOf_PumpVariableSpeed || t == DataPlant::TypeOf_PumpBankVariableSpeed) { + // don't do anything + } else { + totalDispatchedLoadOnBranch += component.MyLoad; + } + } + if (std::abs(totalDispatchedLoadOnBranch) < 0.001) { + branch.disableOverrideForCSBranchPumping = true; + } + } + } + + Real64 HalfLoopData::EvaluateLoopSetPointLoad(int const FirstBranchNum, + int const LastBranchNum, + Real64 ThisLoopSideFlow, + Array1S_int LastComponentSimulated) { + + // FUNCTION INFORMATION: + // AUTHOR Edwin Lee + // DATE WRITTEN August 2010 + // MODIFIED na + // RE-ENGINEERED na + + // Return value + Real64 LoadToLoopSetPoint = 0.0; // function result + + static std::string const RoutineName("PlantLoopSolver::EvaluateLoopSetPointLoad"); + static std::string const RoutineNameAlt("PlantSupplySide:EvaluateLoopSetPointLoad"); + + //~ General variables + Real64 SumMdotTimesTemp = 0.0; + Real64 SumMdot = 0.0; + + auto &thisPlantLoop = DataPlant::PlantLoop(this->myLoopNum); + + // We will place one specialized case in here for common pipe simulations. + // If we are doing a common pipe simulation, and there is greater other-side flow than this side, + // then the "other side" demand needs to include getting the flow through the common pipe to the same setpoint + // as the flow going through the actual supply side + if (this->hasConstSpeedBranchPumps && this->myLoopSideNum == 2 && + thisPlantLoop.CommonPipeType != DataPlant::CommonPipe_No) { + const int OtherSide = 3 - this->myLoopSideNum; + const int otherSideOutletNodeNum = thisPlantLoop.LoopSide(OtherSide).NodeNumOut; + Real64 commonPipeFlow = DataLoopNode::Node(otherSideOutletNodeNum).MassFlowRate - ThisLoopSideFlow; + Real64 otherSideExitingTemperature = DataLoopNode::Node(otherSideOutletNodeNum).Temp; + SumMdotTimesTemp += otherSideExitingTemperature * commonPipeFlow; + SumMdot += commonPipeFlow; + } + + // Sweep across flow paths in this group and calculate the deltaT and then the load + int BranchIndex = 0; // ~ This is a 1 - n value within the current branch group + for (int BranchCounter = FirstBranchNum; BranchCounter <= LastBranchNum; ++BranchCounter) { + + ++BranchIndex; + + //~ Always start from the last component we did the last time around + 1 and + //~ try to make it all the way to the end of the loop + int StartingComponent = LastComponentSimulated(BranchIndex) + 1; + int EnteringNodeNum = this->Branch(BranchCounter).Comp(StartingComponent).NodeNumIn; + + Real64 EnteringTemperature = DataLoopNode::Node(EnteringNodeNum).Temp; + Real64 MassFlowRate = DataLoopNode::Node(EnteringNodeNum).MassFlowRate; + + SumMdotTimesTemp += EnteringTemperature * MassFlowRate; + SumMdot += MassFlowRate; + } + + if (SumMdot < DataBranchAirLoopPlant::MassFlowTolerance) { + return 0.0; + } + + Real64 WeightedInletTemp = SumMdotTimesTemp / SumMdot; + + if (thisPlantLoop.FluidType == DataLoopNode::NodeType_Water) { + + Real64 Cp = FluidProperties::GetSpecificHeatGlycol(thisPlantLoop.FluidName, WeightedInletTemp, + thisPlantLoop.FluidIndex, RoutineName); + + { + auto const SELECT_CASE_var(thisPlantLoop.LoopDemandCalcScheme); + + if (SELECT_CASE_var == DataPlant::SingleSetPoint) { + + // Pick up the loop setpoint temperature + Real64 LoopSetPointTemperature = this->TempSetPoint; + // Calculate the delta temperature + Real64 DeltaTemp = LoopSetPointTemperature - WeightedInletTemp; + + // Calculate the demand on the loop + LoadToLoopSetPoint = SumMdot * Cp * DeltaTemp; + + } else if (SELECT_CASE_var == DataPlant::DualSetPointDeadBand) { + + // Get the range of setpoints + Real64 LoopSetPointTemperatureHi = DataLoopNode::Node(thisPlantLoop.TempSetPointNodeNum).TempSetPointHi; + Real64 LoopSetPointTemperatureLo = DataLoopNode::Node(thisPlantLoop.TempSetPointNodeNum).TempSetPointLo; + + // Calculate the demand on the loop + if (SumMdot > 0.0) { + Real64 LoadToHeatingSetPoint = + SumMdot * Cp * (LoopSetPointTemperatureLo - WeightedInletTemp); + Real64 LoadToCoolingSetPoint = + SumMdot * Cp * (LoopSetPointTemperatureHi - WeightedInletTemp); + // Possible combinations: + // 1 LoadToHeatingSetPoint > 0 & LoadToCoolingSetPoint > 0 --> Heating required + // 2 LoadToHeatingSetPoint < 0 & LoadToCoolingSetPoint < 0 --> Cooling Required + // 3 LoadToHeatingSetPoint <=0 & LoadToCoolingSetPoint >=0 --> Dead Band Operation - includes zero load cases + // 4 LoadToHeatingSetPoint > LoadToCoolingSetPoint --> Not Feasible if LoopSetPointHi >= LoopSetPointLo + // First trap bad set-points + if (LoadToHeatingSetPoint > LoadToCoolingSetPoint) { + ShowSevereError( + "Plant Loop: the Plant Loop Demand Calculation Scheme is set to DualSetPointDeadBand, but the " + "heating-related low setpoint appears to be above the cooling-related high setpoint."); + ShowContinueError( + "For example, if using SetpointManager:Scheduled:DualSetpoint, then check that the low setpoint is " + "below the high setpoint."); + ShowContinueError("Occurs in PlantLoop=" + thisPlantLoop.Name); + ShowContinueError( + "LoadToHeatingSetPoint=" + General::RoundSigDigits(LoadToHeatingSetPoint, 3) + + ", LoadToCoolingSetPoint=" + General::RoundSigDigits(LoadToCoolingSetPoint, 3)); + ShowContinueError("Loop Heating Low Setpoint=" + + General::RoundSigDigits(LoopSetPointTemperatureLo, 2)); + ShowContinueError("Loop Cooling High Setpoint=" + + General::RoundSigDigits(LoopSetPointTemperatureHi, 2)); + + ShowFatalError("Program terminates due to above conditions."); + } + if (LoadToHeatingSetPoint > 0.0 && LoadToCoolingSetPoint > 0.0) { + LoadToLoopSetPoint = LoadToHeatingSetPoint; + } else if (LoadToHeatingSetPoint < 0.0 && LoadToCoolingSetPoint < 0.0) { + LoadToLoopSetPoint = LoadToCoolingSetPoint; + } else if (LoadToHeatingSetPoint <= 0.0 && + LoadToCoolingSetPoint >= 0.0) { // deadband includes zero loads + LoadToLoopSetPoint = 0.0; + } else { + ShowSevereError( + "DualSetPointWithDeadBand: Unanticipated combination of heating and cooling loads - report to EnergyPlus " + "Development Team"); + ShowContinueError("occurs in PlantLoop=" + thisPlantLoop.Name); + ShowContinueError( + "LoadToHeatingSetPoint=" + General::RoundSigDigits(LoadToHeatingSetPoint, 3) + + ", LoadToCoolingSetPoint=" + General::RoundSigDigits(LoadToCoolingSetPoint, 3)); + ShowContinueError("Loop Heating Setpoint=" + + General::RoundSigDigits(LoopSetPointTemperatureLo, 2)); + ShowContinueError("Loop Cooling Setpoint=" + + General::RoundSigDigits(LoopSetPointTemperatureHi, 2)); + ShowFatalError("Program terminates due to above conditions."); + } + } else { + LoadToLoopSetPoint = 0.0; + } + } + } + + } else if (thisPlantLoop.FluidType == DataLoopNode::NodeType_Steam) { + + Real64 Cp = FluidProperties::GetSpecificHeatGlycol(thisPlantLoop.FluidName, WeightedInletTemp, + thisPlantLoop.FluidIndex, RoutineName); + + { + auto const SELECT_CASE_var(thisPlantLoop.LoopDemandCalcScheme); + + if (SELECT_CASE_var == DataPlant::SingleSetPoint) { + + // Pick up the loop setpoint temperature + Real64 LoopSetPointTemperature = this->TempSetPoint; + + // Calculate the delta temperature + Real64 DeltaTemp = LoopSetPointTemperature - WeightedInletTemp; + + Real64 EnthalpySteamSatVapor = + FluidProperties::GetSatEnthalpyRefrig(fluidNameSteam, LoopSetPointTemperature, 1.0, + this->refrigIndex, RoutineNameAlt); + Real64 EnthalpySteamSatLiquid = + FluidProperties::GetSatEnthalpyRefrig(fluidNameSteam, LoopSetPointTemperature, 0.0, + this->refrigIndex, RoutineNameAlt); + + Real64 LatentHeatSteam = EnthalpySteamSatVapor - EnthalpySteamSatLiquid; + + // Calculate the demand on the loop + LoadToLoopSetPoint = SumMdot * (Cp * DeltaTemp + LatentHeatSteam); + } + } + + } else { // only have two types, water serves for glycol. + } + + // Trim the demand to zero if it is very small + if (std::abs(LoadToLoopSetPoint) < DataPlant::LoopDemandTol) LoadToLoopSetPoint = 0.0; + + return LoadToLoopSetPoint; + } + + Real64 HalfLoopData::CalcOtherSideDemand(Real64 ThisLoopSideFlow) { + + // FUNCTION INFORMATION: + // AUTHOR Edwin Lee + // DATE WRITTEN August 2010 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS FUNCTION: + // To evaluate the demand to hit the loop setpoint based on the loop side inlet conditions + + // METHODOLOGY EMPLOYED: + // This routine will simply call the evaluate loop setpoint routine but call it from + // the very beginning of this loop side, so that it is basically for the entire loop side + + // FUNCTION PARAMETER DEFINITIONS: + static Array1D_int const InitCompArray(1, 0); + return this->EvaluateLoopSetPointLoad(1, 1, ThisLoopSideFlow, InitCompArray); + } + + Real64 HalfLoopData::SetupLoopFlowRequest(int const OtherSide) { + + // FUNCTION INFORMATION: + // AUTHOR: Dan Fisher, Edwin Lee + // DATE WRITTEN: August 2010 + // MODIFIED: na + // RE-ENGINEERED: na + + // PURPOSE OF THIS SUBROUTINE: + // This routine sets up the flow request values and sums them up for each loop side + // Then makes a decision on the desired loop flow based on loop configuration + + // METHODOLOGY EMPLOYED: + // Scan through the components on this loop side, and look at the mass flow request + // values on components inlet node. + // Check common pipe/pumping configuration for this loop side and the other loop side + // to determine what the LoopSide should flow + + //~ Initialize + Real64 LoopFlow = 0.0; // Once all flow requests are evaluated, this is the desired flow on this side + + // reference + auto &loop(DataPlant::PlantLoop(this->myLoopNum)); + + //~ First we need to set up the flow requests on each LoopSide + for (int LoopSideCounter = DataPlant::DemandSide; + LoopSideCounter <= DataPlant::SupplySide; ++LoopSideCounter) { + // Clear things out for this LoopSide + Real64 InletBranchRequestNeedAndTurnOn = 0.0; + Real64 InletBranchRequestNeedIfOn = 0.0; + Real64 ParallelBranchRequestsNeedAndTurnOn(0.0); + Real64 ParallelBranchRequestsNeedIfOn(0.0); + Real64 OutletBranchRequestNeedAndTurnOn = 0.0; + Real64 OutletBranchRequestNeedIfOn = 0.0; + + // reference + auto &loop_side(loop.LoopSide(LoopSideCounter)); + + loop_side.flowRequestNeedIfOn = 0.0; + loop_side.flowRequestNeedAndTurnOn = 0.0; + loop_side.flowRequestFinal = 0.0; + loop_side.hasConstSpeedBranchPumps = false; + + // Now loop through all the branches on this LoopSide and get flow requests + int const NumBranchesOnThisLoopSide = loop_side.TotalBranches; + int ParallelBranchIndex = 0; + for (int BranchCounter = 1; BranchCounter <= NumBranchesOnThisLoopSide; ++BranchCounter) { + Real64 ThisBranchFlowRequestNeedAndTurnOn = 0.0; + Real64 ThisBranchFlowRequestNeedIfOn = 0.0; + + // reference + auto &branch(loop_side.Branch(BranchCounter)); + + if (BranchCounter > 1 && BranchCounter < NumBranchesOnThisLoopSide) ++ParallelBranchIndex; + + if (branch.disableOverrideForCSBranchPumping) { + branch.RequestedMassFlow = 0.0; + continue; + } + + int const NumCompsOnThisBranch = branch.TotalComponents; + for (int CompCounter = 1; CompCounter <= NumCompsOnThisBranch; ++CompCounter) { + + // reference + auto &component(branch.Comp(CompCounter)); + + int NodeToCheckRequest = component.NodeNumIn; + int FlowPriorityStatus = component.FlowPriority; + + // reference + auto &node_with_request(DataLoopNode::Node(NodeToCheckRequest)); + + if (!component.isPump()) { + + if (FlowPriorityStatus == DataPlant::LoopFlowStatus_Unknown) { + // do nothing + } else if (FlowPriorityStatus == DataPlant::LoopFlowStatus_NeedyAndTurnsLoopOn) { + ThisBranchFlowRequestNeedAndTurnOn = max(ThisBranchFlowRequestNeedAndTurnOn, + node_with_request.MassFlowRateRequest); + ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, + node_with_request.MassFlowRateRequest); + } else if (FlowPriorityStatus == DataPlant::LoopFlowStatus_NeedyIfLoopOn) { + ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, + node_with_request.MassFlowRateRequest); + } else if (FlowPriorityStatus == DataPlant::LoopFlowStatus_TakesWhatGets) { + // do nothing + } + } else { // handle pumps differently + if ((BranchCounter == 1) && (LoopSideCounter == DataPlant::SupplySide) && + (loop.CommonPipeType == DataPlant::CommonPipe_TwoWay)) { + // special primary side flow request for two way common pipe + int const CompIndex = component.CompNum; + { + auto const SELECT_CASE_var(component.TypeOf_Num); + // remove var speed pumps from this case statement if can set MassFlowRateRequest + if ((SELECT_CASE_var == DataPlant::TypeOf_PumpConstantSpeed) || + (SELECT_CASE_var == DataPlant::TypeOf_PumpVariableSpeed) || + (SELECT_CASE_var == DataPlant::TypeOf_PumpBankVariableSpeed)) { + if (CompIndex > 0) { + ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, + Pumps::PumpEquip( + CompIndex).MassFlowRateMax); + } + } else if (SELECT_CASE_var == DataPlant::TypeOf_PumpBankConstantSpeed) { + if (CompIndex > 0) { + ThisBranchFlowRequestNeedIfOn = + max(ThisBranchFlowRequestNeedIfOn, + Pumps::PumpEquip(CompIndex).MassFlowRateMax / + Pumps::PumpEquip(CompIndex).NumPumpsInBank); + } + } else { + ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, + node_with_request.MassFlowRateRequest); + } + } + + } else if ((BranchCounter == 1) && (LoopSideCounter == DataPlant::SupplySide) && + (loop.CommonPipeType == DataPlant::CommonPipe_Single)) { + int const CompIndex = component.CompNum; + { + auto const SELECT_CASE_var(component.TypeOf_Num); + // remove var speed pumps from this case statement if can set MassFlowRateRequest + if ((SELECT_CASE_var == DataPlant::TypeOf_PumpConstantSpeed) || + (SELECT_CASE_var == DataPlant::TypeOf_PumpVariableSpeed) || + (SELECT_CASE_var == DataPlant::TypeOf_PumpBankVariableSpeed)) { + if (CompIndex > 0) { + ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, + Pumps::PumpEquip( + CompIndex).MassFlowRateMax); + } + } else if (SELECT_CASE_var == DataPlant::TypeOf_PumpBankConstantSpeed) { + if (CompIndex > 0) { + ThisBranchFlowRequestNeedIfOn = + max(ThisBranchFlowRequestNeedIfOn, + Pumps::PumpEquip(CompIndex).MassFlowRateMax / + Pumps::PumpEquip(CompIndex).NumPumpsInBank); + } + } else { + ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, + node_with_request.MassFlowRateRequest); + } + } + } else { + int const CompIndex = component.CompNum; + { + auto const SELECT_CASE_var(component.TypeOf_Num); + if (SELECT_CASE_var == DataPlant::TypeOf_PumpConstantSpeed) { + if (CompIndex > 0) { + auto &this_pump(Pumps::PumpEquip(CompIndex)); + if (ParallelBranchIndex >= 1) { // branch pump + if (branch.max_abs_Comp_MyLoad() > DataHVACGlobals::SmallLoad) { + ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, + this_pump.MassFlowRateMax); + } else if (loop.CommonPipeType != + DataPlant::CommonPipe_No) { // common pipe and constant branch pumps + ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, + this_pump.MassFlowRateMax); + } + loop_side.hasConstSpeedBranchPumps = true; + branch.HasConstantSpeedBranchPump = true; + branch.ConstantSpeedBranchMassFlow = this_pump.MassFlowRateMax; + } else { // inlet pump + ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, + this_pump.MassFlowRateMax); + } + } + } else if (SELECT_CASE_var == DataPlant::TypeOf_PumpBankConstantSpeed) { + if (CompIndex > 0) { + auto &this_pump(Pumps::PumpEquip(CompIndex)); + if (ParallelBranchIndex >= 1) { // branch pump + if (branch.max_abs_Comp_MyLoad() > DataHVACGlobals::SmallLoad) { + ThisBranchFlowRequestNeedIfOn = + max(ThisBranchFlowRequestNeedIfOn, + this_pump.MassFlowRateMax / this_pump.NumPumpsInBank); + } else if (loop.CommonPipeType != + DataPlant::CommonPipe_No) { // common pipe and constant branch pumps + ThisBranchFlowRequestNeedIfOn = + max(ThisBranchFlowRequestNeedIfOn, + this_pump.MassFlowRateMax / this_pump.NumPumpsInBank); + } + loop_side.hasConstSpeedBranchPumps = true; + branch.HasConstantSpeedBranchPump = true; + branch.ConstantSpeedBranchMassFlow = + this_pump.MassFlowRateMax / this_pump.NumPumpsInBank; + } else { // inlet pump + ThisBranchFlowRequestNeedIfOn = + max(ThisBranchFlowRequestNeedIfOn, + this_pump.MassFlowRateMax / this_pump.NumPumpsInBank); + } + } + } + + // overwrite here for branch pumps + if ((SELECT_CASE_var == DataPlant::TypeOf_PumpVariableSpeed) || + (SELECT_CASE_var == DataPlant::TypeOf_PumpBankVariableSpeed) || + (SELECT_CASE_var == DataPlant::TypeOf_PumpCondensate)) { + if (component.CompNum > 0) { + auto &this_pump(Pumps::PumpEquip(component.CompNum)); + this_pump.LoopSolverOverwriteFlag = false; + } + } + } + } + } + } + if (BranchCounter == 1) { // inlet branch + InletBranchRequestNeedAndTurnOn = ThisBranchFlowRequestNeedAndTurnOn; + InletBranchRequestNeedIfOn = ThisBranchFlowRequestNeedIfOn; + } else if (BranchCounter < NumBranchesOnThisLoopSide) { // branchcounter = 1 is already caught + ParallelBranchRequestsNeedAndTurnOn += ThisBranchFlowRequestNeedAndTurnOn; + ParallelBranchRequestsNeedIfOn += ThisBranchFlowRequestNeedIfOn; + } else if (BranchCounter == NumBranchesOnThisLoopSide) { // outlet branch + OutletBranchRequestNeedAndTurnOn = ThisBranchFlowRequestNeedAndTurnOn; + OutletBranchRequestNeedIfOn = ThisBranchFlowRequestNeedIfOn; + } + + branch.RequestedMassFlow = max(ThisBranchFlowRequestNeedIfOn, ThisBranchFlowRequestNeedAndTurnOn); + } + loop_side.flowRequestNeedAndTurnOn = max(InletBranchRequestNeedAndTurnOn, + ParallelBranchRequestsNeedAndTurnOn, + OutletBranchRequestNeedAndTurnOn); + loop_side.flowRequestNeedIfOn = max(InletBranchRequestNeedIfOn, ParallelBranchRequestsNeedIfOn, + OutletBranchRequestNeedIfOn); + } + + auto &this_loop_side(loop.LoopSide(this->myLoopSideNum)); + auto &other_loop_side(loop.LoopSide(OtherSide)); + + //~ Now that we have calculated each sides different status's requests, process to find final + if ((this_loop_side.flowRequestNeedAndTurnOn + other_loop_side.flowRequestNeedAndTurnOn) < + DataBranchAirLoopPlant::MassFlowTolerance) { + this_loop_side.flowRequestFinal = 0.0; + other_loop_side.flowRequestFinal = 0.0; + } else { // some flow is needed and loop should try to run + this_loop_side.flowRequestFinal = max(this_loop_side.flowRequestNeedAndTurnOn, + this_loop_side.flowRequestNeedIfOn); + other_loop_side.flowRequestFinal = max(other_loop_side.flowRequestNeedAndTurnOn, + other_loop_side.flowRequestNeedIfOn); + } + // now store final flow requests on each loop side data structure + this_loop_side.FlowRequest = this_loop_side.flowRequestFinal; + other_loop_side.FlowRequest = other_loop_side.flowRequestFinal; + + if (loop.CommonPipeType == DataPlant::CommonPipe_No) { + // we may or may not have a pump on this side, but the flow request is the larger of the two side's final + if ((!this_loop_side.hasConstSpeedBranchPumps) && (!other_loop_side.hasConstSpeedBranchPumps)) { + LoopFlow = max(this_loop_side.flowRequestFinal, other_loop_side.flowRequestFinal); + } else { // account for stepped loop flow rates required of branch pumps + + // rules for setting flow when there are constant speed branch pumps. + // 1. Check if above routines already selected a loop flow rate based on the constant speed branches, if so then just use it + if (this_loop_side.hasConstSpeedBranchPumps && + (this_loop_side.flowRequestFinal >= other_loop_side.flowRequestFinal)) { + // okay, just use basic logic + LoopFlow = max(this_loop_side.flowRequestFinal, other_loop_side.flowRequestFinal); + } else if (other_loop_side.hasConstSpeedBranchPumps && + (this_loop_side.flowRequestFinal <= other_loop_side.flowRequestFinal)) { + // okay, just use basic logic + LoopFlow = max(this_loop_side.flowRequestFinal, other_loop_side.flowRequestFinal); + } else { // not okay, we have a case that will likely need special correcting + // 2. determine which loop side has the stepped data + int LoopSideIndex = 0; + if (this_loop_side.hasConstSpeedBranchPumps && + (this_loop_side.flowRequestFinal < other_loop_side.flowRequestFinal)) { + LoopSideIndex = this->myLoopSideNum; + } else if (other_loop_side.hasConstSpeedBranchPumps && + (other_loop_side.flowRequestFinal < this_loop_side.flowRequestFinal)) { + LoopSideIndex = OtherSide; + } + auto &loop_side(loop.LoopSide(LoopSideIndex)); + + // 3. step through and find out needed information + // 3a. search the loop side with branch pumps and find the steps available with non-zero Myloads + // 3b. search the loop side with branch pumps and find the steps available with zero Myloads + // LoadedConstantSpeedBranchFlowRateSteps = 0.0; + Real64 LoadedConstantSpeedBranchFlowRateSteps_sum = 0.0; + this_loop_side.noLoadConstantSpeedBranchFlowRateSteps = 0.0; + Real64 NoLoadConstantSpeedBranchFlowRateSteps_sum = 0.0; + int ParallelBranchIndex = 0; + int const NumBranchesOnThisLoopSide = loop_side.TotalBranches; + auto const &loop_branches(loop_side.Branch); + for (int BranchCounter = 1; BranchCounter <= NumBranchesOnThisLoopSide; ++BranchCounter) { + auto const &loop_branch(loop_branches(BranchCounter)); + if (BranchCounter > 1 && BranchCounter < NumBranchesOnThisLoopSide) ++ParallelBranchIndex; + if (loop_branch.HasConstantSpeedBranchPump) { + auto const branch_mass_flow(loop_branch.ConstantSpeedBranchMassFlow); + if (loop_branch.max_abs_Comp_MyLoad() > DataHVACGlobals::SmallLoad) { + LoadedConstantSpeedBranchFlowRateSteps_sum += branch_mass_flow; + } else { + this_loop_side.noLoadConstantSpeedBranchFlowRateSteps( + ParallelBranchIndex) = branch_mass_flow; + NoLoadConstantSpeedBranchFlowRateSteps_sum += branch_mass_flow; + } + } + } + + // 4. allocate which branches to use, + Real64 tmpLoopFlow = max(this_loop_side.flowRequestFinal, other_loop_side.flowRequestFinal); + Real64 MaxBranchPumpLoopSideFlow = + LoadedConstantSpeedBranchFlowRateSteps_sum + NoLoadConstantSpeedBranchFlowRateSteps_sum; + tmpLoopFlow = min(tmpLoopFlow, MaxBranchPumpLoopSideFlow); + // 4b. first use all the branches with non-zero MyLoad + if (tmpLoopFlow > LoadedConstantSpeedBranchFlowRateSteps_sum) { + Real64 AccumFlowSteps = LoadedConstantSpeedBranchFlowRateSteps_sum; + ParallelBranchIndex = 0; + for (int BranchCounter = 1; BranchCounter <= NumBranchesOnThisLoopSide; ++BranchCounter) { + if (BranchCounter > 1 && BranchCounter < NumBranchesOnThisLoopSide) { + ++ParallelBranchIndex; + } else { + continue; + } + auto const steps( + this_loop_side.noLoadConstantSpeedBranchFlowRateSteps(ParallelBranchIndex)); + if (steps > + 0.0) { // add in branches with zero MyLoad in branch input order until satisfied + if (tmpLoopFlow > AccumFlowSteps) { + if (tmpLoopFlow <= AccumFlowSteps + steps) { // found it set requests and exit + tmpLoopFlow = AccumFlowSteps + steps; + loop_side.Branch(BranchCounter).RequestedMassFlow = steps; + LoopFlow = tmpLoopFlow; + break; + } else { + AccumFlowSteps += steps; + loop_side.Branch(BranchCounter).RequestedMassFlow = steps; + } + } + } + } + } + } + } + } else if (loop.CommonPipeType == DataPlant::CommonPipe_TwoWay) { + LoopFlow = this_loop_side.flowRequestFinal; + } else if (loop.CommonPipeType == DataPlant::CommonPipe_Single) { + LoopFlow = this_loop_side.flowRequestFinal; + } + + // overrides the loop solver flow request to allow loop pump to turn off when not in use + if (this_loop_side.TotalPumps == 1) { + if (LoopFlow < DataConvergParams::PlantLowFlowRateToler) { // Update from dataconvergetols... + for (int BranchCounter = 1; BranchCounter <= this_loop_side.TotalBranches; ++BranchCounter) { + // reference + auto &branch(this_loop_side.Branch(BranchCounter)); + int const NumCompsOnThisBranch = branch.TotalComponents; + for (int CompCounter = 1; CompCounter <= NumCompsOnThisBranch; ++CompCounter) { + auto const &component(branch.Comp(CompCounter)); + auto const SELECT_CASE_var(component.TypeOf_Num); + if ((SELECT_CASE_var == DataPlant::TypeOf_PumpVariableSpeed) || + (SELECT_CASE_var == DataPlant::TypeOf_PumpBankVariableSpeed) || + (SELECT_CASE_var == DataPlant::TypeOf_PumpCondensate)) { + if (component.CompNum > 0) { + auto &this_pump(Pumps::PumpEquip(component.CompNum)); + this_pump.LoopSolverOverwriteFlag = true; + } + } + } + } + } + } + + return LoopFlow; + } + + + void HalfLoopData::DoFlowAndLoadSolutionPass(int OtherSide, int ThisSideInletNode, bool FirstHVACIteration) { + + // This is passed in-out deep down into the depths where the load op manager calls EMS and EMS can shut down pumps + bool LoopShutDownFlag = false; + + // First thing is to setup mass flow request information + Real64 ThisLoopSideFlowRequest = this->SetupLoopFlowRequest(OtherSide); + + // Now we know what the loop would "like" to run at, let's see the pump + // operation range (min/max avail) to see whether it is possible this time around + Real64 ThisLoopSideFlow = this->DetermineLoopSideFlowRate(ThisSideInletNode, ThisLoopSideFlowRequest); + + // We also need to establish a baseline "other-side-based" loop demand based on this possible flow rate + this->InitialDemandToLoopSetPoint = this->CalcOtherSideDemand(ThisLoopSideFlow); + this->UpdatedDemandToLoopSetPoint = this->InitialDemandToLoopSetPoint; + this->LoadToLoopSetPointThatWasntMet = 0.0; + + // We now have a loop side flow request, along with inlet min/max avails. + // We can now make a first pass through the component simulation, requesting flow as necessary. + // Normal "supply side" components will set a mass flow rate on their outlet node to request flow, + // while "Demand side" components will set a a mass flow request on their inlet node to request flow. + this->FlowLock = DataPlant::FlowUnlocked; + this->SimulateAllLoopSideBranches(ThisLoopSideFlow, FirstHVACIteration, LoopShutDownFlag); + + // DSU? discussion/comments about loop solver/flow resolver interaction + // At this point, the components have been simulated. They should have either: + // - logged a massflowrequest + // - or logged a MassFlowRate + // We need to decide what the components are going to do on FlowLock=0. + // If we want all control here at the solver level, the components just need to + // log their MassFlowRate on their outlet nodes, or some other mechanism. + // Then the loop solver can scan the branch and get the max, and this will be the requested + // flow rate for the branch. + // The loop solver will then set this as the branch outlet mass flow rate in preparation + // for the flow resolver. + // The loop solver may need to do something to the inlet/outlet branch, but I'm not sure yet. + // The following comment block is what I had already thought of, and it may still make sense. + + // Now that all the flow requests have been logged, we need to prepare them for the + // flow resolver. This will just take the requests and determine the desired flow + // request for that branch according to pump placement, pump type, and other component + // conditions. In many cases, this will just be to simply take the max request from + // the branch, which will already be within pumping limits for that flow path. + // We can then call the flow resolver to lock down branch inlet flow rates. + + // The flow resolver takes information such as requested flows and min/max available flows and + // sets the corrected flow on the inlet to each parallel branch + this->ResolveParallelFlows(ThisLoopSideFlow, FirstHVACIteration); + + // Re-Initialize variables for this next pass + this->InitialDemandToLoopSetPointSAVED = this->InitialDemandToLoopSetPoint; + this->CurrentAlterationsToDemand = 0.0; + this->UpdatedDemandToLoopSetPoint = this->InitialDemandToLoopSetPoint; + + // Now that flow rates have been resolved, we just need to set the flow lock status + // flag, and resimulate. During this simulation each component will still use the + // SetFlowRequest routine, but this routine will also set the outlet flow rate + // equal to the inlet flow rate, according to flowlock logic. + this->FlowLock = DataPlant::FlowLocked; + this->SimulateAllLoopSideBranches(ThisLoopSideFlow, FirstHVACIteration, LoopShutDownFlag); + } + + void HalfLoopData::ResolveParallelFlows( + Real64 const ThisLoopSideFlow, // [kg/s] total flow to be split + bool const FirstHVACIteration // TRUE if First HVAC iteration of Time step + ) { + + // SUBROUTINE INFORMATION: + // AUTHOR Brandon Anderson, Dan Fisher + // DATE WRITTEN October 1999 + // MODIFIED May 2005 Sankaranarayanan K P, Rich Liesen + // RE-ENGINEERED Sept 2010 Dan Fisher, Brent Griffith for demand side update + + // PURPOSE OF THIS SUBROUTINE: + // This subroutine takes the overall loop side flow and distributes + // it among parallel branches. this is the main implementation of + // flow splitting for plant splitter/mixer + + // METHODOLOGY EMPLOYED: + // Flow through the branches is currently determined by + // the active component on the branch, as well as the + // order of the branches following the splitter. + // SimPlantEquipment is run first, and the active components + // request their flow. These flows are compared and a simple + // algorithm balances flow in the branches. The flow in these + // branches is then locked down, via MassFlowRateMaxAvail and MinAvail + // SimPlant Equipment is then run again in order to get correct + // properties. Finally, Max/MinAvail are reset for the next time step. + + // Using/Aliasing + using DataBranchAirLoopPlant::ControlType_Active; + using DataBranchAirLoopPlant::ControlType_Bypass; + using DataBranchAirLoopPlant::ControlType_Passive; + using DataBranchAirLoopPlant::ControlType_SeriesActive; + using DataBranchAirLoopPlant::MassFlowTolerance; + using DataLoopNode::Node; + using DataPlant::TypeOf_PumpBankVariableSpeed; + using DataPlant::TypeOf_PumpVariableSpeed; + using General::RoundSigDigits; + + // SUBROUTINE PARAMETER DEFINITIONS: + static Array1D_string const LoopSideName(2, {"Demand", "Supply"}); + int const LoopSideSingleBranch(1); // For readability + + // SUBROUTINE LOCAL VARIABLE DECLARATIONS: + int NumActiveBranches; // Active branch counter + Real64 ActiveFlowRate; // The flow available when cycling through branches + Real64 PassiveFlowRate; // The flow available when cycling through branches + Real64 FracFlow; // The flow available when cycling through branches + Real64 ThisBranchRequestFrac; // The request ratio + Real64 totalMax; // The flow available when cycling through branches + Real64 FlowRemaining; // The flow available when cycling through branches + int OutletNum; // Splitter outlet + int MixerBranchOut; + int SplitterBranchIn; // As the name implies + int SplitterBranchOut; // As the name implies + int LastNodeOnBranch; // intermediate value used for better readabilty + int FirstNodeOnBranch; // intermediate value used for better readabilty + int BranchNum; // intermediate value used for better readabilty + int iBranch; // DO loop counter for cycling through branches + int NumSplitOutlets; // As the name implies + Real64 BranchFlowReq; + Real64 BranchMinAvail; + Real64 BranchMaxAvail; + Real64 ParallelBranchMaxAvail; + Real64 ParallelBranchMinAvail; + Real64 TotParallelBranchFlowReq; + int FirstNodeOnBranchIn; + int FirstNodeOnBranchOut; + Real64 StartingFlowRate; + Real64 ThisBranchRequest; + int CompCounter; + int CompInletNode; + int CompOutletNode; + + // If there is no splitter then there is no continuity to enforce. + if (!this->Splitter.Exists) { + + // If there's only one branch, then RETURN + if (this->TotalBranches == 1) { + // The branch should just try to meet the request previously calculated. This should be good, + // just need to make sure that during FlowUnlocked, no one constrained Min/Max farther. + // This would have been propagated down the branch, so we can check the outlet node min/max avail for this. + auto &this_single_branch(this->Branch(LoopSideSingleBranch)); + LastNodeOnBranch = this_single_branch.NodeNumOut; + FirstNodeOnBranch = this_single_branch.NodeNumIn; + BranchMinAvail = Node(LastNodeOnBranch).MassFlowRateMinAvail; + BranchMaxAvail = Node(LastNodeOnBranch).MassFlowRateMaxAvail; + Node(FirstNodeOnBranch).MassFlowRate = min(max(ThisLoopSideFlow, BranchMinAvail), BranchMaxAvail); + // now with flow locked, this single branch will just ran at the specified flow rate, so we are done + return; + } else { + ShowSevereError("Plant topology problem on \"" + this->loopSideDescription + "\""); + ShowContinueError( + "There are multiple branches, yet no splitter. This is an invalid configuration."); + ShowContinueError("Add a set of connectors, use put components on a single branch."); + ShowFatalError("Invalid plant topology causes program termination."); + return; + } + } + + // If a splitter/mixer combination exist on the loop + if (this->Splitter.Exists && this->Mixer.Exists) { + + // Zero out local variables + TotParallelBranchFlowReq = 0.0; + NumSplitOutlets = this->Splitter.TotalOutletNodes; + if (NumSplitOutlets < 1) { + ShowSevereError("Plant topology problem on \"" + this->loopSideDescription + "\""); + ShowContinueError("Diagnostic error in PlantLoopSolver::ResolveParallelFlows."); + ShowContinueError("Splitter improperly specified, no splitter outlets."); + ShowFatalError("Invalid plant topology causes program termination."); + } + + NumActiveBranches = 0; + ParallelBranchMaxAvail = 0.0; + ParallelBranchMinAvail = 0.0; + for (iBranch = 1; iBranch <= NumSplitOutlets; ++iBranch) { + + BranchNum = this->Splitter.BranchNumOut(iBranch); + auto &this_branch(this->Branch(BranchNum)); + SplitterBranchOut = this->Splitter.BranchNumOut(iBranch); + auto &this_splitter_outlet_branch(this->Branch(SplitterBranchOut)); + LastNodeOnBranch = this_branch.NodeNumOut; + FirstNodeOnBranch = this_branch.NodeNumIn; + BranchFlowReq = this_branch.DetermineBranchFlowRequest(); + this_branch.RequestedMassFlow = BranchFlowReq; // store this for later use in logic for remaining flow allocations + // now, if we are have branch pumps, here is the situation: + // constant speed pumps lock in a flow request on the inlet node + // variable speed pumps which have other components on the branch do not log a request themselves + // the DetermineBranchFlowRequest routine only looks at the branch inlet node + // for variable speed branch pumps then, this won't work because the branch will be requesting zero + // so let's adjust for this here to make sure these branches get good representation + // This comment above is not true, for series active branches, DetermineBranchFlowRequest does scan down the branch's + // components already, no need to loop over components + BranchMinAvail = Node(LastNodeOnBranch).MassFlowRateMinAvail; + BranchMaxAvail = Node(LastNodeOnBranch).MassFlowRateMaxAvail; + // !sum the branch flow requests to a total parallel branch flow request + bool activeBranch = this_splitter_outlet_branch.ControlType == ControlType_Active; + bool isSeriesActiveAndRequesting = (this_splitter_outlet_branch.ControlType == ControlType_SeriesActive) && (BranchFlowReq > 0.0); + if (activeBranch || isSeriesActiveAndRequesting ) { // revised logic for series active + TotParallelBranchFlowReq += BranchFlowReq; + ++NumActiveBranches; + } + Node(FirstNodeOnBranch).MassFlowRate = BranchFlowReq; + Node(FirstNodeOnBranch).MassFlowRateMinAvail = BranchMinAvail; + Node(FirstNodeOnBranch).MassFlowRateMaxAvail = BranchMaxAvail; + ParallelBranchMaxAvail += BranchMaxAvail; + ParallelBranchMinAvail += BranchMinAvail; + } + // ! Find branch number and flow rates at splitter inlet + SplitterBranchIn = this->Splitter.BranchNumIn; + LastNodeOnBranch = this->Branch(SplitterBranchIn).NodeNumOut; + FirstNodeOnBranchIn = this->Branch(SplitterBranchIn).NodeNumIn; + // ! Find branch number and flow rates at mixer outlet + MixerBranchOut = this->Mixer.BranchNumOut; + LastNodeOnBranch = this->Branch(MixerBranchOut).NodeNumOut; + FirstNodeOnBranchOut = this->Branch(MixerBranchOut).NodeNumIn; + + auto &first_branch_inlet_node(Node(FirstNodeOnBranchIn)); + auto &last_branch_inlet_node(Node(FirstNodeOnBranchOut)); + + // Reset branch inlet node flow rates for the first and last branch on loop + first_branch_inlet_node.MassFlowRate = ThisLoopSideFlow; + last_branch_inlet_node.MassFlowRate = ThisLoopSideFlow; + + // Reset branch inlet node Min/MaxAvails for the first and last branch on loop + first_branch_inlet_node.MassFlowRateMaxAvail = min(first_branch_inlet_node.MassFlowRateMaxAvail, + ParallelBranchMaxAvail); + first_branch_inlet_node.MassFlowRateMaxAvail = + min(first_branch_inlet_node.MassFlowRateMaxAvail, last_branch_inlet_node.MassFlowRateMaxAvail); + first_branch_inlet_node.MassFlowRateMinAvail = max(first_branch_inlet_node.MassFlowRateMinAvail, + ParallelBranchMinAvail); + first_branch_inlet_node.MassFlowRateMinAvail = + max(first_branch_inlet_node.MassFlowRateMinAvail, last_branch_inlet_node.MassFlowRateMinAvail); + last_branch_inlet_node.MassFlowRateMinAvail = first_branch_inlet_node.MassFlowRateMinAvail; + last_branch_inlet_node.MassFlowRateMaxAvail = first_branch_inlet_node.MassFlowRateMaxAvail; + + // Initialize the remaining flow variable + FlowRemaining = ThisLoopSideFlow; + + // Initialize flow on passive, bypass and uncontrolled parallel branches to zero. For these branches + // MinAvail is not enforced + for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { + SplitterBranchOut = this->Splitter.BranchNumOut(OutletNum); + FirstNodeOnBranch = this->Branch(SplitterBranchOut).NodeNumIn; + if (this->Branch(SplitterBranchOut).ControlType != ControlType_Active && + this->Branch(SplitterBranchOut).ControlType != ControlType_SeriesActive) { + Node(FirstNodeOnBranch).MassFlowRate = 0.0; + this->PushBranchFlowCharacteristics(SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, FirstHVACIteration); + } + } + + // IF SUFFICIENT FLOW TO MEET ALL PARALLEL BRANCH FLOW REQUESTS + if (FlowRemaining < MassFlowTolerance) { // no flow available at all for splitter + for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { + SplitterBranchOut = this->Splitter.BranchNumOut(OutletNum); + for (CompCounter = 1; + CompCounter <= this->Branch(SplitterBranchOut).TotalComponents; ++CompCounter) { + + FirstNodeOnBranch = this->Branch(SplitterBranchOut).NodeNumIn; + CompInletNode = this->Branch(SplitterBranchOut).Comp(CompCounter).NodeNumIn; + CompOutletNode = this->Branch(SplitterBranchOut).Comp(CompCounter).NodeNumOut; + Node(CompInletNode).MassFlowRate = 0.0; + Node(CompInletNode).MassFlowRateMaxAvail = 0.0; + Node(CompOutletNode).MassFlowRate = 0.0; + Node(CompOutletNode).MassFlowRateMaxAvail = 0.0; + } + } + return; + } else if (FlowRemaining >= TotParallelBranchFlowReq) { + + // 1) Satisfy flow demand of ACTIVE splitter outlet branches + for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { + SplitterBranchOut = this->Splitter.BranchNumOut(OutletNum); + FirstNodeOnBranch = this->Branch(SplitterBranchOut).NodeNumIn; + if (this->Branch(SplitterBranchOut).ControlType == ControlType_Active || + this->Branch(SplitterBranchOut).ControlType == ControlType_SeriesActive) { + // branch flow is min of requested flow and remaining flow + Node(FirstNodeOnBranch).MassFlowRate = min(Node(FirstNodeOnBranch).MassFlowRate, + FlowRemaining); + if (Node(FirstNodeOnBranch).MassFlowRate < MassFlowTolerance) + Node(FirstNodeOnBranch).MassFlowRate = 0.0; + this->PushBranchFlowCharacteristics(SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, FirstHVACIteration); + FlowRemaining -= Node(FirstNodeOnBranch).MassFlowRate; + if (FlowRemaining < MassFlowTolerance) FlowRemaining = 0.0; + } + } + // IF the active branches take the entire loop flow, return + if (FlowRemaining == 0.0) return; + + // 2) Distribute remaining flow to PASSIVE branches + totalMax = 0.0; + for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { + SplitterBranchOut = this->Splitter.BranchNumOut(OutletNum); + FirstNodeOnBranch = this->Branch(SplitterBranchOut).NodeNumIn; + if (this->Branch(SplitterBranchOut).ControlType == ControlType_Passive) { + // Calculate the total max available + totalMax += Node(FirstNodeOnBranch).MassFlowRateMaxAvail; + } + } + + if (totalMax > 0) { + for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { + SplitterBranchOut = this->Splitter.BranchNumOut(OutletNum); + FirstNodeOnBranch = this->Branch(SplitterBranchOut).NodeNumIn; + if (this->Branch(SplitterBranchOut).ControlType == ControlType_Passive) { + FracFlow = FlowRemaining / totalMax; + if (FracFlow <= 1.0) { // the passive branches will take all the flow + PassiveFlowRate = FracFlow * Node(FirstNodeOnBranch).MassFlowRateMaxAvail; + // Check against FlowRemaining + PassiveFlowRate = min(FlowRemaining, PassiveFlowRate); + // Allow FlowRequest to be increased to meet minimum on branch + PassiveFlowRate = max(PassiveFlowRate, + Node(FirstNodeOnBranch).MassFlowRateMinAvail); + FlowRemaining = max((FlowRemaining - PassiveFlowRate), 0.0); + Node(FirstNodeOnBranch).MassFlowRate = PassiveFlowRate; + } else { // Each Branch receives maximum flow and BYPASS must be used + Node(FirstNodeOnBranch).MassFlowRate = min( + Node(FirstNodeOnBranch).MassFlowRateMaxAvail, FlowRemaining); + FlowRemaining -= Node(FirstNodeOnBranch).MassFlowRate; + } + this->PushBranchFlowCharacteristics(SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, FirstHVACIteration); + } + } + } // totalMax <=0 and flow should be assigned to active branches + // IF the passive branches take the remaining loop flow, return + if (FlowRemaining == 0.0) return; + + // 3) Distribute remaining flow to the BYPASS + for (OutletNum = 1; OutletNum <= this->Splitter.TotalOutletNodes; ++OutletNum) { + SplitterBranchOut = this->Splitter.BranchNumOut(OutletNum); + FirstNodeOnBranch = this->Branch(SplitterBranchOut).NodeNumIn; + if (this->Branch(SplitterBranchOut).ControlType == ControlType_Bypass) { + Node(FirstNodeOnBranch).MassFlowRate = min(FlowRemaining, + Node(FirstNodeOnBranch).MassFlowRateMaxAvail); + this->PushBranchFlowCharacteristics(SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, FirstHVACIteration); + FlowRemaining -= Node(FirstNodeOnBranch).MassFlowRate; + } + } + // IF the bypass take the remaining loop flow, return + if (FlowRemaining == 0.0) return; + + // 4) If PASSIVE branches and BYPASS are at max and there's still flow, distribute remaining flow to ACTIVE branches but only those + // that had a non-zero flow request. Try to leave branches off that wanted to be off. + if (NumActiveBranches > 0) { + ActiveFlowRate = FlowRemaining / NumActiveBranches; // denominator now only includes active branches that wanted to be "on" + for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { + SplitterBranchOut = this->Splitter.BranchNumOut(OutletNum); + FirstNodeOnBranch = this->Branch(SplitterBranchOut).NodeNumIn; + bool branchIsActive = this->Branch(SplitterBranchOut).ControlType == ControlType_Active; + bool branchIsSeriesActiveAndRequesting = this->Branch(SplitterBranchOut).ControlType == ControlType_SeriesActive && this->Branch(SplitterBranchOut).RequestedMassFlow > 0.0; + if (branchIsActive || branchIsSeriesActiveAndRequesting) { // only series active branches that want to be "on" + // check Remaining flow (should be correct!) + ActiveFlowRate = min(ActiveFlowRate, FlowRemaining); + // set the flow rate to the MIN((MassFlowRate+AvtiveFlowRate), MaxAvail) + StartingFlowRate = Node(FirstNodeOnBranch).MassFlowRate; + Node(FirstNodeOnBranch).MassFlowRate = + min((Node(FirstNodeOnBranch).MassFlowRate + ActiveFlowRate), + Node(FirstNodeOnBranch).MassFlowRateMaxAvail); + this->PushBranchFlowCharacteristics(SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, FirstHVACIteration); + // adjust the remaining flow + FlowRemaining -= (Node(FirstNodeOnBranch).MassFlowRate - StartingFlowRate); + } + if (FlowRemaining == 0) break; + } + // IF the active branches take the remaining loop flow, return + if (FlowRemaining == 0.0) return; + + // 5) Step 4) could have left ACTIVE branches < MaxAvail. Check to makes sure all ACTIVE branches are at MaxAvail + for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { + SplitterBranchOut = this->Splitter.BranchNumOut(OutletNum); + FirstNodeOnBranch = this->Branch(SplitterBranchOut).NodeNumIn; + if (this->Branch(SplitterBranchOut).ControlType == ControlType_Active || + this->Branch(SplitterBranchOut).ControlType == ControlType_SeriesActive) { + StartingFlowRate = Node(FirstNodeOnBranch).MassFlowRate; + ActiveFlowRate = min(FlowRemaining, + (Node(FirstNodeOnBranch).MassFlowRateMaxAvail - StartingFlowRate)); + FlowRemaining -= ActiveFlowRate; + Node(FirstNodeOnBranch).MassFlowRate = StartingFlowRate + ActiveFlowRate; + this->PushBranchFlowCharacteristics(SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, FirstHVACIteration); + } + } + } + // IF the active branches take the remaining loop flow, return + if (FlowRemaining == 0.0) return; + + // 6) Adjust Inlet branch and outlet branch flow rates to match parallel branch rate + // DSU? do we need this logic? or should we fatal on a diagnostic error + TotParallelBranchFlowReq = 0.0; + for (iBranch = 1; iBranch <= NumSplitOutlets; ++iBranch) { + BranchNum = this->Splitter.BranchNumOut(iBranch); + FirstNodeOnBranch = this->Branch(BranchNum).NodeNumIn; + // calculate parallel branch flow rate + TotParallelBranchFlowReq += Node(FirstNodeOnBranch).MassFlowRate; + } + // Reset the flow on the splitter inlet branch + SplitterBranchIn = this->Splitter.BranchNumIn; + FirstNodeOnBranchIn = this->Branch(SplitterBranchIn).NodeNumIn; + Node(FirstNodeOnBranchIn).MassFlowRate = TotParallelBranchFlowReq; + this->PushBranchFlowCharacteristics(SplitterBranchIn, Node(FirstNodeOnBranchIn).MassFlowRate, FirstHVACIteration); + // Reset the flow on the Mixer outlet branch + MixerBranchOut = this->Mixer.BranchNumOut; + FirstNodeOnBranchOut = this->Branch(MixerBranchOut).NodeNumIn; + Node(FirstNodeOnBranchOut).MassFlowRate = TotParallelBranchFlowReq; + this->PushBranchFlowCharacteristics(MixerBranchOut, Node(FirstNodeOnBranchOut).MassFlowRate, FirstHVACIteration); + return; + + // IF INSUFFICIENT FLOW TO MEET ALL PARALLEL BRANCH FLOW REQUESTS + } else if (FlowRemaining < TotParallelBranchFlowReq) { + + // DSU? didn't take the time to figure out what this should be... SplitterFlowIn = SplitterInletFlow(SplitNum) + // 1) apportion flow based on requested fraction of total + for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { + + SplitterBranchOut = this->Splitter.BranchNumOut(OutletNum); + ThisBranchRequest = this->Branch(SplitterBranchOut).DetermineBranchFlowRequest(); + FirstNodeOnBranch = this->Branch(SplitterBranchOut).NodeNumIn; + auto &this_splitter_outlet_branch(this->Branch(SplitterBranchOut)); + + if ((this_splitter_outlet_branch.ControlType == ControlType_Active) || + (this_splitter_outlet_branch.ControlType == ControlType_SeriesActive)) { + + // since we are calculating this fraction based on the total parallel request calculated above, we must mimic the logic to + // make sure the math works every time that means we must make the variable speed pump correction here as well. + for (CompCounter = 1; + CompCounter <= this_splitter_outlet_branch.TotalComponents; ++CompCounter) { + + auto &this_comp(this_splitter_outlet_branch.Comp(CompCounter)); + + // if this isn't a variable speed pump then just keep cycling + if ((this_comp.TypeOf_Num != TypeOf_PumpVariableSpeed) && + (this_comp.TypeOf_Num != TypeOf_PumpBankVariableSpeed)) { + continue; + } + + CompInletNode = this_comp.NodeNumIn; + ThisBranchRequest = max(ThisBranchRequest, Node(CompInletNode).MassFlowRateRequest); + } + + ThisBranchRequestFrac = ThisBranchRequest / TotParallelBranchFlowReq; + // FracFlow = Node(FirstNodeOnBranch)%MassFlowRate/TotParallelBranchFlowReq + // Node(FirstNodeOnBranch)%MassFlowRate = MIN((FracFlow * Node(FirstNodeOnBranch)%MassFlowRate),FlowRemaining) + Node(FirstNodeOnBranch).MassFlowRate = ThisBranchRequestFrac * ThisLoopSideFlow; + this->PushBranchFlowCharacteristics(SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, FirstHVACIteration); + FlowRemaining -= Node(FirstNodeOnBranch).MassFlowRate; + } + } + + // 1b) check if flow all apportioned + if (FlowRemaining > MassFlowTolerance) { + // Call fatal diagnostic error. !The math should work out! + ShowSevereError("ResolveParallelFlows: Dev note, failed to redistribute restricted flow"); + ShowContinueErrorTimeStamp(""); + ShowContinueError("Loop side flow = " + RoundSigDigits(ThisLoopSideFlow, 8) + " (kg/s)"); + ShowContinueError("Flow Remaining = " + RoundSigDigits(FlowRemaining, 8) + " (kg/s)"); + ShowContinueError("Parallel Branch requests = " + RoundSigDigits(TotParallelBranchFlowReq, 8) + + " (kg/s)"); + } + + // 2) ! Reset the flow on the Mixer outlet branch + MixerBranchOut = this->Mixer.BranchNumOut; + FirstNodeOnBranchOut = this->Branch(MixerBranchOut).NodeNumIn; + Node(FirstNodeOnBranchOut).MassFlowRate = TotParallelBranchFlowReq; + this->PushBranchFlowCharacteristics(MixerBranchOut, Node(FirstNodeOnBranchOut).MassFlowRate, FirstHVACIteration); + + } // Total flow requested >= or < Total parallel request + + } // Splitter/Mixer exists + } + + void HalfLoopData::SimulateLoopSideBranchGroup( + int const FirstBranchNum, int const LastBranchNum, Real64 FlowRequest, bool const FirstHVACIteration, bool &LoopShutDownFlag) + { + + // SUBROUTINE INFORMATION: + // AUTHOR Edwin Lee + // DATE WRITTEN July 2010 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS SUBROUTINE: + // This routine will manage the component simulation on a single set of parallel branches + // This routine also reverts to a single branch simulation if there isn't a set of parallel branches + + // METHODOLOGY EMPLOYED: + // Loop through all components, and simulate first the non-load range based on each branch. + // When a load-range based (LRB) is encountered, the simulation moves to the next branch to do non-LRB components. + // When all paths are exhausted the simulation begins simulating LRB components. Before each comp, the load distribution + // engine is called to handle the load distribution for this current pass. If load is successfully distributed, this is + // flagged, and not called again. If load is not distributed (i.e. this component isn't ON right now), then the + // load distribution engine will be called again before the next component. + // After all load distribution is done and those components are complete, the simulation moves back to do any + // remaining components that may be downstream. + + //~ Flags + bool LoadDistributionWasPerformed; + bool DummyInit = false; + bool const DoNotGetCompSizFac(false); + + //~ General variables + Real64 LoadToLoopSetPoint; + PlantLocation PumpLocation; + LoadToLoopSetPoint = 0.0; + + // We now know what plant simulation region is available to us, let's simulate this group + bool EncounteredLRBObjDuringPass1(false); + for (int BranchCounter = FirstBranchNum; BranchCounter <= LastBranchNum; ++BranchCounter) { + auto &branch(this->Branch(BranchCounter)); + + //~ Always start from the last component we did the last time around + 1 and + //~ try to make it all the way to the end of the loop + int const StartingComponent = branch.lastComponentSimulated + 1; + int const EndingComponent = branch.TotalComponents; + for (int CompCounter = StartingComponent; CompCounter <= EndingComponent; ++CompCounter) { + + auto &this_comp(branch.Comp(CompCounter)); + auto const CurOpSchemeType(this_comp.CurOpSchemeType); + + switch (CurOpSchemeType) { + case DataPlant::WSEconOpSchemeType: //~ coils + this_comp.MyLoad = UpdatedDemandToLoopSetPoint; + branch.Comp(CompCounter).simulate(FirstHVACIteration, DummyInit, DoNotGetCompSizFac); + break; + case DataPlant::PumpOpSchemeType: //~ pump + if (this->BranchPumpsExist) { + SimulateSinglePump(this_comp.location, branch.RequestedMassFlow); + } else { + SimulateSinglePump(this_comp.location, FlowRequest); + } + break; + case DataPlant::CompSetPtBasedSchemeType: + PlantCondLoopOperation::ManagePlantLoadDistribution(this->myLoopNum, + this->myLoopSideNum, + BranchCounter, + CompCounter, + LoadToLoopSetPoint, + LoadToLoopSetPointThatWasntMet, + FirstHVACIteration, + LoopShutDownFlag, + LoadDistributionWasPerformed); + branch.Comp(CompCounter).simulate(FirstHVACIteration, DummyInit, DoNotGetCompSizFac); + break; + case DataPlant::EMSOpSchemeType: + if (this->myLoopSideNum == DataPlant::SupplySide) { + int const curCompOpSchemePtr = this_comp.CurCompLevelOpNum; + int const OpSchemePtr = this_comp.OpScheme(curCompOpSchemePtr).OpSchemePtr; + DataPlant::PlantLoop(this->myLoopNum).OpScheme(OpSchemePtr).EMSIntVarLoopDemandRate = InitialDemandToLoopSetPoint; + } + PlantCondLoopOperation::ManagePlantLoadDistribution(this->myLoopNum, + this->myLoopSideNum, + BranchCounter, + CompCounter, + UpdatedDemandToLoopSetPoint, + LoadToLoopSetPointThatWasntMet, + FirstHVACIteration, + LoopShutDownFlag, + LoadDistributionWasPerformed); + branch.Comp(CompCounter).simulate(FirstHVACIteration, DummyInit, DoNotGetCompSizFac); + break; + default: + if ((CurOpSchemeType >= DataPlant::LoadRangeBasedMin) && (CurOpSchemeType <= DataPlant::LoadRangeBasedMax)) { //~ load range based + EncounteredLRBObjDuringPass1 = true; + goto components_end; // don't do any more components on this branch + } else { // demand, , etc. + branch.Comp(CompCounter).simulate(FirstHVACIteration, DummyInit, DoNotGetCompSizFac); + } + } + + // Update loop demand as needed for changes this component may have made + this->UpdateAnyLoopDemandAlterations(BranchCounter, CompCounter); + + //~ If we didn't EXIT early, we must have simulated, so update array + branch.lastComponentSimulated = CompCounter; + + } //~ CompCounter + components_end:; + + if (this->FlowLock == DataPlant::FlowLocked) { + PlantPressureSystem::SimPressureDropSystem( + this->myLoopNum, FirstHVACIteration, DataPlant::PressureCall_Calc, this->myLoopSideNum, BranchCounter); + } + + } //~ BranchCounter + + // So now we have made one pass through all of the available components on these branches, skipping load based + // If we didn't encounter any load based objects during the first pass, then we must be done! + if (!EncounteredLRBObjDuringPass1) return; + + // If we have load based now, we should go ahead and distribute the load + // If not then this branch group is done, since flow path validation was previously done + LoadToLoopSetPoint = UpdatedDemandToLoopSetPoint; + LoadDistributionWasPerformed = false; + + // The way the load distribution is set up, I think I should call this for every load range based component + // encountered until distribution is actually performed. If we don't call for each component then we may + // call for a component that is not on the current equip list and then nothing would come on. + bool EncounteredNonLBObjDuringPass2(false); + for (int BranchCounter = FirstBranchNum; BranchCounter <= LastBranchNum; ++BranchCounter) { + auto &branch(this->Branch(BranchCounter)); + + //~ Always start from the last component we did the last time around + 1 and + //~ try to make it all the way to the end of the loop + int const StartingComponent = branch.lastComponentSimulated + 1; + int const EndingComponent = branch.TotalComponents; + for (int CompCounter = StartingComponent; CompCounter <= EndingComponent; ++CompCounter) { + + auto const CurOpSchemeType(branch.Comp(CompCounter).CurOpSchemeType); + + switch (CurOpSchemeType) { + case DataPlant::NoControlOpSchemeType: //~ pipes, for example + branch.Comp(CompCounter).simulate(FirstHVACIteration, DummyInit, DoNotGetCompSizFac); + break; + case DataPlant::DemandOpSchemeType: + case DataPlant::CompSetPtBasedSchemeType: + case DataPlant::FreeRejectionOpSchemeType: //~ other control types + EncounteredNonLBObjDuringPass2 = true; + goto components2_end; // don't do anymore components on this branch + case DataPlant::PumpOpSchemeType: //~ pump + PumpLocation.loopNum = this->myLoopNum; + PumpLocation.loopSideNum = this->myLoopSideNum; + PumpLocation.branchNum = BranchCounter; + PumpLocation.compNum = CompCounter; + if (this->BranchPumpsExist) { + SimulateSinglePump(PumpLocation, branch.RequestedMassFlow); + } else { + SimulateSinglePump(PumpLocation, FlowRequest); + } + break; + default: + if ((CurOpSchemeType >= DataPlant::LoadRangeBasedMin) && (CurOpSchemeType <= DataPlant::LoadRangeBasedMax)) { //~ load range based + if (!LoadDistributionWasPerformed) { //~ Still need to distribute load among load range based components + PlantCondLoopOperation::ManagePlantLoadDistribution(this->myLoopNum, + this->myLoopSideNum, + BranchCounter, + CompCounter, + LoadToLoopSetPoint, + LoadToLoopSetPointThatWasntMet, + FirstHVACIteration, + LoopShutDownFlag, + LoadDistributionWasPerformed); + } + branch.Comp(CompCounter).simulate(FirstHVACIteration, DummyInit, DoNotGetCompSizFac); + } + } + + //~ If we didn't EXIT early, we must have simulated, so update array + branch.lastComponentSimulated = CompCounter; + + } //~ CompCounter + components2_end:; + + //~ If we are locked, go ahead and simulate the pressure components on this branch + if (this->FlowLock == DataPlant::FlowLocked) { + PlantPressureSystem::SimPressureDropSystem( + this->myLoopNum, FirstHVACIteration, DataPlant::PressureCall_Calc, this->myLoopSideNum, BranchCounter); + } + + } //~ BranchCounter + + // So now we have made the load range based pass through all the components on each branch + // If we didn't see any other component types, then we are done, go away + if (!EncounteredNonLBObjDuringPass2) return; + + // If we did encounter other objects than we just need to go back through and simulate them + for (int BranchCounter = FirstBranchNum; BranchCounter <= LastBranchNum; ++BranchCounter) { + auto &branch(this->Branch(BranchCounter)); + + //~ Always start from the last component we did the last time around + 1 and + //~ try to make it all the way to the end of the loop + int const StartingComponent = branch.lastComponentSimulated + 1; + int const EndingComponent = branch.TotalComponents; + for (int CompCounter = StartingComponent; CompCounter <= EndingComponent; ++CompCounter) { + + auto const CurOpSchemeType(branch.Comp(CompCounter).CurOpSchemeType); + + switch (CurOpSchemeType) { + case DataPlant::DemandOpSchemeType: //~ coils + branch.Comp(CompCounter).simulate(FirstHVACIteration, DummyInit, DoNotGetCompSizFac); + break; + case DataPlant::PumpOpSchemeType: //~ pump + PumpLocation.loopNum = this->myLoopNum; + PumpLocation.loopSideNum = this->myLoopSideNum; + PumpLocation.branchNum = BranchCounter; + PumpLocation.compNum = CompCounter; + if (this->BranchPumpsExist) { + SimulateSinglePump(PumpLocation, branch.RequestedMassFlow); + } else { + SimulateSinglePump(PumpLocation, FlowRequest); + } + break; + default: + if ((CurOpSchemeType >= DataPlant::LoadRangeBasedMin) && (CurOpSchemeType <= DataPlant::LoadRangeBasedMax)) { //~ load range based + ShowFatalError("Encountered Load Based Object after other components, invalid."); + } else { //~ Typical control equipment + branch.Comp(CompCounter).simulate(FirstHVACIteration, DummyInit, DoNotGetCompSizFac); + } + } + + //~ If we didn't EXIT early, we must have simulated, so update array + branch.lastComponentSimulated = CompCounter; + + } //~ CompCounter + + if (this->FlowLock == DataPlant::FlowLocked) { + PlantPressureSystem::SimPressureDropSystem( + this->myLoopNum, FirstHVACIteration, DataPlant::PressureCall_Calc, this->myLoopSideNum, BranchCounter); + } + + } //~ BranchCounter + + // I suppose I could do a check on the last component simulated to make sure we actually exhausted all branches + // This would be the "THIRD" check on flow validation, but would be OK + } + + void HalfLoopData::UpdateAnyLoopDemandAlterations(int const BranchNum, int const CompNum) + { + + // SUBROUTINE INFORMATION: + // AUTHOR Edwin Lee + // DATE WRITTEN August 2010 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS SUBROUTINE: + // This routine will analyze the given component and determine if any + // alterations need to be made to the current loop demand value. If so, + // it will make the changes to the module level loop demand variables. + + // METHODOLOGY EMPLOYED: + // Components will always supply a useful delta T, even if it happens to be zero + // For flow rate, make decisions based on the component's current operating scheme type: + // Demand based: these components will have a flow request on their inlet node + // Pump: these components will not be included, as they no longer include heat at the pump + // component setpoint: these components will have a flow request + + // on their outlet node corresponding to their calculated delta T + // load range based: these components do not 'alter' the load, they reject the load + // Therefore they are not included + + // Using/Aliasing + using DataBranchAirLoopPlant::MassFlowTolerance; + using DataLoopNode::Node; + using DataPlant::FlowLocked; + using DataPlant::FlowUnlocked; + using DataPlant::LoadRangeBasedMax; + using DataPlant::LoadRangeBasedMin; + using DataPlant::PlantLoop; + using FluidProperties::GetSpecificHeatGlycol; + + // SUBROUTINE PARAMETER DEFINITIONS: + static std::string const RoutineName("PlantLoopSolver::UpdateAnyLoopDemandAlterations"); + + // Init to zero, so that if we don't find anything, we exit early + Real64 ComponentMassFlowRate(0.0); + + auto const &this_comp(this->Branch(BranchNum).Comp(CompNum)); + + // Get information + int const InletNode(this_comp.NodeNumIn); + int const OutletNode(this_comp.NodeNumOut); + + if (this->FlowLock == FlowUnlocked) { + + // For unlocked flow, use the inlet request -- !DSU? for now + { + auto const SELECT_CASE_var(this_comp.CurOpSchemeType); + if ((SELECT_CASE_var >= LoadRangeBasedMin) && (SELECT_CASE_var <= LoadRangeBasedMax)) { + // Don't do anything for load based components + } else { + // pumps pipes, etc. will be lumped in here with other component types, but they will have no delta T anyway + ComponentMassFlowRate = Node(InletNode).MassFlowRateRequest; + // DSU? make sure components like economizers use the mass flow request + } + } + + } else if (this->FlowLock == FlowLocked) { + + // For locked flow just use the mass flow rate + { + auto const SELECT_CASE_var(this_comp.CurOpSchemeType); + if ((SELECT_CASE_var >= LoadRangeBasedMin) && (SELECT_CASE_var <= LoadRangeBasedMax)) { + // Don't do anything for load based components + } else { + // pumps pipes, etc. will be lumped in here with other component types, but they will have no delta T anyway + ComponentMassFlowRate = Node(OutletNode).MassFlowRate; + } + } + + } else { // flow pump query? problem? + } + + // Leave early if there wasn't a mass flow rate or request + if (ComponentMassFlowRate < MassFlowTolerance) return; + + // Get an average temperature for the property call + Real64 const InletTemp(Node(InletNode).Temp); + Real64 const OutletTemp(Node(OutletNode).Temp); + Real64 const AverageTemp((InletTemp + OutletTemp) / 2.0); + Real64 const ComponentCp( + GetSpecificHeatGlycol(PlantLoop(this->myLoopNum).FluidName, AverageTemp, PlantLoop(this->myLoopNum).FluidIndex, RoutineName)); + + // Calculate the load altered by this component + Real64 const LoadAlteration(ComponentMassFlowRate * ComponentCp * (OutletTemp - InletTemp)); + + // Now alter the module level variables + this->CurrentAlterationsToDemand += LoadAlteration; + this->UpdatedDemandToLoopSetPoint = this->InitialDemandToLoopSetPoint - this->CurrentAlterationsToDemand; + } + + void HalfLoopData::SimulateSinglePump(PlantLocation const SpecificPumpLocation, Real64 &SpecificPumpFlowRate) + { + + // SUBROUTINE INFORMATION: + // AUTHOR Edwin Lee + // DATE WRITTEN July 2010 + // MODIFIED na + // RE-ENGINEERED na + + auto &loop(DataPlant::PlantLoop(SpecificPumpLocation.loopNum)); + auto &loop_side(loop.LoopSide(SpecificPumpLocation.loopSideNum)); + auto &loop_side_branch(loop_side.Branch(SpecificPumpLocation.branchNum)); + auto &comp(loop_side_branch.Comp(SpecificPumpLocation.compNum)); + int const PumpIndex = comp.IndexInLoopSidePumps; + auto &pump(loop_side.Pumps(PumpIndex)); + + this->AdjustPumpFlowRequestByEMSControls(SpecificPumpLocation.branchNum, + SpecificPumpLocation.compNum, + SpecificPumpFlowRate); + + // Call SimPumps, routine takes a flow request, and returns some info about the status of the pump + bool DummyThisPumpRunning; + Pumps::SimPumps(pump.PumpName, + SpecificPumpLocation.loopNum, + SpecificPumpFlowRate, + DummyThisPumpRunning, + loop_side_branch.PumpIndex, + pump.PumpHeatToFluid); + + //~ Pull some state information from the pump outlet node + pump.CurrentMinAvail = DataLoopNode::Node(pump.PumpOutletNode).MassFlowRateMinAvail; + pump.CurrentMaxAvail = DataLoopNode::Node(pump.PumpOutletNode).MassFlowRateMaxAvail; + + //~ Update the LoopSide pump heat totality here + if (loop_side.TotalPumps > 0) { + loop_side.TotalPumpHeat = sum(loop_side.Pumps, &DataPlant::LoopSidePumpInformation::PumpHeatToFluid); + } + } + + void HalfLoopData::SimulateAllLoopSidePumps(Optional SpecificPumpLocation, + Optional SpecificPumpFlowRate) { + + // SUBROUTINE INFORMATION: + // AUTHOR Edwin Lee + // DATE WRITTEN July 2010 + // MODIFIED na + // RE-ENGINEERED na + + int PumpIndexStart; + int PumpIndexEnd; + int PumpLoopNum; + int PumpLoopSideNum; + + // If we have a specific loop/side/br/comp, then find the index and only do that one, otherwise do all pumps on the loop side + if (present(SpecificPumpLocation)) { + PumpLoopNum = SpecificPumpLocation().loopNum; + PumpLoopSideNum = SpecificPumpLocation().loopSideNum; + int const PumpBranchNum = SpecificPumpLocation().branchNum; + int const PumpCompNum = SpecificPumpLocation().compNum; + PumpIndexStart = DataPlant::PlantLoop(PumpLoopNum).LoopSide(PumpLoopSideNum).Branch(PumpBranchNum).Comp( + PumpCompNum).IndexInLoopSidePumps; + PumpIndexEnd = PumpIndexStart; + } else { + PumpLoopNum = this->myLoopNum; + PumpLoopSideNum = this->myLoopSideNum; + PumpIndexStart = 1; + PumpIndexEnd = this->TotalPumps; + } + + // If we have a flow rate to hit, then go for it, otherwise, just operate in request mode with zero flow + Real64 FlowToRequest; + if (present(SpecificPumpFlowRate)) { + FlowToRequest = SpecificPumpFlowRate; + } else { + FlowToRequest = 0.0; + } + + //~ Now loop through all the pumps and simulate them, keeping track of their status + auto &loop_side(DataPlant::PlantLoop(PumpLoopNum).LoopSide(PumpLoopSideNum)); + auto &loop_side_branch(loop_side.Branch); + for (int PumpCounter = PumpIndexStart; PumpCounter <= PumpIndexEnd; ++PumpCounter) { + + //~ Set some variables + auto &pump(loop_side.Pumps(PumpCounter)); + int const PumpBranchNum = pump.BranchNum; + int const PumpCompNum = pump.CompNum; + int const PumpOutletNode = pump.PumpOutletNode; + + this->AdjustPumpFlowRequestByEMSControls(PumpBranchNum, PumpCompNum, FlowToRequest); + + // Call SimPumps, routine takes a flow request, and returns some info about the status of the pump + bool DummyThisPumpRunning; + Pumps::SimPumps(pump.PumpName, PumpLoopNum, FlowToRequest, DummyThisPumpRunning, + loop_side_branch(PumpBranchNum).PumpIndex, pump.PumpHeatToFluid); + + //~ Pull some state information from the pump outlet node + Real64 const ThisPumpMinAvail = DataLoopNode::Node(PumpOutletNode).MassFlowRateMinAvail; + Real64 const ThisPumpMaxAvail = DataLoopNode::Node(PumpOutletNode).MassFlowRateMaxAvail; + + //~ Now update the data structure + pump.CurrentMinAvail = ThisPumpMinAvail; + pump.CurrentMaxAvail = ThisPumpMaxAvail; + } + + //~ Update the LoopSide pump heat totality here + if (loop_side.TotalPumps > 0) { + loop_side.TotalPumpHeat = sum(loop_side.Pumps, &DataPlant::LoopSidePumpInformation::PumpHeatToFluid); + } + } + + Real64 HalfLoopData::DetermineLoopSideFlowRate(int ThisSideInletNode, Real64 ThisSideLoopFlowRequest) + { + Real64 ThisLoopSideFlow = ThisSideLoopFlowRequest; + Real64 TotalPumpMinAvailFlow = 0.0; + Real64 TotalPumpMaxAvailFlow = 0.0; + if (allocated(this->Pumps)) { + + //~ Initialize pump values + for (auto &e : this->Pumps) { + e.CurrentMinAvail = 0.0; + e.CurrentMaxAvail = 0.0; + } + this->FlowLock = DataPlant::FlowPumpQuery; + + //~ Simulate pumps + this->SimulateAllLoopSidePumps(); + + //~ Calculate totals + for (auto const &e : this->Pumps) { + TotalPumpMinAvailFlow += e.CurrentMinAvail; + TotalPumpMaxAvailFlow += e.CurrentMaxAvail; + } + + // Use the pump min/max avail to attempt to constrain the loop side flow + ThisLoopSideFlow = PlantUtilities::BoundValueToWithinTwoValues(ThisLoopSideFlow, TotalPumpMinAvailFlow, TotalPumpMaxAvailFlow); + } + + // Now we check flow restriction from the other side, both min and max avail. + // Doing this last basically means it wins, so the pump should pull down to meet the flow restriction + ThisLoopSideFlow = PlantUtilities::BoundValueToNodeMinMaxAvail(ThisLoopSideFlow, ThisSideInletNode); + + // Final preparation of loop inlet min/max avail if pumps exist + if (allocated(this->Pumps)) { + // At this point, the pump limits should have been obeyed unless a flow restriction was encountered from the other side + // The pump may, however, have even tighter constraints than the other side + // At this point, the inlet node doesn't know anything about those limits + // Since we have already honored the other side flow restriction, try to honor the pump limits here + PlantUtilities::TightenNodeMinMaxAvails(ThisSideInletNode, TotalPumpMinAvailFlow, TotalPumpMaxAvailFlow); + } + + // Now reset the entering mass flow rate to the decided-upon flow rate + DataLoopNode::Node(ThisSideInletNode).MassFlowRate = ThisLoopSideFlow; + return ThisLoopSideFlow; + } + + void HalfLoopData::UpdatePlantMixer() + { + + // SUBROUTINE INFORMATION: + // AUTHOR Brandon Anderson, Dan Fisher + // DATE WRITTEN October 1999 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS SUBROUTINE: + // calculate the outlet conditions at the mixer + // this is expected to only be called for loops with a mixer + + // Find mixer outlet node number + int const MixerOutletNode = this->Mixer.NodeNumOut; + + // Find corresponding splitter inlet node number--correspondence, but currently + // hard code things to a single split/mix setting it to the mixer number + int const SplitterInNode = this->Splitter.NodeNumIn; + // Initialize Mixer outlet temp and mass flow rate + Real64 MixerOutletTemp = 0.0; + Real64 MixerOutletMassFlow = 0.0; + Real64 MixerOutletMassFlowMaxAvail = 0.0; + Real64 MixerOutletMassFlowMinAvail = 0.0; + Real64 MixerOutletPress = 0.0; + Real64 MixerOutletQuality = 0.0; + + // Calculate Mixer outlet mass flow rate + for (int InletNodeNum = 1; InletNodeNum <= this->Mixer.TotalInletNodes; ++InletNodeNum) { + int const MixerInletNode = this->Mixer.NodeNumIn(InletNodeNum); + MixerOutletMassFlow += DataLoopNode::Node(MixerInletNode).MassFlowRate; + } + + // Calculate Mixer outlet temperature + for (int InletNodeNum = 1; InletNodeNum <= this->Mixer.TotalInletNodes; ++InletNodeNum) { + int const MixerInletNode = this->Mixer.NodeNumIn(InletNodeNum); + if (MixerOutletMassFlow > 0.0) { + Real64 const MixerInletMassFlow = DataLoopNode::Node(MixerInletNode).MassFlowRate; + Real64 const MassFrac = MixerInletMassFlow / MixerOutletMassFlow; + // mass flow weighted temp and enthalpy for each mixer inlet + MixerOutletTemp += MassFrac * DataLoopNode::Node(MixerInletNode).Temp; + MixerOutletQuality += MassFrac * DataLoopNode::Node(MixerInletNode).Quality; + MixerOutletMassFlowMaxAvail += DataLoopNode::Node(MixerInletNode).MassFlowRateMaxAvail; + MixerOutletMassFlowMinAvail += DataLoopNode::Node(MixerInletNode).MassFlowRateMinAvail; + MixerOutletPress = max(MixerOutletPress, DataLoopNode::Node(MixerInletNode).Press); + } else { // MixerOutletMassFlow <=0, then perform the 'no flow' update. + MixerOutletTemp = DataLoopNode::Node(SplitterInNode).Temp; + MixerOutletQuality = DataLoopNode::Node(SplitterInNode).Quality; + MixerOutletMassFlowMaxAvail = DataLoopNode::Node(SplitterInNode).MassFlowRateMaxAvail; + MixerOutletMassFlowMinAvail = DataLoopNode::Node(SplitterInNode).MassFlowRateMinAvail; + MixerOutletPress = DataLoopNode::Node(SplitterInNode).Press; + break; + } + } + + DataLoopNode::Node(MixerOutletNode).MassFlowRate = MixerOutletMassFlow; + DataLoopNode::Node(MixerOutletNode).Temp = MixerOutletTemp; + if (DataPlant::PlantLoop(this->myLoopNum).HasPressureComponents) { + // Don't update pressure, let pressure system handle this... + } else { + // Go ahead and update! + DataLoopNode::Node(MixerOutletNode).Press = MixerOutletPress; + } + DataLoopNode::Node(MixerOutletNode).Quality = MixerOutletQuality; + + // set max/min avails on mixer outlet to be consistent with the following rules + // 1. limited by the max/min avails on splitter inlet + // 2. limited by the sum of max/min avails for each branch's mixer inlet node + + DataLoopNode::Node(MixerOutletNode).MassFlowRateMaxAvail = + min(MixerOutletMassFlowMaxAvail, DataLoopNode::Node(SplitterInNode).MassFlowRateMaxAvail); + DataLoopNode::Node(MixerOutletNode).MassFlowRateMinAvail = + max(MixerOutletMassFlowMinAvail, DataLoopNode::Node(SplitterInNode).MassFlowRateMinAvail); + } + + void HalfLoopData::UpdatePlantSplitter() + { + + // SUBROUTINE INFORMATION: + // AUTHOR Brandon Anderson, Dan Fisher + // DATE WRITTEN October 1999 + // MODIFIED na + // RE-ENGINEERED na + + // PURPOSE OF THIS SUBROUTINE: + // Set the outlet conditions of the splitter + + // Update Temperatures across splitter + if (this->Splitter.Exists) { + + // Set branch number at splitter inlet + int const SplitterInletNode = this->Splitter.NodeNumIn; + + // Loop over outlet nodes + for (int CurNode = 1; CurNode <= this->Splitter.TotalOutletNodes; ++CurNode) { + int const SplitterOutletNode = this->Splitter.NodeNumOut(CurNode); + + // Inlet Temp equals exit Temp to all outlet branches + DataLoopNode::Node(SplitterOutletNode).Temp = DataLoopNode::Node(SplitterInletNode).Temp; + DataLoopNode::Node(SplitterOutletNode).TempMin = DataLoopNode::Node(SplitterInletNode).TempMin; + DataLoopNode::Node(SplitterOutletNode).TempMax = DataLoopNode::Node(SplitterInletNode).TempMax; + if (DataPlant::PlantLoop(this->myLoopNum).HasPressureComponents) { + // Don't update pressure, let pressure system handle this... + } else { + // Go ahead and update! + DataLoopNode::Node(SplitterOutletNode).Press = DataLoopNode::Node(SplitterInletNode).Press; + } + DataLoopNode::Node(SplitterOutletNode).Quality = DataLoopNode::Node(SplitterInletNode).Quality; + + // DSU? These two blocks and the following one which I added need to be cleaned up + // I think we will always pass maxavail down the splitter, min avail is the issue. + // Changed to include hardware max in next line 7/26/2011 + DataLoopNode::Node(SplitterOutletNode).MassFlowRateMaxAvail = + min(DataLoopNode::Node(SplitterInletNode).MassFlowRateMaxAvail, DataLoopNode::Node(SplitterOutletNode).MassFlowRateMax); + DataLoopNode::Node(SplitterOutletNode).MassFlowRateMinAvail = 0.0; + + // DSU? Not sure about passing min avail if it is nonzero. I am testing a pump with nonzero + // min flow rate, and it is causing problems because this routine passes zero down. Perhaps if + // it is a single parallel branch, we are safe to assume we need to just pass it down. + // But need to test for multiple branches (or at least think about it), to see what we need to do... + if (this->Splitter.TotalOutletNodes == 1) { + DataLoopNode::Node(SplitterOutletNode).MassFlowRateMinAvail = DataLoopNode::Node(SplitterInletNode).MassFlowRateMinAvail; + } + } + } + } + +} +} diff --git a/src/EnergyPlus/Plant/LoopSide.hh b/src/EnergyPlus/Plant/LoopSide.hh index b58c57bbaa9..2baa25849ea 100644 --- a/src/EnergyPlus/Plant/LoopSide.hh +++ b/src/EnergyPlus/Plant/LoopSide.hh @@ -86,8 +86,6 @@ namespace DataPlant { std::string NodeNameIn; // Node name for the inlet to this loop int NodeNumOut; // Node number for the outlet to this loop std::string NodeNameOut; // Node name for the outlet to this loop - bool SplitterExists; // Logical Flag indication splitter exists in the half loop - bool MixerExists; // Logical Flag indication mixer exists in the half loop int TotalPumps; // total number of pumps on the half loop bool BranchPumpsExist; // logical flag indication branch pumps exist on half loop Array1D Pumps; @@ -126,6 +124,20 @@ namespace DataPlant { Real64 flowRequestFinal; bool hasConstSpeedBranchPumps; Array1D noLoadConstantSpeedBranchFlowRateSteps; + Real64 InitialDemandToLoopSetPoint; + Real64 CurrentAlterationsToDemand; + Real64 UpdatedDemandToLoopSetPoint; + Real64 LoadToLoopSetPointThatWasntMet; // Unmet Demand + Real64 InitialDemandToLoopSetPointSAVED; + std::string loopSideDescription; + int refrigIndex; // Index denoting refrigerant used (possibly steam) + // report variables + Real64 LoopSetPtDemandAtInlet; + Real64 ThisSideLoadAlterations; + // these are intended to be temporary + int myLoopNum; + int myLoopSideNum; + int myOtherLoopSideNum; // Default Constructor HalfLoopData() @@ -133,16 +145,69 @@ namespace DataPlant { OncePerTimeStepOperations(true), TimeElapsed(0.0), FlowRequest(0.0), FlowRequestTemperature(0.0), TempSetPoint(DataLoopNode::SensedNodeFlagValue), TempSetPointHi(DataLoopNode::SensedNodeFlagValue), TempSetPointLo(DataLoopNode::SensedNodeFlagValue), TempInterfaceTankOutlet(0.0), LastTempInterfaceTankOutlet(0.0), TotalBranches(0), - NodeNumIn(0), NodeNumOut(0), SplitterExists(false), MixerExists(false), TotalPumps(0), + NodeNumIn(0), NodeNumOut(0), TotalPumps(0), BranchPumpsExist(false), TotalPumpHeat(0.0), BypassExists(false), InletNodeSetPt(false), OutletNodeSetPt(false), EMSCtrl(false), EMSValue(0.0), FlowRestrictionFlag(false), FlowLock(0), TotalConnected(0), HasPressureComponents(false), HasParallelPressComps(false), PressureDrop(0.0), PressureEffectiveK(0.0), errCount_LoadWasntDist(0), errIndex_LoadWasntDist(0), errCount_LoadRemains(0), errIndex_LoadRemains(0), LoopSideInlet_TankTemp(0.0), LoopSideInlet_MdotCpDeltaT(0.0), LoopSideInlet_McpDTdt(0.0), LoopSideInlet_CapExcessStorageTime(0.0), LoopSideInlet_CapExcessStorageTimeReport(0.0), LoopSideInlet_TotalTime(0.0), InletNode(0.0, 0.0), OutletNode(0.0, 0.0), flowRequestNeedIfOn(0.0), flowRequestNeedAndTurnOn(0.0), flowRequestFinal(0.0), - hasConstSpeedBranchPumps(false) + hasConstSpeedBranchPumps(false), InitialDemandToLoopSetPoint(0.0), CurrentAlterationsToDemand(0.0), UpdatedDemandToLoopSetPoint(0.0), + LoadToLoopSetPointThatWasntMet(0.0), InitialDemandToLoopSetPointSAVED(0.0), refrigIndex(0), LoopSetPtDemandAtInlet(0.0), ThisSideLoadAlterations(0.0), myLoopNum(0), myLoopSideNum(0), myOtherLoopSideNum(0) { } + + void ValidateFlowControlPaths(); + + Real64 DetermineLoopSideFlowRate(int ThisSideInletNode, Real64 ThisSideLoopFlowRequest); + + void SimulateAllLoopSideBranches(Real64 ThisLoopSideFlow, bool FirstHVACIteration, bool &LoopShutDownFlag); + + void SimulateLoopSideBranchGroup(int FirstBranchNum, + int LastBranchNum, + Real64 FlowRequest, + bool FirstHVACIteration, + bool &LoopShutDownFlag); + + void UpdatePlantSplitter(); + + void UpdatePlantMixer(); + + void TurnOnAllLoopSideBranches(); + + void DisableAnyBranchPumpsConnectedToUnloadedEquipment(); + + void DoFlowAndLoadSolutionPass(int OtherSide, int ThisSideInletNode, bool FirstHVACIteration); + + Real64 CalcOtherSideDemand(Real64 ThisLoopSideFlow); + + Real64 SetupLoopFlowRequest(int OtherSide); + + Real64 EvaluateLoopSetPointLoad(int FirstBranchNum, + int LastBranchNum, + Real64 ThisLoopSideFlow, + Array1S_int LastComponentSimulated); + + void ResolveParallelFlows(Real64 ThisLoopSideFlow, bool FirstHVACIteration); + + void SimulateSinglePump(PlantLocation SpecificPumpLocation, Real64 & SpecificPumpFlowRate); + + void UpdateAnyLoopDemandAlterations(int BranchNum, int CompNum); + + void SimulateAllLoopSidePumps(Optional SpecificPumpLocation = _, + Optional SpecificPumpFlowRate = _); + + void AdjustPumpFlowRequestByEMSControls(int BranchNum, int CompNum, Real64 &FlowToRequest); + + void PushBranchFlowCharacteristics(int BranchNum, + Real64 ValueToPush, + bool FirstHVACIteration // TRUE if First HVAC iteration of Time step + ); + + bool CheckPlantConvergence(bool FirstHVACIteration); + + void solve(bool FirstHVACIteration, bool &ReSimOtherSideNeeded); + }; } // namespace DataPlant } // namespace EnergyPlus diff --git a/src/EnergyPlus/Plant/LoopSideReportVars.hh b/src/EnergyPlus/Plant/LoopSideReportVars.hh deleted file mode 100644 index 39e49db81fd..00000000000 --- a/src/EnergyPlus/Plant/LoopSideReportVars.hh +++ /dev/null @@ -1,69 +0,0 @@ -// EnergyPlus, Copyright (c) 1996-2020, The Board of Trustees of the University of Illinois, -// The Regents of the University of California, through Lawrence Berkeley National Laboratory -// (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge -// National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other -// contributors. All rights reserved. -// -// NOTICE: This Software was developed under funding from the U.S. Department of Energy and the -// U.S. Government consequently retains certain rights. As such, the U.S. Government has been -// granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, -// worldwide license in the Software to reproduce, distribute copies to the public, prepare -// derivative works, and perform publicly and display publicly, and to permit others to do so. -// -// Redistribution and use in source and binary forms, with or without modification, are permitted -// provided that the following conditions are met: -// -// (1) Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// (2) Redistributions in binary form must reproduce the above copyright notice, this list of -// conditions and the following disclaimer in the documentation and/or other materials -// provided with the distribution. -// -// (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, -// the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific prior -// written permission. -// -// (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form -// without changes from the version obtained under this License, or (ii) Licensee makes a -// reference solely to the software portion of its product, Licensee must refer to the -// software as "EnergyPlus version X" software, where "X" is the version number Licensee -// obtained under this License and may not use a different name for the software. Except as -// specifically required in this Section (4), Licensee shall not use in a company name, a -// product name, in advertising, publicity, or other promotional activities any name, trade -// name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly -// similar designation, without the U.S. Department of Energy's prior written consent. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef PlantReportingLoopSideReportVars_hh_INCLUDED -#define PlantReportingLoopSideReportVars_hh_INCLUDED - -namespace EnergyPlus { -namespace DataPlant { - - struct LoopSideReportVars - { - // Members - Real64 LoopSetPtDemandAtInlet; - Real64 ThisSideLoadAlterations; - - // Default Constructor - LoopSideReportVars() : LoopSetPtDemandAtInlet(0.0), ThisSideLoadAlterations(0.0) - { - } - }; - -} // namespace DataPlant -} // namespace EnergyPlus - -#endif diff --git a/src/EnergyPlus/Plant/PlantLoopSolver.cc b/src/EnergyPlus/Plant/PlantLoopSolver.cc deleted file mode 100644 index fb90333eda8..00000000000 --- a/src/EnergyPlus/Plant/PlantLoopSolver.cc +++ /dev/null @@ -1,2654 +0,0 @@ -// EnergyPlus, Copyright (c) 1996-2020, The Board of Trustees of the University of Illinois, -// The Regents of the University of California, through Lawrence Berkeley National Laboratory -// (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge -// National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other -// contributors. All rights reserved. -// -// NOTICE: This Software was developed under funding from the U.S. Department of Energy and the -// U.S. Government consequently retains certain rights. As such, the U.S. Government has been -// granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, -// worldwide license in the Software to reproduce, distribute copies to the public, prepare -// derivative works, and perform publicly and display publicly, and to permit others to do so. -// -// Redistribution and use in source and binary forms, with or without modification, are permitted -// provided that the following conditions are met: -// -// (1) Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// (2) Redistributions in binary form must reproduce the above copyright notice, this list of -// conditions and the following disclaimer in the documentation and/or other materials -// provided with the distribution. -// -// (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, -// the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific prior -// written permission. -// -// (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form -// without changes from the version obtained under this License, or (ii) Licensee makes a -// reference solely to the software portion of its product, Licensee must refer to the -// software as "EnergyPlus version X" software, where "X" is the version number Licensee -// obtained under this License and may not use a different name for the software. Except as -// specifically required in this Section (4), Licensee shall not use in a company name, a -// product name, in advertising, publicity, or other promotional activities any name, trade -// name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly -// similar designation, without the U.S. Department of Energy's prior written consent. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -// C++ Headers -#include - -// ObjexxFCL Headers -#include -#include -#include -#include -#include - -// EnergyPlus Headers -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace EnergyPlus { - - namespace PlantLoopSolver { - - // MODULE INFORMATION: - // AUTHOR B. Griffith, Dan Fisher, Sankaranarayanan K P, Rich Liesen, Edwin Lee - // DATE WRITTEN Feb 2010 - // This file developed from PlantSupplySideSolvers.cc by Sankaranarayanan K P, Rich Liesen, Dan Fisher - // MODIFIED na - // RE-ENGINEERED Aug 2010 Edwin Lee - - // PURPOSE OF THIS MODULE: - // This module contains subroutines to solve plant half loops of various configurations. - - // METHODOLOGY EMPLOYED: - // Main worker calling driver for plant loop system model - // Calls various worker routines to model flow rates around a plant half loop - // The procedural flow depends on the pump(s), loop side, and operation scheme at the time (and current flow lock?) - - // MODULE VARIABLE DEFINITIONS - Real64 InitialDemandToLoopSetPoint; - Real64 CurrentAlterationsToDemand; - Real64 UpdatedDemandToLoopSetPoint; - Real64 LoadToLoopSetPointThatWasntMet; // Unmet Demand - Real64 InitialDemandToLoopSetPointSAVED; - int RefrigIndex(0); // Index denoting refrigerant used (possibly steam) - - static std::string const fluidNameSteam("STEAM"); - - // Functions - void clear_state() { - InitialDemandToLoopSetPoint = 0.0; - CurrentAlterationsToDemand = 0.0; - UpdatedDemandToLoopSetPoint = 0.0; - LoadToLoopSetPointThatWasntMet = 0.0; // Unmet Demand - InitialDemandToLoopSetPointSAVED = 0.0; - RefrigIndex = 0; // Index denoting refrigerant used (possibly steam) - } - - void PlantHalfLoopSolver(bool const FirstHVACIteration, // TRUE if First HVAC iteration of Time step - int const LoopSideNum, - int const LoopNum, - bool &ReSimOtherSideNeeded) { - - // SUBROUTINE INFORMATION: - // AUTHORS: Dan Fisher, Sankaranarayanan K P, Edwin Lee - // DATE WRITTEN: April 1998 - // MODIFIED June 2005(Work in the Plant Super Manager Module) - // July 2006 - // RE-ENGINEERED July 2010 - - // PURPOSE OF THIS SUBROUTINE: - // SimSupplyFlowSolution is the driver routine for plant loops. It performs - // the following tasks for each half loop (supply or demand side): - // 1. Calculate flow request for half loop - // 2. Predict Loop Flow - // 3. Simulate the inlet branch - // 4. Simulate the parallel branches, distributing load if necessary - // 5. Set flow rates on parallel branches - // 6. Simulate outlet branch and update node and report variables - - // METHODOLOGY EMPLOYED: - // The algorithm operates on a predictor/corrector flow setting method by simulating all available loop components - // based on component requested flow rates, then enforcing continuity on all loop branch flows by calling - // the flow resolver and locking those flows down. Available components are then re-simulated using the - // corrected flow rates. - - // Initialize variables - InitialDemandToLoopSetPoint = 0.0; - CurrentAlterationsToDemand = 0.0; - UpdatedDemandToLoopSetPoint = 0.0; - int ThisSide = LoopSideNum; - int OtherSide = 3 - ThisSide; // will give us 1 if thisside is 2, or 2 if thisside is 1 - - auto &thisPlantLoop = DataPlant::PlantLoop(LoopNum); - auto &thisLoopSide = thisPlantLoop.LoopSide(ThisSide); - int ThisSideInletNode = thisLoopSide.NodeNumIn; - - // The following block is related to validating the flow control paths of the loop side - // Since the control types are scheduled, I think BeginTimeStep should be a decent check frequency - if (DataGlobals::BeginTimeStepFlag && thisLoopSide.OncePerTimeStepOperations) { - - // Initialize loop side controls -- could just be done for one loop since this routine inherently - // loops over all plant/condenser loops. Not sure if the penalty is worth investigating. - PlantCondLoopOperation::InitLoadDistribution(FirstHVACIteration); - - // Now that the op scheme types are updated, do LoopSide validation - thisPlantLoop.loopSolver.ValidateFlowControlPaths(LoopNum, ThisSide); - - // Set the flag to false so we won't do these again this time step - thisLoopSide.OncePerTimeStepOperations = false; - - } else { - - // Set the flag to true so that it is activated for the next time step - thisLoopSide.OncePerTimeStepOperations = true; - } - - // Do pressure system initialize if this is the demand side (therefore once per whole loop) - if (ThisSide == DataPlant::DemandSide) - PlantPressureSystem::SimPressureDropSystem(LoopNum, FirstHVACIteration, DataPlant::PressureCall_Init); - - // Turn on any previously disabled branches due to constant speed branch pump issue - thisPlantLoop.loopSolver.TurnOnAllLoopSideBranches(thisLoopSide); - - // Do the actual simulation here every time - thisPlantLoop.loopSolver.DoFlowAndLoadSolutionPass(LoopNum, ThisSide, OtherSide, ThisSideInletNode, - FirstHVACIteration); - - // On constant speed branch pump loop sides we need to resimulate - if (thisLoopSide.hasConstSpeedBranchPumps) { - // turn off any pumps connected to unloaded equipment and re-do the flow/load solution pass - thisPlantLoop.loopSolver.DisableAnyBranchPumpsConnectedToUnloadedEquipment(LoopNum, ThisSide); - thisPlantLoop.loopSolver.DoFlowAndLoadSolutionPass(LoopNum, ThisSide, OtherSide, ThisSideInletNode, - FirstHVACIteration); - } - - // A couple things are specific to which LoopSide we are on - if (LoopSideNum == DataPlant::DemandSide) { - - // Pass the loop information via the HVAC interface manager - HVACInterfaceManager::UpdatePlantLoopInterface(LoopNum, - LoopSideNum, - thisPlantLoop.LoopSide(DataPlant::DemandSide).NodeNumOut, - thisPlantLoop.LoopSide(DataPlant::SupplySide).NodeNumIn, - ReSimOtherSideNeeded, - thisPlantLoop.CommonPipeType); - - } else { // LoopSide == SupplySide - - // Update pressure drop reporting, calculate total loop pressure drop for use elsewhere - PlantPressureSystem::SimPressureDropSystem(LoopNum, FirstHVACIteration, DataPlant::PressureCall_Update); - - // Pass the loop information via the HVAC interface manager (only the flow) - HVACInterfaceManager::UpdatePlantLoopInterface(LoopNum, - LoopSideNum, - thisPlantLoop.LoopSide(DataPlant::SupplySide).NodeNumOut, - thisPlantLoop.LoopSide(DataPlant::DemandSide).NodeNumIn, - ReSimOtherSideNeeded, - thisPlantLoop.CommonPipeType); - - // Update the loop outlet node conditions - thisPlantLoop.loopSolver.CheckLoopExitNode(LoopNum, FirstHVACIteration); - } - - // Update some reporting information at Plant half loop level - thisPlantLoop.loopSolver.UpdateLoopSideReportVars(LoopNum, LoopSideNum, InitialDemandToLoopSetPointSAVED, - LoadToLoopSetPointThatWasntMet); - } - - void PlantLoopSolverClass::TurnOnAllLoopSideBranches(DataPlant::HalfLoopData &loop_side) { - for (int branchNum = 2; branchNum <= loop_side.TotalBranches - 1; ++branchNum) { - auto &branch = loop_side.Branch(branchNum); - branch.disableOverrideForCSBranchPumping = false; - } - } - - void PlantLoopSolverClass::DisableAnyBranchPumpsConnectedToUnloadedEquipment(int LoopNum, int ThisSide) { - auto &loop_side = DataPlant::PlantLoop(LoopNum).LoopSide(ThisSide); - for (int branchNum = 2; branchNum <= loop_side.TotalBranches - 1; ++branchNum) { - auto &branch = loop_side.Branch(branchNum); - Real64 totalDispatchedLoadOnBranch = 0.0; - int pumpCompIndexOnBranch = 0; - for (int compNum = 1; compNum <= branch.TotalComponents; ++compNum) { - auto &component = branch.Comp(compNum); - auto &t = component.TypeOf_Num; - if (t == DataPlant::TypeOf_PumpConstantSpeed || t == DataPlant::TypeOf_PumpBankConstantSpeed || - t == DataPlant::TypeOf_PumpVariableSpeed || t == DataPlant::TypeOf_PumpBankVariableSpeed) { - pumpCompIndexOnBranch = compNum; - } else { - totalDispatchedLoadOnBranch += component.MyLoad; - } - } - if (std::abs(totalDispatchedLoadOnBranch) < 0.001) { - branch.disableOverrideForCSBranchPumping = true; - } - } - } - - void - PlantLoopSolverClass::DoFlowAndLoadSolutionPass(int LoopNum, int ThisSide, int OtherSide, int ThisSideInletNode, - bool FirstHVACIteration) { - - // This is passed in-out deep down into the depths where the load op manager calls EMS and EMS can shut down pumps - bool LoopShutDownFlag = false; - - // First thing is to setup mass flow request information - Real64 ThisLoopSideFlowRequest = DataPlant::PlantLoop(LoopNum).loopSolver.SetupLoopFlowRequest(LoopNum, - ThisSide, - OtherSide); - - // Now we know what the loop would "like" to run at, let's see the pump - // operation range (min/max avail) to see whether it is possible this time around - Real64 ThisLoopSideFlow = - DataPlant::PlantLoop(LoopNum).loopSolver.DetermineLoopSideFlowRate(LoopNum, ThisSide, - ThisSideInletNode, - ThisLoopSideFlowRequest); - - // We also need to establish a baseline "other-side-based" loop demand based on this possible flow rate - InitialDemandToLoopSetPoint = DataPlant::PlantLoop(LoopNum).loopSolver.CalcOtherSideDemand(LoopNum, - ThisSide, - ThisLoopSideFlow); - - UpdatedDemandToLoopSetPoint = InitialDemandToLoopSetPoint; - - LoadToLoopSetPointThatWasntMet = 0.0; - - // We now have a loop side flow request, along with inlet min/max avails. - // We can now make a first pass through the component simulation, requesting flow as necessary. - // Normal "supply side" components will set a mass flow rate on their outlet node to request flow, - // while "Demand side" components will set a a mass flow request on their inlet node to request flow. - DataPlant::PlantLoop(LoopNum).LoopSide(ThisSide).FlowLock = DataPlant::FlowUnlocked; - DataPlant::PlantLoop(LoopNum).loopSolver.SimulateAllLoopSideBranches( - LoopNum, ThisSide, ThisLoopSideFlow, FirstHVACIteration, LoopShutDownFlag); - - // DSU? discussion/comments about loop solver/flow resolver interaction - // At this point, the components have been simulated. They should have either: - // - logged a massflowrequest - // - or logged a MassFlowRate - // We need to decide what the components are going to do on FlowLock=0. - // If we want all control here at the solver level, the components just need to - // log their MassFlowRate on their outlet nodes, or some other mechanism. - // Then the loop solver can scan the branch and get the max, and this will be the requested - // flow rate for the branch. - // The loop solver will then set this as the branch outlet mass flow rate in preparation - // for the flow resolver. - // The loop solver may need to do something to the inlet/outlet branch, but I'm not sure yet. - // The following comment block is what I had already thought of, and it may still make sense. - - // Now that all the flow requests have been logged, we need to prepare them for the - // flow resolver. This will just take the requests and determine the desired flow - // request for that branch according to pump placement, pump type, and other component - // conditions. In many cases, this will just be to simply take the max request from - // the branch, which will already be within pumping limits for that flow path. - // We can then call the flow resolver to lock down branch inlet flow rates. - - // The flow resolver takes information such as requested flows and min/max available flows and - // sets the corrected flow on the inlet to each parallel branch - DataPlant::PlantLoop(LoopNum).loopSolver.ResolveParallelFlows(LoopNum, ThisSide, ThisLoopSideFlow, - FirstHVACIteration); - - // Re-Initialize variables for this next pass - InitialDemandToLoopSetPointSAVED = InitialDemandToLoopSetPoint; - CurrentAlterationsToDemand = 0.0; - UpdatedDemandToLoopSetPoint = InitialDemandToLoopSetPoint; - - // Now that flow rates have been resolved, we just need to set the flow lock status - // flag, and resimulate. During this simulation each component will still use the - // SetFlowRequest routine, but this routine will also set the outlet flow rate - // equal to the inlet flow rate, according to flowlock logic. - DataPlant::PlantLoop(LoopNum).LoopSide(ThisSide).FlowLock = DataPlant::FlowLocked; - DataPlant::PlantLoop(LoopNum).loopSolver.SimulateAllLoopSideBranches( - LoopNum, ThisSide, ThisLoopSideFlow, FirstHVACIteration, LoopShutDownFlag); - } - - Real64 PlantLoopSolverClass::DetermineLoopSideFlowRate(int LoopNum, int ThisSide, int ThisSideInletNode, - Real64 ThisSideLoopFlowRequest) { - Real64 ThisLoopSideFlow = ThisSideLoopFlowRequest; - Real64 TotalPumpMinAvailFlow = 0.0; - Real64 TotalPumpMaxAvailFlow = 0.0; - if (allocated(DataPlant::PlantLoop(LoopNum).LoopSide(ThisSide).Pumps)) { - - //~ Initialize pump values - for (auto &e : DataPlant::PlantLoop(LoopNum).LoopSide(ThisSide).Pumps) { - e.CurrentMinAvail = 0.0; - e.CurrentMaxAvail = 0.0; - } - DataPlant::PlantLoop(LoopNum).LoopSide(ThisSide).FlowLock = DataPlant::FlowPumpQuery; - - //~ Simulate pumps - DataPlant::PlantLoop(LoopNum).loopSolver.SimulateAllLoopSidePumps(LoopNum, ThisSide); - - //~ Calculate totals - for (auto const &e : DataPlant::PlantLoop(LoopNum).LoopSide(ThisSide).Pumps) { - TotalPumpMinAvailFlow += e.CurrentMinAvail; - TotalPumpMaxAvailFlow += e.CurrentMaxAvail; - } - - // Use the pump min/max avail to attempt to constrain the loop side flow - ThisLoopSideFlow = PlantUtilities::BoundValueToWithinTwoValues(ThisLoopSideFlow, TotalPumpMinAvailFlow, - TotalPumpMaxAvailFlow); - } - - // Now we check flow restriction from the other side, both min and max avail. - // Doing this last basically means it wins, so the pump should pull down to meet the flow restriction - ThisLoopSideFlow = PlantUtilities::BoundValueToNodeMinMaxAvail(ThisLoopSideFlow, ThisSideInletNode); - - // Final preparation of loop inlet min/max avail if pumps exist - if (allocated(DataPlant::PlantLoop(LoopNum).LoopSide(ThisSide).Pumps)) { - // At this point, the pump limits should have been obeyed unless a flow restriction was encountered from the other side - // The pump may, however, have even tighter constraints than the other side - // At this point, the inlet node doesn't know anything about those limits - // Since we have already honored the other side flow restriction, try to honor the pump limits here - PlantUtilities::TightenNodeMinMaxAvails(ThisSideInletNode, TotalPumpMinAvailFlow, - TotalPumpMaxAvailFlow); - } - - // Now reset the entering mass flow rate to the decided-upon flow rate - DataLoopNode::Node(ThisSideInletNode).MassFlowRate = ThisLoopSideFlow; - return ThisLoopSideFlow; - } - - void PlantLoopSolverClass::ValidateFlowControlPaths(int const LoopNum, int const LoopSideNum) { - - // FUNCTION INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN July 2010 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS FUNCTION: - // This routine will scan all the loop side paths and validate the component topology according - // to current topology rules and regulations. - - // METHODOLOGY EMPLOYED: - // Scan this loop side and begin by scanning the first branch, then follow with the remainder of the flow paths - // - this would be from splitter outlet nodes all the way to the loop side outlet node. - // The current rules are that "other types" of components (as defined below in the references) can be placed along each - // flow path as needed. At this point, any number of "load-range based" components can be placed along the flow - // path. After this, the user is allowed to place another set of any number of "other types" of components. - // The key restriction is that an "other type" of component may not be sandwiched by "load-range based" components. - // This is due to the load range based needing to be simulated all at once along each flow path. - - // REFERENCES: - // "other types" of components: basically not load-range based heat transfer components. This would include: - // - demand based components such as coils - // - component setpoint based operating components - // - heat exchanger components including waterside economizers - // "load-range based" components are heat transfer components which are controlled based on a single load range. - // - currently only one load range based scheme is available at a given time, although other control types - // may be enabled, such as component setpoint. - // Pumps are separate components since the pump heat is not accounted for in the flow path order. - // Improvements during the demand side rewrite has allowed pumps to be placed as -not- the first component on a branch - // Pumps can be placed anywhere, even between load-range based components, since they will not affect loop load - - // RETURN VALUE: - // Returns a control validator flow structure, including a flag for successful or not, then if not successful - // the other values are filled in such as location on the loop where the error occurred and a message error description - - // FUNCTION PARAMETER DEFINITIONS: - int const Parallel(1); - int const Outlet(2); - - // set up a loopside reference - auto &this_loop_side(DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum)); - - //~ Initialze - bool EncounteredLRB = false; - bool EncounteredNonLRBAfterLRB = false; - int const NumParallelPaths = this_loop_side.TotalBranches - 2; - - // We'll start by stepping through the first branch, which may be the only branch - // If we find a load range based, then trip the flag and just keep moving - // If we only have one branch and all is good, then RETURN early - // If we have parallel branches, then start looping through each flow path to - // decide if it is a valid path. - // If any one path is invalid then all is wrong - int firstBranchIndex = 1; - for (int CompIndex = 1; CompIndex <= this_loop_side.Branch(firstBranchIndex).TotalComponents; ++CompIndex) { - - auto &this_component(this_loop_side.Branch(firstBranchIndex).Comp(CompIndex)); - - { - auto const SELECT_CASE_var(this_component.CurOpSchemeType); - - if ((SELECT_CASE_var >= DataPlant::LoadRangeBasedMin) && - (SELECT_CASE_var <= DataPlant::LoadRangeBasedMax)) { //~ load range based - if (EncounteredNonLRBAfterLRB) { - // We must have already encountered a LRB, then a non-LRB, and now another LRB, this is bad - ShowSevereError( - "Plant Topology Problem: Load range based components are separated by other control type components."); - ShowContinueError("Load Range Based should be grouped together on each flow path."); - ShowFatalError("Plant topology issue causes program termination"); - } else { - EncounteredLRB = true; - } - - } else if (SELECT_CASE_var == DataPlant::PumpOpSchemeType) { //~ pump - // For now this is just a placeholder, because I think pumps will be available anywhere, - // and they won't affect the load distribution - - } else if (SELECT_CASE_var == DataPlant::NoControlOpSchemeType) { //~ Such as pipes - // For now this is just a placeholder, because these components shouldn't cause a problem anywhere... - - } else if (SELECT_CASE_var == - DataPlant::UnknownStatusOpSchemeType) { //~ Uninitialized, this should be a sufficient place to catch for this on branch 1 - // throw fatal - ShowSevereError( - "ValidateFlowControlPaths: Uninitialized operation scheme type for component Name: " + - this_component.Name); - ShowFatalError("ValidateFlowControlPaths: developer notice, Inlet path validation loop"); - } else { //~ Other control type - if (EncounteredLRB) { - EncounteredNonLRBAfterLRB = true; - } else { - // For now don't do anything, but we'll see... - } - } - } - } - - // Return early if we only needed to do the one branch - if (NumParallelPaths <= 0) return; - - // Now, if we have multiple parallel branches, I think the easiest way is to go all the way from the inlet node - // of each parallel branch to the loop outlet node and check the flow path - // This way we don't have to remember the conditions on each of the parallel branches when we would finally move - // to analyzing the outlet node when all done - // This will reduce allocation on the heap because we will keep from storing that array - // For each parallel path, we will need to check two branches: the parallel branch and the LoopSide outlet branch - for (int PathCounter = 1; PathCounter <= NumParallelPaths; ++PathCounter) { - for (int ParallelOrOutletIndex = Parallel; ParallelOrOutletIndex <= Outlet; ++ParallelOrOutletIndex) { - int BranchIndex; - if (ParallelOrOutletIndex == Parallel) { - // The branch index will be the current pathtype + 1 to add the inlet branch - BranchIndex = PathCounter + 1; - } else { // ParallelOrOutletIndex == Outlet - // The branch index will be the LoopSide outlet node - BranchIndex = this_loop_side.TotalBranches; - } - - // Now that we have the branch index, let's do the control type check over all the components - for (int CompIndex = 1; - CompIndex <= this_loop_side.Branch(BranchIndex).TotalComponents; ++CompIndex) { - - auto &this_component(this_loop_side.Branch(BranchIndex).Comp(CompIndex)); - - { - auto const SELECT_CASE_var(this_component.CurOpSchemeType); - - if ((SELECT_CASE_var >= DataPlant::LoadRangeBasedMin) && - (SELECT_CASE_var <= DataPlant::LoadRangeBasedMax)) { //~ load range based - if (EncounteredNonLRBAfterLRB) { - // We must have already encountered a LRB, then a non-LRB, and now another LRB, this is bad - ShowSevereError( - "Plant Topology Problem: Load range based components are separated by other control type components."); - ShowContinueError("Load Range Based should be grouped together on each flow path."); - ShowFatalError("Plant topology issue causes program termination"); - } else { - EncounteredLRB = true; - } - - } else if (SELECT_CASE_var == DataPlant::NoControlOpSchemeType) { //~ Such as pipes - // For now this is just a placeholder, because these components shouldn't cause a problem anywhere... - - } else if (SELECT_CASE_var == DataPlant::PumpOpSchemeType) { //~ pump - // For now this is just a placeholder, because I think pumps will be available anywhere, - // and they won't affect the load distribution - - } else if (SELECT_CASE_var == - DataPlant::UnknownStatusOpSchemeType) { //~ Uninitialized, this should be sufficient place to catch for this on other branches - // throw fatal error - ShowSevereError( - "ValidateFlowControlPaths: Uninitialized operation scheme type for component Name: " + - this_component.Name); - ShowFatalError( - "ValidateFlowControlPaths: developer notice, problem in Parallel path validation loop"); - } else { //~ Other control type - if (EncounteredLRB) { - EncounteredNonLRBAfterLRB = true; - } else { - // For now don't do anything, but we'll see... - } - } - } - - } //~ CompIndex - - } //~ Parallel and Outlet Branches - - } //~ Parallel Paths - } - - Real64 PlantLoopSolverClass::SetupLoopFlowRequest(int const LoopNum, int const ThisSide, int const OtherSide) { - - // FUNCTION INFORMATION: - // AUTHOR: Dan Fisher, Edwin Lee - // DATE WRITTEN: August 2010 - // MODIFIED: na - // RE-ENGINEERED: na - - // PURPOSE OF THIS SUBROUTINE: - // This routine sets up the flow request values and sums them up for each loop side - // Then makes a decision on the desired loop flow based on loop configuration - - // METHODOLOGY EMPLOYED: - // Scan through the components on this loop side, and look at the mass flow request - // values on components inlet node. - // Check common pipe/pumping configuration for this loop side and the other loop side - // to determine what the LoopSide should flow - - //~ Initialize - Real64 LoopFlow = 0.0; // Once all flow requests are evaluated, this is the desired flow on this side - - // reference - auto &loop(DataPlant::PlantLoop(LoopNum)); - - //~ First we need to set up the flow requests on each LoopSide - for (int LoopSideCounter = DataPlant::DemandSide; - LoopSideCounter <= DataPlant::SupplySide; ++LoopSideCounter) { - // Clear things out for this LoopSide - Real64 InletBranchRequestNeedAndTurnOn = 0.0; - Real64 InletBranchRequestNeedIfOn = 0.0; - Real64 ParallelBranchRequestsNeedAndTurnOn(0.0); - Real64 ParallelBranchRequestsNeedIfOn(0.0); - Real64 OutletBranchRequestNeedAndTurnOn = 0.0; - Real64 OutletBranchRequestNeedIfOn = 0.0; - - // reference - auto &loop_side(loop.LoopSide(LoopSideCounter)); - - loop_side.flowRequestNeedIfOn = 0.0; - loop_side.flowRequestNeedAndTurnOn = 0.0; - loop_side.flowRequestFinal = 0.0; - loop_side.hasConstSpeedBranchPumps = false; - - // Now loop through all the branches on this LoopSide and get flow requests - int const NumBranchesOnThisLoopSide = loop_side.TotalBranches; - int ParallelBranchIndex = 0; - for (int BranchCounter = 1; BranchCounter <= NumBranchesOnThisLoopSide; ++BranchCounter) { - Real64 ThisBranchFlowRequestNeedAndTurnOn = 0.0; - Real64 ThisBranchFlowRequestNeedIfOn = 0.0; - - // reference - auto &branch(loop_side.Branch(BranchCounter)); - - if (BranchCounter > 1 && BranchCounter < NumBranchesOnThisLoopSide) ++ParallelBranchIndex; - - if (branch.disableOverrideForCSBranchPumping) { - branch.RequestedMassFlow = 0.0; - continue; - } - - int const NumCompsOnThisBranch = branch.TotalComponents; - for (int CompCounter = 1; CompCounter <= NumCompsOnThisBranch; ++CompCounter) { - - // reference - auto &component(branch.Comp(CompCounter)); - - int NodeToCheckRequest = component.NodeNumIn; - int FlowPriorityStatus = component.FlowPriority; - - // reference - auto &node_with_request(DataLoopNode::Node(NodeToCheckRequest)); - - if (component.GeneralEquipType != DataPlant::GenEquipTypes_Pump) { - - if (FlowPriorityStatus == DataPlant::LoopFlowStatus_Unknown) { - // do nothing - } else if (FlowPriorityStatus == DataPlant::LoopFlowStatus_NeedyAndTurnsLoopOn) { - ThisBranchFlowRequestNeedAndTurnOn = max(ThisBranchFlowRequestNeedAndTurnOn, - node_with_request.MassFlowRateRequest); - ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, - node_with_request.MassFlowRateRequest); - } else if (FlowPriorityStatus == DataPlant::LoopFlowStatus_NeedyIfLoopOn) { - ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, - node_with_request.MassFlowRateRequest); - } else if (FlowPriorityStatus == DataPlant::LoopFlowStatus_TakesWhatGets) { - // do nothing - } - } else { // handle pumps differently - if ((BranchCounter == 1) && (LoopSideCounter == DataPlant::SupplySide) && - (loop.CommonPipeType == DataPlant::CommonPipe_TwoWay)) { - // special primary side flow request for two way common pipe - int const CompIndex = component.CompNum; - { - auto const SELECT_CASE_var(component.TypeOf_Num); - // remove var speed pumps from this case statement if can set MassFlowRateRequest - if ((SELECT_CASE_var == DataPlant::TypeOf_PumpConstantSpeed) || - (SELECT_CASE_var == DataPlant::TypeOf_PumpVariableSpeed) || - (SELECT_CASE_var == DataPlant::TypeOf_PumpBankVariableSpeed)) { - if (CompIndex > 0) { - ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, - Pumps::PumpEquip( - CompIndex).MassFlowRateMax); - } - } else if (SELECT_CASE_var == DataPlant::TypeOf_PumpBankConstantSpeed) { - if (CompIndex > 0) { - ThisBranchFlowRequestNeedIfOn = - max(ThisBranchFlowRequestNeedIfOn, - Pumps::PumpEquip(CompIndex).MassFlowRateMax / - Pumps::PumpEquip(CompIndex).NumPumpsInBank); - } - } else { - ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, - node_with_request.MassFlowRateRequest); - } - } - - } else if ((BranchCounter == 1) && (LoopSideCounter == DataPlant::SupplySide) && - (loop.CommonPipeType == DataPlant::CommonPipe_Single)) { - int const CompIndex = component.CompNum; - { - auto const SELECT_CASE_var(component.TypeOf_Num); - // remove var speed pumps from this case statement if can set MassFlowRateRequest - if ((SELECT_CASE_var == DataPlant::TypeOf_PumpConstantSpeed) || - (SELECT_CASE_var == DataPlant::TypeOf_PumpVariableSpeed) || - (SELECT_CASE_var == DataPlant::TypeOf_PumpBankVariableSpeed)) { - if (CompIndex > 0) { - ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, - Pumps::PumpEquip( - CompIndex).MassFlowRateMax); - } - } else if (SELECT_CASE_var == DataPlant::TypeOf_PumpBankConstantSpeed) { - if (CompIndex > 0) { - ThisBranchFlowRequestNeedIfOn = - max(ThisBranchFlowRequestNeedIfOn, - Pumps::PumpEquip(CompIndex).MassFlowRateMax / - Pumps::PumpEquip(CompIndex).NumPumpsInBank); - } - } else { - ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, - node_with_request.MassFlowRateRequest); - } - } - } else { - int const CompIndex = component.CompNum; - { - auto const SELECT_CASE_var(component.TypeOf_Num); - if (SELECT_CASE_var == DataPlant::TypeOf_PumpConstantSpeed) { - if (CompIndex > 0) { - auto &this_pump(Pumps::PumpEquip(CompIndex)); - if (ParallelBranchIndex >= 1) { // branch pump - if (branch.max_abs_Comp_MyLoad() > DataHVACGlobals::SmallLoad) { - ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, - this_pump.MassFlowRateMax); - } else if (loop.CommonPipeType != - DataPlant::CommonPipe_No) { // common pipe and constant branch pumps - ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, - this_pump.MassFlowRateMax); - } - loop_side.hasConstSpeedBranchPumps = true; - branch.HasConstantSpeedBranchPump = true; - branch.ConstantSpeedBranchMassFlow = this_pump.MassFlowRateMax; - } else { // inlet pump - ThisBranchFlowRequestNeedIfOn = max(ThisBranchFlowRequestNeedIfOn, - this_pump.MassFlowRateMax); - } - } - } else if (SELECT_CASE_var == DataPlant::TypeOf_PumpBankConstantSpeed) { - if (CompIndex > 0) { - auto &this_pump(Pumps::PumpEquip(CompIndex)); - if (ParallelBranchIndex >= 1) { // branch pump - if (branch.max_abs_Comp_MyLoad() > DataHVACGlobals::SmallLoad) { - ThisBranchFlowRequestNeedIfOn = - max(ThisBranchFlowRequestNeedIfOn, - this_pump.MassFlowRateMax / this_pump.NumPumpsInBank); - } else if (loop.CommonPipeType != - DataPlant::CommonPipe_No) { // common pipe and constant branch pumps - ThisBranchFlowRequestNeedIfOn = - max(ThisBranchFlowRequestNeedIfOn, - this_pump.MassFlowRateMax / this_pump.NumPumpsInBank); - } - loop_side.hasConstSpeedBranchPumps = true; - branch.HasConstantSpeedBranchPump = true; - branch.ConstantSpeedBranchMassFlow = - this_pump.MassFlowRateMax / this_pump.NumPumpsInBank; - } else { // inlet pump - ThisBranchFlowRequestNeedIfOn = - max(ThisBranchFlowRequestNeedIfOn, - this_pump.MassFlowRateMax / this_pump.NumPumpsInBank); - } - } - } - - // overwrite here for branch pumps - if ((SELECT_CASE_var == DataPlant::TypeOf_PumpVariableSpeed) || - (SELECT_CASE_var == DataPlant::TypeOf_PumpBankVariableSpeed) || - (SELECT_CASE_var == DataPlant::TypeOf_PumpCondensate)) { - if (component.CompNum > 0) { - auto &this_pump(Pumps::PumpEquip(component.CompNum)); - this_pump.LoopSolverOverwriteFlag = false; - } - } - } - } - } - } - if (BranchCounter == 1) { // inlet branch - InletBranchRequestNeedAndTurnOn = ThisBranchFlowRequestNeedAndTurnOn; - InletBranchRequestNeedIfOn = ThisBranchFlowRequestNeedIfOn; - } else if (BranchCounter < NumBranchesOnThisLoopSide) { // branchcounter = 1 is already caught - ParallelBranchRequestsNeedAndTurnOn += ThisBranchFlowRequestNeedAndTurnOn; - ParallelBranchRequestsNeedIfOn += ThisBranchFlowRequestNeedIfOn; - } else if (BranchCounter == NumBranchesOnThisLoopSide) { // outlet branch - OutletBranchRequestNeedAndTurnOn = ThisBranchFlowRequestNeedAndTurnOn; - OutletBranchRequestNeedIfOn = ThisBranchFlowRequestNeedIfOn; - } - - branch.RequestedMassFlow = max(ThisBranchFlowRequestNeedIfOn, ThisBranchFlowRequestNeedAndTurnOn); - } - loop_side.flowRequestNeedAndTurnOn = max(InletBranchRequestNeedAndTurnOn, - ParallelBranchRequestsNeedAndTurnOn, - OutletBranchRequestNeedAndTurnOn); - loop_side.flowRequestNeedIfOn = max(InletBranchRequestNeedIfOn, ParallelBranchRequestsNeedIfOn, - OutletBranchRequestNeedIfOn); - } - - auto &this_loop_side(loop.LoopSide(ThisSide)); - auto &other_loop_side(loop.LoopSide(OtherSide)); - - //~ Now that we have calculated each sides different status's requests, process to find final - if ((this_loop_side.flowRequestNeedAndTurnOn + other_loop_side.flowRequestNeedAndTurnOn) < - DataBranchAirLoopPlant::MassFlowTolerance) { - this_loop_side.flowRequestFinal = 0.0; - other_loop_side.flowRequestFinal = 0.0; - } else { // some flow is needed and loop should try to run - this_loop_side.flowRequestFinal = max(this_loop_side.flowRequestNeedAndTurnOn, - this_loop_side.flowRequestNeedIfOn); - other_loop_side.flowRequestFinal = max(other_loop_side.flowRequestNeedAndTurnOn, - other_loop_side.flowRequestNeedIfOn); - } - // now store final flow requests on each loop side data structure - this_loop_side.FlowRequest = this_loop_side.flowRequestFinal; - other_loop_side.FlowRequest = other_loop_side.flowRequestFinal; - - if (loop.CommonPipeType == DataPlant::CommonPipe_No) { - // we may or may not have a pump on this side, but the flow request is the larger of the two side's final - if ((!this_loop_side.hasConstSpeedBranchPumps) && (!other_loop_side.hasConstSpeedBranchPumps)) { - LoopFlow = max(this_loop_side.flowRequestFinal, other_loop_side.flowRequestFinal); - } else { // account for stepped loop flow rates required of branch pumps - - // rules for setting flow when there are constant speed branch pumps. - // 1. Check if above routines already selected a loop flow rate based on the constant speed branches, if so then just use it - if (this_loop_side.hasConstSpeedBranchPumps && - (this_loop_side.flowRequestFinal >= other_loop_side.flowRequestFinal)) { - // okay, just use basic logic - LoopFlow = max(this_loop_side.flowRequestFinal, other_loop_side.flowRequestFinal); - } else if (other_loop_side.hasConstSpeedBranchPumps && - (this_loop_side.flowRequestFinal <= other_loop_side.flowRequestFinal)) { - // okay, just use basic logic - LoopFlow = max(this_loop_side.flowRequestFinal, other_loop_side.flowRequestFinal); - } else { // not okay, we have a case that will likely need special correcting - // 2. determine which loop side has the stepped data - int LoopSideIndex = 0; - if (this_loop_side.hasConstSpeedBranchPumps && - (this_loop_side.flowRequestFinal < other_loop_side.flowRequestFinal)) { - LoopSideIndex = ThisSide; - } else if (other_loop_side.hasConstSpeedBranchPumps && - (other_loop_side.flowRequestFinal < this_loop_side.flowRequestFinal)) { - LoopSideIndex = OtherSide; - } - auto &loop_side(loop.LoopSide(LoopSideIndex)); - - // 3. step through and find out needed information - // 3a. search the loop side with branch pumps and find the steps available with non-zero Myloads - // 3b. search the loop side with branch pumps and find the steps available with zero Myloads - // LoadedConstantSpeedBranchFlowRateSteps = 0.0; - Real64 LoadedConstantSpeedBranchFlowRateSteps_sum = 0.0; - this_loop_side.noLoadConstantSpeedBranchFlowRateSteps = 0.0; - Real64 NoLoadConstantSpeedBranchFlowRateSteps_sum = 0.0; - int ParallelBranchIndex = 0; - int const NumBranchesOnThisLoopSide = loop_side.TotalBranches; - auto const &loop_branches(loop_side.Branch); - for (int BranchCounter = 1; BranchCounter <= NumBranchesOnThisLoopSide; ++BranchCounter) { - auto const &loop_branch(loop_branches(BranchCounter)); - if (BranchCounter > 1 && BranchCounter < NumBranchesOnThisLoopSide) ++ParallelBranchIndex; - if (loop_branch.HasConstantSpeedBranchPump) { - auto const branch_mass_flow(loop_branch.ConstantSpeedBranchMassFlow); - if (loop_branch.max_abs_Comp_MyLoad() > DataHVACGlobals::SmallLoad) { - LoadedConstantSpeedBranchFlowRateSteps_sum += branch_mass_flow; - } else { - this_loop_side.noLoadConstantSpeedBranchFlowRateSteps( - ParallelBranchIndex) = branch_mass_flow; - NoLoadConstantSpeedBranchFlowRateSteps_sum += branch_mass_flow; - } - } - } - - // 4. allocate which branches to use, - Real64 tmpLoopFlow = max(this_loop_side.flowRequestFinal, other_loop_side.flowRequestFinal); - Real64 AccumFlowSteps = 0.0; - Real64 MaxBranchPumpLoopSideFlow = - LoadedConstantSpeedBranchFlowRateSteps_sum + NoLoadConstantSpeedBranchFlowRateSteps_sum; - tmpLoopFlow = min(tmpLoopFlow, MaxBranchPumpLoopSideFlow); - // 4b. first use all the branches with non-zero MyLoad - if (tmpLoopFlow <= LoadedConstantSpeedBranchFlowRateSteps_sum) { - tmpLoopFlow = LoadedConstantSpeedBranchFlowRateSteps_sum; - } else { - AccumFlowSteps = LoadedConstantSpeedBranchFlowRateSteps_sum; - ParallelBranchIndex = 0; - for (int BranchCounter = 1; BranchCounter <= NumBranchesOnThisLoopSide; ++BranchCounter) { - if (BranchCounter > 1 && BranchCounter < NumBranchesOnThisLoopSide) { - ++ParallelBranchIndex; - } else { - continue; - } - auto const steps( - this_loop_side.noLoadConstantSpeedBranchFlowRateSteps(ParallelBranchIndex)); - if (steps > - 0.0) { // add in branches with zero MyLoad in branch input order until satisfied - if (tmpLoopFlow > AccumFlowSteps) { - if (tmpLoopFlow <= AccumFlowSteps + steps) { // found it set requests and exit - tmpLoopFlow = AccumFlowSteps + steps; - loop_side.Branch(BranchCounter).RequestedMassFlow = steps; - LoopFlow = tmpLoopFlow; - break; - } else { - AccumFlowSteps += steps; - loop_side.Branch(BranchCounter).RequestedMassFlow = steps; - } - } - } - } - } - } - } - } else if (loop.CommonPipeType == DataPlant::CommonPipe_TwoWay) { - LoopFlow = this_loop_side.flowRequestFinal; - } else if (loop.CommonPipeType == DataPlant::CommonPipe_Single) { - LoopFlow = this_loop_side.flowRequestFinal; - } - - // overrides the loop solver flow request to allow loop pump to turn off when not in use - if (this_loop_side.TotalPumps == 1) { - if (LoopFlow < DataConvergParams::PlantLowFlowRateToler) { // Update from dataconvergetols... - for (int BranchCounter = 1; BranchCounter <= this_loop_side.TotalBranches; ++BranchCounter) { - // reference - auto &branch(this_loop_side.Branch(BranchCounter)); - int const NumCompsOnThisBranch = branch.TotalComponents; - for (int CompCounter = 1; CompCounter <= NumCompsOnThisBranch; ++CompCounter) { - auto const &component(branch.Comp(CompCounter)); - auto const SELECT_CASE_var(component.TypeOf_Num); - if ((SELECT_CASE_var == DataPlant::TypeOf_PumpVariableSpeed) || - (SELECT_CASE_var == DataPlant::TypeOf_PumpBankVariableSpeed) || - (SELECT_CASE_var == DataPlant::TypeOf_PumpCondensate)) { - if (component.CompNum > 0) { - auto &this_pump(Pumps::PumpEquip(component.CompNum)); - this_pump.LoopSolverOverwriteFlag = true; - } - } - } - } - } - } - - return LoopFlow; - } - - void PlantLoopSolverClass::SimulateAllLoopSideBranches( - int const LoopNum, int const LoopSideNum, Real64 const ThisLoopSideFlow, bool const FirstHVACIteration, - bool &LoopShutDownFlag) { - - // SUBROUTINE INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN July 2010 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // This routine will step through all branch groups (single branch .OR. inlet/parallels/outlet) - // and call the branch group simulation routine. This routine also calls to update the splitter - // and mixer. - - // METHODOLOGY EMPLOYED: - // The number of branch groups is either 1 or 3. 1 would be a single branch half-loop. 3 would - // be the minimum for an inlet/parallels/outlet set. The number of branch groups can then be - // calculated as #BrGrps = 1 + 2*L; where L is zero for single half loop and one for parallel-type set. - // This calculation can be reduced to the logical/integer conversion as shown in the code. - // The simulation then steps through each branch group. If there are parallel branches, the splitter is - // updated on flowlock=0 to pass information through, then after the parallel branches the mixer is always - // updated. The outlet branch "group" is then simulated. - - // SUBROUTINE PARAMETER DEFINITIONS: - int const InletBranchOrOneBranchHalfLoop(1); - int const ParallelBranchSet(2); - int const OutletBranch(3); - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - auto &thisLoopSide = DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum); - - int NumBranchGroups = 1; - if (thisLoopSide.TotalBranches > 1) { - NumBranchGroups = 3; - } - - // reset branch starting component index back to zero before each pass - for (int BranchCounter = 1; BranchCounter <= thisLoopSide.TotalBranches; ++BranchCounter) { - thisLoopSide.Branch(BranchCounter).lastComponentSimulated = 0; - } - - for (int BranchGroup = 1; BranchGroup <= NumBranchGroups; ++BranchGroup) { - - if ((BranchGroup > 1) && (thisLoopSide.TotalBranches == 1)) break; - - switch (BranchGroup) { - case InletBranchOrOneBranchHalfLoop: - DataPlant::PlantLoop(LoopNum).loopSolver.SimulateLoopSideBranchGroup(LoopNum, LoopSideNum, 1, 1, - ThisLoopSideFlow, - FirstHVACIteration, - LoopShutDownFlag); - break; - case ParallelBranchSet: - PlantUtilities::UpdatePlantSplitter(LoopNum, LoopSideNum); - DataPlant::PlantLoop(LoopNum).loopSolver.SimulateLoopSideBranchGroup(LoopNum, LoopSideNum, 2, - thisLoopSide.TotalBranches - - 1, ThisLoopSideFlow, - FirstHVACIteration, - LoopShutDownFlag); - PlantUtilities::UpdatePlantMixer(LoopNum, LoopSideNum); - break; - case OutletBranch: - DataPlant::PlantLoop(LoopNum).loopSolver.SimulateLoopSideBranchGroup(LoopNum, - LoopSideNum, - thisLoopSide.TotalBranches, - thisLoopSide.TotalBranches, - ThisLoopSideFlow, - FirstHVACIteration, - LoopShutDownFlag); - break; - } - } - } - - void PlantLoopSolverClass::SimulateLoopSideBranchGroup(int const LoopNum, - int const LoopSideNum, - int const FirstBranchNum, - int const LastBranchNum, - Real64 FlowRequest, - bool const FirstHVACIteration, - bool &LoopShutDownFlag) { - - // SUBROUTINE INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN July 2010 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // This routine will manage the component simulation on a single set of parallel branches - // This routine also reverts to a single branch simulation if there isn't a set of parallel branches - - // METHODOLOGY EMPLOYED: - // Loop through all components, and simulate first the non-load range based on each branch. - // When a load-range based (LRB) is encountered, the simulation moves to the next branch to do non-LRB components. - // When all paths are exhausted the simulation begins simulating LRB components. Before each comp, the load distribution - // engine is called to handle the load distribution for this current pass. If load is successfully distributed, this is - // flagged, and not called again. If load is not distributed (i.e. this component isn't ON right now), then the - // load distribution engine will be called again before the next component. - // After all load distribution is done and those components are complete, the simulation moves back to do any - // remaining components that may be downstream. - - //~ Flags - bool LoadDistributionWasPerformed; - bool DummyInit = false; - bool const DoNotGetCompSizFac(false); - - //~ General variables - Real64 LoadToLoopSetPoint; - Location PumpLocation; - LoadToLoopSetPoint = 0.0; - - // We now know what plant simulation region is available to us, let's simulate this group - bool EncounteredLRBObjDuringPass1(false); - auto &loop(DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum)); - for (int BranchCounter = FirstBranchNum; BranchCounter <= LastBranchNum; ++BranchCounter) { - auto &branch(loop.Branch(BranchCounter)); - - //~ Always start from the last component we did the last time around + 1 and - //~ try to make it all the way to the end of the loop - int const StartingComponent = branch.lastComponentSimulated + 1; - int const EndingComponent = branch.TotalComponents; - for (int CompCounter = StartingComponent; CompCounter <= EndingComponent; ++CompCounter) { - - auto &this_comp(branch.Comp(CompCounter)); - auto const CurOpSchemeType(this_comp.CurOpSchemeType); - - switch (CurOpSchemeType) { - case DataPlant::WSEconOpSchemeType: //~ coils - this_comp.MyLoad = UpdatedDemandToLoopSetPoint; - PlantLoopEquip::SimPlantEquip(LoopNum, LoopSideNum, BranchCounter, CompCounter, - FirstHVACIteration, DummyInit, DoNotGetCompSizFac); - break; - case DataPlant::PumpOpSchemeType: //~ pump - PumpLocation.LoopNum = LoopNum; - PumpLocation.LoopSideNum = LoopSideNum; - PumpLocation.BranchNum = BranchCounter; - PumpLocation.CompNum = CompCounter; - if (loop.BranchPumpsExist) { - SimulateSinglePump(PumpLocation, branch.RequestedMassFlow); - } else { - SimulateSinglePump(PumpLocation, FlowRequest); - } - break; - case DataPlant::CompSetPtBasedSchemeType: - PlantCondLoopOperation::ManagePlantLoadDistribution(LoopNum, - LoopSideNum, - BranchCounter, - CompCounter, - LoadToLoopSetPoint, - LoadToLoopSetPointThatWasntMet, - FirstHVACIteration, - LoopShutDownFlag, - LoadDistributionWasPerformed); - PlantLoopEquip::SimPlantEquip(LoopNum, LoopSideNum, BranchCounter, CompCounter, - FirstHVACIteration, DummyInit, DoNotGetCompSizFac); - break; - case DataPlant::EMSOpSchemeType: - if (LoopSideNum == DataPlant::SupplySide) { - int const curCompOpSchemePtr = this_comp.CurCompLevelOpNum; - int const OpSchemePtr = this_comp.OpScheme(curCompOpSchemePtr).OpSchemePtr; - DataPlant::PlantLoop(LoopNum).OpScheme( - OpSchemePtr).EMSIntVarLoopDemandRate = InitialDemandToLoopSetPoint; - } - PlantCondLoopOperation::ManagePlantLoadDistribution(LoopNum, - LoopSideNum, - BranchCounter, - CompCounter, - UpdatedDemandToLoopSetPoint, - LoadToLoopSetPointThatWasntMet, - FirstHVACIteration, - LoopShutDownFlag, - LoadDistributionWasPerformed); - PlantLoopEquip::SimPlantEquip(LoopNum, LoopSideNum, BranchCounter, CompCounter, - FirstHVACIteration, DummyInit, DoNotGetCompSizFac); - break; - default: - if ((CurOpSchemeType >= DataPlant::LoadRangeBasedMin) && - (CurOpSchemeType <= DataPlant::LoadRangeBasedMax)) { //~ load range based - EncounteredLRBObjDuringPass1 = true; - goto components_end; // don't do any more components on this branch - } else { // demand, , etc. - PlantLoopEquip::SimPlantEquip(LoopNum, LoopSideNum, BranchCounter, CompCounter, - FirstHVACIteration, DummyInit, DoNotGetCompSizFac); - } - } - - // Update loop demand as needed for changes this component may have made - DataPlant::PlantLoop(LoopNum).loopSolver.UpdateAnyLoopDemandAlterations(LoopNum, LoopSideNum, - BranchCounter, CompCounter); - - //~ If we didn't EXIT early, we must have simulated, so update array - branch.lastComponentSimulated = CompCounter; - - } //~ CompCounter - components_end:; - - if (loop.FlowLock == DataPlant::FlowLocked) { - PlantPressureSystem::SimPressureDropSystem(LoopNum, FirstHVACIteration, - DataPlant::PressureCall_Calc, LoopSideNum, - BranchCounter); - } - - } //~ BranchCounter - - // So now we have made one pass through all of the available components on these branches, skipping load based - // If we didn't encounter any load based objects during the first pass, then we must be done! - if (!EncounteredLRBObjDuringPass1) return; - - // If we have load based now, we should go ahead and distribute the load - // If not then this branch group is done, since flow path validation was previously done - LoadToLoopSetPoint = UpdatedDemandToLoopSetPoint; - LoadDistributionWasPerformed = false; - - // The way the load distribution is set up, I think I should call this for every load range based component - // encountered until distribution is actually performed. If we don't call for each component then we may - // call for a component that is not on the current equip list and then nothing would come on. - bool EncounteredNonLBObjDuringPass2(false); - for (int BranchCounter = FirstBranchNum; BranchCounter <= LastBranchNum; ++BranchCounter) { - auto &branch(loop.Branch(BranchCounter)); - - //~ Always start from the last component we did the last time around + 1 and - //~ try to make it all the way to the end of the loop - int const StartingComponent = branch.lastComponentSimulated + 1; - int const EndingComponent = branch.TotalComponents; - for (int CompCounter = StartingComponent; CompCounter <= EndingComponent; ++CompCounter) { - - auto const CurOpSchemeType(branch.Comp(CompCounter).CurOpSchemeType); - - switch (CurOpSchemeType) { - case DataPlant::NoControlOpSchemeType: //~ pipes, for example - PlantLoopEquip::SimPlantEquip(LoopNum, LoopSideNum, BranchCounter, CompCounter, - FirstHVACIteration, DummyInit, DoNotGetCompSizFac); - break; - case DataPlant::DemandOpSchemeType: - case DataPlant::CompSetPtBasedSchemeType: - case DataPlant::FreeRejectionOpSchemeType: //~ other control types - EncounteredNonLBObjDuringPass2 = true; - goto components2_end; // don't do anymore components on this branch - case DataPlant::PumpOpSchemeType: //~ pump - PumpLocation.LoopNum = LoopNum; - PumpLocation.LoopSideNum = LoopSideNum; - PumpLocation.BranchNum = BranchCounter; - PumpLocation.CompNum = CompCounter; - if (loop.BranchPumpsExist) { - SimulateSinglePump(PumpLocation, branch.RequestedMassFlow); - } else { - SimulateSinglePump(PumpLocation, FlowRequest); - } - break; - default: - if ((CurOpSchemeType >= DataPlant::LoadRangeBasedMin) && - (CurOpSchemeType <= DataPlant::LoadRangeBasedMax)) { //~ load range based - if (!LoadDistributionWasPerformed) { //~ Still need to distribute load among load range based components - PlantCondLoopOperation::ManagePlantLoadDistribution(LoopNum, - LoopSideNum, - BranchCounter, - CompCounter, - LoadToLoopSetPoint, - LoadToLoopSetPointThatWasntMet, - FirstHVACIteration, - LoopShutDownFlag, - LoadDistributionWasPerformed); - } - PlantLoopEquip::SimPlantEquip(LoopNum, LoopSideNum, BranchCounter, CompCounter, - FirstHVACIteration, DummyInit, DoNotGetCompSizFac); - } - } - - //~ If we didn't EXIT early, we must have simulated, so update array - branch.lastComponentSimulated = CompCounter; - - } //~ CompCounter - components2_end:; - - //~ If we are locked, go ahead and simulate the pressure components on this branch - if (loop.FlowLock == DataPlant::FlowLocked) { - PlantPressureSystem::SimPressureDropSystem(LoopNum, FirstHVACIteration, - DataPlant::PressureCall_Calc, LoopSideNum, - BranchCounter); - } - - } //~ BranchCounter - - // So now we have made the load range based pass through all the components on each branch - // If we didn't see any other component types, then we are done, go away - if (!EncounteredNonLBObjDuringPass2) return; - - // If we did encounter other objects than we just need to go back through and simulate them - for (int BranchCounter = FirstBranchNum; BranchCounter <= LastBranchNum; ++BranchCounter) { - auto &branch(loop.Branch(BranchCounter)); - - //~ Always start from the last component we did the last time around + 1 and - //~ try to make it all the way to the end of the loop - int const StartingComponent = branch.lastComponentSimulated + 1; - int const EndingComponent = branch.TotalComponents; - for (int CompCounter = StartingComponent; CompCounter <= EndingComponent; ++CompCounter) { - - auto const CurOpSchemeType(branch.Comp(CompCounter).CurOpSchemeType); - - switch (CurOpSchemeType) { - case DataPlant::DemandOpSchemeType: //~ coils - PlantLoopEquip::SimPlantEquip(LoopNum, LoopSideNum, BranchCounter, CompCounter, - FirstHVACIteration, DummyInit, DoNotGetCompSizFac); - break; - case DataPlant::PumpOpSchemeType: //~ pump - PumpLocation.LoopNum = LoopNum; - PumpLocation.LoopSideNum = LoopSideNum; - PumpLocation.BranchNum = BranchCounter; - PumpLocation.CompNum = CompCounter; - if (loop.BranchPumpsExist) { - SimulateSinglePump(PumpLocation, branch.RequestedMassFlow); - } else { - SimulateSinglePump(PumpLocation, FlowRequest); - } - break; - default: - if ((CurOpSchemeType >= DataPlant::LoadRangeBasedMin) && - (CurOpSchemeType <= DataPlant::LoadRangeBasedMax)) { //~ load range based - ShowFatalError("Encountered Load Based Object after other components, invalid."); - } else { //~ Typical control equipment - PlantLoopEquip::SimPlantEquip(LoopNum, LoopSideNum, BranchCounter, CompCounter, - FirstHVACIteration, DummyInit, DoNotGetCompSizFac); - } - } - - //~ If we didn't EXIT early, we must have simulated, so update array - branch.lastComponentSimulated = CompCounter; - - } //~ CompCounter - - if (loop.FlowLock == DataPlant::FlowLocked) { - PlantPressureSystem::SimPressureDropSystem(LoopNum, FirstHVACIteration, - DataPlant::PressureCall_Calc, LoopSideNum, - BranchCounter); - } - - } //~ BranchCounter - - // I suppose I could do a check on the last component simulated to make sure we actually exhausted all branches - // This would be the "THIRD" check on flow validation, but would be OK - } - - void PlantLoopSolverClass::SimulateAllLoopSidePumps(int const LoopNum, - int const ThisSide, - Optional SpecificPumpLocation, - Optional SpecificPumpFlowRate) { - - // SUBROUTINE INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN July 2010 - // MODIFIED na - // RE-ENGINEERED na - - int PumpIndexStart; - int PumpIndexEnd; - int PumpLoopNum; - int PumpLoopSideNum; - - // If we have a specific loop/side/br/comp, then find the index and only do that one, otherwise do all pumps on the loop side - if (present(SpecificPumpLocation)) { - PumpLoopNum = SpecificPumpLocation().LoopNum; - PumpLoopSideNum = SpecificPumpLocation().LoopSideNum; - int const PumpBranchNum = SpecificPumpLocation().BranchNum; - int const PumpCompNum = SpecificPumpLocation().CompNum; - PumpIndexStart = DataPlant::PlantLoop(PumpLoopNum).LoopSide(PumpLoopSideNum).Branch(PumpBranchNum).Comp( - PumpCompNum).IndexInLoopSidePumps; - PumpIndexEnd = PumpIndexStart; - } else { - PumpLoopNum = LoopNum; - PumpLoopSideNum = ThisSide; - PumpIndexStart = 1; - PumpIndexEnd = DataPlant::PlantLoop(LoopNum).LoopSide(ThisSide).TotalPumps; - } - - // If we have a flow rate to hit, then go for it, otherwise, just operate in request mode with zero flow - Real64 FlowToRequest; - if (present(SpecificPumpFlowRate)) { - FlowToRequest = SpecificPumpFlowRate; - } else { - FlowToRequest = 0.0; - } - - //~ Now loop through all the pumps and simulate them, keeping track of their status - auto &loop_side(DataPlant::PlantLoop(PumpLoopNum).LoopSide(PumpLoopSideNum)); - auto &loop_side_branch(loop_side.Branch); - for (int PumpCounter = PumpIndexStart; PumpCounter <= PumpIndexEnd; ++PumpCounter) { - - //~ Set some variables - auto &pump(loop_side.Pumps(PumpCounter)); - int const PumpBranchNum = pump.BranchNum; - int const PumpCompNum = pump.CompNum; - int const PumpOutletNode = pump.PumpOutletNode; - - DataPlant::PlantLoop(LoopNum).loopSolver.AdjustPumpFlowRequestByEMSControls( - PumpLoopNum, PumpLoopSideNum, PumpBranchNum, PumpCompNum, FlowToRequest); - - // Call SimPumps, routine takes a flow request, and returns some info about the status of the pump - bool DummyThisPumpRunning; - Pumps::SimPumps(pump.PumpName, PumpLoopNum, FlowToRequest, DummyThisPumpRunning, - loop_side_branch(PumpBranchNum).PumpIndex, pump.PumpHeatToFluid); - - //~ Pull some state information from the pump outlet node - Real64 const ThisPumpMinAvail = DataLoopNode::Node(PumpOutletNode).MassFlowRateMinAvail; - Real64 const ThisPumpMaxAvail = DataLoopNode::Node(PumpOutletNode).MassFlowRateMaxAvail; - - //~ Now update the data structure - pump.CurrentMinAvail = ThisPumpMinAvail; - pump.CurrentMaxAvail = ThisPumpMaxAvail; - } - - //~ Update the LoopSide pump heat totality here - if (loop_side.TotalPumps > 0) { - loop_side.TotalPumpHeat = sum(loop_side.Pumps, &DataPlant::LoopSidePumpInformation::PumpHeatToFluid); - } - } - - void PlantLoopSolverClass::SimulateSinglePump(Location const SpecificPumpLocation, Real64 & SpecificPumpFlowRate) { - - // SUBROUTINE INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN July 2010 - // MODIFIED na - // RE-ENGINEERED na - - auto &loop(DataPlant::PlantLoop(SpecificPumpLocation.LoopNum)); - auto &loop_side(loop.LoopSide(SpecificPumpLocation.LoopSideNum)); - auto &loop_side_branch(loop_side.Branch(SpecificPumpLocation.BranchNum)); - auto &comp(loop_side_branch.Comp(SpecificPumpLocation.CompNum)); - int const PumpIndex = comp.IndexInLoopSidePumps; - auto &pump(loop_side.Pumps(PumpIndex)); - - DataPlant::PlantLoop(SpecificPumpLocation.LoopNum).loopSolver.AdjustPumpFlowRequestByEMSControls( - SpecificPumpLocation.LoopNum, SpecificPumpLocation.LoopSideNum, - SpecificPumpLocation.BranchNum, SpecificPumpLocation.CompNum, SpecificPumpFlowRate); - - // Call SimPumps, routine takes a flow request, and returns some info about the status of the pump - bool DummyThisPumpRunning; - Pumps::SimPumps(pump.PumpName, SpecificPumpLocation.LoopNum, SpecificPumpFlowRate, DummyThisPumpRunning, - loop_side_branch.PumpIndex, pump.PumpHeatToFluid); - - //~ Pull some state information from the pump outlet node - pump.CurrentMinAvail = DataLoopNode::Node(pump.PumpOutletNode).MassFlowRateMinAvail; - pump.CurrentMaxAvail = DataLoopNode::Node(pump.PumpOutletNode).MassFlowRateMaxAvail; - - //~ Update the LoopSide pump heat totality here - if (loop_side.TotalPumps > 0) { - loop_side.TotalPumpHeat = sum(loop_side.Pumps, &DataPlant::LoopSidePumpInformation::PumpHeatToFluid); - } - } - - Real64 - PlantLoopSolverClass::CalcOtherSideDemand(int const LoopNum, int const ThisSide, Real64 ThisLoopSideFlow) { - - // FUNCTION INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN August 2010 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS FUNCTION: - // To evaluate the demand to hit the loop setpoint based on the loop side inlet conditions - - // METHODOLOGY EMPLOYED: - // This routine will simply call the evaluate loop setpoint routine but call it from - // the very beginning of this loop side, so that it is basically for the entire loop side - - // FUNCTION PARAMETER DEFINITIONS: - static Array1D_int const InitCompArray(1, 0); - - Real64 Demand = DataPlant::PlantLoop(LoopNum).loopSolver.EvaluateLoopSetPointLoad(LoopNum, ThisSide, 1, 1, - ThisLoopSideFlow, - InitCompArray); - - return Demand; - } - - Real64 PlantLoopSolverClass::EvaluateLoopSetPointLoad(int const LoopNum, - int const LoopSideNum, - int const FirstBranchNum, - int const LastBranchNum, - Real64 ThisLoopSideFlow, - Array1S_int LastComponentSimulated) { - - // FUNCTION INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN August 2010 - // MODIFIED na - // RE-ENGINEERED na - - // Return value - Real64 LoadToLoopSetPoint = 0.0; // function result - - static std::string const RoutineName("PlantLoopSolver::EvaluateLoopSetPointLoad"); - static std::string const RoutineNameAlt("PlantSupplySide:EvaluateLoopSetPointLoad"); - - //~ General variables - Real64 SumMdotTimesTemp = 0.0; - Real64 SumMdot = 0.0; - - // We will place one specialized case in here for common pipe simulations. - // If we are doing a common pipe simulation, and there is greater other-side flow than this side, - // then the "other side" demand needs to include getting the flow through the common pipe to the same setpoint - // as the flow going through the actual supply side - if (DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).hasConstSpeedBranchPumps && LoopSideNum == 2 && - DataPlant::PlantLoop(LoopNum).CommonPipeType != DataPlant::CommonPipe_No) { - const int OtherSide = 3 - LoopSideNum; - const int otherSideOutletNodeNum = DataPlant::PlantLoop(LoopNum).LoopSide(OtherSide).NodeNumOut; - Real64 commonPipeFlow = DataLoopNode::Node(otherSideOutletNodeNum).MassFlowRate - ThisLoopSideFlow; - Real64 otherSideExitingTemperature = DataLoopNode::Node(otherSideOutletNodeNum).Temp; - SumMdotTimesTemp += otherSideExitingTemperature * commonPipeFlow; - SumMdot += commonPipeFlow; - } - - auto &thisPlantLoop = DataPlant::PlantLoop(LoopNum); - - // Sweep across flow paths in this group and calculate the deltaT and then the load - int BranchIndex = 0; // ~ This is a 1 - n value within the current branch group - for (int BranchCounter = FirstBranchNum; BranchCounter <= LastBranchNum; ++BranchCounter) { - - ++BranchIndex; - - //~ Always start from the last component we did the last time around + 1 and - //~ try to make it all the way to the end of the loop - int StartingComponent = LastComponentSimulated(BranchIndex) + 1; - int EnteringNodeNum = thisPlantLoop.LoopSide(LoopSideNum).Branch(BranchCounter).Comp( - StartingComponent).NodeNumIn; - - Real64 EnteringTemperature = DataLoopNode::Node(EnteringNodeNum).Temp; - Real64 MassFlowRate = DataLoopNode::Node(EnteringNodeNum).MassFlowRate; - - SumMdotTimesTemp += EnteringTemperature * MassFlowRate; - SumMdot += MassFlowRate; - } - - if (SumMdot < DataBranchAirLoopPlant::MassFlowTolerance) { - return 0.0; - } - - Real64 WeightedInletTemp = SumMdotTimesTemp / SumMdot; - - if (thisPlantLoop.FluidType == DataLoopNode::NodeType_Water) { - - Real64 Cp = FluidProperties::GetSpecificHeatGlycol(thisPlantLoop.FluidName, WeightedInletTemp, - thisPlantLoop.FluidIndex, RoutineName); - - { - auto const SELECT_CASE_var(thisPlantLoop.LoopDemandCalcScheme); - - if (SELECT_CASE_var == DataPlant::SingleSetPoint) { - - // Pick up the loop setpoint temperature - Real64 LoopSetPointTemperature = thisPlantLoop.LoopSide(LoopSideNum).TempSetPoint; - // Calculate the delta temperature - Real64 DeltaTemp = LoopSetPointTemperature - WeightedInletTemp; - - // Calculate the demand on the loop - LoadToLoopSetPoint = SumMdot * Cp * DeltaTemp; - - } else if (SELECT_CASE_var == DataPlant::DualSetPointDeadBand) { - - // Get the range of setpoints - Real64 LoopSetPointTemperatureHi = DataLoopNode::Node( - thisPlantLoop.TempSetPointNodeNum).TempSetPointHi; - Real64 LoopSetPointTemperatureLo = DataLoopNode::Node( - thisPlantLoop.TempSetPointNodeNum).TempSetPointLo; - - // Calculate the demand on the loop - if (SumMdot > 0.0) { - Real64 LoadToHeatingSetPoint = - SumMdot * Cp * (LoopSetPointTemperatureLo - WeightedInletTemp); - Real64 LoadToCoolingSetPoint = - SumMdot * Cp * (LoopSetPointTemperatureHi - WeightedInletTemp); - // Possible combinations: - // 1 LoadToHeatingSetPoint > 0 & LoadToCoolingSetPoint > 0 --> Heating required - // 2 LoadToHeatingSetPoint < 0 & LoadToCoolingSetPoint < 0 --> Cooling Required - // 3 LoadToHeatingSetPoint <=0 & LoadToCoolingSetPoint >=0 --> Dead Band Operation - includes zero load cases - // 4 LoadToHeatingSetPoint > LoadToCoolingSetPoint --> Not Feasible if LoopSetPointHi >= LoopSetPointLo - // First trap bad set-points - if (LoadToHeatingSetPoint > LoadToCoolingSetPoint) { - ShowSevereError( - "Plant Loop: the Plant Loop Demand Calculation Scheme is set to DualSetPointDeadBand, but the " - "heating-related low setpoint appears to be above the cooling-related high setpoint."); - ShowContinueError( - "For example, if using SetpointManager:Scheduled:DualSetpoint, then check that the low setpoint is " - "below the high setpoint."); - ShowContinueError("Occurs in PlantLoop=" + thisPlantLoop.Name); - ShowContinueError( - "LoadToHeatingSetPoint=" + General::RoundSigDigits(LoadToHeatingSetPoint, 3) + - ", LoadToCoolingSetPoint=" + General::RoundSigDigits(LoadToCoolingSetPoint, 3)); - ShowContinueError("Loop Heating Low Setpoint=" + - General::RoundSigDigits(LoopSetPointTemperatureLo, 2)); - ShowContinueError("Loop Cooling High Setpoint=" + - General::RoundSigDigits(LoopSetPointTemperatureHi, 2)); - - ShowFatalError("Program terminates due to above conditions."); - } - if (LoadToHeatingSetPoint > 0.0 && LoadToCoolingSetPoint > 0.0) { - LoadToLoopSetPoint = LoadToHeatingSetPoint; - } else if (LoadToHeatingSetPoint < 0.0 && LoadToCoolingSetPoint < 0.0) { - LoadToLoopSetPoint = LoadToCoolingSetPoint; - } else if (LoadToHeatingSetPoint <= 0.0 && - LoadToCoolingSetPoint >= 0.0) { // deadband includes zero loads - LoadToLoopSetPoint = 0.0; - } else { - ShowSevereError( - "DualSetPointWithDeadBand: Unanticipated combination of heating and cooling loads - report to EnergyPlus " - "Development Team"); - ShowContinueError("occurs in PlantLoop=" + thisPlantLoop.Name); - ShowContinueError( - "LoadToHeatingSetPoint=" + General::RoundSigDigits(LoadToHeatingSetPoint, 3) + - ", LoadToCoolingSetPoint=" + General::RoundSigDigits(LoadToCoolingSetPoint, 3)); - ShowContinueError("Loop Heating Setpoint=" + - General::RoundSigDigits(LoopSetPointTemperatureLo, 2)); - ShowContinueError("Loop Cooling Setpoint=" + - General::RoundSigDigits(LoopSetPointTemperatureHi, 2)); - ShowFatalError("Program terminates due to above conditions."); - } - } else { - LoadToLoopSetPoint = 0.0; - } - } - } - - } else if (thisPlantLoop.FluidType == DataLoopNode::NodeType_Steam) { - - Real64 Cp = FluidProperties::GetSpecificHeatGlycol(thisPlantLoop.FluidName, WeightedInletTemp, - thisPlantLoop.FluidIndex, RoutineName); - - { - auto const SELECT_CASE_var(thisPlantLoop.LoopDemandCalcScheme); - - if (SELECT_CASE_var == DataPlant::SingleSetPoint) { - - // Pick up the loop setpoint temperature - Real64 LoopSetPointTemperature = thisPlantLoop.LoopSide(LoopSideNum).TempSetPoint; - - // Calculate the delta temperature - Real64 DeltaTemp = LoopSetPointTemperature - WeightedInletTemp; - - Real64 EnthalpySteamSatVapor = - FluidProperties::GetSatEnthalpyRefrig(fluidNameSteam, LoopSetPointTemperature, 1.0, - RefrigIndex, RoutineNameAlt); - Real64 EnthalpySteamSatLiquid = - FluidProperties::GetSatEnthalpyRefrig(fluidNameSteam, LoopSetPointTemperature, 0.0, - RefrigIndex, RoutineNameAlt); - - Real64 LatentHeatSteam = EnthalpySteamSatVapor - EnthalpySteamSatLiquid; - - // Calculate the demand on the loop - LoadToLoopSetPoint = SumMdot * (Cp * DeltaTemp + LatentHeatSteam); - } - } - - } else { // only have two types, water serves for glycol. - } - - // Trim the demand to zero if it is very small - if (std::abs(LoadToLoopSetPoint) < DataPlant::LoopDemandTol) LoadToLoopSetPoint = 0.0; - - return LoadToLoopSetPoint; - } - - void PlantLoopSolverClass::UpdateAnyLoopDemandAlterations(int const LoopNum, int const LoopSideNum, - int const BranchNum, int const CompNum) { - - // SUBROUTINE INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN August 2010 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // This routine will analyze the given component and determine if any - // alterations need to be made to the current loop demand value. If so, - // it will make the changes to the module level loop demand variables. - - // METHODOLOGY EMPLOYED: - // Components will always supply a useful delta T, even if it happens to be zero - // For flow rate, make decisions based on the component's current operating scheme type: - // Demand based: these components will have a flow request on their inlet node - // Pump: these components will not be included, as they no longer include heat at the pump - // component setpoint: these components will have a flow request - - // on their outlet node corresponding to their calculated delta T - // load range based: these components do not 'alter' the load, they reject the load - // Therefore they are not included - - // Using/Aliasing - using DataBranchAirLoopPlant::MassFlowTolerance; - using DataLoopNode::Node; - using DataPlant::FlowLocked; - using DataPlant::FlowUnlocked; - using DataPlant::LoadRangeBasedMax; - using DataPlant::LoadRangeBasedMin; - using DataPlant::PlantLoop; - using FluidProperties::GetSpecificHeatGlycol; - - // SUBROUTINE PARAMETER DEFINITIONS: - static std::string const RoutineName("PlantLoopSolver::UpdateAnyLoopDemandAlterations"); - - // Init to zero, so that if we don't find anything, we exit early - Real64 ComponentMassFlowRate(0.0); - - auto const &this_loop(PlantLoop(LoopNum).LoopSide(LoopSideNum)); - auto const &this_comp(this_loop.Branch(BranchNum).Comp(CompNum)); - - // Get information - int const InletNode(this_comp.NodeNumIn); - int const OutletNode(this_comp.NodeNumOut); - - if (this_loop.FlowLock == FlowUnlocked) { - - // For unlocked flow, use the inlet request -- !DSU? for now - { - auto const SELECT_CASE_var(this_comp.CurOpSchemeType); - if ((SELECT_CASE_var >= LoadRangeBasedMin) && (SELECT_CASE_var <= LoadRangeBasedMax)) { - // Don't do anything for load based components - } else { - // pumps pipes, etc. will be lumped in here with other component types, but they will have no delta T anyway - ComponentMassFlowRate = Node(InletNode).MassFlowRateRequest; - // DSU? make sure components like economizers use the mass flow request - } - } - - } else if (this_loop.FlowLock == FlowLocked) { - - // For locked flow just use the mass flow rate - { - auto const SELECT_CASE_var(this_comp.CurOpSchemeType); - if ((SELECT_CASE_var >= LoadRangeBasedMin) && (SELECT_CASE_var <= LoadRangeBasedMax)) { - // Don't do anything for load based components - } else { - // pumps pipes, etc. will be lumped in here with other component types, but they will have no delta T anyway - ComponentMassFlowRate = Node(OutletNode).MassFlowRate; - } - } - - } else { // flow pump query? problem? - } - - // Leave early if there wasn't a mass flow rate or request - if (ComponentMassFlowRate < MassFlowTolerance) return; - - // Get an average temperature for the property call - Real64 const InletTemp(Node(InletNode).Temp); - Real64 const OutletTemp(Node(OutletNode).Temp); - Real64 const AverageTemp((InletTemp + OutletTemp) / 2.0); - Real64 const ComponentCp( - GetSpecificHeatGlycol(PlantLoop(LoopNum).FluidName, AverageTemp, PlantLoop(LoopNum).FluidIndex, - RoutineName)); - - // Calculate the load altered by this component - Real64 const LoadAlteration(ComponentMassFlowRate * ComponentCp * (OutletTemp - InletTemp)); - - // Now alter the module level variables - CurrentAlterationsToDemand += LoadAlteration; - UpdatedDemandToLoopSetPoint = InitialDemandToLoopSetPoint - CurrentAlterationsToDemand; - } - - void PlantLoopSolverClass::ResolveParallelFlows( - int const LoopNum, // plant loop number that we are balancing flow for - int const LoopSideNum, // plant loop number that we are balancing flow for - Real64 const ThisLoopSideFlow, // [kg/s] total flow to be split - bool const FirstHVACIteration // TRUE if First HVAC iteration of Time step - ) { - - // SUBROUTINE INFORMATION: - // AUTHOR Brandon Anderson, Dan Fisher - // DATE WRITTEN October 1999 - // MODIFIED May 2005 Sankaranarayanan K P, Rich Liesen - // RE-ENGINEERED Sept 2010 Dan Fisher, Brent Griffith for demand side update - - // PURPOSE OF THIS SUBROUTINE: - // This subroutine takes the overall loop side flow and distributes - // it among parallel branches. this is the main implementation of - // flow splitting for plant splitter/mixer - - // METHODOLOGY EMPLOYED: - // Flow through the branches is currently determined by - // the active component on the branch, as well as the - // order of the branches following the splitter. - // SimPlantEquipment is run first, and the active components - // request their flow. These flows are compared and a simple - // algorithm balances flow in the branches. The flow in these - // branches is then locked down, via MassFlowRateMaxAvail and MinAvail - // SimPlant Equipment is then run again in order to get correct - // properties. Finally, Max/MinAvail are reset for the next time step. - - // Using/Aliasing - using DataBranchAirLoopPlant::ControlType_Active; - using DataBranchAirLoopPlant::ControlType_Bypass; - using DataBranchAirLoopPlant::ControlType_Passive; - using DataBranchAirLoopPlant::ControlType_SeriesActive; - using DataBranchAirLoopPlant::MassFlowTolerance; - using DataLoopNode::Node; - using DataPlant::PlantLoop; - using DataPlant::TypeOf_PumpBankVariableSpeed; - using DataPlant::TypeOf_PumpVariableSpeed; - using General::RoundSigDigits; - - // SUBROUTINE PARAMETER DEFINITIONS: - static Array1D_string const LoopSideName(2, {"Demand", "Supply"}); - int const LoopSideSingleBranch(1); // For readability - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int NumActiveBranches; // Active branch counter - Real64 ActiveFlowRate; // The flow available when cycling through branches - Real64 PassiveFlowRate; // The flow available when cycling through branches - Real64 FracFlow; // The flow available when cycling through branches - Real64 ThisBranchRequestFrac; // The request ratio - Real64 totalMax; // The flow available when cycling through branches - Real64 FlowRemaining; // The flow available when cycling through branches - int OutletNum; // Splitter outlet - int MixerBranchOut; - int SplitterBranchIn; // As the name implies - int SplitterBranchOut; // As the name implies - int LastNodeOnBranch; // intermediate value used for better readabilty - int FirstNodeOnBranch; // intermediate value used for better readabilty - int BranchNum; // intermediate value used for better readabilty - int iBranch; // DO loop counter for cycling through branches - int NumSplitOutlets; // As the name implies - Real64 OutletBranchMinAvail; - Real64 OutletBranchMaxAvail; - Real64 InletBranchMinAvail; - Real64 InletBranchMaxAvail; - Real64 BranchFlowReq; - Real64 BranchMinAvail; - Real64 BranchMaxAvail; - Real64 ParallelBranchMaxAvail; - Real64 ParallelBranchMinAvail; - Real64 TotParallelBranchFlowReq; - Real64 LoopFlowRate; - int FirstNodeOnBranchIn; - int FirstNodeOnBranchOut; - Real64 StartingFlowRate; - Real64 ThisBranchRequest; - int CompCounter; - int CompInletNode; - int CompOutletNode; - - auto &this_loopside(PlantLoop(LoopNum).LoopSide(LoopSideNum)); - - // If there is no splitter then there is no continuity to enforce. - if (!this_loopside.SplitterExists) { - - // If there's only one branch, then RETURN - if (this_loopside.TotalBranches == 1) { - // The branch should just try to meet the request previously calculated. This should be good, - // just need to make sure that during FlowUnlocked, no one constrained Min/Max farther. - // This would have been propagated down the branch, so we can check the outlet node min/max avail for this. - auto &this_single_branch(this_loopside.Branch(LoopSideSingleBranch)); - LastNodeOnBranch = this_single_branch.NodeNumOut; - FirstNodeOnBranch = this_single_branch.NodeNumIn; - BranchMinAvail = Node(LastNodeOnBranch).MassFlowRateMinAvail; - BranchMaxAvail = Node(LastNodeOnBranch).MassFlowRateMaxAvail; - Node(FirstNodeOnBranch).MassFlowRate = min(max(ThisLoopSideFlow, BranchMinAvail), BranchMaxAvail); - // now with flow locked, this single branch will just ran at the specified flow rate, so we are done - return; - } else { - ShowSevereError("Plant topology problem for PlantLoop: " + PlantLoop(LoopNum).Name + ", " + - LoopSideName(LoopSideNum) + " side."); - ShowContinueError( - "There are multiple branches, yet no splitter. This is an invalid configuration."); - ShowContinueError("Add a set of connectors, use put components on a single branch."); - ShowFatalError("Invalid plant topology causes program termination."); - return; - } - } - - // If a splitter/mixer combination exist on the loop - if (this_loopside.SplitterExists && this_loopside.MixerExists) { - - // Zero out local variables - TotParallelBranchFlowReq = 0.0; - NumSplitOutlets = this_loopside.Splitter.TotalOutletNodes; - if (NumSplitOutlets < 1) { - ShowSevereError("Plant topology problem for PlantLoop: " + PlantLoop(LoopNum).Name + ", " + - LoopSideName(LoopSideNum) + " side."); - ShowContinueError("Diagnostic error in PlantLoopSolver::ResolveParallelFlows."); - ShowContinueError("Splitter improperly specified, no splitter outlets."); - ShowFatalError("Invalid plant topology causes program termination."); - } - - NumActiveBranches = 0; - ParallelBranchMaxAvail = 0.0; - ParallelBranchMinAvail = 0.0; - for (iBranch = 1; iBranch <= NumSplitOutlets; ++iBranch) { - - BranchNum = this_loopside.Splitter.BranchNumOut(iBranch); - auto &this_branch(this_loopside.Branch(BranchNum)); - SplitterBranchOut = this_loopside.Splitter.BranchNumOut(iBranch); - auto &this_splitter_outlet_branch(this_loopside.Branch(SplitterBranchOut)); - LastNodeOnBranch = this_branch.NodeNumOut; - FirstNodeOnBranch = this_branch.NodeNumIn; - BranchFlowReq = DataPlant::PlantLoop(LoopNum).loopSolver.DetermineBranchFlowRequest(LoopNum, - LoopSideNum, - BranchNum); - this_branch.RequestedMassFlow = BranchFlowReq; // store this for later use in logic for remaining flow allocations - // now, if we are have branch pumps, here is the situation: - // constant speed pumps lock in a flow request on the inlet node - // variable speed pumps which have other components on the branch do not log a request themselves - // the DetermineBranchFlowRequest routine only looks at the branch inlet node - // for variable speed branch pumps then, this won't work because the branch will be requesting zero - // so let's adjust for this here to make sure these branches get good representation - // This comment above is not true, for series active branches, DetermineBranchFlowRequest does scan down the branch's - // components already, no need to loop over components - BranchMinAvail = Node(LastNodeOnBranch).MassFlowRateMinAvail; - BranchMaxAvail = Node(LastNodeOnBranch).MassFlowRateMaxAvail; - // !sum the branch flow requests to a total parallel branch flow request - bool activeBranch = this_splitter_outlet_branch.ControlType == ControlType_Active; - bool isSeriesActiveAndRequesting = (this_splitter_outlet_branch.ControlType == ControlType_SeriesActive) && (BranchFlowReq > 0.0); - if (activeBranch || isSeriesActiveAndRequesting ) { // revised logic for series active - TotParallelBranchFlowReq += BranchFlowReq; - ++NumActiveBranches; - } - Node(FirstNodeOnBranch).MassFlowRate = BranchFlowReq; - Node(FirstNodeOnBranch).MassFlowRateMinAvail = BranchMinAvail; - Node(FirstNodeOnBranch).MassFlowRateMaxAvail = BranchMaxAvail; - ParallelBranchMaxAvail += BranchMaxAvail; - ParallelBranchMinAvail += BranchMinAvail; - } - // ! Find branch number and flow rates at splitter inlet - SplitterBranchIn = this_loopside.Splitter.BranchNumIn; - LastNodeOnBranch = this_loopside.Branch(SplitterBranchIn).NodeNumOut; - FirstNodeOnBranchIn = this_loopside.Branch(SplitterBranchIn).NodeNumIn; - InletBranchMinAvail = Node(LastNodeOnBranch).MassFlowRateMinAvail; - InletBranchMaxAvail = Node(LastNodeOnBranch).MassFlowRateMaxAvail; - // ! Find branch number and flow rates at mixer outlet - MixerBranchOut = this_loopside.Mixer.BranchNumOut; - LastNodeOnBranch = this_loopside.Branch(MixerBranchOut).NodeNumOut; - FirstNodeOnBranchOut = this_loopside.Branch(MixerBranchOut).NodeNumIn; - OutletBranchMinAvail = Node(LastNodeOnBranch).MassFlowRateMinAvail; - OutletBranchMaxAvail = Node(LastNodeOnBranch).MassFlowRateMaxAvail; - - LoopFlowRate = ThisLoopSideFlow; - - auto &first_branch_inlet_node(Node(FirstNodeOnBranchIn)); - auto &last_branch_inlet_node(Node(FirstNodeOnBranchOut)); - - // Reset branch inlet node flow rates for the first and last branch on loop - first_branch_inlet_node.MassFlowRate = ThisLoopSideFlow; - last_branch_inlet_node.MassFlowRate = ThisLoopSideFlow; - - // Reset branch inlet node Min/MaxAvails for the first and last branch on loop - first_branch_inlet_node.MassFlowRateMaxAvail = min(first_branch_inlet_node.MassFlowRateMaxAvail, - ParallelBranchMaxAvail); - first_branch_inlet_node.MassFlowRateMaxAvail = - min(first_branch_inlet_node.MassFlowRateMaxAvail, last_branch_inlet_node.MassFlowRateMaxAvail); - first_branch_inlet_node.MassFlowRateMinAvail = max(first_branch_inlet_node.MassFlowRateMinAvail, - ParallelBranchMinAvail); - first_branch_inlet_node.MassFlowRateMinAvail = - max(first_branch_inlet_node.MassFlowRateMinAvail, last_branch_inlet_node.MassFlowRateMinAvail); - last_branch_inlet_node.MassFlowRateMinAvail = first_branch_inlet_node.MassFlowRateMinAvail; - last_branch_inlet_node.MassFlowRateMaxAvail = first_branch_inlet_node.MassFlowRateMaxAvail; - - // Initialize the remaining flow variable - FlowRemaining = ThisLoopSideFlow; - - // Initialize flow on passive, bypass and uncontrolled parallel branches to zero. For these branches - // MinAvail is not enforced - for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { - SplitterBranchOut = this_loopside.Splitter.BranchNumOut(OutletNum); - FirstNodeOnBranch = this_loopside.Branch(SplitterBranchOut).NodeNumIn; - if (this_loopside.Branch(SplitterBranchOut).ControlType != ControlType_Active && - this_loopside.Branch(SplitterBranchOut).ControlType != ControlType_SeriesActive) { - Node(FirstNodeOnBranch).MassFlowRate = 0.0; - DataPlant::PlantLoop(LoopNum).loopSolver.PushBranchFlowCharacteristics( - LoopNum, LoopSideNum, SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, - FirstHVACIteration); - } - } - - // IF SUFFICIENT FLOW TO MEET ALL PARALLEL BRANCH FLOW REQUESTS - if (FlowRemaining < MassFlowTolerance) { // no flow available at all for splitter - for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { - SplitterBranchOut = this_loopside.Splitter.BranchNumOut(OutletNum); - for (CompCounter = 1; - CompCounter <= this_loopside.Branch(SplitterBranchOut).TotalComponents; ++CompCounter) { - - FirstNodeOnBranch = this_loopside.Branch(SplitterBranchOut).NodeNumIn; - CompInletNode = this_loopside.Branch(SplitterBranchOut).Comp(CompCounter).NodeNumIn; - CompOutletNode = this_loopside.Branch(SplitterBranchOut).Comp(CompCounter).NodeNumOut; - Node(CompInletNode).MassFlowRate = 0.0; - Node(CompInletNode).MassFlowRateMaxAvail = 0.0; - Node(CompOutletNode).MassFlowRate = 0.0; - Node(CompOutletNode).MassFlowRateMaxAvail = 0.0; - } - } - return; - } else if (FlowRemaining >= TotParallelBranchFlowReq) { - - // 1) Satisfy flow demand of ACTIVE splitter outlet branches - for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { - SplitterBranchOut = this_loopside.Splitter.BranchNumOut(OutletNum); - FirstNodeOnBranch = this_loopside.Branch(SplitterBranchOut).NodeNumIn; - if (this_loopside.Branch(SplitterBranchOut).ControlType == ControlType_Active || - this_loopside.Branch(SplitterBranchOut).ControlType == ControlType_SeriesActive) { - // branch flow is min of requested flow and remaining flow - Node(FirstNodeOnBranch).MassFlowRate = min(Node(FirstNodeOnBranch).MassFlowRate, - FlowRemaining); - if (Node(FirstNodeOnBranch).MassFlowRate < MassFlowTolerance) - Node(FirstNodeOnBranch).MassFlowRate = 0.0; - DataPlant::PlantLoop(LoopNum).loopSolver.PushBranchFlowCharacteristics( - LoopNum, LoopSideNum, SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, - FirstHVACIteration); - FlowRemaining -= Node(FirstNodeOnBranch).MassFlowRate; - if (FlowRemaining < MassFlowTolerance) FlowRemaining = 0.0; - } - } - // IF the active branches take the entire loop flow, return - if (FlowRemaining == 0.0) return; - - // 2) Distribute remaining flow to PASSIVE branches - totalMax = 0.0; - for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { - SplitterBranchOut = this_loopside.Splitter.BranchNumOut(OutletNum); - FirstNodeOnBranch = this_loopside.Branch(SplitterBranchOut).NodeNumIn; - if (this_loopside.Branch(SplitterBranchOut).ControlType == ControlType_Passive) { - // Calculate the total max available - totalMax += Node(FirstNodeOnBranch).MassFlowRateMaxAvail; - } - } - - if (totalMax > 0) { - for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { - SplitterBranchOut = this_loopside.Splitter.BranchNumOut(OutletNum); - FirstNodeOnBranch = this_loopside.Branch(SplitterBranchOut).NodeNumIn; - if (this_loopside.Branch(SplitterBranchOut).ControlType == ControlType_Passive) { - FracFlow = FlowRemaining / totalMax; - if (FracFlow <= 1.0) { // the passive branches will take all the flow - PassiveFlowRate = FracFlow * Node(FirstNodeOnBranch).MassFlowRateMaxAvail; - // Check against FlowRemaining - PassiveFlowRate = min(FlowRemaining, PassiveFlowRate); - // Allow FlowRequest to be increased to meet minimum on branch - PassiveFlowRate = max(PassiveFlowRate, - Node(FirstNodeOnBranch).MassFlowRateMinAvail); - FlowRemaining = max((FlowRemaining - PassiveFlowRate), 0.0); - Node(FirstNodeOnBranch).MassFlowRate = PassiveFlowRate; - } else { // Each Branch receives maximum flow and BYPASS must be used - Node(FirstNodeOnBranch).MassFlowRate = min( - Node(FirstNodeOnBranch).MassFlowRateMaxAvail, FlowRemaining); - FlowRemaining -= Node(FirstNodeOnBranch).MassFlowRate; - } - DataPlant::PlantLoop(LoopNum).loopSolver.PushBranchFlowCharacteristics( - LoopNum, LoopSideNum, SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, - FirstHVACIteration); - } - } - } // totalMax <=0 and flow should be assigned to active branches - // IF the passive branches take the remaining loop flow, return - if (FlowRemaining == 0.0) return; - - // 3) Distribute remaining flow to the BYPASS - for (OutletNum = 1; OutletNum <= this_loopside.Splitter.TotalOutletNodes; ++OutletNum) { - SplitterBranchOut = this_loopside.Splitter.BranchNumOut(OutletNum); - FirstNodeOnBranch = this_loopside.Branch(SplitterBranchOut).NodeNumIn; - if (this_loopside.Branch(SplitterBranchOut).ControlType == ControlType_Bypass) { - Node(FirstNodeOnBranch).MassFlowRate = min(FlowRemaining, - Node(FirstNodeOnBranch).MassFlowRateMaxAvail); - DataPlant::PlantLoop(LoopNum).loopSolver.PushBranchFlowCharacteristics( - LoopNum, LoopSideNum, SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, - FirstHVACIteration); - FlowRemaining -= Node(FirstNodeOnBranch).MassFlowRate; - } - } - // IF the bypass take the remaining loop flow, return - if (FlowRemaining == 0.0) return; - - // 4) If PASSIVE branches and BYPASS are at max and there's still flow, distribute remaining flow to ACTIVE branches but only those - // that had a non-zero flow request. Try to leave branches off that wanted to be off. - if (NumActiveBranches > 0) { - ActiveFlowRate = FlowRemaining / NumActiveBranches; // denominator now only includes active branches that wanted to be "on" - for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { - SplitterBranchOut = this_loopside.Splitter.BranchNumOut(OutletNum); - FirstNodeOnBranch = this_loopside.Branch(SplitterBranchOut).NodeNumIn; - bool branchIsActive = this_loopside.Branch(SplitterBranchOut).ControlType == ControlType_Active; - bool branchIsSeriesActiveAndRequesting = this_loopside.Branch(SplitterBranchOut).ControlType == ControlType_SeriesActive && this_loopside.Branch(SplitterBranchOut).RequestedMassFlow > 0.0; - if (branchIsActive || branchIsSeriesActiveAndRequesting) { // only series active branches that want to be "on" - // check Remaining flow (should be correct!) - ActiveFlowRate = min(ActiveFlowRate, FlowRemaining); - // set the flow rate to the MIN((MassFlowRate+AvtiveFlowRate), MaxAvail) - StartingFlowRate = Node(FirstNodeOnBranch).MassFlowRate; - Node(FirstNodeOnBranch).MassFlowRate = - min((Node(FirstNodeOnBranch).MassFlowRate + ActiveFlowRate), - Node(FirstNodeOnBranch).MassFlowRateMaxAvail); - DataPlant::PlantLoop(LoopNum).loopSolver.PushBranchFlowCharacteristics( - LoopNum, LoopSideNum, SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, - FirstHVACIteration); - // adjust the remaining flow - FlowRemaining -= (Node(FirstNodeOnBranch).MassFlowRate - StartingFlowRate); - } - if (FlowRemaining == 0) break; - } - // IF the active branches take the remaining loop flow, return - if (FlowRemaining == 0.0) return; - - // 5) Step 4) could have left ACTIVE branches < MaxAvail. Check to makes sure all ACTIVE branches are at MaxAvail - for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { - SplitterBranchOut = this_loopside.Splitter.BranchNumOut(OutletNum); - FirstNodeOnBranch = this_loopside.Branch(SplitterBranchOut).NodeNumIn; - if (this_loopside.Branch(SplitterBranchOut).ControlType == ControlType_Active || - this_loopside.Branch(SplitterBranchOut).ControlType == ControlType_SeriesActive) { - StartingFlowRate = Node(FirstNodeOnBranch).MassFlowRate; - ActiveFlowRate = min(FlowRemaining, - (Node(FirstNodeOnBranch).MassFlowRateMaxAvail - StartingFlowRate)); - FlowRemaining -= ActiveFlowRate; - Node(FirstNodeOnBranch).MassFlowRate = StartingFlowRate + ActiveFlowRate; - DataPlant::PlantLoop(LoopNum).loopSolver.PushBranchFlowCharacteristics( - LoopNum, LoopSideNum, SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, - FirstHVACIteration); - } - } - } - // IF the active branches take the remaining loop flow, return - if (FlowRemaining == 0.0) return; - - // 6) Adjust Inlet branch and outlet branch flow rates to match parallel branch rate - // DSU? do we need this logic? or should we fatal on a diagnostic error - TotParallelBranchFlowReq = 0.0; - for (iBranch = 1; iBranch <= NumSplitOutlets; ++iBranch) { - BranchNum = this_loopside.Splitter.BranchNumOut(iBranch); - FirstNodeOnBranch = this_loopside.Branch(BranchNum).NodeNumIn; - // calculate parallel branch flow rate - TotParallelBranchFlowReq += Node(FirstNodeOnBranch).MassFlowRate; - } - // Reset the flow on the splitter inlet branch - SplitterBranchIn = this_loopside.Splitter.BranchNumIn; - FirstNodeOnBranchIn = this_loopside.Branch(SplitterBranchIn).NodeNumIn; - Node(FirstNodeOnBranchIn).MassFlowRate = TotParallelBranchFlowReq; - PushBranchFlowCharacteristics(LoopNum, LoopSideNum, SplitterBranchIn, - Node(FirstNodeOnBranchIn).MassFlowRate, FirstHVACIteration); - // Reset the flow on the Mixer outlet branch - MixerBranchOut = this_loopside.Mixer.BranchNumOut; - FirstNodeOnBranchOut = this_loopside.Branch(MixerBranchOut).NodeNumIn; - Node(FirstNodeOnBranchOut).MassFlowRate = TotParallelBranchFlowReq; - PushBranchFlowCharacteristics(LoopNum, LoopSideNum, MixerBranchOut, - Node(FirstNodeOnBranchOut).MassFlowRate, FirstHVACIteration); - return; - - // IF INSUFFICIENT FLOW TO MEET ALL PARALLEL BRANCH FLOW REQUESTS - } else if (FlowRemaining < TotParallelBranchFlowReq) { - - // DSU? didn't take the time to figure out what this should be... SplitterFlowIn = SplitterInletFlow(SplitNum) - // 1) apportion flow based on requested fraction of total - for (OutletNum = 1; OutletNum <= NumSplitOutlets; ++OutletNum) { - - SplitterBranchOut = this_loopside.Splitter.BranchNumOut(OutletNum); - ThisBranchRequest = DetermineBranchFlowRequest(LoopNum, LoopSideNum, SplitterBranchOut); - FirstNodeOnBranch = this_loopside.Branch(SplitterBranchOut).NodeNumIn; - auto &this_splitter_outlet_branch(this_loopside.Branch(SplitterBranchOut)); - - if ((this_splitter_outlet_branch.ControlType == ControlType_Active) || - (this_splitter_outlet_branch.ControlType == ControlType_SeriesActive)) { - - // since we are calculating this fraction based on the total parallel request calculated above, we must mimic the logic to - // make sure the math works every time that means we must make the variable speed pump correction here as well. - for (CompCounter = 1; - CompCounter <= this_splitter_outlet_branch.TotalComponents; ++CompCounter) { - - auto &this_comp(this_splitter_outlet_branch.Comp(CompCounter)); - - // if this isn't a variable speed pump then just keep cycling - if ((this_comp.TypeOf_Num != TypeOf_PumpVariableSpeed) && - (this_comp.TypeOf_Num != TypeOf_PumpBankVariableSpeed)) { - continue; - } - - CompInletNode = this_comp.NodeNumIn; - ThisBranchRequest = max(ThisBranchRequest, Node(CompInletNode).MassFlowRateRequest); - } - - ThisBranchRequestFrac = ThisBranchRequest / TotParallelBranchFlowReq; - // FracFlow = Node(FirstNodeOnBranch)%MassFlowRate/TotParallelBranchFlowReq - // Node(FirstNodeOnBranch)%MassFlowRate = MIN((FracFlow * Node(FirstNodeOnBranch)%MassFlowRate),FlowRemaining) - Node(FirstNodeOnBranch).MassFlowRate = ThisBranchRequestFrac * ThisLoopSideFlow; - DataPlant::PlantLoop(LoopNum).loopSolver.PushBranchFlowCharacteristics( - LoopNum, LoopSideNum, SplitterBranchOut, Node(FirstNodeOnBranch).MassFlowRate, - FirstHVACIteration); - FlowRemaining -= Node(FirstNodeOnBranch).MassFlowRate; - } - } - - // 1b) check if flow all apportioned - if (FlowRemaining > MassFlowTolerance) { - // Call fatal diagnostic error. !The math should work out! - ShowSevereError("ResolveParallelFlows: Dev note, failed to redistribute restricted flow"); - ShowContinueErrorTimeStamp(""); - ShowContinueError("Loop side flow = " + RoundSigDigits(ThisLoopSideFlow, 8) + " (kg/s)"); - ShowContinueError("Flow Remaining = " + RoundSigDigits(FlowRemaining, 8) + " (kg/s)"); - ShowContinueError("Parallel Branch requests = " + RoundSigDigits(TotParallelBranchFlowReq, 8) + - " (kg/s)"); - } - - // 2) ! Reset the flow on the Mixer outlet branch - MixerBranchOut = this_loopside.Mixer.BranchNumOut; - FirstNodeOnBranchOut = this_loopside.Branch(MixerBranchOut).NodeNumIn; - Node(FirstNodeOnBranchOut).MassFlowRate = TotParallelBranchFlowReq; - DataPlant::PlantLoop(LoopNum).loopSolver.PushBranchFlowCharacteristics( - LoopNum, LoopSideNum, MixerBranchOut, Node(FirstNodeOnBranchOut).MassFlowRate, - FirstHVACIteration); - - } // Total flow requested >= or < Total parallel request - - } // Splitter/Mixer exists - } - - Real64 PlantLoopSolverClass::DetermineBranchFlowRequest(int const LoopNum, int const LoopSideNum, - int const BranchNum) { - - // SUBROUTINE INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN September 2010 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // This routine will analyze the given branch and determine the representative - // flow request. - - // METHODOLOGY EMPLOYED: - // Several possibilities are available. In any case, the request is constrained to within - // branch outlet min/max avail. This assumes that the component flow routines will properly - // propagate the min/max avail down the branch. - // Some possibilities for flow request are: - // 1) take the outlet flow rate -- assumes that the last component wins - // 2) take the inlet flow rate request -- assumes that the request is propogated up and is good - // 3) take the maximum request - // 4) move down the loop and take the maximum "non-load-range-based" request within min/max avail bounds - // This assumes that load range based should not request flow for load-rejection purposes, and we - // should only "respond" to other component types. - - auto &this_branch(DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum)); - int const BranchInletNodeNum = this_branch.NodeNumIn; - int const BranchOutletNodeNum = this_branch.NodeNumOut; - Real64 OverallFlowRequest = 0.0; - - if (this_branch.ControlType != DataBranchAirLoopPlant::ControlType_SeriesActive) { - OverallFlowRequest = DataLoopNode::Node(BranchInletNodeNum).MassFlowRateRequest; - } else { // is series active, so take largest request of all the component inlet nodes - for (int CompCounter = 1; CompCounter <= this_branch.TotalComponents; ++CompCounter) { - int const CompInletNode = this_branch.Comp(CompCounter).NodeNumIn; - OverallFlowRequest = max(OverallFlowRequest, DataLoopNode::Node(CompInletNode).MassFlowRateRequest); - } - } - - //~ Now use a worker to bound the value to outlet min/max avail - OverallFlowRequest = PlantUtilities::BoundValueToNodeMinMaxAvail(OverallFlowRequest, BranchOutletNodeNum); - - return OverallFlowRequest; - - // this block below used to allow testing out different request calculation methods, I've pulled the - // InletFlowRequest method above and commented these out so that future experimentation could be done easily -// int const OutletFlowRate(1); -// int const InletFlowRequest(2); -// int const MaximumRequest(3); -// int const MaxNonLRBRequest(4); -// int const WhichRequestCalculation(InletFlowRequest); -// -// switch (WhichRequestCalculation) { -// -// case OutletFlowRate: -// OverallFlowRequest = Node(BranchOutletNodeNum).MassFlowRate; -// break; -// case InletFlowRequest: -// if (this_branch.ControlType != ControlType_SeriesActive) { -// OverallFlowRequest = Node(BranchInletNodeNum).MassFlowRateRequest; -// } else { // is series active, so take largest request of all the component inlet nodes -// for (CompCounter = 1; CompCounter <= this_branch.TotalComponents; ++CompCounter) { -// CompInletNode = this_branch.Comp(CompCounter).NodeNumIn; -// OverallFlowRequest = max(OverallFlowRequest, Node(CompInletNode).MassFlowRateRequest); -// } -// } -// break; -// -// case MaximumRequest: -// // Assumes component inlet node is where request is held...could bandaid to include outlet node, but trying not to... -// for (CompCounter = 1; CompCounter <= this_branch.TotalComponents; ++CompCounter) { -// CompInletNode = this_branch.Comp(CompCounter).NodeNumIn; -// OverallFlowRequest = max(OverallFlowRequest, Node(CompInletNode).MassFlowRateRequest); -// } -// break; -// -// case MaxNonLRBRequest: -// // Assumes component inlet node is where request is held...could bandaid to include outlet node, but trying not to... -// for (CompCounter = 1; CompCounter <= this_branch.TotalComponents; ++CompCounter) { -// { -// auto const SELECT_CASE_var1(this_branch.Comp(CompCounter).CurOpSchemeType); -// if ((SELECT_CASE_var1 >= LoadRangeBasedMin) && (SELECT_CASE_var1 <= LoadRangeBasedMax)) { -// // don't include this request -// } else { -// // include this -// CompInletNode = this_branch.Comp(CompCounter).NodeNumIn; -// OverallFlowRequest = max(OverallFlowRequest, Node(CompInletNode).MassFlowRateRequest); -// } -// } -// } -// break; -// -// } - - - } - - void PlantLoopSolverClass::PushBranchFlowCharacteristics(int const LoopNum, - int const LoopSideNum, - int const BranchNum, - Real64 const ValueToPush, - bool const FirstHVACIteration // TRUE if First HVAC iteration of Time step - ) { - - // SUBROUTINE INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN September 2010 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // This routine takes the flow resolved flow rate and pushes it - // down a branch. In the process, if an externally connected - // component (air-water coil for example) is found to have a - // differing flow rate, the air sim flag is tripped to true, but - // the flow resolved flow rate is pushed down the loop to allow - // the plant to finish successfully. - - // METHODOLOGY EMPLOYED: - // Push mass flow rate and max avail down each branch. If the component - // is connected (or could be, for now) to an external loop such as - // an air loop, the current component outlet mass flow is checked - // vs the current resolved mass flow. If the mass flow doesn't match, - // the air sim flag is tripped to true. - - // Currently this routine is only performed for starved branches, when - // the coil is requesting too much flow, more than the plant can provide. - // If this were moved to every call type, including a minimum plant flow, - // you would need to provide a mass flow and min/max avail to push - // down the branch as well. - - // Using/Aliasing - using namespace DataPlant; // Use the entire module to allow all TypeOf's, would be a huge ONLY list - using DataBranchAirLoopPlant::MassFlowTolerance; - using DataLoopNode::Node; - using PlantUtilities::CheckPlantConvergence; - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int CompCounter; - int BranchInletNode; - int BranchOutletNode; - int ComponentInletNode; - int ComponentOutletNode; - int ComponentTypeOfNum; - Real64 MassFlowRateFound; - Real64 MassFlow; - bool PlantIsRigid; - - auto &this_loopside(PlantLoop(LoopNum).LoopSide(LoopSideNum)); - auto &this_branch(this_loopside.Branch(BranchNum)); - - BranchInletNode = this_branch.NodeNumIn; - BranchOutletNode = this_branch.NodeNumOut; - - //~ Possible error handling if needed - if (ValueToPush != Node(BranchInletNode).MassFlowRate) { - // Diagnostic problem, flow resolver isn't calling this routine properly - } - - //~ This section would really be useful more later on if this routine has more logic regarding what to push down the branch - MassFlow = ValueToPush; - // MinAvail = ValueToPush - // MaxAvail = ValueToPush - - PlantIsRigid = CheckPlantConvergence(LoopNum, LoopSideNum, FirstHVACIteration); - - //~ Loop across all component outlet nodes and update their mass flow and max avail - for (CompCounter = 1; CompCounter <= this_branch.TotalComponents; ++CompCounter) { - - auto &this_comp(this_branch.Comp(CompCounter)); - - //~ Pick up some values for convenience - ComponentInletNode = this_comp.NodeNumIn; - ComponentOutletNode = this_comp.NodeNumOut; - MassFlowRateFound = Node(ComponentOutletNode).MassFlowRate; - ComponentTypeOfNum = this_comp.TypeOf_Num; - - //~ Push the values through - Node(ComponentOutletNode).MassFlowRate = MassFlow; - - if (PlantIsRigid) { - Node(ComponentInletNode).MassFlowRateMinAvail = MassFlow; - Node(ComponentInletNode).MassFlowRateMaxAvail = MassFlow; - Node(ComponentOutletNode).MassFlowRateMinAvail = MassFlow; - Node(ComponentOutletNode).MassFlowRateMaxAvail = MassFlow; - } - // Node(ComponentOutletNode)%MassFlowRateMinAvail = MinAvail - // no this is 2-way valve which messes up flow options - // for demand components Node(ComponentOutletNode)%MassFlowRateMaxAvail = MaxAvail - - //~ If this value matches then we are good to move to the next component - if (std::abs(MassFlow - MassFlowRateFound) < CriteriaDelta_MassFlowRate) continue; - //~ Since there is a difference, we have to decide what to do based on the component type: - //~ For plant connections, don't do anything, it SHOULD work itself out - //~ For air connections, trip the LoopSide air flag - //~ Similar for zone, none zone, and electric load center - { - auto const SELECT_CASE_var(ComponentTypeOfNum); - - // possibly air-connected components - if ((SELECT_CASE_var == TypeOf_CoilWaterCooling) || - (SELECT_CASE_var == TypeOf_CoilWaterDetailedFlatCooling) || - (SELECT_CASE_var == TypeOf_CoilWaterSimpleHeating) || - (SELECT_CASE_var == TypeOf_CoilSteamAirHeating) || - (SELECT_CASE_var == TypeOf_CoilWAHPHeatingEquationFit) || - (SELECT_CASE_var == TypeOf_CoilWAHPCoolingEquationFit) || - (SELECT_CASE_var == TypeOf_CoilWAHPHeatingParamEst) || - (SELECT_CASE_var == TypeOf_CoilWAHPCoolingParamEst) || - (SELECT_CASE_var == TypeOf_CoilUserDefined) || - (SELECT_CASE_var == TypeOf_CoilVSWAHPCoolingEquationFit) || - (SELECT_CASE_var == TypeOf_CoilVSWAHPHeatingEquationFit) || - (SELECT_CASE_var == TypeOf_PackagedTESCoolingCoil)) { - - this_loopside.SimAirLoopsNeeded = true; - // sometimes these coils are children in ZoneHVAC equipment - // PlantLoop(LoopNum)%LoopSide(LoopSideNum)%SimZoneEquipNeeded= .TRUE. - - } else if ((SELECT_CASE_var == TypeOf_CoolingPanel_Simple) || - (SELECT_CASE_var == TypeOf_Baseboard_Conv_Water) || - (SELECT_CASE_var == TypeOf_Baseboard_Rad_Conv_Steam) || - (SELECT_CASE_var == TypeOf_Baseboard_Rad_Conv_Water) || - (SELECT_CASE_var == TypeOf_LowTempRadiant_VarFlow) || - (SELECT_CASE_var == TypeOf_LowTempRadiant_ConstFlow) || - (SELECT_CASE_var == TypeOf_CooledBeamAirTerminal) || - (SELECT_CASE_var == TypeOf_ZoneHVACAirUserDefined) || - (SELECT_CASE_var == TypeOf_AirTerminalUserDefined) || - (SELECT_CASE_var == TypeOf_FourPipeBeamAirTerminal)) { // zone connected components - - this_loopside.SimZoneEquipNeeded = true; - - } else if ((SELECT_CASE_var == TypeOf_Generator_FCExhaust) || - (SELECT_CASE_var == TypeOf_Generator_FCStackCooler) || - (SELECT_CASE_var == TypeOf_Generator_MicroCHP) || - (SELECT_CASE_var == TypeOf_Generator_MicroTurbine) || - (SELECT_CASE_var == TypeOf_Generator_ICEngine) || - (SELECT_CASE_var == TypeOf_Generator_CTurbine)) { // electric center connected components - - this_loopside.SimElectLoadCentrNeeded = true; - } - } - } - } - - void PlantLoopSolverClass::UpdateLoopSideReportVars( - int const LoopNum, - int const LoopSide, - Real64 const OtherSideDemand, // This is the 'other side' demand, based on other side flow - Real64 const LocalRemLoopDemand // Unmet Demand after equipment has been simulated (report variable) - ) { - - // SUBROUTINE INFORMATION: - // AUTHOR Dan Fisher - // DATE WRITTEN July 1998 - // MODIFIED Aug 2010 Edwin Lee -- add per LoopSide variable support - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // Update the report variables - - // Using/Aliasing - using DataLoopNode::Node; - using DataPlant::PlantLoop; - using DataPlant::PlantReport; - using DataPlant::SupplySide; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - // and delta T (inlet to SetPt) - // This is evaluated once at the beginning of the loop side solver, before - // any of this side equipment alters it - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - auto &this_supplyside(PlantLoop(LoopNum).LoopSide(SupplySide)); - auto &this_loop_report(PlantReport(LoopNum)); - - if (LoopSide == SupplySide) { - this_loop_report.InletNodeFlowrate = Node(this_supplyside.NodeNumIn).MassFlowRate; - this_loop_report.InletNodeTemperature = Node(this_supplyside.NodeNumIn).Temp; - this_loop_report.OutletNodeFlowrate = Node(this_supplyside.NodeNumOut).MassFlowRate; - this_loop_report.OutletNodeTemperature = Node(this_supplyside.NodeNumOut).Temp; - - // In the baseline code, only reported supply side demand. so putting in "SupplySide" IF block for now but might expand later - if (OtherSideDemand < 0.0) { - this_loop_report.CoolingDemand = std::abs(OtherSideDemand); - this_loop_report.HeatingDemand = 0.0; - this_loop_report.DemandNotDispatched = -LocalRemLoopDemand; // Setting sign based on old logic for now - } else { - this_loop_report.HeatingDemand = OtherSideDemand; - this_loop_report.CoolingDemand = 0.0; - this_loop_report.DemandNotDispatched = LocalRemLoopDemand; // Setting sign based on old logic for now - } - - DataPlant::PlantLoop(LoopNum).loopSolver.CalcUnmetPlantDemand(LoopNum, LoopSide); - } - } - - void PlantLoopSolverClass::CalcUnmetPlantDemand(int const LoopNum, int const LoopSideNum) { - - // SUBROUTINE INFORMATION: - // AUTHOR Brent Griffith - // DATE WRITTEN June 2011 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // determine the magnitude of unmet plant loads after the half loop simulation is done - - // METHODOLOGY EMPLOYED: - // using the loop setpoint node, look at target vs current and - // calculate a demand based on mass flow times specific heat times delta T - - // Using/Aliasing - using DataBranchAirLoopPlant::MassFlowTolerance; - using DataLoopNode::Node; - using DataLoopNode::NodeType_Steam; - using DataLoopNode::NodeType_Water; - using DataPlant::DualSetPointDeadBand; - using DataPlant::LoopDemandTol; - using DataPlant::PlantLoop; - using DataPlant::PlantReport; - using DataPlant::SingleSetPoint; - using FluidProperties::GetSatEnthalpyRefrig; - using FluidProperties::GetSpecificHeatGlycol; - - // SUBROUTINE PARAMETER DEFINITIONS: - static std::string const RoutineName("PlantLoopSolver::EvaluateLoopSetPointLoad"); - static std::string const RoutineNameAlt("PlantSupplySide:EvaluateLoopSetPointLoad"); - - //~ General variables - Real64 MassFlowRate; - Real64 TargetTemp; - Real64 LoopSetPointTemperature; - Real64 LoopSetPointTemperatureHi; - Real64 LoopSetPointTemperatureLo; - Real64 LoadToHeatingSetPoint; - Real64 LoadToCoolingSetPoint; - Real64 DeltaTemp; - Real64 Cp; - Real64 EnthalpySteamSatVapor; // Enthalpy of saturated vapor - Real64 EnthalpySteamSatLiquid; // Enthalpy of saturated liquid - Real64 LatentHeatSteam; // Latent heat of steam - Real64 LoadToLoopSetPoint; - - // Initialize - LoadToLoopSetPoint = 0.0; - auto &this_loop(PlantLoop(LoopNum)); - - // Get temperature at loop setpoint node. - TargetTemp = Node(this_loop.TempSetPointNodeNum).Temp; - MassFlowRate = Node(this_loop.TempSetPointNodeNum).MassFlowRate; - - if (this_loop.FluidType == NodeType_Water) { - - Cp = GetSpecificHeatGlycol(this_loop.FluidName, TargetTemp, this_loop.FluidIndex, RoutineName); - - { - auto const SELECT_CASE_var(this_loop.LoopDemandCalcScheme); - - if (SELECT_CASE_var == SingleSetPoint) { - - // Pick up the loop setpoint temperature - LoopSetPointTemperature = this_loop.LoopSide(LoopSideNum).TempSetPoint; - // Calculate the delta temperature - DeltaTemp = LoopSetPointTemperature - TargetTemp; - - // Calculate the demand on the loop - LoadToLoopSetPoint = MassFlowRate * Cp * DeltaTemp; - - } else if (SELECT_CASE_var == DualSetPointDeadBand) { - - // Get the range of setpoints - LoopSetPointTemperatureHi = Node(this_loop.TempSetPointNodeNum).TempSetPointHi; - LoopSetPointTemperatureLo = Node(this_loop.TempSetPointNodeNum).TempSetPointLo; - - // Calculate the demand on the loop - if (MassFlowRate > 0.0) { - LoadToHeatingSetPoint = MassFlowRate * Cp * (LoopSetPointTemperatureLo - TargetTemp); - LoadToCoolingSetPoint = MassFlowRate * Cp * (LoopSetPointTemperatureHi - TargetTemp); - // Possible combinations: - // 1 LoadToHeatingSetPoint > 0 & LoadToCoolingSetPoint > 0 --> Heating required - // 2 LoadToHeatingSetPoint < 0 & LoadToCoolingSetPoint < 0 --> Cooling Required - // 3 LoadToHeatingSetPoint <=0 & LoadToCoolingSetPoint >=0 --> Dead Band Operation - includes zero load cases - // 4 LoadToHeatingSetPoint > LoadToCoolingSetPoint --> Not Feasible if LoopSetPointHi >= LoopSetPointLo - if (LoadToHeatingSetPoint > 0.0 && LoadToCoolingSetPoint > 0.0) { - LoadToLoopSetPoint = LoadToHeatingSetPoint; - } else if (LoadToHeatingSetPoint < 0.0 && LoadToCoolingSetPoint < 0.0) { - LoadToLoopSetPoint = LoadToCoolingSetPoint; - } else if (LoadToHeatingSetPoint <= 0.0 && - LoadToCoolingSetPoint >= 0.0) { // deadband includes zero loads - LoadToLoopSetPoint = 0.0; - } - } else { - LoadToLoopSetPoint = 0.0; - } - } - } - - } else if (this_loop.FluidType == NodeType_Steam) { - - Cp = GetSpecificHeatGlycol(this_loop.FluidName, TargetTemp, this_loop.FluidIndex, RoutineName); - - { - auto const SELECT_CASE_var(this_loop.LoopDemandCalcScheme); - - if (SELECT_CASE_var == SingleSetPoint) { - - // Pick up the loop setpoint temperature - LoopSetPointTemperature = this_loop.LoopSide(LoopSideNum).TempSetPoint; - - // Calculate the delta temperature - DeltaTemp = LoopSetPointTemperature - TargetTemp; - - EnthalpySteamSatVapor = GetSatEnthalpyRefrig(fluidNameSteam, LoopSetPointTemperature, 1.0, - RefrigIndex, RoutineNameAlt); - EnthalpySteamSatLiquid = GetSatEnthalpyRefrig(fluidNameSteam, LoopSetPointTemperature, 0.0, - RefrigIndex, RoutineNameAlt); - - LatentHeatSteam = EnthalpySteamSatVapor - EnthalpySteamSatLiquid; - - // Calculate the demand on the loop - LoadToLoopSetPoint = MassFlowRate * (Cp * DeltaTemp + LatentHeatSteam); - } - } - - } else { // only have two types, water serves for glycol. - } - - // Trim the demand to zero if it is very small - if (std::abs(LoadToLoopSetPoint) < LoopDemandTol) LoadToLoopSetPoint = 0.0; - - PlantReport(LoopNum).UnmetDemand = LoadToLoopSetPoint; - } - - void PlantLoopSolverClass::CheckLoopExitNode(int const LoopNum, // plant loop counter - bool const FirstHVACIteration // TRUE if First HVAC iteration of Time step - ) { - - // SUBROUTINE INFORMATION: - // AUTHOR Dan Fisher - // DATE WRITTEN October 1998 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // This subroutine sets the temperature - // and mass flow rate of the plant loop supply side exit - // node. As written, the routine calculates the exit - // temperature based on the fraction of loop demand met - // by the plant equipment. This assumes that each piece - // of operating plant equipment produced chilled/hot water - // at the loop setpoint temperature. - - // Using/Aliasing - using DataBranchAirLoopPlant::MassFlowTolerance; - using DataGlobals::WarmupFlag; - using DataLoopNode::Node; - using DataLoopNode::NodeID; - using DataPlant::DemandSide; - using DataPlant::PlantLoop; - using DataPlant::SupplySide; - using General::RoundSigDigits; - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int LoopInlet; // plant loop inlet node num. - int LoopOutlet; // plant loop outlet node num. - - // set local variables: loop inlet and outlet nodes - LoopInlet = PlantLoop(LoopNum).LoopSide(SupplySide).NodeNumIn; - LoopOutlet = PlantLoop(LoopNum).LoopSide(SupplySide).NodeNumOut; - // Check continuity invalid...loop pumps now turned on and off - if (!FirstHVACIteration && !WarmupFlag) { - if (std::abs(Node(LoopOutlet).MassFlowRate - Node(LoopInlet).MassFlowRate) > MassFlowTolerance) { - if (PlantLoop(LoopNum).MFErrIndex == 0) { - ShowWarningError("PlantSupplySide: PlantLoop=\"" + PlantLoop(LoopNum).Name + - "\", Error (CheckLoopExitNode) -- Mass Flow Rate Calculation. Outlet and Inlet differ by more than tolerance."); - ShowContinueErrorTimeStamp(""); - ShowContinueError("Loop inlet node=" + NodeID(LoopInlet) + ", flowrate=" + - RoundSigDigits(Node(LoopInlet).MassFlowRate, 4) + - " kg/s"); - ShowContinueError("Loop outlet node=" + NodeID(LoopOutlet) + ", flowrate=" + - RoundSigDigits(Node(LoopOutlet).MassFlowRate, 4) + - " kg/s"); - ShowContinueError("This loop might be helped by a bypass."); - } - ShowRecurringWarningErrorAtEnd("PlantSupplySide: PlantLoop=\"" + PlantLoop(LoopNum).Name + - "\", Error -- Mass Flow Rate Calculation -- continues ** ", - PlantLoop(LoopNum).MFErrIndex); - } - } - // Reset Max loop flow rate based on pump performance - Node(LoopOutlet).MassFlowRateMax = Node(LoopInlet).MassFlowRateMax; - } - - void PlantLoopSolverClass::AdjustPumpFlowRequestByEMSControls( - int const LoopNum, int const LoopSideNum, int const BranchNum, int const CompNum, - Real64 &FlowToRequest) { - - // SUBROUTINE INFORMATION: - // AUTHOR Brent Griffith - // DATE WRITTEN April 2012 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // modify flow request to pump simulation if EMS is overriding pump component - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - auto &this_loopside(DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum)); - auto &this_branch(this_loopside.Branch(BranchNum)); - auto &this_comp(this_branch.Comp(CompNum)); - - if ((this_loopside.EMSCtrl) && (this_loopside.EMSValue <= 0.0)) { - FlowToRequest = 0.0; - return; - } - - if ((this_branch.EMSCtrlOverrideOn) && (this_branch.EMSCtrlOverrideValue <= 0.0)) { - FlowToRequest = 0.0; - return; - } - - if (this_comp.EMSLoadOverrideOn) { - if (this_comp.EMSLoadOverrideValue == 0.0) { - FlowToRequest = 0.0; - } - } - } - - } // namespace PlantLoopSolver - -} // namespace EnergyPlus diff --git a/src/EnergyPlus/Plant/PlantLoopSolver.hh b/src/EnergyPlus/Plant/PlantLoopSolver.hh deleted file mode 100644 index e0470e32400..00000000000 --- a/src/EnergyPlus/Plant/PlantLoopSolver.hh +++ /dev/null @@ -1,171 +0,0 @@ -// EnergyPlus, Copyright (c) 1996-2020, The Board of Trustees of the University of Illinois, -// The Regents of the University of California, through Lawrence Berkeley National Laboratory -// (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge -// National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other -// contributors. All rights reserved. -// -// NOTICE: This Software was developed under funding from the U.S. Department of Energy and the -// U.S. Government consequently retains certain rights. As such, the U.S. Government has been -// granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, -// worldwide license in the Software to reproduce, distribute copies to the public, prepare -// derivative works, and perform publicly and display publicly, and to permit others to do so. -// -// Redistribution and use in source and binary forms, with or without modification, are permitted -// provided that the following conditions are met: -// -// (1) Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// (2) Redistributions in binary form must reproduce the above copyright notice, this list of -// conditions and the following disclaimer in the documentation and/or other materials -// provided with the distribution. -// -// (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, -// the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific prior -// written permission. -// -// (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form -// without changes from the version obtained under this License, or (ii) Licensee makes a -// reference solely to the software portion of its product, Licensee must refer to the -// software as "EnergyPlus version X" software, where "X" is the version number Licensee -// obtained under this License and may not use a different name for the software. Except as -// specifically required in this Section (4), Licensee shall not use in a company name, a -// product name, in advertising, publicity, or other promotional activities any name, trade -// name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly -// similar designation, without the U.S. Department of Energy's prior written consent. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef PlantLoopSolver_hh_INCLUDED -#define PlantLoopSolver_hh_INCLUDED - -// ObjexxFCL Headers -#include -#include - -// EnergyPlus Headers -#include -#include - -namespace EnergyPlus { - -namespace PlantLoopSolver { - - // MODULE VARIABLE DEFINITIONS - extern Real64 InitialDemandToLoopSetPoint; - extern Real64 CurrentAlterationsToDemand; - extern Real64 UpdatedDemandToLoopSetPoint; - extern Real64 LoadToLoopSetPointThatWasntMet; // Unmet Demand - extern Real64 InitialDemandToLoopSetPointSAVED; - extern int RefrigIndex; // Index denoting refrigerant used (possibly steam) - - struct Location - { - // Members - int LoopNum; - int LoopSideNum; - int BranchNum; - int CompNum; - - // Default Constructor - Location() : LoopNum(0), LoopSideNum(0), BranchNum(0), CompNum(0) - { - } - }; - - struct PlantLoopSolverClass - { - - void ValidateFlowControlPaths(int const LoopNum, int const LoopSideNum); - - Real64 SetupLoopFlowRequest(int const LoopNum, int const ThisSide, int const OtherSide); - - Real64 DetermineLoopSideFlowRate(int LoopNum, int ThisSide, int ThisSideInletNode, Real64 ThisSideLoopFlowRequest); - - void SimulateAllLoopSideBranches( - int const LoopNum, int const LoopSideNum, Real64 const ThisLoopSideFlow, bool const FirstHVACIteration, bool &LoopShutDownFlag); - - void SimulateLoopSideBranchGroup(int const LoopNum, - int const LoopSideNum, - int const FirstBranchNum, - int const LastBranchNum, - Real64 const FlowRequest, - bool const FirstHVACIteration, - bool &LoopShutDownFlag); - - void SimulateAllLoopSidePumps(int const LoopNum, - int const ThisSide, - Optional SpecificPumpLocation = _, - Optional SpecificPumpFlowRate = _); - - void SimulateSinglePump(Location const SpecificPumpLocation, Real64 & SpecificPumpFlowRate); - - Real64 CalcOtherSideDemand(int const LoopNum, int const ThisSide, Real64 ThisLoopSideFlow); - - void DisableAnyBranchPumpsConnectedToUnloadedEquipment(int LoopNum, int ThisSide); - - void TurnOnAllLoopSideBranches(DataPlant::HalfLoopData &loop_side); - - void DoFlowAndLoadSolutionPass(int LoopNum, int ThisSide, int OtherSide, int ThisSideInletNode, bool FirstHVACIteration); - - Real64 EvaluateLoopSetPointLoad(int const LoopNum, - int const LoopSideNum, - int const FirstBranchNum, - int const LastBranchNum, - Real64 ThisLoopSideFlow, - Array1S_int LastComponentSimulated); - - void UpdateAnyLoopDemandAlterations(int const LoopNum, int const LoopSideNum, int const BranchNum, int const CompNum); - - void ResolveParallelFlows(int const LoopNum, // plant loop number that we are balancing flow for - int const LoopSideNum, // plant loop number that we are balancing flow for - Real64 const ThisLoopSideFlow, // [kg/s] total flow to be split - bool const FirstHVACIteration // TRUE if First HVAC iteration of Time step - ); - - Real64 DetermineBranchFlowRequest(int const LoopNum, int const LoopSideNum, int const BranchNum); - - void UpdateLoopSideReportVars(int const LoopNum, - int const LoopSide, - Real64 const OtherSideDemand, // This is the 'other side' demand, based on other side flow - Real64 const LocalRemLoopDemand // Unmet Demand after equipment has been simulated (report variable) - ); - - void PushBranchFlowCharacteristics(int const LoopNum, - int const LoopSideNum, - int const BranchNum, - Real64 const ValueToPush, - bool const FirstHVACIteration // TRUE if First HVAC iteration of Time step - ); - - void CalcUnmetPlantDemand(int const LoopNum, int const LoopSideNum); - - void CheckLoopExitNode(int const LoopNum, // plant loop counter - bool const FirstHVACIteration // TRUE if First HVAC iteration of Time step - ); - - void - AdjustPumpFlowRequestByEMSControls(int const LoopNum, int const LoopSideNum, int const BranchNum, int const CompNum, Real64 &FlowToRequest); - }; - - void clear_state(); - - void PlantHalfLoopSolver(bool const FirstHVACIteration, // TRUE if First HVAC iteration of Time step - int const LoopSideNum, - int const LoopNum, - bool &ReSimOtherSideNeeded); - -} // namespace PlantLoopSolver - -} // namespace EnergyPlus - -#endif diff --git a/src/EnergyPlus/Plant/PlantManager.cc b/src/EnergyPlus/Plant/PlantManager.cc index 130b4b6c2d6..91a50d0b9f3 100644 --- a/src/EnergyPlus/Plant/PlantManager.cc +++ b/src/EnergyPlus/Plant/PlantManager.cc @@ -97,14 +97,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include @@ -116,7 +114,6 @@ #include #include #include -#include #include #include #include @@ -151,7 +148,6 @@ namespace EnergyPlus { using namespace DataBranchAirLoopPlant; using namespace DataLoopNode; using namespace FluidProperties; - using PlantLoopSolver::PlantHalfLoopSolver; // MODULE PARAMETER DEFINITIONS int const Plant(1); @@ -165,7 +161,6 @@ namespace EnergyPlus { Array1D_int SupplySideInletNode; // Node number for the supply side inlet Array1D_int SupplySideOutletNode; // Node number for the supply side outlet Array1D_int DemandSideInletNode; // Inlet node on the demand side - TempLoopData TempLoop; // =(' ',' ',' ',0, , , ,.FALSE.,.FALSE.,.FALSE.,.FALSE.,.FALSE.) void clear_state() { InitLoopEquip = true; @@ -173,7 +168,6 @@ namespace EnergyPlus { SupplySideInletNode.deallocate(); SupplySideOutletNode.deallocate(); DemandSideInletNode.deallocate(); - TempLoop = TempLoopData(); } void ManagePlantLoops(bool const FirstHVACIteration, @@ -247,7 +241,7 @@ namespace EnergyPlus { if (SimHalfLoopFlag || IterPlant <= CurntMinPlantSubIterations) { - PlantHalfLoopSolver(FirstHVACIteration, LoopSide, LoopNum, other_loop_side.SimLoopSideNeeded); + this_loop_side.solve(FirstHVACIteration, other_loop_side.SimLoopSideNeeded); // Always set this side to false, so that it won't keep being turned on just because of first hvac this_loop_side.SimLoopSideNeeded = false; @@ -260,7 +254,7 @@ namespace EnergyPlus { } // Update the report variable - PlantReport(LoopNum).LastLoopSideSimulated = LoopSide; + this_loop.LastLoopSideSimulated = LoopSide; ++PlantManageHalfLoopCalls; } @@ -777,7 +771,6 @@ namespace EnergyPlus { int MixNum; int NumConnectorsInLoop; int ConnNum; - std::string::size_type Pos; int TotCompsOnBranch; int MaxNumAlphas; @@ -800,73 +793,62 @@ namespace EnergyPlus { static Array1D_bool SplitOutBranch; static Array1D_bool MixerInBranch; bool errFlag; - int GeneralEquipType; - int TypeOfNum; int LoopNumInArray; inputProcessor->getObjectDefMaxArgs("Connector:Splitter", NumParams, NumAlphas, NumNumbers); MaxNumAlphas = NumAlphas; inputProcessor->getObjectDefMaxArgs("Connector:Mixer", NumParams, NumAlphas, NumNumbers); MaxNumAlphas = max(MaxNumAlphas, NumAlphas); - NumPipes = 0; - NumPlantPipes = 0; - NumCondPipes = 0; HalfLoopNum = 0; - for (LoopNum = 1; LoopNum <= - TotNumLoops; ++LoopNum) { // Begin demand side loops ... When condenser is added becomes NumLoops - TempLoop.LoopHasConnectionComp = false; - TempLoop.Name = PlantLoop(LoopNum).Name; + for (LoopNum = 1; LoopNum <= TotNumLoops; ++LoopNum) { + auto &plantLoop = PlantLoop(LoopNum); + plantLoop.LoopHasConnectionComp = false; for (LoopSideNum = DemandSide; LoopSideNum <= SupplySide; ++LoopSideNum) { + auto &loopSide = plantLoop.LoopSide(LoopSideNum); ASeriesBranchHasPump = false; AParallelBranchHasPump = false; NumOfPipesInLoop = 0; // Initialization ++HalfLoopNum; - TempLoop.BypassExists = false; - if (PlantLoop(LoopNum).TypeOfLoop == Plant && LoopSideNum == DemandSide) { + loopSide.BypassExists = false; + if (plantLoop.TypeOfLoop == Plant && LoopSideNum == DemandSide) { LoopIdentifier = "Plant Demand"; - } else if (PlantLoop(LoopNum).TypeOfLoop == Plant && LoopSideNum == SupplySide) { + } else if (plantLoop.TypeOfLoop == Plant && LoopSideNum == SupplySide) { LoopIdentifier = "Plant Supply"; - } else if (PlantLoop(LoopNum).TypeOfLoop == Condenser && LoopSideNum == DemandSide) { + } else if (plantLoop.TypeOfLoop == Condenser && LoopSideNum == DemandSide) { LoopIdentifier = "Condenser Demand"; - } else if (PlantLoop(LoopNum).TypeOfLoop == Condenser && LoopSideNum == SupplySide) { + } else if (plantLoop.TypeOfLoop == Condenser && LoopSideNum == SupplySide) { LoopIdentifier = "Condenser Supply"; } - TempLoop.BranchList = PlantLoop(LoopNum).LoopSide(LoopSideNum).BranchList; - TempLoop.ConnectList = PlantLoop(LoopNum).LoopSide(LoopSideNum).ConnectList; - // Get the branch list and size the Branch portion of the Loop derived type - TempLoop.TotalBranches = NumBranchesInBranchList(TempLoop.BranchList); - BranchNames.allocate(TempLoop.TotalBranches); + loopSide.TotalBranches = NumBranchesInBranchList(loopSide.BranchList); + BranchNames.allocate(loopSide.TotalBranches); BranchNames = ""; - GetBranchList(TempLoop.Name, TempLoop.BranchList, TempLoop.TotalBranches, BranchNames, - LoopIdentifier); - TempLoop.Branch.allocate(TempLoop.TotalBranches); + GetBranchList(plantLoop.Name, loopSide.BranchList, loopSide.TotalBranches, BranchNames, LoopIdentifier); + loopSide.Branch.allocate(loopSide.TotalBranches); // Cycle through all of the branches and set up the node data - for (BranchNum = 1; BranchNum <= TempLoop.TotalBranches; ++BranchNum) { - - TempLoop.Branch(BranchNum).Name = BranchNames(BranchNum); - - TempLoop.Branch(BranchNum).TotalComponents = NumCompsInBranch(BranchNames(BranchNum)); - - TempLoop.Branch(BranchNum).IsBypass = false; - - CompTypes.allocate(TempLoop.Branch(BranchNum).TotalComponents); - CompNames.allocate(TempLoop.Branch(BranchNum).TotalComponents); - CompCtrls.dimension(TempLoop.Branch(BranchNum).TotalComponents, 0); - InletNodeNames.allocate(TempLoop.Branch(BranchNum).TotalComponents); - InletNodeNumbers.dimension(TempLoop.Branch(BranchNum).TotalComponents, 0); - OutletNodeNames.allocate(TempLoop.Branch(BranchNum).TotalComponents); - OutletNodeNumbers.dimension(TempLoop.Branch(BranchNum).TotalComponents, 0); - - GetBranchData(TempLoop.Name, + for (BranchNum = 1; BranchNum <= loopSide.TotalBranches; ++BranchNum) { + auto &branch = loopSide.Branch(BranchNum); + branch.Name = BranchNames(BranchNum); + branch.TotalComponents = NumCompsInBranch(BranchNames(BranchNum)); + branch.IsBypass = false; + + CompTypes.allocate(branch.TotalComponents); + CompNames.allocate(branch.TotalComponents); + CompCtrls.dimension(branch.TotalComponents, 0); + InletNodeNames.allocate(branch.TotalComponents); + InletNodeNumbers.dimension(branch.TotalComponents, 0); + OutletNodeNames.allocate(branch.TotalComponents); + OutletNodeNumbers.dimension(branch.TotalComponents, 0); + + GetBranchData(plantLoop.Name, BranchNames(BranchNum), - TempLoop.Branch(BranchNum).PressureCurveType, - TempLoop.Branch(BranchNum).PressureCurveIndex, - TempLoop.Branch(BranchNum).TotalComponents, + branch.PressureCurveType, + branch.PressureCurveIndex, + branch.TotalComponents, CompTypes, CompNames, InletNodeNames, @@ -875,59 +857,54 @@ namespace EnergyPlus { OutletNodeNumbers, ErrorsFound); - TempLoop.Branch(BranchNum).Comp.allocate(TempLoop.Branch(BranchNum).TotalComponents); + branch.Comp.allocate(branch.TotalComponents); - for (CompNum = 1; CompNum <= TempLoop.Branch(BranchNum).TotalComponents; ++CompNum) { + for (CompNum = 1; CompNum <= PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum).TotalComponents; ++CompNum) { // set up some references auto &this_comp_type(CompTypes(CompNum)); - auto &this_comp(TempLoop.Branch(BranchNum).Comp(CompNum)); + auto &this_comp(PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(CompNum)); this_comp.CurOpSchemeType = UnknownStatusOpSchemeType; this_comp.TypeOf = this_comp_type; + this_comp.location = EnergyPlus::PlantLocation(LoopNum, LoopSideNum, BranchNum, CompNum); if (UtilityRoutines::SameString(this_comp_type, "Pipe:Adiabatic")) { this_comp.TypeOf_Num = TypeOf_Pipe; - this_comp.GeneralEquipType = GenEquipTypes_Pipe; this_comp.CurOpSchemeType = NoControlOpSchemeType; this_comp.compPtr = Pipes::LocalPipeData::factory(TypeOf_Pipe, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Pipe:Adiabatic:Steam")) { this_comp.TypeOf_Num = TypeOf_PipeSteam; - this_comp.GeneralEquipType = GenEquipTypes_Pipe; this_comp.CurOpSchemeType = NoControlOpSchemeType; this_comp.compPtr = Pipes::LocalPipeData::factory(TypeOf_PipeSteam, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Pipe:Outdoor")) { this_comp.TypeOf_Num = TypeOf_PipeExterior; - this_comp.GeneralEquipType = GenEquipTypes_Pipe; this_comp.CurOpSchemeType = NoControlOpSchemeType; this_comp.compPtr = PipeHeatTransfer::PipeHTData::factory(TypeOf_PipeExterior, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Pipe:Indoor")) { this_comp.TypeOf_Num = TypeOf_PipeInterior; - this_comp.GeneralEquipType = GenEquipTypes_Pipe; this_comp.CurOpSchemeType = NoControlOpSchemeType; this_comp.compPtr = PipeHeatTransfer::PipeHTData::factory(TypeOf_PipeInterior, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Pipe:Underground")) { this_comp.TypeOf_Num = TypeOf_PipeUnderground; - this_comp.GeneralEquipType = GenEquipTypes_Pipe; this_comp.CurOpSchemeType = NoControlOpSchemeType; this_comp.compPtr = PipeHeatTransfer::PipeHTData::factory(TypeOf_PipeUnderground, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "PipingSystem:Underground:PipeCircuit")) { this_comp.TypeOf_Num = TypeOf_PipingSystemPipeCircuit; - this_comp.GeneralEquipType = GenEquipTypes_Pipe; this_comp.CurOpSchemeType = NoControlOpSchemeType; this_comp.compPtr = PlantPipingSystemsManager::Circuit::factory( TypeOf_PipingSystemPipeCircuit, CompNames(CompNum)); } else if (has_prefixi(this_comp_type, "Pump") || has_prefixi(this_comp_type, "HeaderedPumps")) { - if (has_prefixi(this_comp_type, "Pump:VariableSpeed")) { - this_comp.TypeOf_Num = TypeOf_PumpVariableSpeed; + if (has_prefixi(this_comp_type, "Pump:VariableSpeed:Condensate")) { + this_comp.TypeOf_Num = TypeOf_PumpCondensate; } else if (has_prefixi(this_comp_type, "Pump:ConstantSpeed")) { this_comp.TypeOf_Num = TypeOf_PumpConstantSpeed; - } else if (has_prefixi(this_comp_type, "Pump:VariableSpeed:Condensate")) { - this_comp.TypeOf_Num = TypeOf_PumpCondensate; + } else if (has_prefixi(this_comp_type, "Pump:VariableSpeed")) { + this_comp.TypeOf_Num = TypeOf_PumpVariableSpeed; } else if (has_prefixi(this_comp_type, "HeaderedPumps:ConstantSpeed")) { this_comp.TypeOf_Num = TypeOf_PumpBankConstantSpeed; } else if (has_prefixi(this_comp_type, "HeaderedPumps:VariableSpeed")) { @@ -938,19 +915,22 @@ namespace EnergyPlus { "GetPlantInput: trying to process a pump type that is not supported, dev note"); ShowContinueError("Component Type =" + this_comp_type); } - this_comp.GeneralEquipType = GenEquipTypes_Pump; this_comp.CurOpSchemeType = PumpOpSchemeType; - if (BranchNum == 1 || BranchNum == TempLoop.TotalBranches) { + if (BranchNum == 1 || BranchNum == PlantLoop(LoopNum).LoopSide(LoopSideNum).TotalBranches) { ASeriesBranchHasPump = true; } else { AParallelBranchHasPump = true; } - StoreAPumpOnCurrentTempLoop( - LoopNum, LoopSideNum, BranchNum, CompNum, CompNames(CompNum), - OutletNodeNumbers(CompNum), AParallelBranchHasPump); + LoopSidePumpInformation p; + p.PumpName = CompNames(CompNum); + p.BranchNum = BranchNum; + p.CompNum = CompNum; + p.PumpOutletNode = OutletNodeNumbers(CompNum); + DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).BranchPumpsExist = AParallelBranchHasPump; + DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Pumps.push_back(p); + DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).TotalPumps++; } else if (UtilityRoutines::SameString(this_comp_type, "WaterHeater:Mixed")) { this_comp.TypeOf_Num = TypeOf_WtrHeaterMixed; - this_comp.GeneralEquipType = GenEquipTypes_WaterThermalTank; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -959,7 +939,6 @@ namespace EnergyPlus { this_comp.compPtr = WaterThermalTanks::WaterThermalTankData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "WaterHeater:Stratified")) { this_comp.TypeOf_Num = TypeOf_WtrHeaterStratified; - this_comp.GeneralEquipType = GenEquipTypes_WaterThermalTank; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -969,17 +948,14 @@ namespace EnergyPlus { } else if (UtilityRoutines::SameString(this_comp_type, "ChillerHeater:Absorption:Directfired")) { this_comp.TypeOf_Num = TypeOf_Chiller_DFAbsorption; - this_comp.GeneralEquipType = GenEquipTypes_Chiller; this_comp.compPtr = ChillerGasAbsorption::GasAbsorberSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "ChillerHeater:Absorption:DoubleEffect")) { this_comp.TypeOf_Num = TypeOf_Chiller_ExhFiredAbsorption; - this_comp.GeneralEquipType = GenEquipTypes_Chiller; this_comp.compPtr = ChillerExhaustAbsorption::ExhaustAbsorberSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "ThermalStorage:ChilledWater:Mixed")) { this_comp.TypeOf_Num = TypeOf_ChilledWaterTankMixed; - this_comp.GeneralEquipType = GenEquipTypes_ThermalStorage; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -989,7 +965,6 @@ namespace EnergyPlus { } else if (UtilityRoutines::SameString(this_comp_type, "ThermalStorage:ChilledWater:Stratified")) { this_comp.TypeOf_Num = TypeOf_ChilledWaterTankStratified; - this_comp.GeneralEquipType = GenEquipTypes_ThermalStorage; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -998,29 +973,23 @@ namespace EnergyPlus { this_comp.compPtr = WaterThermalTanks::WaterThermalTankData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "WaterUse:Connections")) { this_comp.TypeOf_Num = TypeOf_WaterUseConnection; - this_comp.GeneralEquipType = GenEquipTypes_WaterUse; this_comp.CurOpSchemeType = DemandOpSchemeType; this_comp.compPtr = WaterUse::WaterConnectionsType::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Cooling:Water")) { this_comp.TypeOf_Num = TypeOf_CoilWaterCooling; - this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Cooling:Water:DetailedGeometry")) { this_comp.TypeOf_Num = TypeOf_CoilWaterDetailedFlatCooling; - this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Heating:Water")) { this_comp.TypeOf_Num = TypeOf_CoilWaterSimpleHeating; - this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Heating:Steam")) { this_comp.TypeOf_Num = TypeOf_CoilSteamAirHeating; - this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "SolarCollector:FlatPlate:Water")) { this_comp.TypeOf_Num = TypeOf_SolarCollectorFlatPlate; - this_comp.GeneralEquipType = GenEquipTypes_SolarCollector; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1030,7 +999,6 @@ namespace EnergyPlus { } else if (UtilityRoutines::SameString(this_comp_type, "SolarCollector:IntegralCollectorStorage")) { this_comp.TypeOf_Num = TypeOf_SolarCollectorICS; - this_comp.GeneralEquipType = GenEquipTypes_SolarCollector; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1039,37 +1007,31 @@ namespace EnergyPlus { this_comp.compPtr = SolarCollectors::CollectorData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "LoadProfile:Plant")) { this_comp.TypeOf_Num = TypeOf_PlantLoadProfile; - this_comp.GeneralEquipType = GenEquipTypes_LoadProfile; this_comp.CurOpSchemeType = DemandOpSchemeType; this_comp.compPtr = PlantLoadProfile::PlantProfileData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "GroundHeatExchanger:System")) { this_comp.TypeOf_Num = TypeOf_GrndHtExchgSystem; - this_comp.GeneralEquipType = GenEquipTypes_GroundHeatExchanger; this_comp.CurOpSchemeType = UncontrolledOpSchemeType; this_comp.compPtr = GroundHeatExchangers::GLHEBase::factory(TypeOf_GrndHtExchgSystem, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "GroundHeatExchanger:Surface")) { this_comp.TypeOf_Num = TypeOf_GrndHtExchgSurface; - this_comp.GeneralEquipType = GenEquipTypes_GroundHeatExchanger; this_comp.CurOpSchemeType = UncontrolledOpSchemeType; this_comp.compPtr = SurfaceGroundHeatExchanger::SurfaceGroundHeatExchangerData::factory( TypeOf_GrndHtExchgSurface, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "GroundHeatExchanger:Pond")) { this_comp.TypeOf_Num = TypeOf_GrndHtExchgPond; - this_comp.GeneralEquipType = GenEquipTypes_GroundHeatExchanger; this_comp.CurOpSchemeType = UncontrolledOpSchemeType; this_comp.compPtr = PondGroundHeatExchanger::PondGroundHeatExchangerData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "GroundHeatExchanger:Slinky")) { this_comp.TypeOf_Num = TypeOf_GrndHtExchgSlinky; - this_comp.GeneralEquipType = GenEquipTypes_GroundHeatExchanger; this_comp.CurOpSchemeType = UncontrolledOpSchemeType; this_comp.compPtr = GroundHeatExchangers::GLHEBase::factory(TypeOf_GrndHtExchgSlinky, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Chiller:Electric:EIR")) { this_comp.TypeOf_Num = TypeOf_Chiller_ElectricEIR; - this_comp.GeneralEquipType = GenEquipTypes_Chiller; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1079,7 +1041,6 @@ namespace EnergyPlus { } else if (UtilityRoutines::SameString(this_comp_type, "Chiller:Electric:ReformulatedEIR")) { this_comp.TypeOf_Num = TypeOf_Chiller_ElectricReformEIR; - this_comp.GeneralEquipType = GenEquipTypes_Chiller; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1088,7 +1049,6 @@ namespace EnergyPlus { this_comp.compPtr = ChillerReformulatedEIR::ReformulatedEIRChillerSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Chiller:Electric")) { this_comp.TypeOf_Num = TypeOf_Chiller_Electric; - this_comp.GeneralEquipType = GenEquipTypes_Chiller; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1097,7 +1057,6 @@ namespace EnergyPlus { this_comp.compPtr = PlantChillers::ElectricChillerSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Chiller:EngineDriven")) { this_comp.TypeOf_Num = TypeOf_Chiller_EngineDriven; - this_comp.GeneralEquipType = GenEquipTypes_Chiller; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1106,7 +1065,6 @@ namespace EnergyPlus { this_comp.compPtr = PlantChillers::EngineDrivenChillerSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Chiller:CombustionTurbine")) { this_comp.TypeOf_Num = TypeOf_Chiller_CombTurbine; - this_comp.GeneralEquipType = GenEquipTypes_Chiller; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1115,7 +1073,6 @@ namespace EnergyPlus { this_comp.compPtr = PlantChillers::GTChillerSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Chiller:ConstantCOP")) { this_comp.TypeOf_Num = TypeOf_Chiller_ConstCOP; - this_comp.GeneralEquipType = GenEquipTypes_Chiller; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1124,17 +1081,14 @@ namespace EnergyPlus { this_comp.compPtr = PlantChillers::ConstCOPChillerSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Boiler:HotWater")) { this_comp.TypeOf_Num = TypeOf_Boiler_Simple; - this_comp.GeneralEquipType = GenEquipTypes_Boiler; this_comp.CurOpSchemeType = UnknownStatusOpSchemeType; this_comp.compPtr = Boilers::BoilerSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Boiler:Steam")) { this_comp.TypeOf_Num = TypeOf_Boiler_Steam; - this_comp.GeneralEquipType = GenEquipTypes_Boiler; this_comp.CurOpSchemeType = UnknownStatusOpSchemeType; this_comp.compPtr = BoilerSteam::BoilerSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Chiller:Absorption:Indirect")) { this_comp.TypeOf_Num = TypeOf_Chiller_Indirect_Absorption; - this_comp.GeneralEquipType = GenEquipTypes_Chiller; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1143,7 +1097,6 @@ namespace EnergyPlus { this_comp.compPtr = ChillerIndirectAbsorption::IndirectAbsorberSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Chiller:Absorption")) { this_comp.TypeOf_Num = TypeOf_Chiller_Absorption; - this_comp.GeneralEquipType = GenEquipTypes_Chiller; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1152,25 +1105,20 @@ namespace EnergyPlus { this_comp.compPtr = ChillerAbsorption::BLASTAbsorberSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "CoolingTower:SingleSpeed")) { this_comp.TypeOf_Num = TypeOf_CoolingTower_SingleSpd; - this_comp.GeneralEquipType = GenEquipTypes_CoolingTower; this_comp.CurOpSchemeType = UnknownStatusOpSchemeType; this_comp.compPtr = CondenserLoopTowers::CoolingTower::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "CoolingTower:TwoSpeed")) { this_comp.TypeOf_Num = TypeOf_CoolingTower_TwoSpd; - this_comp.GeneralEquipType = GenEquipTypes_CoolingTower; this_comp.CurOpSchemeType = UnknownStatusOpSchemeType; this_comp.compPtr = CondenserLoopTowers::CoolingTower::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "CoolingTower:VariableSpeed")) { this_comp.TypeOf_Num = TypeOf_CoolingTower_VarSpd; - this_comp.GeneralEquipType = GenEquipTypes_CoolingTower; this_comp.compPtr = CondenserLoopTowers::CoolingTower::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "CoolingTower:VariableSpeed:Merkel")) { this_comp.TypeOf_Num = TypeOf_CoolingTower_VarSpdMerkel; - this_comp.GeneralEquipType = GenEquipTypes_CoolingTower; this_comp.compPtr = CondenserLoopTowers::CoolingTower::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Generator:FuelCell:ExhaustGasToWaterHeatExchanger")) { this_comp.TypeOf_Num = TypeOf_Generator_FCExhaust; - this_comp.GeneralEquipType = GenEquipTypes_Generator; this_comp.compPtr = FuelCellElectricGenerator::FCDataStruct::factory_exhaust(CompNames(CompNum)); if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; @@ -1180,13 +1128,11 @@ namespace EnergyPlus { } else if (UtilityRoutines::SameString(this_comp_type, "WaterHeater:HeatPump:PumpedCondenser")) { this_comp.TypeOf_Num = TypeOf_HeatPumpWtrHeaterPumped; - this_comp.GeneralEquipType = GenEquipTypes_WaterThermalTank; this_comp.CurOpSchemeType = DemandOpSchemeType; this_comp.compPtr = WaterThermalTanks::HeatPumpWaterHeaterData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "WaterHeater:HeatPump:WrappedCondenser")) { this_comp.TypeOf_Num = TypeOf_HeatPumpWtrHeaterWrapped; - this_comp.GeneralEquipType = GenEquipTypes_WaterThermalTank; this_comp.CurOpSchemeType = DemandOpSchemeType; this_comp.compPtr = WaterThermalTanks::HeatPumpWaterHeaterData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, @@ -1194,7 +1140,6 @@ namespace EnergyPlus { this_comp.compPtr = HeatPumpWaterToWaterSimple::GshpSpecs::factory( TypeOf_HPWaterEFCooling, CompNames(CompNum)); this_comp.TypeOf_Num = TypeOf_HPWaterEFCooling; - this_comp.GeneralEquipType = GenEquipTypes_HeatPump; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1205,7 +1150,6 @@ namespace EnergyPlus { this_comp.compPtr = HeatPumpWaterToWaterSimple::GshpSpecs::factory( TypeOf_HPWaterEFHeating, CompNames(CompNum)); this_comp.TypeOf_Num = TypeOf_HPWaterEFHeating; - this_comp.GeneralEquipType = GenEquipTypes_HeatPump; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1215,7 +1159,6 @@ namespace EnergyPlus { "HeatPump:WaterToWater:ParameterEstimation:Heating")) { this_comp.compPtr = HeatPumpWaterToWaterHEATING::GshpPeHeatingSpecs::factory(CompNames(CompNum)); this_comp.TypeOf_Num = TypeOf_HPWaterPEHeating; - this_comp.GeneralEquipType = GenEquipTypes_HeatPump; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1225,7 +1168,6 @@ namespace EnergyPlus { "HeatPump:WaterToWater:ParameterEstimation:Cooling")) { this_comp.compPtr = HeatPumpWaterToWaterCOOLING::GshpPeCoolingSpecs::factory(CompNames(CompNum)); this_comp.TypeOf_Num = TypeOf_HPWaterPECooling; - this_comp.GeneralEquipType = GenEquipTypes_HeatPump; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1236,7 +1178,6 @@ namespace EnergyPlus { this_comp.compPtr = EIRPlantLoopHeatPumps::EIRPlantLoopHeatPump::factory( TypeOf_HeatPumpEIRHeating, CompNames(CompNum)); this_comp.TypeOf_Num = TypeOf_HeatPumpEIRHeating; - this_comp.GeneralEquipType = GenEquipTypes_HeatPump; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1247,7 +1188,6 @@ namespace EnergyPlus { this_comp.compPtr = EIRPlantLoopHeatPumps::EIRPlantLoopHeatPump::factory( TypeOf_HeatPumpEIRCooling, CompNames(CompNum)); this_comp.TypeOf_Num = TypeOf_HeatPumpEIRCooling; - this_comp.GeneralEquipType = GenEquipTypes_HeatPump; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1256,7 +1196,6 @@ namespace EnergyPlus { } else if (UtilityRoutines::SameString(this_comp_type, "AirConditioner:VariableRefrigerantFlow")) { this_comp.TypeOf_Num = TypeOf_HeatPumpVRF; - this_comp.GeneralEquipType = GenEquipTypes_HeatPump; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1265,27 +1204,21 @@ namespace EnergyPlus { this_comp.compPtr = HVACVariableRefrigerantFlow::VRFCondenserEquipment::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "DistrictCooling")) { this_comp.TypeOf_Num = TypeOf_PurchChilledWater; - this_comp.GeneralEquipType = GenEquipTypes_Purchased; this_comp.compPtr = OutsideEnergySources::OutsideEnergySourceSpecs::factory(TypeOf_PurchChilledWater, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "DistrictHeating")) { this_comp.TypeOf_Num = TypeOf_PurchHotWater; - this_comp.GeneralEquipType = GenEquipTypes_Purchased; this_comp.compPtr = OutsideEnergySources::OutsideEnergySourceSpecs::factory(TypeOf_PurchHotWater, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "ThermalStorage:Ice:Simple")) { this_comp.TypeOf_Num = TypeOf_TS_IceSimple; - this_comp.GeneralEquipType = GenEquipTypes_ThermalStorage; this_comp.compPtr = IceThermalStorage::SimpleIceStorageData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "ThermalStorage:Ice:Detailed")) { this_comp.TypeOf_Num = TypeOf_TS_IceDetailed; - this_comp.GeneralEquipType = GenEquipTypes_ThermalStorage; this_comp.compPtr = IceThermalStorage::DetailedIceStorageData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "TemperingValve")) { this_comp.compPtr = PlantValves::TemperValveData::factory(CompNames(CompNum)); this_comp.TypeOf_Num = TypeOf_ValveTempering; - this_comp.GeneralEquipType = GenEquipTypes_Valve; } else if (UtilityRoutines::SameString(this_comp_type, "HeatExchanger:FluidToFluid")) { this_comp.TypeOf_Num = TypeOf_FluidToFluidPlantHtExchg; - this_comp.GeneralEquipType = GenEquipTypes_HeatExchanger; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1294,7 +1227,6 @@ namespace EnergyPlus { this_comp.compPtr = PlantHeatExchangerFluidToFluid::HeatExchangerStruct::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Generator:MicroTurbine")) { this_comp.TypeOf_Num = TypeOf_Generator_MicroTurbine; - this_comp.GeneralEquipType = GenEquipTypes_Generator; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1304,7 +1236,6 @@ namespace EnergyPlus { } else if (UtilityRoutines::SameString(this_comp_type, "Generator:InternalCombustionEngine")) { this_comp.TypeOf_Num = TypeOf_Generator_ICEngine; - this_comp.GeneralEquipType = GenEquipTypes_Generator; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1314,7 +1245,6 @@ namespace EnergyPlus { } else if (UtilityRoutines::SameString(this_comp_type, "Generator:CombustionTurbine")) { this_comp.TypeOf_Num = TypeOf_Generator_CTurbine; - this_comp.GeneralEquipType = GenEquipTypes_Generator; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1323,7 +1253,6 @@ namespace EnergyPlus { this_comp.compPtr = CTElectricGenerator::CTGeneratorData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Generator:MicroCHP")) { this_comp.TypeOf_Num = TypeOf_Generator_MicroCHP; - this_comp.GeneralEquipType = GenEquipTypes_Generator; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1332,7 +1261,6 @@ namespace EnergyPlus { this_comp.compPtr = MicroCHPElectricGenerator::MicroCHPDataStruct::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Generator:FuelCell:StackCooler")) { this_comp.TypeOf_Num = TypeOf_Generator_FCStackCooler; - this_comp.GeneralEquipType = GenEquipTypes_Generator; this_comp.compPtr = FuelCellElectricGenerator::FCDataStruct::factory(CompNames(CompNum)); if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; @@ -1341,28 +1269,23 @@ namespace EnergyPlus { } } else if (UtilityRoutines::SameString(this_comp_type, "FluidCooler:SingleSpeed")) { this_comp.TypeOf_Num = TypeOf_FluidCooler_SingleSpd; - this_comp.GeneralEquipType = GenEquipTypes_FluidCooler; this_comp.compPtr = FluidCoolers::FluidCoolerspecs::factory( TypeOf_FluidCooler_SingleSpd, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "FluidCooler:TwoSpeed")) { this_comp.TypeOf_Num = TypeOf_FluidCooler_TwoSpd; - this_comp.GeneralEquipType = GenEquipTypes_FluidCooler; this_comp.compPtr = FluidCoolers::FluidCoolerspecs::factory( TypeOf_FluidCooler_TwoSpd, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "EvaporativeFluidCooler:SingleSpeed")) { this_comp.TypeOf_Num = TypeOf_EvapFluidCooler_SingleSpd; - this_comp.GeneralEquipType = GenEquipTypes_EvapFluidCooler; this_comp.compPtr = EvaporativeFluidCoolers::EvapFluidCoolerSpecs::factory( TypeOf_EvapFluidCooler_SingleSpd, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "EvaporativeFluidCooler:TwoSpeed")) { this_comp.TypeOf_Num = TypeOf_EvapFluidCooler_TwoSpd; - this_comp.GeneralEquipType = GenEquipTypes_EvapFluidCooler; this_comp.compPtr = EvaporativeFluidCoolers::EvapFluidCoolerSpecs::factory( TypeOf_EvapFluidCooler_TwoSpd, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "SolarCollector:FlatPlate:PhotovoltaicThermal")) { this_comp.TypeOf_Num = TypeOf_PVTSolarCollectorFlatPlate; - this_comp.GeneralEquipType = GenEquipTypes_SolarCollector; if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1371,137 +1294,110 @@ namespace EnergyPlus { 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; this_comp.compPtr = PlantCentralGSHP::WrapperSpecs::factory(CompNames(CompNum)); // now deal with demand components of the ZoneHVAC type served by ControlCompOutput } else if (UtilityRoutines::SameString(this_comp_type, "ZoneHVAC:Baseboard:RadiantConvective:Water")) { this_comp.TypeOf_Num = TypeOf_Baseboard_Rad_Conv_Water; - this_comp.GeneralEquipType = GenEquipTypes_ZoneHVACDemand; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "ZoneHVAC:Baseboard:Convective:Water")) { this_comp.TypeOf_Num = TypeOf_Baseboard_Conv_Water; - this_comp.GeneralEquipType = GenEquipTypes_ZoneHVACDemand; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "ZoneHVAC:Baseboard:RadiantConvective:Steam")) { this_comp.TypeOf_Num = TypeOf_Baseboard_Rad_Conv_Steam; - this_comp.GeneralEquipType = GenEquipTypes_ZoneHVACDemand; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "ZoneHVAC:CoolingPanel:RadiantConvective:Water")) { this_comp.TypeOf_Num = TypeOf_CoolingPanel_Simple; - this_comp.GeneralEquipType = GenEquipTypes_ZoneHVACDemand; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "ZoneHVAC:LowTemperatureRadiant:VariableFlow")) { this_comp.TypeOf_Num = TypeOf_LowTempRadiant_VarFlow; - this_comp.GeneralEquipType = GenEquipTypes_ZoneHVACDemand; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "ZoneHVAC:LowTemperatureRadiant:ConstantFlow")) { this_comp.TypeOf_Num = TypeOf_LowTempRadiant_ConstFlow; - this_comp.GeneralEquipType = GenEquipTypes_ZoneHVACDemand; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "AirTerminal:SingleDuct:ConstantVolume:CooledBeam")) { this_comp.TypeOf_Num = TypeOf_CooledBeamAirTerminal; - this_comp.GeneralEquipType = GenEquipTypes_ZoneHVACDemand; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "AirTerminal:SingleDuct:ConstantVolume:FourPipeBeam")) { this_comp.TypeOf_Num = TypeOf_FourPipeBeamAirTerminal; - this_comp.GeneralEquipType = GenEquipTypes_ZoneHVACDemand; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed")) { this_comp.TypeOf_Num = TypeOf_MultiSpeedHeatPumpRecovery; - this_comp.GeneralEquipType = GenEquipTypes_ZoneHVACDemand; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "AirLoopHVAC:UnitarySystem")) { this_comp.TypeOf_Num = TypeOf_UnitarySysRecovery; - this_comp.GeneralEquipType = GenEquipTypes_ZoneHVACDemand; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Heating:WaterToAirHeatPump:EquationFit")) { this_comp.TypeOf_Num = TypeOf_CoilWAHPHeatingEquationFit; - this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Cooling:WaterToAirHeatPump:EquationFit")) { this_comp.TypeOf_Num = TypeOf_CoilWAHPCoolingEquationFit; - this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit")) { this_comp.TypeOf_Num = TypeOf_CoilVSWAHPHeatingEquationFit; - this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit")) { this_comp.TypeOf_Num = TypeOf_CoilVSWAHPCoolingEquationFit; - this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Heating:WaterToAirHeatPump:ParameterEstimation")) { this_comp.TypeOf_Num = TypeOf_CoilWAHPHeatingParamEst; - this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation")) { this_comp.TypeOf_Num = TypeOf_CoilWAHPCoolingParamEst; - this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "Refrigeration:Condenser:WaterCooled")) { this_comp.TypeOf_Num = TypeOf_RefrigSystemWaterCondenser; - this_comp.GeneralEquipType = GenEquipTypes_Refrigeration; this_comp.CurOpSchemeType = DemandOpSchemeType; this_comp.compPtr = RefrigeratedCase::RefrigCondenserData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Refrigeration:CompressorRack")) { this_comp.TypeOf_Num = TypeOf_RefrigerationWaterCoolRack; - this_comp.GeneralEquipType = GenEquipTypes_Refrigeration; this_comp.CurOpSchemeType = DemandOpSchemeType; this_comp.compPtr = RefrigeratedCase::RefrigRackData::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "PlantComponent:UserDefined")) { this_comp.TypeOf_Num = TypeOf_PlantComponentUserDefined; - this_comp.GeneralEquipType = GenEquipTypes_PlantComponent; this_comp.CurOpSchemeType = UnknownStatusOpSchemeType; this_comp.compPtr = UserDefinedComponents::UserPlantComponentStruct::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Coil:UserDefined")) { this_comp.TypeOf_Num = TypeOf_CoilUserDefined; - this_comp.GeneralEquipType = GenEquipTypes_PlantComponent; this_comp.CurOpSchemeType = UnknownStatusOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "ZoneHVAC:ForcedAir:UserDefined")) { this_comp.TypeOf_Num = TypeOf_ZoneHVACAirUserDefined; - this_comp.GeneralEquipType = GenEquipTypes_PlantComponent; this_comp.CurOpSchemeType = UnknownStatusOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "AirTerminal:SingleDuct:UserDefined")) { this_comp.TypeOf_Num = TypeOf_AirTerminalUserDefined; - this_comp.GeneralEquipType = GenEquipTypes_PlantComponent; this_comp.CurOpSchemeType = UnknownStatusOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type,"PlantComponent:TemperatureSource")) { this_comp.TypeOf_Num = TypeOf_WaterSource; - this_comp.GeneralEquipType = GenEquipTypes_PlantComponent; this_comp.CurOpSchemeType = UncontrolledOpSchemeType; this_comp.compPtr = PlantComponentTemperatureSources::WaterSourceSpecs::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "GroundHeatExchanger:HorizontalTrench")) { this_comp.TypeOf_Num = TypeOf_GrndHtExchgHorizTrench; - this_comp.GeneralEquipType = GenEquipTypes_Pipe; this_comp.CurOpSchemeType = TypeOf_GrndHtExchgHorizTrench; this_comp.compPtr = PlantPipingSystemsManager::Circuit::factory( TypeOf_GrndHtExchgHorizTrench, CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Cooling:DX:SingleSpeed:ThermalStorage")) { this_comp.TypeOf_Num = TypeOf_PackagedTESCoolingCoil; - this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (UtilityRoutines::SameString(this_comp_type, "SwimmingPool:Indoor")) { this_comp.TypeOf_Num = TypeOf_SwimmingPool_Indoor; - this_comp.GeneralEquipType = GenEquipTypes_ZoneHVACDemand; this_comp.CurOpSchemeType = DemandOpSchemeType; } else { // discover unsupported equipment on branches. @@ -1518,28 +1414,12 @@ namespace EnergyPlus { this_comp.NodeNameOut = OutletNodeNames(CompNum); this_comp.NodeNumOut = OutletNodeNumbers(CompNum); - // Increment pipe counter if component is a pipe - if (this_comp.TypeOf_Num == TypeOf_Pipe || this_comp.TypeOf_Num == TypeOf_PipeInterior || - this_comp.TypeOf_Num == TypeOf_PipeExterior || - this_comp.TypeOf_Num == TypeOf_PipeUnderground || - this_comp.TypeOf_Num == TypeOf_PipeSteam) { - ++NumOfPipesInLoop; - if (PlantLoop(LoopNum).TypeOfLoop == Plant) { - ++NumPlantPipes; - } else if (PlantLoop(LoopNum).TypeOfLoop == Condenser) { - ++NumCondPipes; - } - ++NumPipes; - } - - TempLoop.Branch(BranchNum).NodeNumIn = TempLoop.Branch(BranchNum).Comp(1).NodeNumIn; - - // find branch outlet node - TempLoop.Branch(BranchNum).NodeNumOut = - TempLoop.Branch(BranchNum).Comp( - TempLoop.Branch(BranchNum).TotalComponents).NodeNumOut; } + // set branch inlet/outlet nodes + branch.NodeNumIn = branch.Comp(1).NodeNumIn; + branch.NodeNumOut = branch.Comp(branch.TotalComponents).NodeNumOut; + CompTypes.deallocate(); CompNames.deallocate(); CompCtrls.deallocate(); @@ -1553,31 +1433,29 @@ namespace EnergyPlus { if (ASeriesBranchHasPump && AParallelBranchHasPump) { ShowSevereError("Current version does not support Loop pumps and branch pumps together"); - ShowContinueError("Occurs in loop " + TempLoop.Name); + ShowContinueError("Occurs in loop " + PlantLoop(LoopNum).Name); ErrorsFound = true; } // Obtain the Splitter and Mixer information - if (TempLoop.ConnectList.empty()) { + if (loopSide.ConnectList.empty()) { NumofSplitters = 0; NumofMixers = 0; } else { errFlag = false; - GetNumSplitterMixerInConntrList(TempLoop.Name, TempLoop.ConnectList, NumofSplitters, - NumofMixers, errFlag); + GetNumSplitterMixerInConntrList(plantLoop.Name, loopSide.ConnectList, NumofSplitters, NumofMixers, errFlag); if (errFlag) { ErrorsFound = true; } if (NumofSplitters != NumofMixers) { - ShowSevereError("GetPlantInput: Loop Name=" + TempLoop.Name + ", ConnectorList=" + - TempLoop.ConnectList + - ", unequal number of splitters and mixers"); + ShowSevereError("GetPlantInput: Loop Name=" + plantLoop.Name + ", ConnectorList=" + + loopSide.ConnectList + ", unequal number of splitters and mixers"); ErrorsFound = true; } } - TempLoop.SplitterExists = NumofSplitters > 0; - TempLoop.MixerExists = NumofMixers > 0; + loopSide.Splitter.Exists = NumofSplitters > 0; + loopSide.Mixer.Exists = NumofMixers > 0; if (ErrorsFound) { ShowFatalError("GetPlantInput: Previous Severe errors cause termination."); @@ -1590,13 +1468,13 @@ namespace EnergyPlus { if (SplitNum > NumofSplitters) break; OutletNodeNames.allocate(MaxNumAlphas); OutletNodeNumbers.allocate(MaxNumAlphas); - GetLoopSplitter(TempLoop.Name, - TempLoop.ConnectList, - TempLoop.Splitter.Name, - TempLoop.Splitter.Exists, - TempLoop.Splitter.NodeNameIn, - TempLoop.Splitter.NodeNumIn, - TempLoop.Splitter.TotalOutletNodes, + GetLoopSplitter(plantLoop.Name, + loopSide.ConnectList, + loopSide.Splitter.Name, + loopSide.Splitter.Exists, + loopSide.Splitter.NodeNameIn, + loopSide.Splitter.NodeNumIn, + loopSide.Splitter.TotalOutletNodes, OutletNodeNames, OutletNodeNumbers, ErrorsFound, @@ -1610,54 +1488,52 @@ namespace EnergyPlus { } // Map the inlet node to the splitter to a branch number - if (TempLoop.Splitter.Exists) { + if (loopSide.Splitter.Exists) { // Map the inlet node to the splitter to a branch number SplitInBranch = false; - for (BranchNum = 1; BranchNum <= TempLoop.TotalBranches; ++BranchNum) { - CompNum = TempLoop.Branch(BranchNum).TotalComponents; - if (TempLoop.Splitter.NodeNumIn == - TempLoop.Branch(BranchNum).Comp(CompNum).NodeNumOut) { - TempLoop.Splitter.BranchNumIn = BranchNum; + for (BranchNum = 1; BranchNum <= loopSide.TotalBranches; ++BranchNum) { + auto &branch = loopSide.Branch(BranchNum); + CompNum = branch.TotalComponents; + if (loopSide.Splitter.NodeNumIn == branch.Comp(CompNum).NodeNumOut) { + loopSide.Splitter.BranchNumIn = BranchNum; SplitInBranch = true; break; // BranchNum DO loop } } if (!SplitInBranch) { - ShowSevereError("Splitter Inlet Branch not found, Splitter=" + TempLoop.Splitter.Name); - ShowContinueError("Splitter Branch Inlet name=" + TempLoop.Splitter.NodeNameIn); - ShowContinueError("In Loop=" + TempLoop.Name); + ShowSevereError("Splitter Inlet Branch not found, Splitter=" + loopSide.Splitter.Name); + ShowContinueError("Splitter Branch Inlet name=" + loopSide.Splitter.NodeNameIn); + ShowContinueError("In Loop=" + plantLoop.Name); ErrorsFound = true; } - TempLoop.Splitter.NodeNameOut.allocate(TempLoop.Splitter.TotalOutletNodes); - TempLoop.Splitter.NodeNumOut.dimension(TempLoop.Splitter.TotalOutletNodes, 0); - TempLoop.Splitter.BranchNumOut.dimension(TempLoop.Splitter.TotalOutletNodes, 0); + loopSide.Splitter.NodeNameOut.allocate(loopSide.Splitter.TotalOutletNodes); + loopSide.Splitter.NodeNumOut.dimension(loopSide.Splitter.TotalOutletNodes, 0); + loopSide.Splitter.BranchNumOut.dimension(loopSide.Splitter.TotalOutletNodes, 0); - SplitOutBranch.allocate(TempLoop.Splitter.TotalOutletNodes); + SplitOutBranch.allocate(loopSide.Splitter.TotalOutletNodes); SplitOutBranch = false; - for (NodeNum = 1; NodeNum <= TempLoop.Splitter.TotalOutletNodes; ++NodeNum) { - TempLoop.Splitter.NodeNameOut(NodeNum) = OutletNodeNames(NodeNum); - TempLoop.Splitter.NodeNumOut(NodeNum) = OutletNodeNumbers(NodeNum); + for (NodeNum = 1; NodeNum <= loopSide.Splitter.TotalOutletNodes; ++NodeNum) { + loopSide.Splitter.NodeNameOut(NodeNum) = OutletNodeNames(NodeNum); + loopSide.Splitter.NodeNumOut(NodeNum) = OutletNodeNumbers(NodeNum); // The following DO loop series is intended to store the branch number for each outlet // branch of the splitter - for (BranchNum = 1; BranchNum <= TempLoop.TotalBranches; ++BranchNum) { - if (TempLoop.Splitter.NodeNumOut(NodeNum) == - TempLoop.Branch(BranchNum).Comp(1).NodeNumIn) { - TempLoop.Splitter.BranchNumOut(NodeNum) = BranchNum; + for (BranchNum = 1; BranchNum <= loopSide.TotalBranches; ++BranchNum) { + if (loopSide.Splitter.NodeNumOut(NodeNum) == loopSide.Branch(BranchNum).Comp(1).NodeNumIn) { + loopSide.Splitter.BranchNumOut(NodeNum) = BranchNum; SplitOutBranch(NodeNum) = true; break; // BranchNum DO loop } } } - for (Outlet = 1; Outlet <= TempLoop.Splitter.TotalOutletNodes; ++Outlet) { + for (Outlet = 1; Outlet <= loopSide.Splitter.TotalOutletNodes; ++Outlet) { if (SplitOutBranch(Outlet)) continue; - ShowSevereError("Splitter Outlet Branch not found, Splitter=" + TempLoop.Splitter.Name); - ShowContinueError( - "Splitter Branch Outlet node name=" + TempLoop.Splitter.NodeNameOut(Outlet)); - ShowContinueError("In Loop=" + TempLoop.Name); - ShowContinueError("Loop BranchList=" + TempLoop.BranchList); - ShowContinueError("Loop ConnectorList=" + TempLoop.ConnectList); + ShowSevereError("Splitter Outlet Branch not found, Splitter=" + loopSide.Splitter.Name); + ShowContinueError("Splitter Branch Outlet node name=" + loopSide.Splitter.NodeNameOut(Outlet)); + ShowContinueError("In Loop=" + plantLoop.Name); + ShowContinueError("Loop BranchList=" + loopSide.BranchList); + ShowContinueError("Loop ConnectorList=" + loopSide.ConnectList); ErrorsFound = true; } @@ -1674,13 +1550,13 @@ namespace EnergyPlus { if (MixNum > NumofMixers) break; InletNodeNames.allocate(MaxNumAlphas); InletNodeNumbers.allocate(MaxNumAlphas); - GetLoopMixer(TempLoop.Name, - TempLoop.ConnectList, - TempLoop.Mixer.Name, - TempLoop.Mixer.Exists, - TempLoop.Mixer.NodeNameOut, - TempLoop.Mixer.NodeNumOut, - TempLoop.Mixer.TotalInletNodes, + GetLoopMixer(plantLoop.Name, + loopSide.ConnectList, + loopSide.Mixer.Name, + loopSide.Mixer.Exists, + loopSide.Mixer.NodeNameOut, + loopSide.Mixer.NodeNumOut, + loopSide.Mixer.TotalInletNodes, InletNodeNames, InletNodeNumbers, ErrorsFound, @@ -1693,50 +1569,49 @@ namespace EnergyPlus { continue; } // Map the outlet node of the mixer to a branch number - if (TempLoop.Mixer.Exists) { + if (loopSide.Mixer.Exists) { // Map the outlet node of the mixer to a branch number MixerOutBranch = false; - for (BranchNum = 1; BranchNum <= TempLoop.TotalBranches; ++BranchNum) { - if (TempLoop.Mixer.NodeNumOut == TempLoop.Branch(BranchNum).Comp(1).NodeNumIn) { - TempLoop.Mixer.BranchNumOut = BranchNum; + for (BranchNum = 1; BranchNum <= loopSide.TotalBranches; ++BranchNum) { + if (loopSide.Mixer.NodeNumOut == loopSide.Branch(BranchNum).Comp(1).NodeNumIn) { + loopSide.Mixer.BranchNumOut = BranchNum; MixerOutBranch = true; break; // BranchNum DO loop } } if (!MixerOutBranch) { - ShowSevereError("Mixer Outlet Branch not found, Mixer=" + TempLoop.Mixer.Name); + ShowSevereError("Mixer Outlet Branch not found, Mixer=" + loopSide.Mixer.Name); ErrorsFound = true; } - TempLoop.Mixer.NodeNameIn.allocate(TempLoop.Mixer.TotalInletNodes); - TempLoop.Mixer.NodeNumIn.dimension(TempLoop.Mixer.TotalInletNodes, 0); - TempLoop.Mixer.BranchNumIn.dimension(TempLoop.Mixer.TotalInletNodes, 0); + loopSide.Mixer.NodeNameIn.allocate(loopSide.Mixer.TotalInletNodes); + loopSide.Mixer.NodeNumIn.dimension(loopSide.Mixer.TotalInletNodes, 0); + loopSide.Mixer.BranchNumIn.dimension(loopSide.Mixer.TotalInletNodes, 0); - MixerInBranch.allocate(TempLoop.Mixer.TotalInletNodes); + MixerInBranch.allocate(loopSide.Mixer.TotalInletNodes); MixerInBranch = false; - for (NodeNum = 1; NodeNum <= TempLoop.Mixer.TotalInletNodes; ++NodeNum) { - TempLoop.Mixer.NodeNameIn(NodeNum) = InletNodeNames(NodeNum); - TempLoop.Mixer.NodeNumIn(NodeNum) = InletNodeNumbers(NodeNum); - // The following DO loop series is intended to store the branch number for each inlet - // branch of the mixer - for (BranchNum = 1; BranchNum <= TempLoop.TotalBranches; ++BranchNum) { - CompNum = TempLoop.Branch(BranchNum).TotalComponents; - if (TempLoop.Mixer.NodeNumIn(NodeNum) == - TempLoop.Branch(BranchNum).Comp(CompNum).NodeNumOut) { - TempLoop.Mixer.BranchNumIn(NodeNum) = BranchNum; + for (NodeNum = 1; NodeNum <= loopSide.Mixer.TotalInletNodes; ++NodeNum) { + loopSide.Mixer.NodeNameIn(NodeNum) = InletNodeNames(NodeNum); + loopSide.Mixer.NodeNumIn(NodeNum) = InletNodeNumbers(NodeNum); + // The following DO loop series is intended to store the branch number for each inlet branch of the mixer + for (BranchNum = 1; BranchNum <= loopSide.TotalBranches; ++BranchNum) { + auto &branch = loopSide.Branch(BranchNum); + CompNum = branch.TotalComponents; + if (loopSide.Mixer.NodeNumIn(NodeNum) == branch.Comp(CompNum).NodeNumOut) { + loopSide.Mixer.BranchNumIn(NodeNum) = BranchNum; MixerInBranch(NodeNum) = true; break; // BranchNum DO loop } } } - for (Inlet = 1; Inlet <= TempLoop.Mixer.TotalInletNodes; ++Inlet) { + for (Inlet = 1; Inlet <= loopSide.Mixer.TotalInletNodes; ++Inlet) { if (MixerInBranch(Inlet)) continue; - ShowSevereError("Mixer Inlet Branch not found, Mixer=" + TempLoop.Mixer.Name); - ShowContinueError("Mixer Branch Inlet name=" + TempLoop.Mixer.NodeNameIn(Inlet)); - ShowContinueError("In Loop=" + TempLoop.Name); - ShowContinueError("Loop BranchList=" + TempLoop.BranchList); - ShowContinueError("Loop ConnectorList=" + TempLoop.ConnectList); + ShowSevereError("Mixer Inlet Branch not found, Mixer=" + loopSide.Mixer.Name); + ShowContinueError("Mixer Branch Inlet name=" + loopSide.Mixer.NodeNameIn(Inlet)); + ShowContinueError("In Loop=" + plantLoop.Name); + ShowContinueError("Loop BranchList=" + loopSide.BranchList); + ShowContinueError("Loop ConnectorList=" + loopSide.ConnectList); ErrorsFound = true; } @@ -1746,156 +1621,47 @@ namespace EnergyPlus { InletNodeNumbers.deallocate(); } - PlantLoop(LoopNum).LoopSide(LoopSideNum).SplitterExists = TempLoop.SplitterExists; - PlantLoop(LoopNum).LoopSide(LoopSideNum).MixerExists = TempLoop.MixerExists; - PlantLoop(LoopNum).LoopSide(LoopSideNum).BypassExists = TempLoop.BypassExists; - - PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch.allocate(TempLoop.TotalBranches); - PlantLoop(LoopNum).LoopSide(LoopSideNum).TotalBranches = TempLoop.TotalBranches; - PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch = TempLoop.Branch; - - PlantLoop(LoopNum).LoopSide(LoopSideNum).Splitter = TempLoop.Splitter; - PlantLoop(LoopNum).LoopSide(LoopSideNum).Mixer = TempLoop.Mixer; - - PlantLoop(LoopNum).LoopSide(LoopSideNum).noLoadConstantSpeedBranchFlowRateSteps.allocate( - TempLoop.TotalBranches - 2); + loopSide.noLoadConstantSpeedBranchFlowRateSteps.allocate(loopSide.TotalBranches - 2); - // Add condenser CASE statement when required. - - TempLoop.Branch.deallocate(); + // TODO: this is just intended to be temporary + loopSide.myLoopNum = LoopNum; + loopSide.myLoopSideNum = LoopSideNum; + loopSide.myOtherLoopSideNum = 3 - LoopSideNum; } // ... end LoopSideNum=DemandSide,SupplySide - PlantLoop(LoopNum).LoopHasConnectionComp = TempLoop.LoopHasConnectionComp; + plantLoop.LoopSide(1).loopSideDescription = plantLoop.Name + " - Demand Side"; + plantLoop.LoopSide(2).loopSideDescription = plantLoop.Name + " - Supply Side"; // a nice little spot to report out bad pump/common-pipe configurations - bool const ThisSideHasPumps = (PlantLoop(LoopNum).LoopSide(1).TotalPumps > 0); - bool const OtherSideHasPumps = (PlantLoop(LoopNum).LoopSide(2).TotalPumps > 0); - if ((PlantLoop(LoopNum).CommonPipeType != CommonPipe_No) && (!ThisSideHasPumps || !OtherSideHasPumps)) { + bool const ThisSideHasPumps = (plantLoop.LoopSide(1).TotalPumps > 0); + bool const OtherSideHasPumps = (plantLoop.LoopSide(2).TotalPumps > 0); + if ((plantLoop.CommonPipeType != CommonPipe_No) && (!ThisSideHasPumps || !OtherSideHasPumps)) { ShowSevereError("Input Error: Common Pipe configurations must have pumps on both sides of loop"); - ShowContinueError("Occurs on plant loop name =\"" + PlantLoop(LoopNum).Name + "\""); + ShowContinueError("Occurs on plant loop name =\"" + plantLoop.Name + "\""); ShowContinueError("Make sure both demand and supply sides have a pump"); ErrorsFound = true; - } else if ((PlantLoop(LoopNum).CommonPipeType == CommonPipe_No) && ThisSideHasPumps && - OtherSideHasPumps) { + } else if ((plantLoop.CommonPipeType == CommonPipe_No) && ThisSideHasPumps && OtherSideHasPumps) { ShowSevereError("Input Error: Pumps on both loop sides must utilize a common pipe"); - ShowContinueError("Occurs on plant loop name =\"" + PlantLoop(LoopNum).Name + "\""); + ShowContinueError("Occurs on plant loop name =\"" + plantLoop.Name + "\""); ShowContinueError("Add common pipe or remove one loop side pump"); ErrorsFound = true; } else if (!ThisSideHasPumps && !OtherSideHasPumps) { ShowSevereError("SetupLoopFlowRequest: Problem in plant topology, no pumps specified on the loop"); - ShowContinueError("Occurs on plant loop name =\"" + PlantLoop(LoopNum).Name + "\""); + ShowContinueError("Occurs on plant loop name =\"" + plantLoop.Name + "\""); ShowContinueError("All plant loops require at least one pump"); ErrorsFound = true; } // set up some pump indexing for convenience later for (int LoopSideCounter = 1; LoopSideCounter <= 2; ++LoopSideCounter) { - for (int PumpCounter = 1; PumpCounter <= DataPlant::PlantLoop(LoopNum).LoopSide( - LoopSideCounter).TotalPumps; ++PumpCounter) { - int const PumpBranchNum = DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideCounter).Pumps( - PumpCounter).BranchNum; - int const PumpCompNum = DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideCounter).Pumps( - PumpCounter).CompNum; - DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideCounter).Branch(PumpBranchNum).Comp( - PumpCompNum).IndexInLoopSidePumps = PumpCounter; + for (int PumpCounter = 1; PumpCounter <= plantLoop.LoopSide(LoopSideCounter).TotalPumps; ++PumpCounter) { + int const PumpBranchNum = plantLoop.LoopSide(LoopSideCounter).Pumps(PumpCounter).BranchNum; + int const PumpCompNum = plantLoop.LoopSide(LoopSideCounter).Pumps(PumpCounter).CompNum; + plantLoop.LoopSide(LoopSideCounter).Branch(PumpBranchNum).Comp(PumpCompNum).IndexInLoopSidePumps = PumpCounter; } } - } // ...end of demand side loops DO loop - - // DSU? can we clean this out this next do loop now? looks like bandaids. - for (LoopNum = 1; LoopNum <= TotNumLoops; ++LoopNum) { - auto &this_supply_side(PlantLoop(LoopNum).LoopSide(SupplySide)); - for (BranchNum = 1; BranchNum <= this_supply_side.TotalBranches; ++BranchNum) { - auto &this_branch(this_supply_side.Branch(BranchNum)); - for (CompNum = 1; CompNum <= this_branch.TotalComponents; ++CompNum) { - auto &this_comp(this_branch.Comp(CompNum)); - Pos = index(this_comp.TypeOf, ':'); - if (Pos != std::string::npos) { - GeneralEquipType = UtilityRoutines::FindItemInList(this_comp.TypeOf.substr(0, Pos), - GeneralEquipTypes, NumGeneralEquipTypes); - } else { - GeneralEquipType = 0; - } - if (GeneralEquipType == 0) { - if (has_prefixi(this_comp.TypeOf, "HeaderedPumps")) { - GeneralEquipType = GenEquipTypes_Pump; - } else if (has_prefixi(this_comp.TypeOf, "WaterHeater:HeatPump")) { - GeneralEquipType = GenEquipTypes_WaterThermalTank; - } else if (UtilityRoutines::SameString(this_comp.TypeOf, "TemperingValve")) { - GeneralEquipType = GenEquipTypes_Valve; - } else if (has_prefixi(this_comp.TypeOf, "Pipe:Adiabatic")) { - GeneralEquipType = GenEquipTypes_Pipe; - } else if (has_prefixi(this_comp.TypeOf, "PipingSystem")) { - GeneralEquipType = GenEquipTypes_Pipe; - } else if (has_prefixi(this_comp.TypeOf, "Thermalstorage:ChilledWater:Mixed")) { - GeneralEquipType = GenEquipTypes_ThermalStorage; - } else if (has_prefixi(this_comp.TypeOf, "Thermalstorage:ChilledWater:Stratified")) { - GeneralEquipType = GenEquipTypes_ThermalStorage; - } else if (UtilityRoutines::SameString(this_comp.TypeOf, - "ChillerHeater:Absorption:DirectFired")) { - GeneralEquipType = GenEquipTypes_Chiller; - } else if (UtilityRoutines::SameString(this_comp.TypeOf, - "ChillerHeater:Absorption:DoubleEffect")) { - GeneralEquipType = GenEquipTypes_Chiller; - } else if (has_prefixi(this_comp.TypeOf, "District")) { - GeneralEquipType = GenEquipTypes_Purchased; - } else if (UtilityRoutines::SameString(this_comp.TypeOf, "GroundHeatExchanger:System")) { - GeneralEquipType = GenEquipTypes_GroundHeatExchanger; - } else if (UtilityRoutines::SameString(this_comp.TypeOf, "GroundHeatExchanger:Surface")) { - GeneralEquipType = GenEquipTypes_GroundHeatExchanger; - } else if (UtilityRoutines::SameString(this_comp.TypeOf, "GroundHeatExchanger:Pond")) { - GeneralEquipType = GenEquipTypes_GroundHeatExchanger; - } else if (UtilityRoutines::SameString(this_comp.TypeOf, "GroundHeatExchanger:Slinky")) { - GeneralEquipType = GenEquipTypes_GroundHeatExchanger; - } else if (UtilityRoutines::SameString(this_comp.TypeOf, - "PlantComponent:TemperatureSource")) { - GeneralEquipType = GenEquipTypes_HeatExchanger; - } else if (UtilityRoutines::SameString(this_comp.TypeOf, "CentralHeatPumpSystem")) { - GeneralEquipType = GenEquipTypes_CentralHeatPumpSystem; - } else { - ShowSevereError("GetPlantInput: PlantLoop=\"" + PlantLoop(LoopNum).Name + - "\" invalid equipment type."); - ShowContinueError("...on Branch=\"" + - PlantLoop(LoopNum).LoopSide(SupplySide).Branch(BranchNum).Name + - "\"."); - ShowContinueError("...Equipment type=\"" + this_comp.TypeOf + "\"."); - ShowContinueError("...Equipment name=\"" + this_comp.Name + "\"."); - ErrorsFound = true; - } - } - - this_comp.GeneralEquipType = GeneralEquipType; - - // Set up "TypeOf" Num - TypeOfNum = UtilityRoutines::FindItemInList(this_comp.TypeOf, SimPlantEquipTypes, - NumSimPlantEquipTypes); - if (TypeOfNum == 0) { - if (UtilityRoutines::SameString(this_comp.TypeOf, "WaterHeater:HeatPump:PumpedCondenser")) { - this_comp.TypeOf_Num = TypeOf_HeatPumpWtrHeaterPumped; - } else if (UtilityRoutines::SameString(this_comp.TypeOf, - "WaterHeater:HeatPump:WrappedCondenser")) { - this_comp.TypeOf_Num = TypeOf_HeatPumpWtrHeaterWrapped; - } else if (!has_prefixi(this_comp.TypeOf, "Pump") && - !has_prefixi(this_comp.TypeOf, "HeaderedPump")) { - // Error. May have already been flagged under General - if (GeneralEquipType != 0) { // if GeneralEquipmentType == 0, then already flagged - ShowSevereError("GetPlantInput: PlantLoop=\"" + PlantLoop(LoopNum).Name + - "\" invalid equipment type."); - ShowContinueError("...on Branch=\"" + - PlantLoop(LoopNum).LoopSide(SupplySide).Branch(BranchNum).Name + - "\"."); - ShowContinueError("...Equipment type=\"" + this_comp.TypeOf + "\"."); - ShowContinueError("...Equipment name=\"" + this_comp.Name + "\"."); - ErrorsFound = true; - } - } - } else { - this_comp.TypeOf_Num = TypeOfNum; - } - } - } } if (ErrorsFound) { @@ -2109,35 +1875,13 @@ namespace EnergyPlus { // This subroutine initializes the plant supply side reports. // It was created during the splitting of supply and demand side functions. - // METHODOLOGY EMPLOYED: - // na - - // REFERENCES: - // na - - // USE STATEMENTS: - // na // Using/Aliasing using DataGlobals::DisplayAdvancedReportVariables; using DataPlant::DemandOpSchemeType; using DataPlant::DemandSide; using DataPlant::PlantLoop; - using DataPlant::PlantReport; using DataPlant::SupplySide; - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - // na - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS - // na - - // DERIVED TYPE DEFINITIONS - // na - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: int LoopNum; // DO loop counter (plant supply sides) int LoopSideNum; @@ -2149,27 +1893,23 @@ namespace EnergyPlus { // FLOW: MaxBranches = 0; - for (LoopNum = 1; LoopNum <= TotNumLoops; ++LoopNum) { - MaxBranches = max(MaxBranches, PlantLoop(LoopNum).LoopSide(DemandSide).TotalBranches); - MaxBranches = max(MaxBranches, PlantLoop(LoopNum).LoopSide(SupplySide).TotalBranches); - PlantLoop(LoopNum).MaxBranch = MaxBranches; - } - - PlantReport.allocate(TotNumLoops); - - for (auto &e : PlantReport) { - e.CoolingDemand = 0.0; - e.HeatingDemand = 0.0; - e.DemandNotDispatched = 0.0; - e.UnmetDemand = 0.0; - e.InletNodeTemperature = 0.0; - e.OutletNodeTemperature = 0.0; - e.InletNodeFlowrate = 0.0; - e.BypassFrac = 0.0; - e.OutletNodeFlowrate = 0.0; + for (auto &loop : PlantLoop) { + MaxBranches = max(MaxBranches, loop.LoopSide(DemandSide).TotalBranches); + MaxBranches = max(MaxBranches, loop.LoopSide(SupplySide).TotalBranches); + loop.MaxBranch = MaxBranches; + loop.CoolingDemand = 0.0; + loop.HeatingDemand = 0.0; + loop.DemandNotDispatched = 0.0; + loop.UnmetDemand = 0.0; + loop.InletNodeTemperature = 0.0; + loop.OutletNodeTemperature = 0.0; + loop.InletNodeFlowrate = 0.0; + loop.BypassFrac = 0.0; + loop.OutletNodeFlowrate = 0.0; } for (LoopNum = 1; LoopNum <= TotNumLoops; ++LoopNum) { + auto &loop = PlantLoop(LoopNum); if (LoopNum <= NumPlantLoops) { CurrentModuleObject = "Plant Loop"; } else { @@ -2178,67 +1918,57 @@ namespace EnergyPlus { // CurrentModuleObject='Plant/Condenser Loop' SetupOutputVariable("Plant Supply Side Cooling Demand Rate", OutputProcessor::Unit::W, - PlantReport(LoopNum).CoolingDemand, + loop.CoolingDemand, "System", "Average", PlantLoop(LoopNum).Name); SetupOutputVariable("Plant Supply Side Heating Demand Rate", OutputProcessor::Unit::W, - PlantReport(LoopNum).HeatingDemand, + loop.HeatingDemand, "System", "Average", PlantLoop(LoopNum).Name); SetupOutputVariable("Plant Supply Side Inlet Mass Flow Rate", OutputProcessor::Unit::kg_s, - PlantReport(LoopNum).InletNodeFlowrate, + loop.InletNodeFlowrate, "System", "Average", PlantLoop(LoopNum).Name); SetupOutputVariable("Plant Supply Side Inlet Temperature", OutputProcessor::Unit::C, - PlantReport(LoopNum).InletNodeTemperature, + loop.InletNodeTemperature, "System", "Average", PlantLoop(LoopNum).Name); SetupOutputVariable("Plant Supply Side Outlet Temperature", OutputProcessor::Unit::C, - PlantReport(LoopNum).OutletNodeTemperature, + loop.OutletNodeTemperature, "System", "Average", PlantLoop(LoopNum).Name); SetupOutputVariable("Plant Supply Side Not Distributed Demand Rate", OutputProcessor::Unit::W, - PlantReport(LoopNum).DemandNotDispatched, + loop.DemandNotDispatched, "System", "Average", PlantLoop(LoopNum).Name); SetupOutputVariable("Plant Supply Side Unmet Demand Rate", OutputProcessor::Unit::W, - PlantReport(LoopNum).UnmetDemand, + loop.UnmetDemand, "System", "Average", PlantLoop(LoopNum).Name); - - // Debug variables -- used by OSU developers SetupOutputVariable("Debug Plant Loop Bypass Fraction", OutputProcessor::Unit::None, - PlantReport(LoopNum).BypassFrac, + loop.BypassFrac, "System", "Average", PlantLoop(LoopNum).Name); - // CALL SetupOutputVariable('Debug SSInletNode Flowrate[kg/s]', & - // PlantReport(LoopNum)%InletNodeFlowrate,'System','Average',PlantLoop(LoopNum)%Name) - // CALL SetupOutputVariable('Debug SSInletNode Temperature[C]', & - // PlantReport(LoopNum)%InletNodeTemperature,'System','Average',PlantLoop(LoopNum)%Name) - // CALL SetupOutputVariable('Debug SSOutletNode Flowrate [kg/s]', & - // PlantReport(LoopNum)%OutletNodeFlowrate,'System','Average',PlantLoop(LoopNum)%Name) - // CALL SetupOutputVariable('Debug SSOutletNode Temperature[C]', & - // PlantReport(LoopNum)%OutletNodeTemperature,'System','Average',PlantLoop(LoopNum)%Name) SetupOutputVariable("Debug Plant Last Simulated Loop Side", OutputProcessor::Unit::None, - PlantReport(LoopNum).LastLoopSideSimulated, + loop.LastLoopSideSimulated, "System", "Average", PlantLoop(LoopNum).Name); @@ -2367,7 +2097,6 @@ namespace EnergyPlus { using EMSManager::iTemperatureMinSetPoint; using EMSManager::iTemperatureSetPoint; using General::RoundSigDigits; - using PlantLoopEquip::SimPlantEquip; using PlantUtilities::SetAllFlowLocks; // SUBROUTINE LOCAL VARIABLE DECLARATIONS: @@ -2474,8 +2203,7 @@ namespace EnergyPlus { BranchNum <= PlantLoop(LoopNum).LoopSide(LoopSideNum).TotalBranches; ++BranchNum) { for (CompNum = 1; CompNum <= PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch( BranchNum).TotalComponents; ++CompNum) { - SimPlantEquip(LoopNum, LoopSideNum, BranchNum, CompNum, FirstHVACIteration, - InitLoopEquip, GetCompSizFac); + PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(CompNum).simulate(FirstHVACIteration, InitLoopEquip, GetCompSizFac); } //-CompNum } //-BranchNum } @@ -2519,13 +2247,12 @@ namespace EnergyPlus { SizePlantLoop(LoopNum, FinishSizingFlag); } // pumps are special so call them directly - PlantLoop(LoopNum).loopSolver.SimulateAllLoopSidePumps(LoopNum, LoopSideNum); + PlantLoop(LoopNum).LoopSide(LoopSideNum).SimulateAllLoopSidePumps(); for (BranchNum = 1; BranchNum <= PlantLoop(LoopNum).LoopSide(LoopSideNum).TotalBranches; ++BranchNum) { for (CompNum = 1; CompNum <= PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch( BranchNum).TotalComponents; ++CompNum) { - SimPlantEquip(LoopNum, LoopSideNum, BranchNum, CompNum, FirstHVACIteration, InitLoopEquip, - GetCompSizFac); + PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(CompNum).simulate(FirstHVACIteration, InitLoopEquip, GetCompSizFac); } //-CompNum } //-BranchNum // if ( PlantLoop( LoopNum ).PlantSizNum > 0 ) PlantSizData( PlantLoop( LoopNum ).PlantSizNum @@ -2555,8 +2282,7 @@ namespace EnergyPlus { BranchNum <= PlantLoop(LoopNum).LoopSide(LoopSideNum).TotalBranches; ++BranchNum) { for (CompNum = 1; CompNum <= PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch( BranchNum).TotalComponents; ++CompNum) { - SimPlantEquip(LoopNum, LoopSideNum, BranchNum, CompNum, FirstHVACIteration, InitLoopEquip, - GetCompSizFac); + PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(CompNum).simulate(FirstHVACIteration, InitLoopEquip, GetCompSizFac); } //-CompNum } //-BranchNum } @@ -2579,12 +2305,11 @@ namespace EnergyPlus { BranchNum <= PlantLoop(LoopNum).LoopSide(LoopSideNum).TotalBranches; ++BranchNum) { for (CompNum = 1; CompNum <= PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch( BranchNum).TotalComponents; ++CompNum) { - SimPlantEquip(LoopNum, LoopSideNum, BranchNum, CompNum, FirstHVACIteration, InitLoopEquip, - GetCompSizFac); + PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(CompNum).simulate(FirstHVACIteration, InitLoopEquip, GetCompSizFac); } //-CompNum } //-BranchNum // pumps are special so call them directly - PlantLoop(LoopNum).loopSolver.SimulateAllLoopSidePumps(LoopNum, LoopSideNum); + PlantLoop(LoopNum).LoopSide(LoopSideNum).SimulateAllLoopSidePumps(); } PlantReSizingCompleted = true; @@ -2884,16 +2609,16 @@ namespace EnergyPlus { } // BRANCH LOOP } // LOOPSIDE } // PLANT LOOP - for (auto &e : PlantReport) { - e.CoolingDemand = 0.0; - e.HeatingDemand = 0.0; - e.DemandNotDispatched = 0.0; - e.UnmetDemand = 0.0; - e.LastLoopSideSimulated = 0; - e.InletNodeFlowrate = 0.0; - e.InletNodeTemperature = 0.0; - e.OutletNodeFlowrate = 0.0; - e.OutletNodeTemperature = 0.0; + for (auto &loop : PlantLoop) { + loop.CoolingDemand = 0.0; + loop.HeatingDemand = 0.0; + loop.DemandNotDispatched = 0.0; + loop.UnmetDemand = 0.0; + loop.LastLoopSideSimulated = 0; + loop.InletNodeFlowrate = 0.0; + loop.InletNodeTemperature = 0.0; + loop.OutletNodeFlowrate = 0.0; + loop.OutletNodeTemperature = 0.0; } MyEnvrnFlag = false; @@ -3085,7 +2810,7 @@ namespace EnergyPlus { for (LoopNum = 1; LoopNum <= TotNumLoops; ++LoopNum) { numLoopSides = 2; for (SideNum = 1; SideNum <= numLoopSides; ++SideNum) { - if (!(PlantLoop(LoopNum).LoopSide(SideNum).SplitterExists)) continue; + if (!(PlantLoop(LoopNum).LoopSide(SideNum).Splitter.Exists)) continue; for (ParalBranchNum = 1; ParalBranchNum <= PlantLoop(LoopNum).LoopSide(SideNum).Splitter.TotalOutletNodes; @@ -3276,7 +3001,6 @@ namespace EnergyPlus { using namespace DataSizing; using FluidProperties::GetDensityGlycol; using General::RoundSigDigits; - using PlantLoopEquip::SimPlantEquip; using ReportSizingManager::ReportSizingOutput; // Locals @@ -3327,7 +3051,7 @@ namespace EnergyPlus { continue; for (CompNum = 1; CompNum <= PlantLoop(LoopNum).LoopSide(SupplySide).Branch( BranchNum).TotalComponents; ++CompNum) { - SimPlantEquip(LoopNum, SupplySide, BranchNum, CompNum, true, localInitLoopEquip, GetCompSizFac); + PlantLoop(LoopNum).LoopSide(SupplySide).Branch(BranchNum).Comp(CompNum).simulate(true, localInitLoopEquip, GetCompSizFac); BranchSizFac = max(BranchSizFac, PlantLoop(LoopNum).LoopSide(SupplySide).Branch(BranchNum).Comp( CompNum).SizFac); @@ -3705,8 +3429,6 @@ namespace EnergyPlus { PlantCallingOrderInfo(OrderIndex).LoopSide = SupplySide; } - // legacy one-time calling control stuff moved here from manager routine, hopefully remove - if (!allocated(LoadChangeDownStream)) LoadChangeDownStream.allocate(TotNumLoops); } void RevisePlantCallingOrder() { @@ -3859,44 +3581,6 @@ namespace EnergyPlus { return CallingIndex; } - void StoreAPumpOnCurrentTempLoop(int const LoopNum, - int const LoopSideNum, - int const BranchNum, - int const CompNum, - std::string const &PumpName, - int const PumpOutletNode, - bool const HasBranchPumps) { - - // SUBROUTINE INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN April 2010 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // This routine reallocates the pumps data structure in the LoopSide data structure - // and adds the pump data passed in as the next pump - - // METHODOLOGY EMPLOYED: - // Fills the following location items in the pump data structure which resides on the LoopSide - // TYPE LoopSidePumpInformation - // CHARACTER(len=MaxNameLength) :: PumpName = ' ' - // INTEGER :: PumpTypeOf = 0 - // INTEGER :: BranchNum = 0 - // INTEGER :: CompNum = 0 - // ... - - auto &loop_side(PlantLoop(LoopNum).LoopSide(LoopSideNum)); - auto &pumps(loop_side.Pumps); - int const nPumpsAfterIncrement = loop_side.TotalPumps = pumps.size() + 1; - pumps.redimension(nPumpsAfterIncrement); - pumps(nPumpsAfterIncrement).PumpName = PumpName; - pumps(nPumpsAfterIncrement).BranchNum = BranchNum; - pumps(nPumpsAfterIncrement).CompNum = CompNum; - pumps(nPumpsAfterIncrement).PumpOutletNode = PumpOutletNode; - loop_side.BranchPumpsExist = HasBranchPumps; - } - void SetupBranchControlTypes() { // SUBROUTINE INFORMATION: @@ -3935,27 +3619,22 @@ namespace EnergyPlus { } else { NumCount = 0; } - for (LoopCtr = 1; LoopCtr <= NumCount; ++LoopCtr) { // SIZE(PlantLoop) + for (LoopCtr = 1; LoopCtr <= NumCount; ++LoopCtr) { for (LoopSideCtr = DemandSide; LoopSideCtr <= SupplySide; ++LoopSideCtr) { - for (BranchCtr = 1; - BranchCtr <= PlantLoop(LoopCtr).LoopSide(LoopSideCtr).TotalBranches; ++BranchCtr) { + for (BranchCtr = 1; BranchCtr <= PlantLoop(LoopCtr).LoopSide(LoopSideCtr).TotalBranches; ++BranchCtr) { BranchIsInSplitterMixer = false; // test if this branch is inside a splitter/mixer - if (PlantLoop(LoopCtr).LoopSide(LoopSideCtr).SplitterExists) { - if ((BranchCtr > 1) && - (BranchCtr < PlantLoop(LoopCtr).LoopSide(LoopSideCtr).TotalBranches)) { + if (PlantLoop(LoopCtr).LoopSide(LoopSideCtr).Splitter.Exists) { + if ((BranchCtr > 1) && (BranchCtr < PlantLoop(LoopCtr).LoopSide(LoopSideCtr).TotalBranches)) { BranchIsInSplitterMixer = true; } } - NumComponentsOnBranch = PlantLoop(LoopCtr).LoopSide(LoopSideCtr).Branch( - BranchCtr).TotalComponents; + NumComponentsOnBranch = PlantLoop(LoopCtr).LoopSide(LoopSideCtr).Branch(BranchCtr).TotalComponents; - for (CompCtr = 1; CompCtr <= isize(PlantLoop(LoopCtr).LoopSide(LoopSideCtr).Branch( - BranchCtr).Comp); ++CompCtr) { + for (CompCtr = 1; CompCtr <= isize(PlantLoop(LoopCtr).LoopSide(LoopSideCtr).Branch(BranchCtr).Comp); ++CompCtr) { - auto &this_component( - PlantLoop(LoopCtr).LoopSide(LoopSideCtr).Branch(BranchCtr).Comp(CompCtr)); + auto &this_component(PlantLoop(LoopCtr).LoopSide(LoopSideCtr).Branch(BranchCtr).Comp(CompCtr)); { auto const SELECT_CASE_var(this_component.TypeOf_Num); diff --git a/src/EnergyPlus/Plant/PlantManager.hh b/src/EnergyPlus/Plant/PlantManager.hh index 26a911f093b..149849f362b 100644 --- a/src/EnergyPlus/Plant/PlantManager.hh +++ b/src/EnergyPlus/Plant/PlantManager.hh @@ -53,7 +53,7 @@ // EnergyPlus Headers #include -#include +#include #include namespace EnergyPlus { @@ -77,34 +77,9 @@ namespace PlantManager { extern Array1D_int SupplySideOutletNode; // Node number for the supply side outlet extern Array1D_int DemandSideInletNode; // Inlet node on the demand side - struct TempLoopData - { - // Members - std::string Name; // Name of the component list - // Loop connections - std::string BranchList; // Branch list name for the half loop - std::string ConnectList; // Connector list name for the half loop - int TotalBranches; // Total number of branches on the loop - Array1D Branch; // Branch data - SplitterData Splitter; // Data for splitter on branch (if any) - MixerData Mixer; // Data for mixer on branch (if any) - bool SplitterExists; // Logical Flag indication splitter exists in the half loop - bool MixerExists; // Logical Flag indication mixer exists in the half loop - bool BypassExists; - bool LoopHasConnectionComp; - - // Default Constructor - TempLoopData() : TotalBranches(0), SplitterExists(false), MixerExists(false), BypassExists(false), LoopHasConnectionComp(false) - { - } - }; - - // Object Data - extern TempLoopData TempLoop; // =(' ',' ',' ',0, , , ,.FALSE.,.FALSE.,.FALSE.,.FALSE.,.FALSE.) - void clear_state(); - void ManagePlantLoops(bool const FirstHVACIteration, + void ManagePlantLoops(bool FirstHVACIteration, bool &SimAirLoops, // True when the air loops need to be (re)simulated bool &SimZoneEquipment, // True when zone equipment components need to be (re)simulated bool &SimNonZoneEquipment, // True when non-zone equipment components need to be (re)simulated @@ -118,7 +93,7 @@ namespace PlantManager { void SetupReports(); - void InitializeLoops(bool const FirstHVACIteration); // true if first iteration of the simulation + void InitializeLoops(bool FirstHVACIteration); // true if first iteration of the simulation void ReInitPlantLoopsAtFirstHVACIteration(); @@ -126,26 +101,18 @@ namespace PlantManager { void CheckPlantOnAbort(); - void InitOneTimePlantSizingInfo(int const LoopNum); // loop being initialized for sizing + void InitOneTimePlantSizingInfo(int LoopNum); // loop being initialized for sizing - void SizePlantLoop(int const LoopNum, // Supply side loop being simulated - bool const OkayToFinish); + void SizePlantLoop(int LoopNum, // Supply side loop being simulated + bool OkayToFinish); - void ResizePlantLoopLevelSizes(int const LoopNum); + void ResizePlantLoopLevelSizes(int LoopNum); void SetupInitialPlantCallingOrder(); void RevisePlantCallingOrder(); - int FindLoopSideInCallingOrder(int const LoopNum, int const LoopSide); - - void StoreAPumpOnCurrentTempLoop(int const LoopNum, - int const LoopSideNum, - int const BranchNum, - int const CompNum, - std::string const &PumpName, - int const PumpOutletNode, - bool const HasBranchPumps); + int FindLoopSideInCallingOrder(int LoopNum, int LoopSide); void SetupBranchControlTypes(); diff --git a/src/EnergyPlus/Plant/ReportCompData.hh b/src/EnergyPlus/Plant/ReportCompData.hh index 40c5f39f074..63dc6fa75a0 100644 --- a/src/EnergyPlus/Plant/ReportCompData.hh +++ b/src/EnergyPlus/Plant/ReportCompData.hh @@ -58,7 +58,6 @@ namespace DataPlant { struct ReportCompData { // Members - bool Parent; // TRUE = designated component is made up of sub-components std::string TypeOf; // The 'keyWord' identifying component type std::string Name; // Component name int CompIndex; // Component Index in whatever is using this component @@ -79,7 +78,7 @@ namespace DataPlant { // Default Constructor ReportCompData() - : Parent(false), CompIndex(0), NodeNumIn(0), NodeNumOut(0), NumMeteredVars(0), NumSubComps(0), LoopLoadFrac(0.0), TotPlantSupplyElec(0.0), + : CompIndex(0), NodeNumIn(0), NodeNumOut(0), NumMeteredVars(0), NumSubComps(0), LoopLoadFrac(0.0), TotPlantSupplyElec(0.0), TotPlantSupplyGas(0.0), TotPlantSupplyPurch(0.0), TotPlantSupplyOther(0.0) { } diff --git a/src/EnergyPlus/PlantCentralGSHP.cc b/src/EnergyPlus/PlantCentralGSHP.cc index 7716b899dcf..df05bd50771 100644 --- a/src/EnergyPlus/PlantCentralGSHP.cc +++ b/src/EnergyPlus/PlantCentralGSHP.cc @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PlantChillers.cc b/src/EnergyPlus/PlantChillers.cc index 719488b4e37..cb44f698b42 100644 --- a/src/EnergyPlus/PlantChillers.cc +++ b/src/EnergyPlus/PlantChillers.cc @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PlantComponentTemperatureSources.hh b/src/EnergyPlus/PlantComponentTemperatureSources.hh index a360e33e7af..a6145366759 100644 --- a/src/EnergyPlus/PlantComponentTemperatureSources.hh +++ b/src/EnergyPlus/PlantComponentTemperatureSources.hh @@ -53,7 +53,7 @@ // EnergyPlus Headers #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PlantCondLoopOperation.cc b/src/EnergyPlus/PlantCondLoopOperation.cc index f0a1612bf26..0524744a5b3 100644 --- a/src/EnergyPlus/PlantCondLoopOperation.cc +++ b/src/EnergyPlus/PlantCondLoopOperation.cc @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include #include #include @@ -3231,7 +3231,7 @@ namespace PlantCondLoopOperation { for (MachineOnBranch = 1; MachineOnBranch <= PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(Num).TotalComponents; ++MachineOnBranch) { // Sankar Non Integrated Economizer - if (PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(Num).Comp(MachineOnBranch).GeneralEquipType != GenEquipTypes_Pump) { + if (!PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(Num).Comp(MachineOnBranch).isPump()) { PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(Num).Comp(MachineOnBranch).ON = false; PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(Num).Comp(MachineOnBranch).MyLoad = 0.0; } @@ -3272,7 +3272,7 @@ namespace PlantCondLoopOperation { for (Num = 1; Num <= PlantLoop(LoopNum).LoopSide(LoopSideNum).TotalBranches; ++Num) { for (MachineOnBranch = 1; MachineOnBranch <= PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(Num).TotalComponents; ++MachineOnBranch) { // Sankar Non Integrated Economizer - if (PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(Num).Comp(MachineOnBranch).GeneralEquipType != GenEquipTypes_Pump) { + if (!PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(Num).Comp(MachineOnBranch).isPump()) { PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(Num).Comp(MachineOnBranch).ON = false; PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(Num).Comp(MachineOnBranch).MyLoad = 0.0; } diff --git a/src/EnergyPlus/PlantHeatExchangerFluidToFluid.cc b/src/EnergyPlus/PlantHeatExchangerFluidToFluid.cc index b3340071305..60740860f9f 100644 --- a/src/EnergyPlus/PlantHeatExchangerFluidToFluid.cc +++ b/src/EnergyPlus/PlantHeatExchangerFluidToFluid.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PlantLoadProfile.cc b/src/EnergyPlus/PlantLoadProfile.cc index 4611639498d..f6839fee20a 100644 --- a/src/EnergyPlus/PlantLoadProfile.cc +++ b/src/EnergyPlus/PlantLoadProfile.cc @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PlantLoopEquip.hh b/src/EnergyPlus/PlantLoopEquip.hh deleted file mode 100644 index dfde27f5be7..00000000000 --- a/src/EnergyPlus/PlantLoopEquip.hh +++ /dev/null @@ -1,76 +0,0 @@ -// EnergyPlus, Copyright (c) 1996-2020, The Board of Trustees of the University of Illinois, -// The Regents of the University of California, through Lawrence Berkeley National Laboratory -// (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge -// National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other -// contributors. All rights reserved. -// -// NOTICE: This Software was developed under funding from the U.S. Department of Energy and the -// U.S. Government consequently retains certain rights. As such, the U.S. Government has been -// granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, -// worldwide license in the Software to reproduce, distribute copies to the public, prepare -// derivative works, and perform publicly and display publicly, and to permit others to do so. -// -// Redistribution and use in source and binary forms, with or without modification, are permitted -// provided that the following conditions are met: -// -// (1) Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// (2) Redistributions in binary form must reproduce the above copyright notice, this list of -// conditions and the following disclaimer in the documentation and/or other materials -// provided with the distribution. -// -// (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, -// the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific prior -// written permission. -// -// (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form -// without changes from the version obtained under this License, or (ii) Licensee makes a -// reference solely to the software portion of its product, Licensee must refer to the -// software as "EnergyPlus version X" software, where "X" is the version number Licensee -// obtained under this License and may not use a different name for the software. Except as -// specifically required in this Section (4), Licensee shall not use in a company name, a -// product name, in advertising, publicity, or other promotional activities any name, trade -// name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly -// similar designation, without the U.S. Department of Energy's prior written consent. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef PlantLoopEquip_hh_INCLUDED -#define PlantLoopEquip_hh_INCLUDED - -// EnergyPlus Headers -#include - -namespace EnergyPlus { - -namespace PlantLoopEquip { - - // Data - // SUBROUTINE SPECIFICATION - - // Functions - - void SimPlantEquip(int const LoopNum, // loop counter - int const LoopSideNum, // loop counter - int const BranchNum, - int const Num, - bool const FirstHVACIteration, // TRUE if First iteration of simulation - bool &InitLoopEquip, - bool const GetCompSizFac // Tells component routine to return the component sizing fraction - ); - -} // namespace PlantLoopEquip - -} // namespace EnergyPlus - -#endif diff --git a/src/EnergyPlus/PlantLoopHeatPumpEIR.cc b/src/EnergyPlus/PlantLoopHeatPumpEIR.cc index e4047106ba6..aec27285932 100644 --- a/src/EnergyPlus/PlantLoopHeatPumpEIR.cc +++ b/src/EnergyPlus/PlantLoopHeatPumpEIR.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PlantPipingSystemsManager.cc b/src/EnergyPlus/PlantPipingSystemsManager.cc index d058246342c..bd83e1ef815 100644 --- a/src/EnergyPlus/PlantPipingSystemsManager.cc +++ b/src/EnergyPlus/PlantPipingSystemsManager.cc @@ -70,7 +70,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PlantPressureSystem.cc b/src/EnergyPlus/PlantPressureSystem.cc index 4be8819cd96..1007a99520d 100644 --- a/src/EnergyPlus/PlantPressureSystem.cc +++ b/src/EnergyPlus/PlantPressureSystem.cc @@ -59,7 +59,7 @@ #include #include #include -#include +#include #include #include #include @@ -678,7 +678,6 @@ namespace PlantPressureSystem { // Using/Aliasing using DataLoopNode::Node; using DataPlant::DemandSide; - using DataPlant::GenEquipTypes_Pump; using DataPlant::PlantLoop; using DataPlant::SupplySide; @@ -698,7 +697,7 @@ namespace PlantPressureSystem { } // If the last component on the branch is the pump, then check if a pressure drop is detected and set the flag and leave - if (PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(NumCompsOnBranch).GeneralEquipType == GenEquipTypes_Pump) { + if (PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(NumCompsOnBranch).isPump()) { PumpFound = true; if (TempBranchPressureDrop != 0.0) { ShowSevereError("Error in plant pressure simulation for plant loop: " + PlantLoop(LoopNum).Name); @@ -730,7 +729,7 @@ namespace PlantPressureSystem { for (CompNum = NumCompsOnBranch - 1; CompNum >= 1; --CompNum) { // If this component is a pump, stop passing pressure upstream, and set flag to true for calling routine - if (PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(CompNum).GeneralEquipType == GenEquipTypes_Pump) { + if (PlantLoop(LoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(CompNum).isPump()) { PumpFound = true; break; } diff --git a/src/EnergyPlus/PlantUtilities.cc b/src/EnergyPlus/PlantUtilities.cc index 1b78db3736b..1f1e94b2172 100644 --- a/src/EnergyPlus/PlantUtilities.cc +++ b/src/EnergyPlus/PlantUtilities.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include @@ -577,79 +577,6 @@ namespace PlantUtilities { return FlowVal; } - void UpdatePlantMixer(int const LoopNum, int const LoopSideNum) - { - - // SUBROUTINE INFORMATION: - // AUTHOR Brandon Anderson, Dan Fisher - // DATE WRITTEN October 1999 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // calculate the outlet conditions at the mixer - // this is expected to only be called for loops with a mixer - - // Find mixer outlet node number - int const MixerOutletNode = DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Mixer.NodeNumOut; - - // Find corresponding splitter inlet node number--correspondence, but currently - // hard code things to a single split/mix setting it to the mixer number - int const SplitterInNode = DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Splitter.NodeNumIn; - // Initialize Mixer outlet temp and mass flow rate - Real64 MixerOutletTemp = 0.0; - Real64 MixerOutletMassFlow = 0.0; - Real64 MixerOutletMassFlowMaxAvail = 0.0; - Real64 MixerOutletMassFlowMinAvail = 0.0; - Real64 MixerOutletPress = 0.0; - Real64 MixerOutletQuality = 0.0; - - // Calculate Mixer outlet mass flow rate - for (int InletNodeNum = 1; InletNodeNum <= DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Mixer.TotalInletNodes; ++InletNodeNum) { - int const MixerInletNode = DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Mixer.NodeNumIn(InletNodeNum); - MixerOutletMassFlow += DataLoopNode::Node(MixerInletNode).MassFlowRate; - } - - // Calculate Mixer outlet temperature - for (int InletNodeNum = 1; InletNodeNum <= DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Mixer.TotalInletNodes; ++InletNodeNum) { - int const MixerInletNode = DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Mixer.NodeNumIn(InletNodeNum); - if (MixerOutletMassFlow > 0.0) { - Real64 const MixerInletMassFlow = DataLoopNode::Node(MixerInletNode).MassFlowRate; - Real64 const MassFrac = MixerInletMassFlow / MixerOutletMassFlow; - // mass flow weighted temp and enthalpy for each mixer inlet - MixerOutletTemp += MassFrac * DataLoopNode::Node(MixerInletNode).Temp; - MixerOutletQuality += MassFrac * DataLoopNode::Node(MixerInletNode).Quality; - MixerOutletMassFlowMaxAvail += DataLoopNode::Node(MixerInletNode).MassFlowRateMaxAvail; - MixerOutletMassFlowMinAvail += DataLoopNode::Node(MixerInletNode).MassFlowRateMinAvail; - MixerOutletPress = max(MixerOutletPress, DataLoopNode::Node(MixerInletNode).Press); - } else { // MixerOutletMassFlow <=0, then perform the 'no flow' update. - MixerOutletTemp = DataLoopNode::Node(SplitterInNode).Temp; - MixerOutletQuality = DataLoopNode::Node(SplitterInNode).Quality; - MixerOutletMassFlowMaxAvail = DataLoopNode::Node(SplitterInNode).MassFlowRateMaxAvail; - MixerOutletMassFlowMinAvail = DataLoopNode::Node(SplitterInNode).MassFlowRateMinAvail; - MixerOutletPress = DataLoopNode::Node(SplitterInNode).Press; - break; - } - } - - DataLoopNode::Node(MixerOutletNode).MassFlowRate = MixerOutletMassFlow; - DataLoopNode::Node(MixerOutletNode).Temp = MixerOutletTemp; - if (DataPlant::PlantLoop(LoopNum).HasPressureComponents) { - // Don't update pressure, let pressure system handle this... - } else { - // Go ahead and update! - DataLoopNode::Node(MixerOutletNode).Press = MixerOutletPress; - } - DataLoopNode::Node(MixerOutletNode).Quality = MixerOutletQuality; - - // set max/min avails on mixer outlet to be consistent with the following rules - // 1. limited by the max/min avails on splitter inlet - // 2. limited by the sum of max/min avails for each branch's mixer inlet node - - DataLoopNode::Node(MixerOutletNode).MassFlowRateMaxAvail = min(MixerOutletMassFlowMaxAvail, DataLoopNode::Node(SplitterInNode).MassFlowRateMaxAvail); - DataLoopNode::Node(MixerOutletNode).MassFlowRateMinAvail = max(MixerOutletMassFlowMinAvail, DataLoopNode::Node(SplitterInNode).MassFlowRateMinAvail); - } - bool AnyPlantSplitterMixerLacksContinuity() { @@ -663,7 +590,7 @@ namespace PlantUtilities { // Similar to CheckPlantMixerSplitterConsistency, but used to decide if plant needs to iterate again for (int LoopNum = 1; LoopNum <= DataPlant::TotNumLoops; ++LoopNum) { for (int LoopSide = DataPlant::DemandSide; LoopSide <= DataPlant::SupplySide; ++LoopSide) { - if (DataPlant::PlantLoop(LoopNum).LoopSide(LoopSide).SplitterExists) { + if (DataPlant::PlantLoop(LoopNum).LoopSide(LoopSide).Splitter.Exists) { int const SplitterInletNode = DataPlant::PlantLoop(LoopNum).LoopSide(LoopSide).Splitter.NodeNumIn; // loop across branch outlet nodes and check mass continuity int const NumSplitterOutlets = DataPlant::PlantLoop(LoopNum).LoopSide(LoopSide).Splitter.TotalOutletNodes; @@ -721,7 +648,7 @@ namespace PlantUtilities { int LastNodeOnBranch; if (!PlantLoop(LoopNum).LoopHasConnectionComp) { - if (!DoingSizing && !WarmupFlag && PlantLoop(LoopNum).LoopSide(LoopSideNum).MixerExists && !FirstHVACIteration) { + if (!DoingSizing && !WarmupFlag && PlantLoop(LoopNum).LoopSide(LoopSideNum).Mixer.Exists && !FirstHVACIteration) { // Find mixer outlet node number MixerOutletNode = PlantLoop(LoopNum).LoopSide(LoopSideNum).Mixer.NodeNumOut; // Find splitter inlet node number @@ -826,7 +753,6 @@ namespace PlantUtilities { using DataLoopNode::NodeID; using DataPlant::DemandSide; using DataPlant::PlantLoop; - using DataPlant::PlantReport; using DataPlant::SupplySide; using General::RoundSigDigits; @@ -934,10 +860,10 @@ namespace PlantUtilities { " {kg/s}"); ShowContinueError("PlantLoop PumpHeat (SupplySide)=" + RoundSigDigits(PlantLoop(LoopNum).LoopSide(SupplySide).TotalPumpHeat, 1) + " {W}"); ShowContinueError("PlantLoop PumpHeat (DemandSide)=" + RoundSigDigits(PlantLoop(LoopNum).LoopSide(DemandSide).TotalPumpHeat, 1) + " {W}"); - ShowContinueError("PlantLoop Cooling Demand=" + RoundSigDigits(PlantReport(LoopNum).CoolingDemand, 1) + " {W}"); - ShowContinueError("PlantLoop Heating Demand=" + RoundSigDigits(PlantReport(LoopNum).HeatingDemand, 1) + " {W}"); - ShowContinueError("PlantLoop Demand not Dispatched=" + RoundSigDigits(PlantReport(LoopNum).DemandNotDispatched, 1) + " {W}"); - ShowContinueError("PlantLoop Unmet Demand=" + RoundSigDigits(PlantReport(LoopNum).UnmetDemand, 1) + " {W}"); + ShowContinueError("PlantLoop Cooling Demand=" + RoundSigDigits(PlantLoop(LoopNum).CoolingDemand, 1) + " {W}"); + ShowContinueError("PlantLoop Heating Demand=" + RoundSigDigits(PlantLoop(LoopNum).HeatingDemand, 1) + " {W}"); + ShowContinueError("PlantLoop Demand not Dispatched=" + RoundSigDigits(PlantLoop(LoopNum).DemandNotDispatched, 1) + " {W}"); + ShowContinueError("PlantLoop Unmet Demand=" + RoundSigDigits(PlantLoop(LoopNum).UnmetDemand, 1) + " {W}"); LoopCapacity = 0.0; DispatchedCapacity = 0.0; @@ -976,58 +902,6 @@ namespace PlantUtilities { } } - void UpdatePlantSplitter(int const LoopNum, int const LoopSideNum) - { - - // SUBROUTINE INFORMATION: - // AUTHOR Brandon Anderson, Dan Fisher - // DATE WRITTEN October 1999 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // Set the outlet conditions of the splitter - - // Update Temperatures across splitter - if (DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).SplitterExists) { - - // Set branch number at splitter inlet - int const SplitterInletNode = DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Splitter.NodeNumIn; - - // Loop over outlet nodes - for (int CurNode = 1; CurNode <= DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Splitter.TotalOutletNodes; ++CurNode) { - int const SplitterOutletNode = DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Splitter.NodeNumOut(CurNode); - - // Inlet Temp equals exit Temp to all outlet branches - DataLoopNode::Node(SplitterOutletNode).Temp = DataLoopNode::Node(SplitterInletNode).Temp; - DataLoopNode::Node(SplitterOutletNode).TempMin = DataLoopNode::Node(SplitterInletNode).TempMin; - DataLoopNode::Node(SplitterOutletNode).TempMax = DataLoopNode::Node(SplitterInletNode).TempMax; - if (DataPlant::PlantLoop(LoopNum).HasPressureComponents) { - // Don't update pressure, let pressure system handle this... - } else { - // Go ahead and update! - DataLoopNode::Node(SplitterOutletNode).Press = DataLoopNode::Node(SplitterInletNode).Press; - } - DataLoopNode::Node(SplitterOutletNode).Quality = DataLoopNode::Node(SplitterInletNode).Quality; - - // DSU? These two blocks and the following one which I added need to be cleaned up - // I think we will always pass maxavail down the splitter, min avail is the issue. - // Changed to include hardware max in next line 7/26/2011 - DataLoopNode::Node(SplitterOutletNode).MassFlowRateMaxAvail = - min(DataLoopNode::Node(SplitterInletNode).MassFlowRateMaxAvail, DataLoopNode::Node(SplitterOutletNode).MassFlowRateMax); - DataLoopNode::Node(SplitterOutletNode).MassFlowRateMinAvail = 0.0; - - // DSU? Not sure about passing min avail if it is nonzero. I am testing a pump with nonzero - // min flow rate, and it is causing problems because this routine passes zero down. Perhaps if - // it is a single parallel branch, we are safe to assume we need to just pass it down. - // But need to test for multiple branches (or at least think about it), to see what we need to do... - if (DataPlant::PlantLoop(LoopNum).LoopSide(LoopSideNum).Splitter.TotalOutletNodes == 1) { - DataLoopNode::Node(SplitterOutletNode).MassFlowRateMinAvail = DataLoopNode::Node(SplitterInletNode).MassFlowRateMinAvail; - } - } - } - } - void SetAllFlowLocks(int const Value) { @@ -1860,68 +1734,6 @@ namespace PlantUtilities { } } - bool CheckPlantConvergence(int const ThisLoopNum, int const ThisLoopSide, bool const FirstHVACIteration) - { - - // FUNCTION INFORMATION: - // AUTHOR Edwin Lee - // DATE WRITTEN Summer 2011 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS FUNCTION: - // This routine checks the history values in the convergence arrays of this loop/LoopSide combination - - // METHODOLOGY EMPLOYED: - // On FirstHVAC, we are not converged yet, thus forcing at least two iterations - // Calculate the average of each related variable history (generalized: could be any number of history terms) - // If any of the history terms do not match this average, then at least one value is different, so not converged - // Although this routine appears to check for convergence, it is also used to check for stuck (max iteration) conditions - // in cases where demand side (air loop, for example) equipment is "fighting" with the plant loop - // The result of this routine can help the plant "lock-in" and take action to stop the iteration - - // Using/Aliasing - using namespace DataPlant; - using namespace DataLoopNode; - - // FUNCTION LOCAL VARIABLE DECLARATIONS: - Real64 InletAvgTemp; - Real64 InletAvgMdot; - Real64 OutletAvgTemp; - Real64 OutletAvgMdot; - - if (FirstHVACIteration) { - return false; - } - - InletAvgTemp = sum(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).InletNode.TemperatureHistory) / - size(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).InletNode.TemperatureHistory); - if (any_ne(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).InletNode.TemperatureHistory, InletAvgTemp)) { - return false; - } - - InletAvgMdot = sum(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).InletNode.MassFlowRateHistory) / - size(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).InletNode.MassFlowRateHistory); - if (any_ne(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).InletNode.MassFlowRateHistory, InletAvgMdot)) { - return false; - } - - OutletAvgTemp = sum(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).OutletNode.TemperatureHistory) / - size(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).OutletNode.TemperatureHistory); - if (any_ne(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).OutletNode.TemperatureHistory, OutletAvgTemp)) { - return false; - } - - OutletAvgMdot = sum(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).OutletNode.MassFlowRateHistory) / - size(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).OutletNode.MassFlowRateHistory); - if (any_ne(PlantLoop(ThisLoopNum).LoopSide(ThisLoopSide).OutletNode.MassFlowRateHistory, OutletAvgMdot)) { - return false; - } - - // If we made it this far, we're good! - return true; - } - void ScanPlantLoopsForObject(std::string const &CompName, int const CompType, int &LoopNum, diff --git a/src/EnergyPlus/PlantUtilities.hh b/src/EnergyPlus/PlantUtilities.hh index ecaccac28bd..e58e0dc94d6 100644 --- a/src/EnergyPlus/PlantUtilities.hh +++ b/src/EnergyPlus/PlantUtilities.hh @@ -91,8 +91,6 @@ namespace PlantUtilities { Real64 RegulateCondenserCompFlowReqOp( int const LoopNum, int const LoopSideNum, int const BranchNum, int const CompNum, Real64 const TentativeFlowRequest); - void UpdatePlantMixer(int const LoopNum, int const LoopSideNum); - bool AnyPlantSplitterMixerLacksContinuity(); void @@ -100,8 +98,6 @@ namespace PlantUtilities { void CheckForRunawayPlantTemps(int const LoopNum, int const LoopSideNum); - void UpdatePlantSplitter(int const LoopNum, int const LoopSideNum); - void SetAllFlowLocks(int const Value); void ResetAllPlantInterConnectFlags(); @@ -178,8 +174,6 @@ namespace PlantUtilities { void LogPlantConvergencePoints(bool const FirstHVACIteration); - bool CheckPlantConvergence(int const ThisLoopNum, int const ThisLoopSide, bool const FirstHVACIteration); - void ScanPlantLoopsForObject(std::string const &CompName, int const CompType, int &LoopNum, diff --git a/src/EnergyPlus/PlantValves.cc b/src/EnergyPlus/PlantValves.cc index ae945dcd419..e309ff417b3 100644 --- a/src/EnergyPlus/PlantValves.cc +++ b/src/EnergyPlus/PlantValves.cc @@ -57,7 +57,7 @@ #include #include #include -#include +#include #include #include #include @@ -303,7 +303,7 @@ namespace PlantValves { if (thisBranch.ControlType == DataBranchAirLoopPlant::ControlType_Active) IsBranchActive = true; // is Valve inlet node an outlet node of a splitter - if (thisLoopSide.SplitterExists) { + if (thisLoopSide.Splitter.Exists) { if (allocated(thisLoopSide.Splitter.NodeNumOut)) { if (any_eq(thisLoopSide.Splitter.NodeNumOut, this->PltInletNodeNum)) { InNodeOnSplitter = true; @@ -317,7 +317,7 @@ namespace PlantValves { } // has splitter // is stream 2 node an inlet to the mixer ? - if (thisLoopSide.MixerExists) { + if (thisLoopSide.Mixer.Exists) { if (any_eq(thisLoopSide.Mixer.NodeNumIn, this->PltStream2NodeNum)) { int thisInnerBranchCtr = 0; for (auto & thisInnerBranch : thisLoopSide.Branch) { @@ -336,7 +336,7 @@ namespace PlantValves { for (auto & thisInnerBranch : thisLoopSide.Branch) { if (thisInnerBranch.NodeNumOut == this->PltPumpOutletNodeNum) { for (auto & thisInnerComp : thisInnerBranch.Comp) { - if (thisInnerComp.GeneralEquipType == DataPlant::GenEquipTypes_Pump) { + if (thisInnerComp.isPump()) { PumpOutNodeOkay = true; } } diff --git a/src/EnergyPlus/PondGroundHeatExchanger.cc b/src/EnergyPlus/PondGroundHeatExchanger.cc index d7f8bc7eb75..767ae99eb3e 100644 --- a/src/EnergyPlus/PondGroundHeatExchanger.cc +++ b/src/EnergyPlus/PondGroundHeatExchanger.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/PoweredInductionUnits.cc b/src/EnergyPlus/PoweredInductionUnits.cc index 17f7aa700ed..680e2c3bbeb 100644 --- a/src/EnergyPlus/PoweredInductionUnits.cc +++ b/src/EnergyPlus/PoweredInductionUnits.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/Pumps.cc b/src/EnergyPlus/Pumps.cc index 6bdcbe821f8..ffb03723e7e 100644 --- a/src/EnergyPlus/Pumps.cc +++ b/src/EnergyPlus/Pumps.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/RefrigeratedCase.cc b/src/EnergyPlus/RefrigeratedCase.cc index 90b3d7ef359..4081d6c2fc9 100644 --- a/src/EnergyPlus/RefrigeratedCase.cc +++ b/src/EnergyPlus/RefrigeratedCase.cc @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/ReportCoilSelection.cc b/src/EnergyPlus/ReportCoilSelection.cc index 0a689a97a7a..7e1278b377c 100644 --- a/src/EnergyPlus/ReportCoilSelection.cc +++ b/src/EnergyPlus/ReportCoilSelection.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/ReportSizingManager.cc b/src/EnergyPlus/ReportSizingManager.cc index ef319c4ce27..9bf7eccb568 100644 --- a/src/EnergyPlus/ReportSizingManager.cc +++ b/src/EnergyPlus/ReportSizingManager.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/SetPointManager.cc b/src/EnergyPlus/SetPointManager.cc index 0607ac0ea15..c0c688e5a21 100644 --- a/src/EnergyPlus/SetPointManager.cc +++ b/src/EnergyPlus/SetPointManager.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include @@ -7304,7 +7304,7 @@ namespace SetPointManager { PlantLoop(LoopIndexPlantSide).LoopSide(SupplySide).Branch(BranchIndexPlantSide).Comp(ChillerIndexPlantSide).TempDesEvapOut; DCESPMDesignClgCapacity_Watts = PlantLoop(LoopIndexPlantSide).LoopSide(SupplySide).Branch(BranchIndexPlantSide).Comp(ChillerIndexPlantSide).MaxLoad; - DCESPMCurrentLoad_Watts = PlantReport(LoopIndexPlantSide).CoolingDemand; + DCESPMCurrentLoad_Watts = PlantLoop(LoopIndexPlantSide).CoolingDemand; } else if (TypeNum == TypeOf_Chiller_Indirect_Absorption || TypeNum == TypeOf_Chiller_DFAbsorption) { TempDesCondIn = PlantLoop(LoopIndexPlantSide).LoopSide(SupplySide).Branch(BranchIndexPlantSide).Comp(ChillerIndexPlantSide).TempDesCondIn; diff --git a/src/EnergyPlus/SimulationManager.cc b/src/EnergyPlus/SimulationManager.cc index e6f26795ee8..425d7cccef7 100644 --- a/src/EnergyPlus/SimulationManager.cc +++ b/src/EnergyPlus/SimulationManager.cc @@ -82,7 +82,7 @@ extern "C" { #include #include #include -#include +#include #include #include #include @@ -2314,7 +2314,7 @@ namespace SimulationManager { PlantLoop(Count).LoopSide(LoopSideNum).NodeNameOut + ',' + PlantLoop(Count).LoopSide(LoopSideNum).BranchList + ',' + PlantLoop(Count).LoopSide(LoopSideNum).ConnectList; // Plant Supply Side Splitter - if (PlantLoop(Count).LoopSide(LoopSideNum).SplitterExists) { + if (PlantLoop(Count).LoopSide(LoopSideNum).Splitter.Exists) { ObjexxFCL::gio::write(ChrOut, fmtLD) << PlantLoop(Count).LoopSide(LoopSideNum).Splitter.TotalOutletNodes; ObjexxFCL::gio::write(OutputFileBNDetails, Format_713) << " Plant Loop Connector,Splitter," + PlantLoop(Count).LoopSide(LoopSideNum).Splitter.Name + ',' + @@ -2374,7 +2374,7 @@ namespace SimulationManager { } // Plant Supply Side Mixer - if (PlantLoop(Count).LoopSide(LoopSideNum).MixerExists) { + if (PlantLoop(Count).LoopSide(LoopSideNum).Mixer.Exists) { ObjexxFCL::gio::write(ChrOut, fmtLD) << PlantLoop(Count).LoopSide(LoopSideNum).Mixer.TotalInletNodes; ObjexxFCL::gio::write(OutputFileBNDetails, Format_713) << " Plant Loop Connector,Mixer," + PlantLoop(Count).LoopSide(LoopSideNum).Mixer.Name + ',' + @@ -2475,7 +2475,7 @@ namespace SimulationManager { PlantLoop(Count).LoopSide(LoopSideNum).NodeNameOut + ',' + PlantLoop(Count).LoopSide(LoopSideNum).BranchList + ',' + PlantLoop(Count).LoopSide(LoopSideNum).ConnectList; // Plant Supply Side Splitter - if (PlantLoop(Count).LoopSide(LoopSideNum).SplitterExists) { + if (PlantLoop(Count).LoopSide(LoopSideNum).Splitter.Exists) { ObjexxFCL::gio::write(ChrOut, fmtLD) << PlantLoop(Count).LoopSide(LoopSideNum).Splitter.TotalOutletNodes; ObjexxFCL::gio::write(OutputFileBNDetails, Format_713) << " Plant Loop Connector,Splitter," + PlantLoop(Count).LoopSide(LoopSideNum).Splitter.Name + ',' + diff --git a/src/EnergyPlus/SingleDuct.cc b/src/EnergyPlus/SingleDuct.cc index ee59c0b04fb..b8a5f1bd745 100644 --- a/src/EnergyPlus/SingleDuct.cc +++ b/src/EnergyPlus/SingleDuct.cc @@ -65,7 +65,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/SizingAnalysisObjects.cc b/src/EnergyPlus/SizingAnalysisObjects.cc index f29c8816856..f961f94afa4 100644 --- a/src/EnergyPlus/SizingAnalysisObjects.cc +++ b/src/EnergyPlus/SizingAnalysisObjects.cc @@ -54,7 +54,7 @@ #include "OutputFiles.hh" #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/SolarCollectors.cc b/src/EnergyPlus/SolarCollectors.cc index d65e14e06c5..353cbe35c12 100644 --- a/src/EnergyPlus/SolarCollectors.cc +++ b/src/EnergyPlus/SolarCollectors.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/StandardRatings.cc b/src/EnergyPlus/StandardRatings.cc index d3039650a53..41b843f5871 100644 --- a/src/EnergyPlus/StandardRatings.cc +++ b/src/EnergyPlus/StandardRatings.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/SteamBaseboardRadiator.cc b/src/EnergyPlus/SteamBaseboardRadiator.cc index e1e1460c7e9..7fbf25c4619 100644 --- a/src/EnergyPlus/SteamBaseboardRadiator.cc +++ b/src/EnergyPlus/SteamBaseboardRadiator.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/SteamCoils.cc b/src/EnergyPlus/SteamCoils.cc index 43264e773fa..9c6797665ac 100644 --- a/src/EnergyPlus/SteamCoils.cc +++ b/src/EnergyPlus/SteamCoils.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/SurfaceGroundHeatExchanger.cc b/src/EnergyPlus/SurfaceGroundHeatExchanger.cc index eb6964ab32f..7a76879cbb5 100644 --- a/src/EnergyPlus/SurfaceGroundHeatExchanger.cc +++ b/src/EnergyPlus/SurfaceGroundHeatExchanger.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/SwimmingPool.cc b/src/EnergyPlus/SwimmingPool.cc index bb9127c90e3..19c3381e11a 100644 --- a/src/EnergyPlus/SwimmingPool.cc +++ b/src/EnergyPlus/SwimmingPool.cc @@ -65,7 +65,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/SystemAvailabilityManager.cc b/src/EnergyPlus/SystemAvailabilityManager.cc index 3246c0fd1f1..6c6cf101479 100644 --- a/src/EnergyPlus/SystemAvailabilityManager.cc +++ b/src/EnergyPlus/SystemAvailabilityManager.cc @@ -67,7 +67,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/SystemReports.cc b/src/EnergyPlus/SystemReports.cc index fe35bf018da..53aa918e6a1 100644 --- a/src/EnergyPlus/SystemReports.cc +++ b/src/EnergyPlus/SystemReports.cc @@ -70,7 +70,7 @@ #include #include #include -#include +#include #include #include #include @@ -3195,7 +3195,6 @@ namespace SystemReports { // Get complete list of components for complex branches if (IsParentObject(TypeOfComp, NameOfComp)) { - thisComp.Parent = true; NumChildren = GetNumChildren(TypeOfComp, NameOfComp); SubCompTypes.allocate(NumChildren); @@ -3235,7 +3234,6 @@ namespace SystemReports { } else { NumChildren = 0; - thisComp.Parent = false; } thisComp.NumSubComps = NumChildren; diff --git a/src/EnergyPlus/UnitHeater.cc b/src/EnergyPlus/UnitHeater.cc index 3d9b260bbbe..8b4c49a1d39 100644 --- a/src/EnergyPlus/UnitHeater.cc +++ b/src/EnergyPlus/UnitHeater.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/UnitVentilator.cc b/src/EnergyPlus/UnitVentilator.cc index 4a4cab21720..be5ca41be14 100644 --- a/src/EnergyPlus/UnitVentilator.cc +++ b/src/EnergyPlus/UnitVentilator.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/UnitarySystem.cc b/src/EnergyPlus/UnitarySystem.cc index 912968c5148..cf79a25cf18 100644 --- a/src/EnergyPlus/UnitarySystem.cc +++ b/src/EnergyPlus/UnitarySystem.cc @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/UserDefinedComponents.hh b/src/EnergyPlus/UserDefinedComponents.hh index 23f42aeb8d5..269187b28b9 100644 --- a/src/EnergyPlus/UserDefinedComponents.hh +++ b/src/EnergyPlus/UserDefinedComponents.hh @@ -53,7 +53,7 @@ // EnergyPlus Headers #include -#include +#include #include #include diff --git a/src/EnergyPlus/VentilatedSlab.cc b/src/EnergyPlus/VentilatedSlab.cc index 6e4e4395733..249ad85e85f 100644 --- a/src/EnergyPlus/VentilatedSlab.cc +++ b/src/EnergyPlus/VentilatedSlab.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/WaterCoils.cc b/src/EnergyPlus/WaterCoils.cc index 7af0dce7949..c01b0f9f3ce 100644 --- a/src/EnergyPlus/WaterCoils.cc +++ b/src/EnergyPlus/WaterCoils.cc @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/WaterThermalTanks.cc b/src/EnergyPlus/WaterThermalTanks.cc index 80d564b618d..98ccb20b32f 100644 --- a/src/EnergyPlus/WaterThermalTanks.cc +++ b/src/EnergyPlus/WaterThermalTanks.cc @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include #include #include @@ -10129,7 +10129,7 @@ namespace WaterThermalTanks { ErrorsFound = true; } // Is this wh Use side plumbed in series (default) or are there other branches in parallel? - if (DataPlant::PlantLoop(PlantLoopNum).LoopSide(LoopSideNum).SplitterExists) { + if (DataPlant::PlantLoop(PlantLoopNum).LoopSide(LoopSideNum).Splitter.Exists) { if (any_eq(DataPlant::PlantLoop(PlantLoopNum).LoopSide(LoopSideNum).Splitter.NodeNumOut, this->UseInletNode)) { // this wh is on the splitter if (DataPlant::PlantLoop(PlantLoopNum).LoopSide(LoopSideNum).Splitter.TotalOutletNodes > 1) { @@ -10148,7 +10148,7 @@ namespace WaterThermalTanks { ErrorsFound = true; } // Is this wh Source side plumbed in series (default) or are there other branches in parallel? - if (DataPlant::PlantLoop(this->SrcSide.loopNum).LoopSide(this->SrcSide.loopSideNum).SplitterExists) { + if (DataPlant::PlantLoop(this->SrcSide.loopNum).LoopSide(this->SrcSide.loopSideNum).Splitter.Exists) { if (any_eq(DataPlant::PlantLoop(this->SrcSide.loopNum).LoopSide(this->SrcSide.loopSideNum).Splitter.NodeNumOut, this->SourceInletNode)) { // this wh is on the splitter if (DataPlant::PlantLoop(this->SrcSide.loopNum).LoopSide(this->SrcSide.loopSideNum).Splitter.TotalOutletNodes > 1) { diff --git a/src/EnergyPlus/WaterToAirHeatPump.cc b/src/EnergyPlus/WaterToAirHeatPump.cc index 812fd9e576c..b7440382cbc 100644 --- a/src/EnergyPlus/WaterToAirHeatPump.cc +++ b/src/EnergyPlus/WaterToAirHeatPump.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/WaterToAirHeatPumpSimple.cc b/src/EnergyPlus/WaterToAirHeatPumpSimple.cc index 60c8c7acd2a..b7eebbf954c 100644 --- a/src/EnergyPlus/WaterToAirHeatPumpSimple.cc +++ b/src/EnergyPlus/WaterToAirHeatPumpSimple.cc @@ -59,7 +59,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/EnergyPlus/WaterUse.cc b/src/EnergyPlus/WaterUse.cc index d7896b374e0..224fcef172e 100644 --- a/src/EnergyPlus/WaterUse.cc +++ b/src/EnergyPlus/WaterUse.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/BaseboardRadiator.unit.cc b/tst/EnergyPlus/unit/BaseboardRadiator.unit.cc index 5a248b404e0..f86b54e523c 100644 --- a/tst/EnergyPlus/unit/BaseboardRadiator.unit.cc +++ b/tst/EnergyPlus/unit/BaseboardRadiator.unit.cc @@ -54,7 +54,7 @@ #include "Fixtures/EnergyPlusFixture.hh" #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/BoilerHotWater.unit.cc b/tst/EnergyPlus/unit/BoilerHotWater.unit.cc index fff88ec1cd7..e4893f1867e 100644 --- a/tst/EnergyPlus/unit/BoilerHotWater.unit.cc +++ b/tst/EnergyPlus/unit/BoilerHotWater.unit.cc @@ -52,7 +52,7 @@ // EnergyPlus Headers #include -#include +#include #include #include diff --git a/tst/EnergyPlus/unit/ChillerAbsorption.unit.cc b/tst/EnergyPlus/unit/ChillerAbsorption.unit.cc index b8113ea65c8..c01c3bc5b45 100644 --- a/tst/EnergyPlus/unit/ChillerAbsorption.unit.cc +++ b/tst/EnergyPlus/unit/ChillerAbsorption.unit.cc @@ -56,7 +56,7 @@ // EnergyPlus Headers #include #include -#include +#include #include #include diff --git a/tst/EnergyPlus/unit/ChillerConstantCOP.unit.cc b/tst/EnergyPlus/unit/ChillerConstantCOP.unit.cc index 357ea35f185..5219f7bcb05 100644 --- a/tst/EnergyPlus/unit/ChillerConstantCOP.unit.cc +++ b/tst/EnergyPlus/unit/ChillerConstantCOP.unit.cc @@ -54,7 +54,7 @@ #include "Fixtures/EnergyPlusFixture.hh" #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/ChillerElectric.unit.cc b/tst/EnergyPlus/unit/ChillerElectric.unit.cc index e7166579bb9..bd40a089496 100644 --- a/tst/EnergyPlus/unit/ChillerElectric.unit.cc +++ b/tst/EnergyPlus/unit/ChillerElectric.unit.cc @@ -54,7 +54,7 @@ #include "Fixtures/EnergyPlusFixture.hh" #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/ChillerElectricEIR.unit.cc b/tst/EnergyPlus/unit/ChillerElectricEIR.unit.cc index e87e30cd0c6..6802f46851a 100644 --- a/tst/EnergyPlus/unit/ChillerElectricEIR.unit.cc +++ b/tst/EnergyPlus/unit/ChillerElectricEIR.unit.cc @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include diff --git a/tst/EnergyPlus/unit/DataPlant.unit.cc b/tst/EnergyPlus/unit/DataPlant.unit.cc index 11aeee519b7..321227cce64 100644 --- a/tst/EnergyPlus/unit/DataPlant.unit.cc +++ b/tst/EnergyPlus/unit/DataPlant.unit.cc @@ -51,7 +51,7 @@ #include // EnergyPlus Headers -#include +#include #include #include diff --git a/tst/EnergyPlus/unit/EMSManager.unit.cc b/tst/EnergyPlus/unit/EMSManager.unit.cc index 580e1e009ca..c2563779608 100644 --- a/tst/EnergyPlus/unit/EMSManager.unit.cc +++ b/tst/EnergyPlus/unit/EMSManager.unit.cc @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/FanCoilUnits.unit.cc b/tst/EnergyPlus/unit/FanCoilUnits.unit.cc index 447ffffa35b..bf89ec0713e 100644 --- a/tst/EnergyPlus/unit/FanCoilUnits.unit.cc +++ b/tst/EnergyPlus/unit/FanCoilUnits.unit.cc @@ -59,7 +59,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc b/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc index 247b638a879..aff13bda5b0 100644 --- a/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc +++ b/tst/EnergyPlus/unit/Fixtures/EnergyPlusFixture.cc @@ -94,7 +94,7 @@ #include #include #include -#include +#include #include #include #include @@ -176,7 +176,6 @@ #include #include #include -#include #include #include #include @@ -432,7 +431,6 @@ void EnergyPlusFixture::clear_all_states() PlantCondLoopOperation::clear_state(); PlantHeatExchangerFluidToFluid::clear_state(); PlantLoadProfile::clear_state(); - PlantLoopSolver::clear_state(); PlantManager::clear_state(); PlantPipingSystemsManager::clear_state(); PlantPipingSystemsManager::clear_state(); diff --git a/tst/EnergyPlus/unit/Furnaces.unit.cc b/tst/EnergyPlus/unit/Furnaces.unit.cc index f52a5f052c1..7ccfa818c53 100644 --- a/tst/EnergyPlus/unit/Furnaces.unit.cc +++ b/tst/EnergyPlus/unit/Furnaces.unit.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/GroundHeatExchangers.unit.cc b/tst/EnergyPlus/unit/GroundHeatExchangers.unit.cc index 3a398614f1d..c84869e886f 100644 --- a/tst/EnergyPlus/unit/GroundHeatExchangers.unit.cc +++ b/tst/EnergyPlus/unit/GroundHeatExchangers.unit.cc @@ -52,7 +52,7 @@ // EnergyPlus Headers #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/HVACInterfaceManager.unit.cc b/tst/EnergyPlus/unit/HVACInterfaceManager.unit.cc index 9710a83daab..544b475710d 100644 --- a/tst/EnergyPlus/unit/HVACInterfaceManager.unit.cc +++ b/tst/EnergyPlus/unit/HVACInterfaceManager.unit.cc @@ -57,7 +57,7 @@ #include "Fixtures/EnergyPlusFixture.hh" #include #include -#include +#include #include namespace EnergyPlus { diff --git a/tst/EnergyPlus/unit/HVACSizingSimulationManager.unit.cc b/tst/EnergyPlus/unit/HVACSizingSimulationManager.unit.cc index 263f7b9bc70..8cef8b88106 100644 --- a/tst/EnergyPlus/unit/HVACSizingSimulationManager.unit.cc +++ b/tst/EnergyPlus/unit/HVACSizingSimulationManager.unit.cc @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include #include @@ -116,10 +116,6 @@ class HVACSizingSimulationManagerTest : public EnergyPlusFixture PlantLoop(1).FluidIndex = 1; PlantLoop(1).LoopSide(SupplySide).NodeNumIn = 1; - // set up plant loop Reporting - - PlantReport.allocate(TotNumLoops); - SetPredefinedTables(); // need a node to log mass flow rate from @@ -202,7 +198,7 @@ TEST_F(HVACSizingSimulationManagerTest, WeatherFileDaysTest3) Node(1).MassFlowRate = HourOfDay * 0.1; Node(1).Temp = 10.0; - PlantReport(1).HeatingDemand = HourOfDay * 10.0; + PlantLoop(1).HeatingDemand = HourOfDay * 10.0; testSizeSimManagerObj.sizingLogger.UpdateSizingLogValuesSystemStep(); } TimeValue.at(OutputProcessor::TimeStepType::TimeStepZone).CurMinute += TimeValue.at(OutputProcessor::TimeStepType::TimeStepZone).TimeStep * 60.0; @@ -226,7 +222,7 @@ TEST_F(HVACSizingSimulationManagerTest, WeatherFileDaysTest3) Node(1).MassFlowRate = HourOfDay * 0.1; Node(1).Temp = 10.0; - PlantReport(1).HeatingDemand = HourOfDay * 10.0; + PlantLoop(1).HeatingDemand = HourOfDay * 10.0; testSizeSimManagerObj.sizingLogger.UpdateSizingLogValuesSystemStep(); } @@ -252,7 +248,7 @@ TEST_F(HVACSizingSimulationManagerTest, WeatherFileDaysTest3) Node(1).MassFlowRate = HourOfDay * 0.1; Node(1).Temp = 10.0; - PlantReport(1).HeatingDemand = HourOfDay * 10.0; + PlantLoop(1).HeatingDemand = HourOfDay * 10.0; testSizeSimManagerObj.sizingLogger.UpdateSizingLogValuesSystemStep(); } TimeValue.at(OutputProcessor::TimeStepType::TimeStepZone).CurMinute += TimeValue.at(OutputProcessor::TimeStepType::TimeStepZone).TimeStep * 60.0; @@ -278,7 +274,7 @@ TEST_F(HVACSizingSimulationManagerTest, WeatherFileDaysTest3) Node(1).MassFlowRate = HourOfDay * 0.1; Node(1).Temp = 10.0; - PlantReport(1).HeatingDemand = HourOfDay * 10.0; + PlantLoop(1).HeatingDemand = HourOfDay * 10.0; testSizeSimManagerObj.sizingLogger.UpdateSizingLogValuesSystemStep(); } TimeValue.at(OutputProcessor::TimeStepType::TimeStepZone).CurMinute += TimeValue.at(OutputProcessor::TimeStepType::TimeStepZone).TimeStep * 60.0; @@ -395,7 +391,7 @@ TEST_F(HVACSizingSimulationManagerTest, TopDownTestSysTimestep3) Node(1).MassFlowRate = HourOfDay * 0.1; Node(1).Temp = 10.0; - PlantReport(1).HeatingDemand = HourOfDay * 10.0; + PlantLoop(1).HeatingDemand = HourOfDay * 10.0; testSizeSimManagerObj.sizingLogger.UpdateSizingLogValuesSystemStep(); } TimeValue.at(OutputProcessor::TimeStepType::TimeStepZone).CurMinute += TimeValue.at(OutputProcessor::TimeStepType::TimeStepZone).TimeStep * 60.0; @@ -418,7 +414,7 @@ TEST_F(HVACSizingSimulationManagerTest, TopDownTestSysTimestep3) Node(1).MassFlowRate = HourOfDay * 0.1; Node(1).Temp = 10.0; - PlantReport(1).HeatingDemand = HourOfDay * 10.0; + PlantLoop(1).HeatingDemand = HourOfDay * 10.0; testSizeSimManagerObj.sizingLogger.UpdateSizingLogValuesSystemStep(); } @@ -528,7 +524,7 @@ TEST_F(HVACSizingSimulationManagerTest, TopDownTestSysTimestep1) Node(1).MassFlowRate = HourOfDay * 0.1; Node(1).Temp = 10.0; - PlantReport(1).HeatingDemand = HourOfDay * 10.0; + PlantLoop(1).HeatingDemand = HourOfDay * 10.0; testSizeSimManagerObj.sizingLogger.UpdateSizingLogValuesSystemStep(); } // E+ doesn't really update zone step data until system steps are done @@ -553,7 +549,7 @@ TEST_F(HVACSizingSimulationManagerTest, TopDownTestSysTimestep1) Node(1).MassFlowRate = HourOfDay * 0.1; Node(1).Temp = 10.0; - PlantReport(1).HeatingDemand = HourOfDay * 10.0; + PlantLoop(1).HeatingDemand = HourOfDay * 10.0; testSizeSimManagerObj.sizingLogger.UpdateSizingLogValuesSystemStep(); } @@ -615,7 +611,7 @@ TEST_F(HVACSizingSimulationManagerTest, VarySysTimesteps) Node(1).MassFlowRate = HourOfDay * 0.1; Node(1).Temp = 10.0; - PlantReport(1).HeatingDemand = HourOfDay * 10.0; + PlantLoop(1).HeatingDemand = HourOfDay * 10.0; testSizeSimManagerObj.sizingLogger.UpdateSizingLogValuesSystemStep(); } // E+ doesn't really update zone step data until system steps are done @@ -642,7 +638,7 @@ TEST_F(HVACSizingSimulationManagerTest, VarySysTimesteps) Node(1).MassFlowRate = HourOfDay * 0.1; Node(1).Temp = 10.0; - PlantReport(1).HeatingDemand = HourOfDay * 10.0; + PlantLoop(1).HeatingDemand = HourOfDay * 10.0; testSizeSimManagerObj.sizingLogger.UpdateSizingLogValuesSystemStep(); } diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index c29398842d4..2756410f275 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -71,7 +71,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/HWBaseboardRadiator.unit.cc b/tst/EnergyPlus/unit/HWBaseboardRadiator.unit.cc index 13c2c73a674..82b12a5c5db 100644 --- a/tst/EnergyPlus/unit/HWBaseboardRadiator.unit.cc +++ b/tst/EnergyPlus/unit/HWBaseboardRadiator.unit.cc @@ -52,7 +52,7 @@ // EnergyPlus Headers #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/LowTempRadiantSystem.unit.cc b/tst/EnergyPlus/unit/LowTempRadiantSystem.unit.cc index e6d97e8ca9c..16aef77fec8 100644 --- a/tst/EnergyPlus/unit/LowTempRadiantSystem.unit.cc +++ b/tst/EnergyPlus/unit/LowTempRadiantSystem.unit.cc @@ -53,7 +53,7 @@ // EnergyPlus Headers #include "Fixtures/EnergyPlusFixture.hh" #include -#include +#include #include #include #include @@ -62,7 +62,6 @@ #include #include -#include #include #include #include diff --git a/tst/EnergyPlus/unit/OutdoorAirUnit.unit.cc b/tst/EnergyPlus/unit/OutdoorAirUnit.unit.cc index c07c091b9e0..793b761f81b 100644 --- a/tst/EnergyPlus/unit/OutdoorAirUnit.unit.cc +++ b/tst/EnergyPlus/unit/OutdoorAirUnit.unit.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc b/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc index eaf28049de6..327f75ad499 100644 --- a/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc +++ b/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc @@ -57,7 +57,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/Pipes.unit.cc b/tst/EnergyPlus/unit/Pipes.unit.cc index 0f525b1e79a..0af37a7912d 100644 --- a/tst/EnergyPlus/unit/Pipes.unit.cc +++ b/tst/EnergyPlus/unit/Pipes.unit.cc @@ -51,7 +51,7 @@ #include #include "Fixtures/EnergyPlusFixture.hh" -#include +#include #include namespace EnergyPlus { diff --git a/tst/EnergyPlus/unit/PlantCentralGSHP.unit.cc b/tst/EnergyPlus/unit/PlantCentralGSHP.unit.cc index cd1ec2a0686..62b18815d78 100644 --- a/tst/EnergyPlus/unit/PlantCentralGSHP.unit.cc +++ b/tst/EnergyPlus/unit/PlantCentralGSHP.unit.cc @@ -51,7 +51,7 @@ #include // EnergyPlus Headers -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/PlantChillers.unit.cc b/tst/EnergyPlus/unit/PlantChillers.unit.cc index 3e55ed676e1..93c84f3323b 100644 --- a/tst/EnergyPlus/unit/PlantChillers.unit.cc +++ b/tst/EnergyPlus/unit/PlantChillers.unit.cc @@ -51,7 +51,7 @@ #include // EnergyPlus Headers -#include +#include #include #include diff --git a/tst/EnergyPlus/unit/PlantComponentTemperatureSources.unit.cc b/tst/EnergyPlus/unit/PlantComponentTemperatureSources.unit.cc index 2b98816bdaa..4074fc7e000 100644 --- a/tst/EnergyPlus/unit/PlantComponentTemperatureSources.unit.cc +++ b/tst/EnergyPlus/unit/PlantComponentTemperatureSources.unit.cc @@ -51,7 +51,7 @@ #include #include "Fixtures/EnergyPlusFixture.hh" -#include +#include #include #include diff --git a/tst/EnergyPlus/unit/PlantCondLoopOperation.unit.cc b/tst/EnergyPlus/unit/PlantCondLoopOperation.unit.cc index 2649cd6921b..92bf32aa4f3 100644 --- a/tst/EnergyPlus/unit/PlantCondLoopOperation.unit.cc +++ b/tst/EnergyPlus/unit/PlantCondLoopOperation.unit.cc @@ -51,7 +51,7 @@ #include // EnergyPlus Headers -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/PlantLoopHeatPumpEIR.unit.cc b/tst/EnergyPlus/unit/PlantLoopHeatPumpEIR.unit.cc index 30408a1e591..4a9d982a1b4 100644 --- a/tst/EnergyPlus/unit/PlantLoopHeatPumpEIR.unit.cc +++ b/tst/EnergyPlus/unit/PlantLoopHeatPumpEIR.unit.cc @@ -59,7 +59,7 @@ #include "Fixtures/EnergyPlusFixture.hh" #include -#include +#include #include #include diff --git a/tst/EnergyPlus/unit/PlantManager.unit.cc b/tst/EnergyPlus/unit/PlantManager.unit.cc index 3262906f210..54661c4d8e7 100644 --- a/tst/EnergyPlus/unit/PlantManager.unit.cc +++ b/tst/EnergyPlus/unit/PlantManager.unit.cc @@ -57,7 +57,7 @@ // EnergyPlus Headers #include "Fixtures/EnergyPlusFixture.hh" #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/PlantPipingSystemsManager.unit.cc b/tst/EnergyPlus/unit/PlantPipingSystemsManager.unit.cc index d2d3e27949f..0f8111a2fe0 100644 --- a/tst/EnergyPlus/unit/PlantPipingSystemsManager.unit.cc +++ b/tst/EnergyPlus/unit/PlantPipingSystemsManager.unit.cc @@ -50,11 +50,11 @@ // Google Test Headers #include -#include "EnergyPlus/DataPlant.hh" -#include "EnergyPlus/DataSurfaces.hh" -#include "EnergyPlus/HeatBalanceManager.hh" -#include "EnergyPlus/PlantPipingSystemsManager.hh" -#include "EnergyPlus/SurfaceGeometry.hh" +#include +#include +#include +#include +#include #include "Fixtures/EnergyPlusFixture.hh" #include #include diff --git a/tst/EnergyPlus/unit/PlantUtilities.unit.cc b/tst/EnergyPlus/unit/PlantUtilities.unit.cc index 9a07771cff4..60045efca80 100644 --- a/tst/EnergyPlus/unit/PlantUtilities.unit.cc +++ b/tst/EnergyPlus/unit/PlantUtilities.unit.cc @@ -54,7 +54,7 @@ // EnergyPlus Headers #include "Fixtures/EnergyPlusFixture.hh" -#include +#include #include #include #include @@ -210,11 +210,11 @@ TEST_F(EnergyPlusFixture, TestAnyPlantSplitterMixerLacksContinuity) DataPlant::TotNumLoops = 1; DataPlant::PlantLoop.allocate(1); DataPlant::PlantLoop(1).LoopSide.allocate(2); - DataPlant::PlantLoop(1).LoopSide(1).SplitterExists = false; + DataPlant::PlantLoop(1).LoopSide(1).Splitter.Exists = false; DataPlant::PlantLoop(1).LoopSide(2).Branch.allocate(2); DataPlant::PlantLoop(1).LoopSide(2).Branch(1).NodeNumOut = 2; DataPlant::PlantLoop(1).LoopSide(2).Branch(2).NodeNumOut = 3; - DataPlant::PlantLoop(1).LoopSide(2).SplitterExists = true; + DataPlant::PlantLoop(1).LoopSide(2).Splitter.Exists = true; DataPlant::PlantLoop(1).LoopSide(2).Splitter.NodeNumIn = 1; DataPlant::PlantLoop(1).LoopSide(2).Splitter.TotalOutletNodes = 2; DataPlant::PlantLoop(1).LoopSide(2).Splitter.BranchNumOut.allocate(2); @@ -382,58 +382,58 @@ TEST_F(EnergyPlusFixture, TestCheckPlantConvergence) EXPECT_NEAR(0.0, sum(DataPlant::PlantLoop(1).LoopSide(1).OutletNode.MassFlowRateHistory), 0.001); // If we check the plant convergence right now with first hvac true, it should require a resimulation - EXPECT_FALSE(PlantUtilities::CheckPlantConvergence(1, 1, true)); + EXPECT_FALSE(DataPlant::PlantLoop(1).LoopSide(1).CheckPlantConvergence(true)); // But if we check it with first hvac false, everything should be stable and pass - EXPECT_TRUE(PlantUtilities::CheckPlantConvergence(1, 1, false)); + EXPECT_TRUE(DataPlant::PlantLoop(1).LoopSide(1).CheckPlantConvergence(false)); // Now let's introduce a disturbance by changing the inlet node temperature and logging it inNode.Temp = roomTemp; PlantUtilities::LogPlantConvergencePoints(false); // We expect it to be false here since the temperature changed - EXPECT_FALSE(PlantUtilities::CheckPlantConvergence(1, 1, false)); + EXPECT_FALSE(DataPlant::PlantLoop(1).LoopSide(1).CheckPlantConvergence(false)); // But if we run it 4 more times and let the value propagate, we expect it to be stable and pass // Need to call it 5 times total to fully initialize the history for (int i = 1; i < 5; ++i) { PlantUtilities::LogPlantConvergencePoints(false); } - EXPECT_TRUE(PlantUtilities::CheckPlantConvergence(1, 1, false)); + EXPECT_TRUE(DataPlant::PlantLoop(1).LoopSide(1).CheckPlantConvergence(false)); // Repeat this for the outlet node temperature outNode.Temp = roomTemp; PlantUtilities::LogPlantConvergencePoints(false); // We expect it to be false here since the temperature changed - EXPECT_FALSE(PlantUtilities::CheckPlantConvergence(1, 1, false)); + EXPECT_FALSE(DataPlant::PlantLoop(1).LoopSide(1).CheckPlantConvergence(false)); // But if we run it 4 more times and let the value propagate, we expect it to be stable and pass // Need to call it 5 times total to fully initialize the history for (int i = 1; i < 5; ++i) { PlantUtilities::LogPlantConvergencePoints(false); } - EXPECT_TRUE(PlantUtilities::CheckPlantConvergence(1, 1, false)); + EXPECT_TRUE(DataPlant::PlantLoop(1).LoopSide(1).CheckPlantConvergence(false)); // Repeat this for the inlet node mass flow rate inNode.MassFlowRate = nonZeroFlow; PlantUtilities::LogPlantConvergencePoints(false); // We expect it to be false here since the temperature changed - EXPECT_FALSE(PlantUtilities::CheckPlantConvergence(1, 1, false)); + EXPECT_FALSE(DataPlant::PlantLoop(1).LoopSide(1).CheckPlantConvergence(false)); // But if we run it 4 more times and let the value propagate, we expect it to be stable and pass // Need to call it 5 times total to fully initialize the history for (int i = 1; i < 5; ++i) { PlantUtilities::LogPlantConvergencePoints(false); } - EXPECT_TRUE(PlantUtilities::CheckPlantConvergence(1, 1, false)); + EXPECT_TRUE(DataPlant::PlantLoop(1).LoopSide(1).CheckPlantConvergence(false)); // And finally the outlet node mass flow rate outNode.MassFlowRate = nonZeroFlow; PlantUtilities::LogPlantConvergencePoints(false); // We expect it to be false here since the temperature changed - EXPECT_FALSE(PlantUtilities::CheckPlantConvergence(1, 1, false)); + EXPECT_FALSE(DataPlant::PlantLoop(1).LoopSide(1).CheckPlantConvergence(false)); // But if we run it 4 more times and let the value propagate, we expect it to be stable and pass // Need to call it 5 times total to fully initialize the history for (int i = 1; i < 5; ++i) { PlantUtilities::LogPlantConvergencePoints(false); } - EXPECT_TRUE(PlantUtilities::CheckPlantConvergence(1, 1, false)); + EXPECT_TRUE(DataPlant::PlantLoop(1).LoopSide(1).CheckPlantConvergence(false)); } TEST_F(EnergyPlusFixture, TestScanPlantLoopsErrorFlagReturnType) { diff --git a/tst/EnergyPlus/unit/Pumps.unit.cc b/tst/EnergyPlus/unit/Pumps.unit.cc index 05787a7f2d9..a1ad43413c9 100644 --- a/tst/EnergyPlus/unit/Pumps.unit.cc +++ b/tst/EnergyPlus/unit/Pumps.unit.cc @@ -51,7 +51,7 @@ #include #include "Fixtures/EnergyPlusFixture.hh" -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/ReportCoilSelection.unit.cc b/tst/EnergyPlus/unit/ReportCoilSelection.unit.cc index 973c488c79a..37a7a1ce88b 100644 --- a/tst/EnergyPlus/unit/ReportCoilSelection.unit.cc +++ b/tst/EnergyPlus/unit/ReportCoilSelection.unit.cc @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/SetPointManager.unit.cc b/tst/EnergyPlus/unit/SetPointManager.unit.cc index d0b32a6956e..144ed5c199e 100644 --- a/tst/EnergyPlus/unit/SetPointManager.unit.cc +++ b/tst/EnergyPlus/unit/SetPointManager.unit.cc @@ -66,7 +66,7 @@ #include #include #include -#include +#include #include #include #include @@ -357,7 +357,6 @@ TEST_F(EnergyPlusFixture, SetPointManager_DefineCondEntSetPointManager) // Set up ChW loop manually, way too much input to do that here in idf, all I care about is the DataPlant::TotNumLoops = 2; DataPlant::PlantLoop.allocate(2); - DataPlant::PlantReport.allocate(1); DataPlant::PlantLoop(chwLoopIndex).LoopSide.allocate(2); DataPlant::PlantLoop(chwLoopIndex).LoopSide(supplySide).Branch.allocate(1); @@ -393,14 +392,14 @@ TEST_F(EnergyPlusFixture, SetPointManager_DefineCondEntSetPointManager) thisSPM.TypeNum = DataPlant::TypeOf_Chiller_Electric; // switch: Weighted ratio > 9 && etc... - DataPlant::PlantReport(1).CoolingDemand = 4700; + DataPlant::PlantLoop(1).CoolingDemand = 4700; // Now call and check thisSPM.calculate(); EXPECT_NEAR(designCondenserEnteringTemp + 1.0, thisSPM.SetPt, 0.001); // switch: Weighted ratio < 9 || etc... - DataPlant::PlantReport(1).CoolingDemand = 4000; + DataPlant::PlantLoop(1).CoolingDemand = 4000; // switch: OAWB>MinWb && DesignWB>MinDesignWB && CurLift>MinLift DataEnvironment::OutWetBulbTemp = 40; diff --git a/tst/EnergyPlus/unit/SizeWaterHeatingCoil.unit.cc b/tst/EnergyPlus/unit/SizeWaterHeatingCoil.unit.cc index 4e7e94c5f09..0b156b33507 100644 --- a/tst/EnergyPlus/unit/SizeWaterHeatingCoil.unit.cc +++ b/tst/EnergyPlus/unit/SizeWaterHeatingCoil.unit.cc @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/SizingAnalysisObjects.unit.cc b/tst/EnergyPlus/unit/SizingAnalysisObjects.unit.cc index df68f2a5719..ae213b75fa2 100644 --- a/tst/EnergyPlus/unit/SizingAnalysisObjects.unit.cc +++ b/tst/EnergyPlus/unit/SizingAnalysisObjects.unit.cc @@ -53,7 +53,7 @@ // EnergyPlus Headers #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/StandardRatings.unit.cc b/tst/EnergyPlus/unit/StandardRatings.unit.cc index ab8f04c8dda..f80ecf6a5db 100644 --- a/tst/EnergyPlus/unit/StandardRatings.unit.cc +++ b/tst/EnergyPlus/unit/StandardRatings.unit.cc @@ -59,7 +59,7 @@ #include #include #include -#include +#include using namespace EnergyPlus; using namespace EnergyPlus::StandardRatings; diff --git a/tst/EnergyPlus/unit/SwimmingPool.unit.cc b/tst/EnergyPlus/unit/SwimmingPool.unit.cc index 1abcb629430..71dcb58c8c4 100644 --- a/tst/EnergyPlus/unit/SwimmingPool.unit.cc +++ b/tst/EnergyPlus/unit/SwimmingPool.unit.cc @@ -53,7 +53,7 @@ // EnergyPlus Headers #include "Fixtures/EnergyPlusFixture.hh" #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/UnitHeater.unit.cc b/tst/EnergyPlus/unit/UnitHeater.unit.cc index 94e84df3e77..7e0b60cda7b 100644 --- a/tst/EnergyPlus/unit/UnitHeater.unit.cc +++ b/tst/EnergyPlus/unit/UnitHeater.unit.cc @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/UnitarySystem.unit.cc b/tst/EnergyPlus/unit/UnitarySystem.unit.cc index d77689c5db3..b38c6fd6813 100644 --- a/tst/EnergyPlus/unit/UnitarySystem.unit.cc +++ b/tst/EnergyPlus/unit/UnitarySystem.unit.cc @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/WaterCoils.unit.cc b/tst/EnergyPlus/unit/WaterCoils.unit.cc index 752fdfb4b03..ee39482c3a7 100644 --- a/tst/EnergyPlus/unit/WaterCoils.unit.cc +++ b/tst/EnergyPlus/unit/WaterCoils.unit.cc @@ -66,7 +66,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc b/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc index efe2e7ebd25..72ea1dcf79c 100644 --- a/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc +++ b/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/WaterToAirHeatPump.unit.cc b/tst/EnergyPlus/unit/WaterToAirHeatPump.unit.cc index e2ad319fae4..5144235ac25 100644 --- a/tst/EnergyPlus/unit/WaterToAirHeatPump.unit.cc +++ b/tst/EnergyPlus/unit/WaterToAirHeatPump.unit.cc @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tst/EnergyPlus/unit/WaterToAirHeatPumpSimple.unit.cc b/tst/EnergyPlus/unit/WaterToAirHeatPumpSimple.unit.cc index 0cbd99715dc..b00a61ac64d 100644 --- a/tst/EnergyPlus/unit/WaterToAirHeatPumpSimple.unit.cc +++ b/tst/EnergyPlus/unit/WaterToAirHeatPumpSimple.unit.cc @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include #include #include