LCOV - code coverage report
Current view: top level - EnergyPlus/Plant - EquipAndOperations.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 52.5 % 1110 583
Test Date: 2025-05-22 16:09:37 Functions: 100.0 % 10 10

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      49              : #include <EnergyPlus/DataAirLoop.hh>
      50              : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
      51              : #include <EnergyPlus/DataEnvironment.hh>
      52              : #include <EnergyPlus/DataHVACGlobals.hh>
      53              : #include <EnergyPlus/DataHeatBalance.hh>
      54              : #include <EnergyPlus/DataLoopNode.hh>
      55              : #include <EnergyPlus/DataPrecisionGlobals.hh>
      56              : #include <EnergyPlus/DataSizing.hh>
      57              : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      58              : #include <EnergyPlus/FluidProperties.hh>
      59              : #include <EnergyPlus/General.hh>
      60              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      61              : #include <EnergyPlus/Plant/DataPlant.hh>
      62              : #include <EnergyPlus/Plant/EquipAndOperations.hh>
      63              : #include <EnergyPlus/Plant/Loop.hh>
      64              : #include <EnergyPlus/PlantUtilities.hh>
      65              : #include <EnergyPlus/Psychrometrics.hh>
      66              : #include <EnergyPlus/UtilityRoutines.hh>
      67              : 
      68              : namespace EnergyPlus {
      69              : namespace DataPlant {
      70              : 
      71            4 :     void ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme(EnergyPlusData &state)
      72              :     {
      73            4 :         if (this->oneTimeSetupComplete) return;
      74              : 
      75            2 :         SetupOutputVariable(state,
      76              :                             "Supervisory Plant Heat Pump Operation Mode",
      77              :                             Constant::Units::unknown,
      78            2 :                             this->Report.AirSourcePlant_OpMode,
      79              :                             OutputProcessor::TimeStepType::System,
      80              :                             OutputProcessor::StoreType::Average,
      81            2 :                             this->Name);
      82              : 
      83            2 :         SetupOutputVariable(state,
      84              :                             "Supervisory Plant Auxiliary Boiler Mode",
      85              :                             Constant::Units::unknown,
      86            2 :                             this->Report.BoilerAux_OpMode,
      87              :                             OutputProcessor::TimeStepType::System,
      88              :                             OutputProcessor::StoreType::Average,
      89            2 :                             this->Name);
      90            4 :         SetupOutputVariable(state,
      91              :                             "Supervisory Plant Operation Polled Building Heating Load",
      92              :                             Constant::Units::W,
      93            2 :                             this->Report.BuildingPolledHeatingLoad,
      94              :                             OutputProcessor::TimeStepType::System,
      95              :                             OutputProcessor::StoreType::Average,
      96            2 :                             this->Name);
      97            4 :         SetupOutputVariable(state,
      98              :                             "Supervisory Plant Operation Polled Building Cooling Load",
      99              :                             Constant::Units::W,
     100            2 :                             this->Report.BuildingPolledCoolingLoad,
     101              :                             OutputProcessor::TimeStepType::System,
     102              :                             OutputProcessor::StoreType::Average,
     103            2 :                             this->Name);
     104            4 :         SetupOutputVariable(state,
     105              :                             "Supervisory Plant Operation Primary Plant Heating Load",
     106              :                             Constant::Units::W,
     107            2 :                             this->Report.PrimaryPlantHeatingLoad,
     108              :                             OutputProcessor::TimeStepType::System,
     109              :                             OutputProcessor::StoreType::Average,
     110            2 :                             this->Name);
     111            4 :         SetupOutputVariable(state,
     112              :                             "Supervisory Plant Operation Primary Plant Cooling Load",
     113              :                             Constant::Units::W,
     114            2 :                             this->Report.PrimaryPlantCoolingLoad,
     115              :                             OutputProcessor::TimeStepType::System,
     116              :                             OutputProcessor::StoreType::Average,
     117            2 :                             this->Name);
     118              : 
     119              :         // routine for setup of chiller heater supervisory plant operation scheme
     120            4 :         for (int zoneListNum = 1; zoneListNum <= state.dataHeatBal->NumOfZoneLists; ++zoneListNum) {
     121            2 :             if (this->ZoneListName == state.dataHeatBal->ZoneList(zoneListNum).Name) {
     122              : 
     123            2 :                 this->PlantOps.NumOfZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
     124            2 :                 this->ZonePtrs.allocate(this->PlantOps.NumOfZones);
     125           10 :                 for (int zoneNumInList = 1; zoneNumInList <= state.dataHeatBal->ZoneList(zoneListNum).NumOfZones; ++zoneNumInList) {
     126            8 :                     this->ZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
     127              :                 }
     128              :             }
     129              :         }
     130              : 
     131            2 :         if (state.dataHVACGlobal->NumPrimaryAirSys > 0) {
     132            2 :             this->AirLoopPtrs.allocate(state.dataHVACGlobal->NumPrimaryAirSys); // size to all, if zero then that airloop is not served
     133            2 :             this->PlantOps.NumOfAirLoops = state.dataHVACGlobal->NumPrimaryAirSys;
     134            2 :             this->AirLoopPtrs = 0;
     135            4 :             for (int AirLoopIndex = 1; AirLoopIndex <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopIndex) { // loop over the air systems
     136            2 :                 auto &AirToZoneNodeInfo(state.dataAirLoop->AirToZoneNodeInfo(AirLoopIndex));
     137           10 :                 for (int ZonesPolledIndex = 1; ZonesPolledIndex <= this->PlantOps.NumOfZones; ++ZonesPolledIndex) {
     138           40 :                     for (int ZonesCooledIndex = 1; ZonesCooledIndex <= AirToZoneNodeInfo.NumZonesCooled; ++ZonesCooledIndex) {
     139           32 :                         if (AirToZoneNodeInfo.CoolCtrlZoneNums(ZonesCooledIndex) == this->ZonePtrs(ZonesPolledIndex)) {
     140            8 :                             this->AirLoopPtrs(AirLoopIndex) = AirLoopIndex;
     141              :                         }
     142              :                     }
     143            8 :                     for (int ZonesHeatedIndex = 1; ZonesHeatedIndex <= AirToZoneNodeInfo.NumZonesHeated; ++ZonesHeatedIndex) {
     144            0 :                         if (AirToZoneNodeInfo.HeatCtrlZoneNums(ZonesHeatedIndex) == this->ZonePtrs(ZonesPolledIndex)) {
     145            0 :                             this->AirLoopPtrs(AirLoopIndex) = AirLoopIndex;
     146              :                         }
     147              :                     }
     148              :                 }
     149              :             }
     150              :         }
     151              : 
     152            2 :         if (this->PlantOps.NumSimultHeatCoolHeatingEquipLists > 0 && this->PlantOps.NumSimultHeatCoolCoolingEquipLists > 0) {
     153            1 :             this->PlantOps.SimultHeatCoolOpAvailable = true;
     154              :         }
     155              : 
     156            2 :         this->PlantLoopIndicesBeingSupervised.allocate(state.dataPlnt->TotNumLoops);
     157            2 :         this->PlantLoopIndicesBeingSupervised = 0;
     158            6 :         for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     159            4 :             auto &this_plant_loop(state.dataPlnt->PlantLoop(LoopNum));
     160            8 :             for (int OpNum = 1, OpNum_end = this_plant_loop.NumOpSchemes; OpNum <= OpNum_end; ++OpNum) {
     161            4 :                 auto const &this_op_scheme(this_plant_loop.OpScheme(OpNum));
     162            4 :                 if (this_op_scheme.Type == OpScheme::ChillerHeaterSupervisory) {
     163            4 :                     this->PlantLoopIndicesBeingSupervised(LoopNum) = LoopNum;
     164              :                 }
     165              :             }
     166              :         }
     167              : 
     168              :         // find an setup any Plant Load Profile objects on the supervised loops
     169            2 :         int numLoadProfileOnSupervisedLoops = 0;
     170            6 :         for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     171            4 :             if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
     172              :                 // search for any plant load profile on loop demand side
     173            4 :                 auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Demand));
     174           12 :                 for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
     175           16 :                     for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
     176            8 :                         if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::PlantLoadProfile) {
     177            0 :                             ++numLoadProfileOnSupervisedLoops;
     178              :                         }
     179              :                     }
     180              :                 }
     181              :             }
     182              :         }
     183            2 :         this->PlantOps.numPlantLoadProfiles = numLoadProfileOnSupervisedLoops;
     184              : 
     185            2 :         this->PlantLoadProfileComps.allocate(this->PlantOps.numPlantLoadProfiles);
     186            2 :         int loadProfileCompNum = 1;
     187            6 :         for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     188            4 :             if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
     189              :                 // search for any plant load profile on loop demand side
     190            4 :                 auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Demand));
     191           12 :                 for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
     192           16 :                     for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
     193            8 :                         if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::PlantLoadProfile) {
     194            0 :                             PlantLocation foundLoc;
     195            0 :                             foundLoc.loopNum = LoopNum;
     196            0 :                             foundLoc.loopSideNum = DataPlant::LoopSideLocation::Demand;
     197            0 :                             foundLoc.branchNum = BranchNum;
     198            0 :                             foundLoc.compNum = CompNum;
     199            0 :                             PlantLoadProfileComps(loadProfileCompNum) = foundLoc;
     200            0 :                             ++loadProfileCompNum;
     201              :                         }
     202              :                     }
     203              :                 }
     204              :             }
     205              :         } // end load profile setup
     206              : 
     207              :         // find and setup any boilers on the supervised loops
     208            2 :         int numBoilersOnSupervisedLoops = 0;
     209            6 :         for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     210            4 :             if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
     211              :                 // search for any Boiler on loop supply side
     212            4 :                 auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Supply));
     213           12 :                 for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
     214           16 :                     for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
     215            8 :                         if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::Boiler_Simple) {
     216            0 :                             ++numBoilersOnSupervisedLoops;
     217              :                         }
     218              :                     }
     219              :                 }
     220              :             }
     221              :         }
     222            2 :         this->PlantOps.numBoilers = numBoilersOnSupervisedLoops;
     223            2 :         this->PlantBoilerComps.allocate(this->PlantOps.numBoilers);
     224            2 :         int BoilerCompNum = 1;
     225            6 :         for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     226            4 :             if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
     227              :                 // search for  boiler on loop supply side
     228            4 :                 auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Supply));
     229           12 :                 for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
     230           16 :                     for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
     231            8 :                         if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::Boiler_Simple) {
     232            0 :                             PlantLocation foundLoc;
     233            0 :                             foundLoc.loopNum = LoopNum;
     234            0 :                             foundLoc.loopSideNum = DataPlant::LoopSideLocation::Supply;
     235            0 :                             foundLoc.branchNum = BranchNum;
     236            0 :                             foundLoc.compNum = CompNum;
     237            0 :                             PlantBoilerComps(BoilerCompNum) = foundLoc;
     238            0 :                             ++BoilerCompNum;
     239              :                         }
     240              :                     }
     241              :                 }
     242              :             }
     243              :         } // end boiler setup
     244              : 
     245              :         // find and setup any fluid to fluid heat exchangers on the supervised loops
     246            2 :         this->SecondaryPlantLoopIndicesBeingSupervised.allocate(state.dataPlnt->TotNumLoops);
     247            2 :         this->SecondaryPlantLoopIndicesBeingSupervised = 0;
     248            2 :         int numHXsOnSupervisedLoops = 0;
     249            6 :         for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     250            4 :             if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
     251              :                 // search for any Heat exchangers on loop supply side
     252            4 :                 auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Supply));
     253           12 :                 for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
     254           16 :                     for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
     255            8 :                         if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::FluidToFluidPlantHtExchg) {
     256            0 :                             ++numHXsOnSupervisedLoops;
     257              :                         }
     258              :                     }
     259              :                 }
     260              :             }
     261              :         }
     262            2 :         this->PlantOps.numPlantHXs = numHXsOnSupervisedLoops;
     263            2 :         this->PlantHXComps.allocate(this->PlantOps.numPlantHXs);
     264            2 :         int HXCompNum = 1;
     265            6 :         for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     266            4 :             if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
     267              :                 // search for  boiler on loop supply side
     268            4 :                 auto &this_plant_loopside(state.dataPlnt->PlantLoop(LoopNum).LoopSide(DataPlant::LoopSideLocation::Supply));
     269           12 :                 for (int BranchNum = 1; BranchNum <= this_plant_loopside.TotalBranches; ++BranchNum) {
     270           16 :                     for (int CompNum = 1; CompNum <= this_plant_loopside.Branch(BranchNum).TotalComponents; ++CompNum) {
     271            8 :                         if (this_plant_loopside.Branch(BranchNum).Comp(CompNum).Type == DataPlant::PlantEquipmentType::FluidToFluidPlantHtExchg) {
     272            0 :                             PlantLocation foundLoc;
     273            0 :                             foundLoc.loopNum = LoopNum;
     274            0 :                             foundLoc.loopSideNum = DataPlant::LoopSideLocation::Supply;
     275            0 :                             foundLoc.branchNum = BranchNum;
     276            0 :                             foundLoc.compNum = CompNum;
     277            0 :                             PlantHXComps(HXCompNum) = foundLoc;
     278            0 :                             ++HXCompNum;
     279              : 
     280              :                             // store this loop as being a secondary loop
     281              :                             // assuming that since there is a heat exchanger on the supply side of this loop it is a secondary loop.
     282            0 :                             this->SecondaryPlantLoopIndicesBeingSupervised(LoopNum) = LoopNum;
     283              :                         }
     284              :                     }
     285              :                 }
     286              :             }
     287              :         } // end HX setup
     288              : 
     289              :         // setup Comp.SetPointNodeNum for machines
     290            2 :         if (this->PlantOps.NumCoolingOnlyEquipLists > 0) {
     291            5 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumCoolingOnlyEquipLists; ++equipListNum) {
     292              : 
     293            3 :                 int NumComps = this->CoolingOnlyEquipList(equipListNum).NumComps;
     294            7 :                 for (int compNum = 1; compNum <= NumComps; ++compNum) {
     295            4 :                     auto &this_equip(this->CoolingOnlyEquipList(equipListNum).Comp(compNum));
     296            4 :                     PlantLocation compLoc;
     297              :                     DataPlant::PlantEquipmentType Type =
     298            4 :                         static_cast<DataPlant::PlantEquipmentType>(getEnumValue(PlantEquipTypeNamesUC, Util::makeUPPER(this_equip.TypeOf)));
     299            4 :                     bool errFlag1(false);
     300            4 :                     int NumSearchResults(0);
     301            4 :                     PlantUtilities::ScanPlantLoopsForObject(state, this_equip.Name, Type, compLoc, errFlag1, _, _, NumSearchResults);
     302            4 :                     if (NumSearchResults == 1) {
     303              : 
     304            4 :                         this_equip.LoopNumPtr = compLoc.loopNum;
     305            4 :                         this_equip.LoopSideNumPtr = compLoc.loopSideNum;
     306            4 :                         this_equip.BranchNumPtr = compLoc.branchNum;
     307            4 :                         this_equip.CompNumPtr = compLoc.compNum;
     308            4 :                         this->PlantOps.PrimaryChWLoopIndex = compLoc.loopNum;
     309            0 :                     } else if (NumSearchResults > 1) {
     310            0 :                         bool foundit = false;
     311            0 :                         for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     312            0 :                             if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
     313            0 :                                 int PltSizNum = state.dataPlnt->PlantLoop(LoopNum).PlantSizNum;
     314            0 :                                 if (PltSizNum > 0) {
     315            0 :                                     if (state.dataSize->PlantSizData(PltSizNum).LoopType == DataSizing::TypeOfPlantLoop::Cooling) {
     316            0 :                                         int innerNumSearchResults = 0;
     317            0 :                                         PlantUtilities::ScanPlantLoopsForObject(
     318              :                                             state, this_equip.Name, Type, compLoc, errFlag1, _, _, innerNumSearchResults, _, LoopNum);
     319            0 :                                         if (innerNumSearchResults == 1) {
     320            0 :                                             this_equip.LoopNumPtr = compLoc.loopNum;
     321            0 :                                             this_equip.LoopSideNumPtr = compLoc.loopSideNum;
     322            0 :                                             this_equip.BranchNumPtr = compLoc.branchNum;
     323            0 :                                             this_equip.CompNumPtr = compLoc.compNum;
     324            0 :                                             foundit = true;
     325            0 :                                             continue;
     326              :                                         }
     327              :                                     }
     328              :                                 }
     329              :                             }
     330              :                         }
     331            0 :                         if (!foundit) {
     332            0 :                             ShowSevereError(state,
     333            0 :                                             format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
     334              :                                                    "component \"{}\" was not found on a cooling plant loop.",
     335            0 :                                                    this->Name,
     336            0 :                                                    this_equip.Name));
     337              :                         }
     338            0 :                     } else if (NumSearchResults == 0) {
     339            0 :                         ShowSevereError(state,
     340            0 :                                         format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
     341              :                                                "component \"{}\" was not found on a plant loop.",
     342            0 :                                                this->Name,
     343            0 :                                                this_equip.Name));
     344              :                     }
     345            4 :                     int inletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     346            4 :                                         .LoopSide(this_equip.LoopSideNumPtr)
     347            4 :                                         .Branch(this_equip.BranchNumPtr)
     348            4 :                                         .Comp(this_equip.CompNumPtr)
     349            4 :                                         .NodeNumIn;
     350            4 :                     int outletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     351            4 :                                          .LoopSide(this_equip.LoopSideNumPtr)
     352            4 :                                          .Branch(this_equip.BranchNumPtr)
     353            4 :                                          .Comp(this_equip.CompNumPtr)
     354            4 :                                          .NodeNumOut;
     355            4 :                     this_equip.DemandNodeNum = inletNode;
     356            4 :                     this_equip.SetPointNodeNum = outletNode;
     357            4 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     358            4 :                         .LoopSide(this_equip.LoopSideNumPtr)
     359            4 :                         .Branch(this_equip.BranchNumPtr)
     360            4 :                         .Comp(this_equip.CompNumPtr)
     361            4 :                         .OpScheme.allocate(1);
     362            4 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     363            4 :                         .LoopSide(this_equip.LoopSideNumPtr)
     364            4 :                         .Branch(this_equip.BranchNumPtr)
     365            4 :                         .Comp(this_equip.CompNumPtr)
     366            4 :                         .OpScheme(1)
     367            4 :                         .OpSchemePtr = 1; // TODO check
     368            4 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     369            4 :                         .LoopSide(this_equip.LoopSideNumPtr)
     370            4 :                         .Branch(this_equip.BranchNumPtr)
     371            4 :                         .Comp(this_equip.CompNumPtr)
     372            8 :                         .CurOpSchemeType = this->Type;
     373              :                 }
     374              :             }
     375              :         }
     376            2 :         if (this->PlantOps.NumHeatingOnlyEquipLists > 0) {
     377            5 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumHeatingOnlyEquipLists; ++equipListNum) {
     378              : 
     379            3 :                 int NumComps = this->HeatingOnlyEquipList(equipListNum).NumComps;
     380            7 :                 for (int compNum = 1; compNum <= NumComps; ++compNum) {
     381            4 :                     auto &this_equip(this->HeatingOnlyEquipList(equipListNum).Comp(compNum));
     382            4 :                     PlantLocation compLoc;
     383              :                     DataPlant::PlantEquipmentType Type;
     384            4 :                     Type = static_cast<DataPlant::PlantEquipmentType>(getEnumValue(PlantEquipTypeNamesUC, Util::makeUPPER(this_equip.TypeOf)));
     385            4 :                     bool errFlag1(false);
     386            4 :                     int NumSearchResults(0);
     387            4 :                     PlantUtilities::ScanPlantLoopsForObject(state, this_equip.Name, Type, compLoc, errFlag1, _, _, NumSearchResults);
     388            4 :                     if (NumSearchResults == 1) {
     389              : 
     390            4 :                         this_equip.LoopNumPtr = compLoc.loopNum;
     391            4 :                         this_equip.LoopSideNumPtr = compLoc.loopSideNum;
     392            4 :                         this_equip.BranchNumPtr = compLoc.branchNum;
     393            4 :                         this_equip.CompNumPtr = compLoc.compNum;
     394            4 :                         this->PlantOps.PrimaryHWLoopIndex = compLoc.loopNum;
     395              : 
     396            0 :                     } else if (NumSearchResults > 1) {
     397              : 
     398            0 :                         bool foundit = false;
     399            0 :                         for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     400            0 :                             if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
     401            0 :                                 int PltSizNum = state.dataPlnt->PlantLoop(LoopNum).PlantSizNum;
     402            0 :                                 if (PltSizNum > 0) {
     403            0 :                                     if (state.dataSize->PlantSizData(PltSizNum).LoopType == DataSizing::TypeOfPlantLoop::Heating) {
     404            0 :                                         int innerNumSearchResults = 0;
     405            0 :                                         PlantUtilities::ScanPlantLoopsForObject(
     406              :                                             state, this_equip.Name, Type, compLoc, errFlag1, _, _, innerNumSearchResults, _, LoopNum);
     407            0 :                                         if (innerNumSearchResults == 1) {
     408            0 :                                             this_equip.LoopNumPtr = compLoc.loopNum;
     409            0 :                                             this_equip.LoopSideNumPtr = compLoc.loopSideNum;
     410            0 :                                             this_equip.BranchNumPtr = compLoc.branchNum;
     411            0 :                                             this_equip.CompNumPtr = compLoc.compNum;
     412            0 :                                             foundit = true;
     413            0 :                                             continue;
     414              :                                         }
     415              :                                     }
     416              :                                 }
     417              :                             }
     418              :                         }
     419            0 :                         if (!foundit) {
     420            0 :                             ShowSevereError(state,
     421            0 :                                             format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
     422              :                                                    "component \"{}\" was not found on a heating plant loop.",
     423            0 :                                                    this->Name,
     424            0 :                                                    this_equip.Name));
     425              :                         }
     426            0 :                     } else if (NumSearchResults == 0) {
     427            0 :                         ShowSevereError(state,
     428            0 :                                         format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
     429              :                                                "component \"{}\" was not found on a plant loop.",
     430            0 :                                                this->Name,
     431            0 :                                                this_equip.Name));
     432              :                     }
     433            4 :                     int inletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     434            4 :                                         .LoopSide(this_equip.LoopSideNumPtr)
     435            4 :                                         .Branch(this_equip.BranchNumPtr)
     436            4 :                                         .Comp(this_equip.CompNumPtr)
     437            4 :                                         .NodeNumIn;
     438            4 :                     int outletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     439            4 :                                          .LoopSide(this_equip.LoopSideNumPtr)
     440            4 :                                          .Branch(this_equip.BranchNumPtr)
     441            4 :                                          .Comp(this_equip.CompNumPtr)
     442            4 :                                          .NodeNumOut;
     443            4 :                     this_equip.DemandNodeNum = inletNode;
     444            4 :                     this_equip.SetPointNodeNum = outletNode;
     445            4 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     446            4 :                         .LoopSide(this_equip.LoopSideNumPtr)
     447            4 :                         .Branch(this_equip.BranchNumPtr)
     448            4 :                         .Comp(this_equip.CompNumPtr)
     449            4 :                         .OpScheme.allocate(1);
     450            4 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     451            4 :                         .LoopSide(this_equip.LoopSideNumPtr)
     452            4 :                         .Branch(this_equip.BranchNumPtr)
     453            4 :                         .Comp(this_equip.CompNumPtr)
     454            4 :                         .OpScheme(1)
     455            4 :                         .OpSchemePtr = 1; // TODO check
     456            4 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     457            4 :                         .LoopSide(this_equip.LoopSideNumPtr)
     458            4 :                         .Branch(this_equip.BranchNumPtr)
     459            4 :                         .Comp(this_equip.CompNumPtr)
     460            8 :                         .CurOpSchemeType = this->Type;
     461              :                 }
     462              :             }
     463              :         }
     464              : 
     465            2 :         if (this->PlantOps.NumSimultHeatCoolCoolingEquipLists > 0) {
     466            2 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolCoolingEquipLists; ++equipListNum) {
     467              : 
     468            1 :                 int NumComps = this->SimultHeatCoolCoolingEquipList(equipListNum).NumComps;
     469            2 :                 for (int compNum = 1; compNum <= NumComps; ++compNum) {
     470            1 :                     auto &this_equip(this->SimultHeatCoolCoolingEquipList(equipListNum).Comp(compNum));
     471            1 :                     PlantLocation compLoc;
     472              :                     DataPlant::PlantEquipmentType Type;
     473            1 :                     Type = static_cast<DataPlant::PlantEquipmentType>(getEnumValue(PlantEquipTypeNamesUC, Util::makeUPPER(this_equip.TypeOf)));
     474            1 :                     bool errFlag1(false);
     475            1 :                     int NumSearchResults(0);
     476            1 :                     PlantUtilities::ScanPlantLoopsForObject(state, this_equip.Name, Type, compLoc, errFlag1, _, _, NumSearchResults);
     477            1 :                     if (NumSearchResults == 1) {
     478              : 
     479            1 :                         this_equip.LoopNumPtr = compLoc.loopNum;
     480            1 :                         this_equip.LoopSideNumPtr = compLoc.loopSideNum;
     481            1 :                         this_equip.BranchNumPtr = compLoc.branchNum;
     482            1 :                         this_equip.CompNumPtr = compLoc.compNum;
     483              : 
     484            0 :                     } else if (NumSearchResults > 1) {
     485              : 
     486            0 :                         bool foundit = false;
     487            0 :                         for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     488            0 :                             if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
     489            0 :                                 int PltSizNum = state.dataPlnt->PlantLoop(LoopNum).PlantSizNum;
     490            0 :                                 if (PltSizNum > 0) {
     491            0 :                                     if (state.dataSize->PlantSizData(PltSizNum).LoopType == DataSizing::TypeOfPlantLoop::Cooling) {
     492            0 :                                         int innerNumSearchResults = 0;
     493            0 :                                         PlantUtilities::ScanPlantLoopsForObject(
     494              :                                             state, this_equip.Name, Type, compLoc, errFlag1, _, _, innerNumSearchResults, _, LoopNum);
     495            0 :                                         if (innerNumSearchResults == 1) {
     496            0 :                                             this_equip.LoopNumPtr = compLoc.loopNum;
     497            0 :                                             this_equip.LoopSideNumPtr = compLoc.loopSideNum;
     498            0 :                                             this_equip.BranchNumPtr = compLoc.branchNum;
     499            0 :                                             this_equip.CompNumPtr = compLoc.compNum;
     500            0 :                                             foundit = true;
     501            0 :                                             continue;
     502              :                                         }
     503              :                                     }
     504              :                                 }
     505              :                             }
     506              :                         }
     507            0 :                         if (!foundit) {
     508            0 :                             ShowSevereError(state,
     509            0 :                                             format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
     510              :                                                    "component \"{}\" was not found on a cooling plant loop.",
     511            0 :                                                    this->Name,
     512            0 :                                                    this_equip.Name));
     513              :                         }
     514            0 :                     } else if (NumSearchResults == 0) {
     515            0 :                         ShowSevereError(state,
     516            0 :                                         format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
     517              :                                                "component \"{}\" was not found on a plant loop.",
     518            0 :                                                this->Name,
     519            0 :                                                this_equip.Name));
     520              :                     }
     521            1 :                     int inletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     522            1 :                                         .LoopSide(this_equip.LoopSideNumPtr)
     523            1 :                                         .Branch(this_equip.BranchNumPtr)
     524            1 :                                         .Comp(this_equip.CompNumPtr)
     525            1 :                                         .NodeNumIn;
     526            1 :                     int outletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     527            1 :                                          .LoopSide(this_equip.LoopSideNumPtr)
     528            1 :                                          .Branch(this_equip.BranchNumPtr)
     529            1 :                                          .Comp(this_equip.CompNumPtr)
     530            1 :                                          .NodeNumOut;
     531            1 :                     this_equip.DemandNodeNum = inletNode;
     532            1 :                     this_equip.SetPointNodeNum = outletNode;
     533            1 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     534            1 :                         .LoopSide(this_equip.LoopSideNumPtr)
     535            1 :                         .Branch(this_equip.BranchNumPtr)
     536            1 :                         .Comp(this_equip.CompNumPtr)
     537            1 :                         .OpScheme.allocate(1);
     538            1 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     539            1 :                         .LoopSide(this_equip.LoopSideNumPtr)
     540            1 :                         .Branch(this_equip.BranchNumPtr)
     541            1 :                         .Comp(this_equip.CompNumPtr)
     542            1 :                         .OpScheme(1)
     543            1 :                         .OpSchemePtr = 1; // TODO check
     544            1 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     545            1 :                         .LoopSide(this_equip.LoopSideNumPtr)
     546            1 :                         .Branch(this_equip.BranchNumPtr)
     547            1 :                         .Comp(this_equip.CompNumPtr)
     548            2 :                         .CurOpSchemeType = this->Type;
     549              :                 }
     550              :             }
     551              :         }
     552              : 
     553            2 :         if (this->PlantOps.NumSimultHeatCoolHeatingEquipLists > 0) {
     554            2 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolHeatingEquipLists; ++equipListNum) {
     555              : 
     556            1 :                 int NumComps = this->SimultHeatCoolHeatingEquipList(equipListNum).NumComps;
     557            2 :                 for (int compNum = 1; compNum <= NumComps; ++compNum) {
     558            1 :                     auto &this_equip(this->SimultHeatCoolHeatingEquipList(equipListNum).Comp(compNum));
     559            1 :                     PlantLocation compLoc;
     560              :                     DataPlant::PlantEquipmentType Type;
     561            1 :                     Type = static_cast<DataPlant::PlantEquipmentType>(getEnumValue(PlantEquipTypeNamesUC, Util::makeUPPER(this_equip.TypeOf)));
     562            1 :                     bool errFlag1(false);
     563            1 :                     int NumSearchResults(0);
     564            1 :                     PlantUtilities::ScanPlantLoopsForObject(state, this_equip.Name, Type, compLoc, errFlag1, _, _, NumSearchResults);
     565            1 :                     if (NumSearchResults == 1) {
     566              : 
     567            1 :                         this_equip.LoopNumPtr = compLoc.loopNum;
     568            1 :                         this_equip.LoopSideNumPtr = compLoc.loopSideNum;
     569            1 :                         this_equip.BranchNumPtr = compLoc.branchNum;
     570            1 :                         this_equip.CompNumPtr = compLoc.compNum;
     571              : 
     572            0 :                     } else if (NumSearchResults > 1) {
     573              : 
     574            0 :                         bool foundit = false;
     575            0 :                         for (int LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     576            0 :                             if (this->PlantLoopIndicesBeingSupervised(LoopNum) > 0) {
     577            0 :                                 int PltSizNum = state.dataPlnt->PlantLoop(LoopNum).PlantSizNum;
     578            0 :                                 if (PltSizNum > 0) {
     579            0 :                                     if (state.dataSize->PlantSizData(PltSizNum).LoopType == DataSizing::TypeOfPlantLoop::Heating) {
     580            0 :                                         int innerNumSearchResults = 0;
     581            0 :                                         PlantUtilities::ScanPlantLoopsForObject(
     582              :                                             state, this_equip.Name, Type, compLoc, errFlag1, _, _, innerNumSearchResults, _, LoopNum);
     583            0 :                                         if (innerNumSearchResults == 1) {
     584            0 :                                             this_equip.LoopNumPtr = compLoc.loopNum;
     585            0 :                                             this_equip.LoopSideNumPtr = compLoc.loopSideNum;
     586            0 :                                             this_equip.BranchNumPtr = compLoc.branchNum;
     587            0 :                                             this_equip.CompNumPtr = compLoc.compNum;
     588            0 :                                             foundit = true;
     589            0 :                                             continue;
     590              :                                         }
     591              :                                     }
     592              :                                 }
     593              :                             }
     594              :                         }
     595            0 :                         if (!foundit) {
     596            0 :                             ShowSevereError(state,
     597            0 :                                             format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
     598              :                                                    "component \"{}\" was not found on a heating plant loop.",
     599            0 :                                                    this->Name,
     600            0 :                                                    this_equip.Name));
     601              :                         }
     602            0 :                     } else if (NumSearchResults == 0) {
     603            0 :                         ShowSevereError(state,
     604            0 :                                         format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" "
     605              :                                                "component \"{}\" was not found on a plant loop.",
     606            0 :                                                this->Name,
     607            0 :                                                this_equip.Name));
     608              :                     }
     609            1 :                     int inletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     610            1 :                                         .LoopSide(this_equip.LoopSideNumPtr)
     611            1 :                                         .Branch(this_equip.BranchNumPtr)
     612            1 :                                         .Comp(this_equip.CompNumPtr)
     613            1 :                                         .NodeNumIn;
     614            1 :                     int outletNode = state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     615            1 :                                          .LoopSide(this_equip.LoopSideNumPtr)
     616            1 :                                          .Branch(this_equip.BranchNumPtr)
     617            1 :                                          .Comp(this_equip.CompNumPtr)
     618            1 :                                          .NodeNumOut;
     619            1 :                     this_equip.DemandNodeNum = inletNode;
     620            1 :                     this_equip.SetPointNodeNum = outletNode;
     621            1 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     622            1 :                         .LoopSide(this_equip.LoopSideNumPtr)
     623            1 :                         .Branch(this_equip.BranchNumPtr)
     624            1 :                         .Comp(this_equip.CompNumPtr)
     625            1 :                         .OpScheme.allocate(1);
     626            1 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     627            1 :                         .LoopSide(this_equip.LoopSideNumPtr)
     628            1 :                         .Branch(this_equip.BranchNumPtr)
     629            1 :                         .Comp(this_equip.CompNumPtr)
     630            1 :                         .OpScheme(1)
     631            1 :                         .OpSchemePtr = 1; // TODO check
     632            1 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
     633            1 :                         .LoopSide(this_equip.LoopSideNumPtr)
     634            1 :                         .Branch(this_equip.BranchNumPtr)
     635            1 :                         .Comp(this_equip.CompNumPtr)
     636            2 :                         .CurOpSchemeType = this->Type;
     637              :                 }
     638              :             }
     639              :         }
     640              : 
     641              :         // process primary loops for supply inlet node numbers
     642              : 
     643              :         // examine supply inlet branch on primary chilled water loop to see if there is a tank, use outlet of tank if so
     644              : 
     645            2 :         if (this->PlantOps.PrimaryChWLoopIndex > 0) {
     646              : 
     647            2 :             this->PlantOps.PrimaryChWLoopSupInletNode =
     648            2 :                 state.dataPlnt->PlantLoop(this->PlantOps.PrimaryChWLoopIndex).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).NodeNumIn;
     649            4 :             for (int numComps = 1; numComps <= state.dataPlnt->PlantLoop(this->PlantOps.PrimaryChWLoopIndex)
     650            4 :                                                    .LoopSide(DataPlant::LoopSideLocation::Supply)
     651            4 :                                                    .Branch(1)
     652            4 :                                                    .TotalComponents;
     653              :                  ++numComps) {
     654            2 :                 auto const &this_Comp(state.dataPlnt->PlantLoop(this->PlantOps.PrimaryChWLoopIndex)
     655            2 :                                           .LoopSide(DataPlant::LoopSideLocation::Supply)
     656            2 :                                           .Branch(1)
     657            2 :                                           .Comp(numComps));
     658            2 :                 if (this_Comp.Type == DataPlant::PlantEquipmentType::ChilledWaterTankMixed ||
     659            2 :                     this_Comp.Type == DataPlant::PlantEquipmentType::ChilledWaterTankStratified) {
     660              :                     // assume tank is on chilled water return for use as a buffer tank, use the outlet of the tank instead of the inlet when
     661              :                     // calculating the current load on the primary chilled water plant
     662            0 :                     this->PlantOps.PrimaryChWLoopSupInletNode = this_Comp.NodeNumOut;
     663              :                 }
     664              :             }
     665              :         }
     666              : 
     667            2 :         if (this->PlantOps.PrimaryHWLoopIndex > 0) {
     668            2 :             this->PlantOps.PrimaryHWLoopSupInletNode =
     669            2 :                 state.dataPlnt->PlantLoop(this->PlantOps.PrimaryHWLoopIndex).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).NodeNumIn;
     670              :         }
     671              :         // process dedicated heat recovery water to water heatpumps to control
     672            2 :         if (this->PlantOps.DedicatedHR_ChWRetControl_Input && this->PlantOps.DedicatedHR_HWRetControl_Input) {
     673            0 :             bool founditCooling = false;
     674            0 :             bool founditHeating = false;
     675            0 :             for (auto &thisHP : state.dataEIRPlantLoopHeatPump->heatPumps) {
     676            0 :                 std::string const thisPLHPName = Util::makeUPPER(thisHP.name);
     677              :                 // find cooling side heat pump
     678            0 :                 std::string const targetDedHRCoolName = Util::makeUPPER(this->DedicatedHR_ChWRetControl_Name);
     679            0 :                 if (thisPLHPName == targetDedHRCoolName) {  // found it
     680            0 :                     this->DedicatedHR_CoolingPLHP = thisHP; // store pointer to cooling side of heat pump
     681            0 :                     founditCooling = true;
     682              : 
     683            0 :                     int pltSizNum = state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum).PlantSizNum;
     684            0 :                     this->PlantOps.DedicatedHR_SecChW_DesignCapacity = state.dataSize->PlantSizData(pltSizNum).DesCapacity;
     685            0 :                     this->PlantOps.SecondaryChWLoopIndex = this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum;
     686              : 
     687              :                     // set up load side plant loop information for cooling side of heat pump
     688            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
     689            0 :                         .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
     690            0 :                         .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
     691            0 :                         .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
     692            0 :                         .OpScheme.allocate(1);
     693            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
     694            0 :                         .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
     695            0 :                         .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
     696            0 :                         .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
     697            0 :                         .OpScheme(1)
     698            0 :                         .OpSchemePtr = 1;
     699            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
     700            0 :                         .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
     701            0 :                         .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
     702            0 :                         .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
     703            0 :                         .CurOpSchemeType = this->Type;
     704              : 
     705              :                     // setup source side plant loop data structure information for cooling side of heat pump
     706            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
     707            0 :                         .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
     708            0 :                         .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
     709            0 :                         .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
     710            0 :                         .OpScheme.allocate(1);
     711            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
     712            0 :                         .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
     713            0 :                         .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
     714            0 :                         .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
     715            0 :                         .OpScheme(1)
     716            0 :                         .OpSchemePtr = 1;
     717            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
     718            0 :                         .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
     719            0 :                         .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
     720            0 :                         .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
     721            0 :                         .CurOpSchemeType = this->Type;
     722              :                 }
     723              : 
     724              :                 // find heating side heat pump
     725            0 :                 std::string const targetDedHRHeatName = Util::makeUPPER(this->DedicatedHR_HWRetControl_Name);
     726            0 :                 if (thisPLHPName == targetDedHRHeatName) {  // found it
     727            0 :                     this->DedicatedHR_HeatingPLHP = thisHP; // store pointer to heating side of heat pump
     728            0 :                     founditHeating = true;
     729              : 
     730            0 :                     int pltSizNum = state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum).PlantSizNum;
     731            0 :                     this->PlantOps.DedicatedHR_SecHW_DesignCapacity = state.dataSize->PlantSizData(pltSizNum).DesCapacity;
     732            0 :                     this->PlantOps.SecondaryHWLoopIndex = this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum;
     733              : 
     734            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
     735            0 :                         .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
     736            0 :                         .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
     737            0 :                         .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
     738            0 :                         .OpScheme.allocate(1);
     739            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
     740            0 :                         .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
     741            0 :                         .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
     742            0 :                         .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
     743            0 :                         .OpScheme(1)
     744            0 :                         .OpSchemePtr = 1;
     745            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
     746            0 :                         .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
     747            0 :                         .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
     748            0 :                         .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
     749            0 :                         .CurOpSchemeType = this->Type;
     750              : 
     751              :                     // setup source side plant loop data structure information for heating side of heat pump
     752            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
     753            0 :                         .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
     754            0 :                         .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
     755            0 :                         .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
     756            0 :                         .OpScheme.allocate(1);
     757            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
     758            0 :                         .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
     759            0 :                         .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
     760            0 :                         .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
     761            0 :                         .OpScheme(1)
     762            0 :                         .OpSchemePtr = 1;
     763            0 :                     state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
     764            0 :                         .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
     765            0 :                         .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
     766            0 :                         .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
     767            0 :                         .CurOpSchemeType = this->Type;
     768              :                 }
     769            0 :             }
     770              : 
     771            0 :             if (!founditCooling) {
     772            0 :                 ShowSevereError(state,
     773            0 :                                 format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" component "
     774              :                                        "\"{}\" was not found on a cooling plant loop.",
     775            0 :                                        this->Name,
     776            0 :                                        this->DedicatedHR_ChWRetControl_Name));
     777              :             }
     778            0 :             if (!founditHeating) {
     779            0 :                 ShowSevereError(state,
     780            0 :                                 format("ChillerHeaterSupervisoryOperationData::OneTimeInitChillerHeaterChangeoverOpScheme problem=\"{}\" component "
     781              :                                        "\"{}\" was not found on a heating plant loop.",
     782            0 :                                        this->Name,
     783            0 :                                        this->DedicatedHR_ChWRetControl_Name));
     784              :             }
     785            0 :             if (founditCooling && founditHeating) {
     786            0 :                 this->PlantOps.DedicatedHR_Present = true;
     787            0 :                 SetupOutputVariable(state,
     788              :                                     "Supervisory Plant Heat Recovery Operation Mode",
     789              :                                     Constant::Units::unknown,
     790            0 :                                     this->Report.DedicHR_OpMode,
     791              :                                     OutputProcessor::TimeStepType::System,
     792              :                                     OutputProcessor::StoreType::Average,
     793            0 :                                     this->Name);
     794            0 :                 SetupOutputVariable(state,
     795              :                                     "Supervisory Plant Operation Secondary Plant Heating Load",
     796              :                                     Constant::Units::W,
     797            0 :                                     this->Report.SecondaryPlantHeatingLoad,
     798              :                                     OutputProcessor::TimeStepType::System,
     799              :                                     OutputProcessor::StoreType::Average,
     800            0 :                                     this->Name);
     801            0 :                 SetupOutputVariable(state,
     802              :                                     "Supervisory Plant Operation Secondary Plant Cooling Load",
     803              :                                     Constant::Units::W,
     804            0 :                                     this->Report.SecondaryPlantCoolingLoad,
     805              :                                     OutputProcessor::TimeStepType::System,
     806              :                                     OutputProcessor::StoreType::Average,
     807            0 :                                     this->Name);
     808              :             }
     809              :         }
     810              : 
     811            2 :         this->oneTimeSetupComplete = true;
     812              :     }
     813              : 
     814           11 :     void ChillerHeaterSupervisoryOperationData::EvaluateChillerHeaterChangeoverOpScheme(EnergyPlusData &state)
     815              :     {
     816              : 
     817           11 :         DetermineCurrentBuildingLoads(state);
     818           11 :         DetermineCurrentPlantLoads(state);
     819           11 :         ProcessSupervisoryControlLogicForAirSourcePlants(state);
     820           11 :         InitAirSourcePlantEquipmentOff(state);
     821           11 :         ProcessAndSetAirSourcePlantEquipLists(state);
     822           11 :         ProcessAndSetDedicatedHeatRecovWWHP(state);
     823           11 :         ProcessAndSetAuxilBoiler(state);
     824           11 :     }
     825              : 
     826           11 :     void ChillerHeaterSupervisoryOperationData::DetermineCurrentBuildingLoads(EnergyPlusData &state)
     827              :     {
     828              :         // Poll the loads on the zones to help decide how to run
     829              : 
     830           11 :         Real64 sumZonePredictedHeatingLoad(0.0);
     831           11 :         Real64 sumZonePredictedCoolingLoad(0.0);
     832           55 :         for (int zoneIndexinList = 1; zoneIndexinList <= this->PlantOps.NumOfZones; ++zoneIndexinList) {
     833           44 :             int thisZoneIndex = this->ZonePtrs(zoneIndexinList);
     834           44 :             Real64 ZoneMult = state.dataHeatBal->Zone(thisZoneIndex).Multiplier * state.dataHeatBal->Zone(thisZoneIndex).ListMultiplier;
     835              :             // aggregate required outputs to setpoint, with zone multipliers included
     836           44 :             sumZonePredictedCoolingLoad +=
     837           44 :                 min(0.0,
     838           44 :                     state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisZoneIndex).OutputRequiredToCoolingSP * ZoneMult); // sum only negative values
     839           44 :             sumZonePredictedHeatingLoad +=
     840           44 :                 max(0.0,
     841           44 :                     state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisZoneIndex).OutputRequiredToHeatingSP * ZoneMult); // sum only positive values
     842              :         }
     843              : 
     844              :         // now add in ventilation loading at the central air system level
     845           11 :         Real64 sumAirSysVentHeatingLoad(0.0);
     846           11 :         Real64 sumAirSysVentCoolingLoad(0.0);
     847              : 
     848           22 :         for (int airLoopsServedIndex = 1; airLoopsServedIndex <= this->PlantOps.NumOfAirLoops; ++airLoopsServedIndex) {
     849           11 :             int AirLoopNum = this->AirLoopPtrs(airLoopsServedIndex);
     850           11 :             Real64 outAir_H = state.dataEnvrn->OutEnthalpy;
     851           11 :             Real64 outAirMdot = state.dataAirLoop->AirLoopFlow(AirLoopNum).OAFlow;
     852           11 :             Real64 retAir_Tdb = state.dataLoopNodes->Node(state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopReturnNodeNum(1)).Temp;
     853           11 :             Real64 retAir_w = state.dataLoopNodes->Node(state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopReturnNodeNum(1)).HumRat;
     854           11 :             Real64 ventLoad = outAirMdot * (Psychrometrics::PsyHFnTdbW(retAir_Tdb, retAir_w) - outAir_H); // negative is cooling
     855           11 :             if (ventLoad > HVAC::SmallLoad) {                                                             // add to heating
     856            0 :                 sumAirSysVentHeatingLoad += ventLoad;
     857           11 :             } else if (ventLoad < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) { // add to cooling
     858            0 :                 sumAirSysVentCoolingLoad += ventLoad;
     859              :             }
     860              :         }
     861              : 
     862              :         // now add in any process loads from plant load profiles on the controlled loops.
     863           11 :         Real64 sumLoadProfileHeatingLoad(0.0);
     864           11 :         Real64 sumLoadProfileCoolingLoad(0.0);
     865           11 :         for (int NumProcLoad = 1; NumProcLoad <= this->PlantOps.numPlantLoadProfiles; ++NumProcLoad) {
     866            0 :             Real64 load = 0.0;
     867            0 :             DataPlant::CompData::getPlantComponent(state, PlantLoadProfileComps(NumProcLoad)).compPtr->getCurrentPower(state, load);
     868            0 :             if (load > 0.0) {
     869            0 :                 sumLoadProfileHeatingLoad += load;
     870              :             } else {
     871            0 :                 sumLoadProfileCoolingLoad += load;
     872              :             }
     873              :         }
     874              : 
     875           11 :         this->Report.BuildingPolledCoolingLoad = sumZonePredictedCoolingLoad + sumAirSysVentCoolingLoad + sumLoadProfileCoolingLoad;
     876           11 :         this->Report.BuildingPolledHeatingLoad = sumZonePredictedHeatingLoad + sumAirSysVentHeatingLoad + sumLoadProfileHeatingLoad;
     877              :         // end  collect loads.
     878           11 :     }
     879              : 
     880           11 :     void ChillerHeaterSupervisoryOperationData::DetermineCurrentPlantLoads(EnergyPlusData &state)
     881              :     {
     882              : 
     883              :         // Calculate load on primary chilled water loop and store in PrimaryPlantCoolingLoad
     884              : 
     885           11 :         Real64 CW_RetMdot = state.dataLoopNodes->Node(this->PlantOps.PrimaryChWLoopSupInletNode).MassFlowRate;
     886           11 :         Real64 const CpCW = state.dataPlnt->PlantLoop(this->PlantOps.PrimaryChWLoopIndex)
     887           11 :                                 .glycol->getSpecificHeat(
     888           11 :                                     state, state.dataLoopNodes->Node(this->PlantOps.PrimaryChWLoopSupInletNode).Temp, "DetermineCurrentPlantLoads");
     889              :         Real64 CW_Qdot =
     890           11 :             min(0.0,
     891           11 :                 CW_RetMdot * CpCW *
     892           22 :                     (this->Setpoint.PrimCW -
     893           11 :                      state.dataLoopNodes->Node(this->PlantOps.PrimaryChWLoopSupInletNode).Temp)); // power = Mdot Cp Delta T, cooling load is negative
     894           11 :         this->Report.PrimaryPlantCoolingLoad = CW_Qdot;
     895              : 
     896              :         // Calculate load on primary hot water loop and store in PrimaryPlantHeatingLoad
     897              :         // int HWSupInletNode = this->PlantOps.PrimaryHWLoopSupInletNode;
     898              :         //      state.dataPlnt->PlantLoop(this->PlantOps.PrimaryHWLoopIndex).LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).NodeNumIn;
     899           11 :         Real64 HW_RetMdot = state.dataLoopNodes->Node(this->PlantOps.PrimaryHWLoopSupInletNode).MassFlowRate;
     900           11 :         Real64 const CpHW = state.dataPlnt->PlantLoop(this->PlantOps.PrimaryHWLoopIndex)
     901           11 :                                 .glycol->getSpecificHeat(
     902           11 :                                     state, state.dataLoopNodes->Node(this->PlantOps.PrimaryHWLoopSupInletNode).Temp, "DetermineCurrentPlantLoads");
     903              : 
     904              :         Real64 HW_Qdot =
     905           11 :             max(0.0,
     906           11 :                 HW_RetMdot * CpHW *
     907           11 :                     (this->DetermineHWSetpointOARest(state) -
     908           11 :                      state.dataLoopNodes->Node(this->PlantOps.PrimaryHWLoopSupInletNode).Temp)); // power = Mdot Cp Delta T, heating load is positive
     909           11 :         this->Report.PrimaryPlantHeatingLoad = HW_Qdot;
     910           11 :     }
     911              : 
     912           11 :     void ChillerHeaterSupervisoryOperationData::ProcessSupervisoryControlLogicForAirSourcePlants(EnergyPlusData &state)
     913              :     {
     914              :         // this routine decides which of three modes the plants should operate in,  Heating Only, Cooling Only, Simultaneous Heating and Cooling.
     915              : 
     916              :         // step 1, initialize control bools
     917           11 :         this->PlantOps.AirSourcePlantCoolingOnly = false;
     918           11 :         this->PlantOps.AirSourcePlantHeatingOnly = false;
     919           11 :         this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = false;
     920           11 :         this->PlantOps.SimultaneousHeatingCoolingWithCoolingDominant = false;
     921           11 :         this->PlantOps.SimultaneousHeatingCoolingWithHeatingDominant = false;
     922              : 
     923              :         // step 2, process logic based on poll results for building loads.
     924           11 :         if (this->Report.BuildingPolledHeatingLoad < HVAC::SmallLoad &&
     925            7 :             this->Report.BuildingPolledCoolingLoad < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) {
     926            2 :             this->PlantOps.AirSourcePlantCoolingOnly = true;
     927            9 :         } else if (this->Report.BuildingPolledCoolingLoad > DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad &&
     928            7 :                    this->Report.BuildingPolledHeatingLoad > HVAC::SmallLoad) {
     929            2 :             this->PlantOps.AirSourcePlantHeatingOnly = true;
     930              : 
     931            2 :             if (state.dataEnvrn->OutDryBulbTemp < this->TempReset.LowOutdoorTemp) { // too cold for airsource HPs so
     932            0 :                 this->PlantOps.AirSourcePlantHeatingOnly = false;
     933              :             }
     934              : 
     935            7 :         } else if ((this->Report.BuildingPolledCoolingLoad < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) &&
     936            2 :                    (this->Report.BuildingPolledHeatingLoad > HVAC::SmallLoad)) {
     937            2 :             this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = true;
     938            2 :             if (this->Report.BuildingPolledHeatingLoad > abs(this->Report.BuildingPolledCoolingLoad)) {
     939            0 :                 this->PlantOps.SimultaneousHeatingCoolingWithHeatingDominant = true;
     940            0 :                 if (this->PlantOps.SimultHeatCoolOpAvailable) {
     941            0 :                     this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = true;
     942              :                 } else {
     943            0 :                     this->PlantOps.AirSourcePlantHeatingOnly = true;
     944            0 :                     this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = false;
     945              :                 }
     946            2 :             } else if (abs(this->Report.BuildingPolledCoolingLoad) > this->Report.BuildingPolledHeatingLoad) {
     947            1 :                 this->PlantOps.SimultaneousHeatingCoolingWithCoolingDominant = true;
     948            1 :                 if (this->PlantOps.SimultHeatCoolOpAvailable) {
     949            0 :                     this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = true;
     950              :                 } else {
     951            1 :                     this->PlantOps.AirSourcePlantCoolingOnly = true;
     952            1 :                     this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = false;
     953              :                 }
     954              :             }
     955            2 :             if (state.dataEnvrn->OutDryBulbTemp < this->TempReset.LowOutdoorTemp) { // too cold for airsource HPs
     956            0 :                 this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = false;
     957            0 :                 this->PlantOps.AirSourcePlantCoolingOnly = true;
     958              :             }
     959              :         }
     960              : 
     961              :         // step 3, revise control decision based on current loads on primary plant loops
     962           11 :         if (this->PlantOps.AirSourcePlantHeatingOnly &&
     963            2 :             this->Report.PrimaryPlantCoolingLoad < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) {
     964              :             // polled building loads indicate all heating, but cooling plant has cooling load, try to switch to simultaneous cooling and heating with
     965              :             // heating dominant
     966            0 :             if (this->PlantOps.SimultHeatCoolOpAvailable) {
     967            0 :                 this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = true;
     968            0 :                 this->PlantOps.SimultaneousHeatingCoolingWithHeatingDominant = true;
     969            0 :                 this->PlantOps.AirSourcePlantHeatingOnly = false;
     970              :             }
     971              :         }
     972              : 
     973           12 :         if (this->PlantOps.AirSourcePlantCoolingOnly && this->Report.PrimaryPlantHeatingLoad > HVAC::SmallLoad &&
     974            1 :             state.dataEnvrn->OutDryBulbTemp >= this->TempReset.LowOutdoorTemp) {
     975              :             // polled building loads indicate all cooling, but heating plant has heating load, and outdoor air is warm enough for heat pump, try to
     976              :             // switch to simultaneous cooling and heating with cooling dominant
     977            1 :             if (this->PlantOps.SimultHeatCoolOpAvailable) {
     978            0 :                 this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling = true;
     979            0 :                 this->PlantOps.SimultaneousHeatingCoolingWithCoolingDominant = true;
     980            0 :                 this->PlantOps.AirSourcePlantCoolingOnly = false;
     981              :             }
     982              :         }
     983              : 
     984              :         // do we need to turn on cooling-only if in off mode but PrimaryPlantCoolingLoad is loaded?
     985           11 :         if (!this->PlantOps.AirSourcePlantCoolingOnly && !this->PlantOps.AirSourcePlantHeatingOnly &&
     986            6 :             !this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) { // all off
     987            5 :             if (this->Report.PrimaryPlantCoolingLoad < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) {
     988            0 :                 this->PlantOps.AirSourcePlantCoolingOnly = true;
     989              :             }
     990              :         }
     991              : 
     992              :         // override reset AirSourcePlantHeatingOnly to false and AirSourcePlantCoolingOnly to true if the plant cooling load is higher
     993              :         // the plant heating load and the plant heating load is small.
     994           11 :         if (!this->PlantOps.AirSourcePlantCoolingOnly && this->PlantOps.AirSourcePlantHeatingOnly &&
     995            2 :             !this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) { // all off
     996            2 :             if (std::abs(this->Report.PrimaryPlantCoolingLoad) > this->Report.PrimaryPlantHeatingLoad &&
     997            0 :                 this->Report.PrimaryPlantHeatingLoad < HVAC::SmallLoad) {
     998            0 :                 this->PlantOps.AirSourcePlantCoolingOnly = true;
     999            0 :                 this->PlantOps.AirSourcePlantHeatingOnly = false;
    1000              :             }
    1001              :         }
    1002              : 
    1003              :         // override reset AirSourcePlantHeatingOnly to true and AirSourcePlantCoolingOnly to false if the plant heating load is higher
    1004              :         // the plant cooling load and the plant cooling load is small.
    1005           11 :         if (this->PlantOps.AirSourcePlantCoolingOnly && !this->PlantOps.AirSourcePlantHeatingOnly &&
    1006            3 :             !this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) { // all off
    1007            4 :             if (this->Report.PrimaryPlantHeatingLoad > std::abs(this->Report.PrimaryPlantCoolingLoad) &&
    1008            1 :                 this->Report.PrimaryPlantCoolingLoad > DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) {
    1009            1 :                 this->PlantOps.AirSourcePlantHeatingOnly = true;
    1010            1 :                 this->PlantOps.AirSourcePlantCoolingOnly = false;
    1011              :             }
    1012              :         }
    1013              : 
    1014              :         // do we need to turn on heating-only if in off mode but PrimaryPlantHeatingLoad is loaded?
    1015           11 :         if (!this->PlantOps.AirSourcePlantCoolingOnly && !this->PlantOps.AirSourcePlantHeatingOnly &&
    1016            6 :             !this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) { // all off
    1017            5 :             if (this->Report.PrimaryPlantHeatingLoad > HVAC::SmallLoad && state.dataEnvrn->OutDryBulbTemp >= this->TempReset.LowOutdoorTemp) {
    1018            0 :                 this->PlantOps.AirSourcePlantHeatingOnly = true;
    1019              :             }
    1020              :         }
    1021              : 
    1022              :         // step 4, convert logical flags into integers for output variable reporting
    1023           11 :         if (this->PlantOps.AirSourcePlantHeatingOnly) {
    1024            3 :             this->Report.AirSourcePlant_OpMode = 1;
    1025            8 :         } else if (this->PlantOps.AirSourcePlantCoolingOnly) {
    1026            2 :             this->Report.AirSourcePlant_OpMode = 2;
    1027            6 :         } else if (this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) {
    1028            1 :             this->Report.AirSourcePlant_OpMode = 3;
    1029              :         } else {
    1030            5 :             this->Report.AirSourcePlant_OpMode = 0;
    1031              :         }
    1032           11 :     }
    1033              : 
    1034           11 :     void ChillerHeaterSupervisoryOperationData::InitAirSourcePlantEquipmentOff(EnergyPlusData &state)
    1035              :     {
    1036              :         //_____________________________________________________________________________
    1037              :         // initialize all possible equipment to turn off machines before applying controls to turn them on.
    1038              :         // set .Available and .ON to false in plant structure
    1039              : 
    1040           11 :         if (this->PlantOps.NumCoolingOnlyEquipLists > 0) {
    1041           28 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumCoolingOnlyEquipLists; ++equipListNum) {
    1042           17 :                 int NumComps = this->CoolingOnlyEquipList(equipListNum).NumComps;
    1043           40 :                 for (int compNum = 1; compNum <= NumComps; ++compNum) {
    1044           23 :                     auto &this_equip(this->CoolingOnlyEquipList(equipListNum).Comp(compNum));
    1045           23 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1046           23 :                         .LoopSide(this_equip.LoopSideNumPtr)
    1047           23 :                         .Branch(this_equip.BranchNumPtr)
    1048           23 :                         .Comp(this_equip.CompNumPtr)
    1049           23 :                         .Available = false;
    1050           23 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1051           23 :                         .LoopSide(this_equip.LoopSideNumPtr)
    1052           23 :                         .Branch(this_equip.BranchNumPtr)
    1053           23 :                         .Comp(this_equip.CompNumPtr)
    1054           23 :                         .ON = false;
    1055              :                 }
    1056              :             }
    1057              :         }
    1058              : 
    1059           11 :         if (this->PlantOps.NumHeatingOnlyEquipLists > 0) {
    1060           28 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumHeatingOnlyEquipLists; ++equipListNum) {
    1061           17 :                 int NumComps = this->HeatingOnlyEquipList(equipListNum).NumComps;
    1062           40 :                 for (int compNum = 1; compNum <= NumComps; ++compNum) {
    1063           23 :                     auto &this_equip(this->HeatingOnlyEquipList(equipListNum).Comp(compNum));
    1064           23 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1065           23 :                         .LoopSide(this_equip.LoopSideNumPtr)
    1066           23 :                         .Branch(this_equip.BranchNumPtr)
    1067           23 :                         .Comp(this_equip.CompNumPtr)
    1068           23 :                         .Available = false;
    1069           23 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1070           23 :                         .LoopSide(this_equip.LoopSideNumPtr)
    1071           23 :                         .Branch(this_equip.BranchNumPtr)
    1072           23 :                         .Comp(this_equip.CompNumPtr)
    1073           23 :                         .ON = false;
    1074              :                 }
    1075              :             }
    1076              :         }
    1077              : 
    1078           11 :         if (this->PlantOps.NumSimultHeatCoolCoolingEquipLists > 0) {
    1079           12 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolCoolingEquipLists; ++equipListNum) {
    1080              : 
    1081            6 :                 int NumComps = this->SimultHeatCoolCoolingEquipList(equipListNum).NumComps;
    1082           12 :                 for (int compNum = 1; compNum <= NumComps; ++compNum) {
    1083            6 :                     auto &this_equip(this->SimultHeatCoolCoolingEquipList(equipListNum).Comp(compNum));
    1084            6 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1085            6 :                         .LoopSide(this_equip.LoopSideNumPtr)
    1086            6 :                         .Branch(this_equip.BranchNumPtr)
    1087            6 :                         .Comp(this_equip.CompNumPtr)
    1088            6 :                         .Available = false;
    1089            6 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1090            6 :                         .LoopSide(this_equip.LoopSideNumPtr)
    1091            6 :                         .Branch(this_equip.BranchNumPtr)
    1092            6 :                         .Comp(this_equip.CompNumPtr)
    1093            6 :                         .ON = false;
    1094              :                 }
    1095              :             }
    1096              :         }
    1097              : 
    1098           11 :         if (this->PlantOps.NumSimultHeatCoolHeatingEquipLists > 0) {
    1099           12 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolHeatingEquipLists; ++equipListNum) {
    1100              : 
    1101            6 :                 int NumComps = this->SimultHeatCoolHeatingEquipList(equipListNum).NumComps;
    1102           12 :                 for (int compNum = 1; compNum <= NumComps; ++compNum) {
    1103            6 :                     auto &this_equip(this->SimultHeatCoolHeatingEquipList(equipListNum).Comp(compNum));
    1104            6 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1105            6 :                         .LoopSide(this_equip.LoopSideNumPtr)
    1106            6 :                         .Branch(this_equip.BranchNumPtr)
    1107            6 :                         .Comp(this_equip.CompNumPtr)
    1108            6 :                         .Available = false;
    1109            6 :                     state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1110            6 :                         .LoopSide(this_equip.LoopSideNumPtr)
    1111            6 :                         .Branch(this_equip.BranchNumPtr)
    1112            6 :                         .Comp(this_equip.CompNumPtr)
    1113            6 :                         .ON = false;
    1114              :                 }
    1115              :             }
    1116              :         }
    1117              :         // end init machines off
    1118           11 :     }
    1119              : 
    1120           11 :     void ChillerHeaterSupervisoryOperationData::ProcessAndSetAirSourcePlantEquipLists(EnergyPlusData &state)
    1121              :     {
    1122              :         // TODO this routine is currently code to compare real current plant loads, polled building loads have also been studied.
    1123           11 :         Real64 CoolingLoadSignal = this->Report.PrimaryPlantCoolingLoad;
    1124           11 :         Real64 HeatingLoadSignal = this->Report.PrimaryPlantHeatingLoad;
    1125              : 
    1126              :         //___________________________________________________________________________
    1127           11 :         if (this->PlantOps.AirSourcePlantCoolingOnly) {
    1128              :             // use zone loads to find range based cooling loads
    1129            5 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumCoolingOnlyEquipLists; ++equipListNum) {
    1130              :                 // zone cooling loads are negative, switch to positive for range based limiting
    1131            5 :                 if (CoolingLoadSignal * DataPrecisionGlobals::constant_minusone > this->CoolingOnlyEquipList(equipListNum).RangeLowerLimit &&
    1132            2 :                     this->CoolingOnlyEquipList(equipListNum).RangeUpperLimit > CoolingLoadSignal * DataPrecisionGlobals::constant_minusone) {
    1133              :                     // found that this equipment list load ranges match the zone predicted cooling loads
    1134              : 
    1135            2 :                     int NumComps = this->CoolingOnlyEquipList(equipListNum).NumComps;
    1136            4 :                     for (int compNum = 1; compNum <= NumComps; ++compNum) {
    1137            2 :                         auto &this_equip(this->CoolingOnlyEquipList(equipListNum).Comp(compNum));
    1138              :                         // set cooling setpoint at outlet
    1139              : 
    1140              :                         // todo, oa reset ?
    1141              : 
    1142            2 :                         state.dataLoopNodes->Node(this_equip.SetPointNodeNum).TempSetPoint = this->Setpoint.PrimCW;
    1143            2 :                         state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this_equip.LoopNumPtr).TempSetPointNodeNum).TempSetPoint =
    1144            2 :                             this->Setpoint.PrimCW;
    1145            2 :                         if (state.dataLoopNodes->Node(this_equip.DemandNodeNum).Temp > this->Setpoint.PrimCW) {
    1146              : 
    1147            2 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1148            2 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1149            2 :                                 .Branch(this_equip.BranchNumPtr)
    1150            2 :                                 .Comp(this_equip.CompNumPtr)
    1151            2 :                                 .Available = true;
    1152            2 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1153            2 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1154            2 :                                 .Branch(this_equip.BranchNumPtr)
    1155            2 :                                 .Comp(this_equip.CompNumPtr)
    1156            2 :                                 .ON = true;
    1157            2 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1158            2 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1159            2 :                                 .Branch(this_equip.BranchNumPtr)
    1160            2 :                                 .Comp(this_equip.CompNumPtr)
    1161            4 :                                 .CurOpSchemeType = this->Type;
    1162              :                         }
    1163              :                         //
    1164              :                     }
    1165              :                 }
    1166              :             }
    1167              :         }
    1168              : 
    1169              :         //____________________________________________________________________________
    1170           11 :         if (this->PlantOps.AirSourcePlantHeatingOnly) { // Use Heating Only equipment operation
    1171              : 
    1172            3 :             Real64 HWsetpt = DetermineHWSetpointOARest(state);
    1173              :             // use zone loads to find range based heating loads
    1174            7 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumHeatingOnlyEquipLists; ++equipListNum) {
    1175            7 :                 if (HeatingLoadSignal > this->HeatingOnlyEquipList(equipListNum).RangeLowerLimit &&
    1176            3 :                     this->HeatingOnlyEquipList(equipListNum).RangeUpperLimit > HeatingLoadSignal) {
    1177              :                     // found that this equipment list load ranges match the zone predicted heating loads
    1178              : 
    1179            3 :                     int NumComps = this->HeatingOnlyEquipList(equipListNum).NumComps;
    1180            6 :                     for (int compNum = 1; compNum <= NumComps; ++compNum) {
    1181            3 :                         auto &this_equip(this->HeatingOnlyEquipList(equipListNum).Comp(compNum));
    1182              :                         // set heating setpoint at outlet
    1183              : 
    1184            3 :                         state.dataLoopNodes->Node(this_equip.SetPointNodeNum).TempSetPoint = HWsetpt;
    1185            3 :                         state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this_equip.LoopNumPtr).TempSetPointNodeNum).TempSetPoint = HWsetpt;
    1186              : 
    1187            3 :                         if (state.dataLoopNodes->Node(this_equip.DemandNodeNum).Temp < HWsetpt) {
    1188            3 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1189            3 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1190            3 :                                 .Branch(this_equip.BranchNumPtr)
    1191            3 :                                 .Comp(this_equip.CompNumPtr)
    1192            3 :                                 .Available = true;
    1193            3 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1194            3 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1195            3 :                                 .Branch(this_equip.BranchNumPtr)
    1196            3 :                                 .Comp(this_equip.CompNumPtr)
    1197            3 :                                 .ON = true;
    1198            3 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1199            3 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1200            3 :                                 .Branch(this_equip.BranchNumPtr)
    1201            3 :                                 .Comp(this_equip.CompNumPtr)
    1202            6 :                                 .CurOpSchemeType = this->Type;
    1203              :                         }
    1204              :                         //
    1205              :                     }
    1206              :                 }
    1207              :             }
    1208              :         }
    1209              : 
    1210           11 :         if (this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling) {
    1211              : 
    1212              :             // use zone cooling loads to find range based equipment
    1213            2 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolCoolingEquipLists; ++equipListNum) {
    1214              :                 // zone cooling loads are negative, switch to positive for range based limiting
    1215            2 :                 if (CoolingLoadSignal * DataPrecisionGlobals::constant_minusone >
    1216            2 :                         this->SimultHeatCoolCoolingEquipList(equipListNum).RangeLowerLimit &&
    1217            1 :                     this->SimultHeatCoolCoolingEquipList(equipListNum).RangeUpperLimit >
    1218            1 :                         CoolingLoadSignal * DataPrecisionGlobals::constant_minusone) {
    1219              :                     // found that this equipment list load ranges match the zone predicted cooling loads
    1220              : 
    1221            1 :                     int NumComps = this->SimultHeatCoolCoolingEquipList(equipListNum).NumComps;
    1222            2 :                     for (int compNum = 1; compNum <= NumComps; ++compNum) {
    1223            1 :                         auto &this_equip(this->SimultHeatCoolCoolingEquipList(equipListNum).Comp(compNum));
    1224              :                         // set cooling setpoint at outlet
    1225              : 
    1226            1 :                         state.dataLoopNodes->Node(this_equip.SetPointNodeNum).TempSetPoint = this->Setpoint.PrimCW;
    1227            1 :                         state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this_equip.LoopNumPtr).TempSetPointNodeNum).TempSetPoint =
    1228            1 :                             this->Setpoint.PrimCW;
    1229            1 :                         if (state.dataLoopNodes->Node(this_equip.DemandNodeNum).Temp > this->Setpoint.PrimCW) {
    1230            1 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1231            1 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1232            1 :                                 .Branch(this_equip.BranchNumPtr)
    1233            1 :                                 .Comp(this_equip.CompNumPtr)
    1234            1 :                                 .Available = true;
    1235            1 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1236            1 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1237            1 :                                 .Branch(this_equip.BranchNumPtr)
    1238            1 :                                 .Comp(this_equip.CompNumPtr)
    1239            1 :                                 .ON = true;
    1240            1 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1241            1 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1242            1 :                                 .Branch(this_equip.BranchNumPtr)
    1243            1 :                                 .Comp(this_equip.CompNumPtr)
    1244            2 :                                 .CurOpSchemeType = this->Type;
    1245              :                         }
    1246              :                         //
    1247              :                     }
    1248              :                 }
    1249              :             }
    1250              : 
    1251              :             // use zone loads to find range based heating loads
    1252            1 :             Real64 HWsetpt = DetermineHWSetpointOARest(state);
    1253            2 :             for (int equipListNum = 1; equipListNum <= this->PlantOps.NumSimultHeatCoolHeatingEquipLists; ++equipListNum) {
    1254            2 :                 if (HeatingLoadSignal > this->SimultHeatCoolHeatingEquipList(equipListNum).RangeLowerLimit &&
    1255            1 :                     this->SimultHeatCoolHeatingEquipList(equipListNum).RangeUpperLimit > HeatingLoadSignal) {
    1256              :                     // found that this equipment list load ranges match the zone predicted heating loads
    1257              : 
    1258            1 :                     int NumComps = this->SimultHeatCoolHeatingEquipList(equipListNum).NumComps;
    1259            2 :                     for (int compNum = 1; compNum <= NumComps; ++compNum) {
    1260            1 :                         auto &this_equip(this->SimultHeatCoolHeatingEquipList(equipListNum).Comp(compNum));
    1261              :                         // set heating setpoint at outlet
    1262              : 
    1263            1 :                         state.dataLoopNodes->Node(this_equip.SetPointNodeNum).TempSetPoint = HWsetpt;
    1264            1 :                         state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this_equip.LoopNumPtr).TempSetPointNodeNum).TempSetPoint = HWsetpt;
    1265              : 
    1266            1 :                         if (state.dataLoopNodes->Node(this_equip.DemandNodeNum).Temp < HWsetpt) {
    1267            1 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1268            1 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1269            1 :                                 .Branch(this_equip.BranchNumPtr)
    1270            1 :                                 .Comp(this_equip.CompNumPtr)
    1271            1 :                                 .Available = true;
    1272            1 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1273            1 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1274            1 :                                 .Branch(this_equip.BranchNumPtr)
    1275            1 :                                 .Comp(this_equip.CompNumPtr)
    1276            1 :                                 .ON = true;
    1277            1 :                             state.dataPlnt->PlantLoop(this_equip.LoopNumPtr)
    1278            1 :                                 .LoopSide(this_equip.LoopSideNumPtr)
    1279            1 :                                 .Branch(this_equip.BranchNumPtr)
    1280            1 :                                 .Comp(this_equip.CompNumPtr)
    1281            2 :                                 .CurOpSchemeType = this->Type;
    1282              :                         }
    1283              :                         //
    1284              :                     }
    1285              :                 }
    1286              :             }
    1287              :         }
    1288           11 :     }
    1289              : 
    1290           11 :     void ChillerHeaterSupervisoryOperationData::ProcessAndSetDedicatedHeatRecovWWHP(EnergyPlusData &state)
    1291              :     {
    1292              :         // evaluate if and how dedicated heat recovery WWHP should run
    1293              : 
    1294           11 :         if (!this->PlantOps.DedicatedHR_Present) {
    1295           11 :             return;
    1296              :         }
    1297              : 
    1298              :         // initialize off
    1299            0 :         state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
    1300            0 :             .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
    1301            0 :             .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
    1302            0 :             .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
    1303            0 :             .Available = false;
    1304            0 :         state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
    1305            0 :             .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
    1306            0 :             .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
    1307            0 :             .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
    1308            0 :             .ON = false;
    1309            0 :         state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
    1310            0 :             .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
    1311            0 :             .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
    1312            0 :             .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
    1313            0 :             .Available = false;
    1314            0 :         state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
    1315            0 :             .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
    1316            0 :             .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
    1317            0 :             .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
    1318            0 :             .ON = false;
    1319              : 
    1320            0 :         state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
    1321            0 :             .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
    1322            0 :             .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
    1323            0 :             .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
    1324            0 :             .Available = false;
    1325            0 :         state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
    1326            0 :             .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
    1327            0 :             .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
    1328            0 :             .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
    1329            0 :             .ON = false;
    1330            0 :         state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
    1331            0 :             .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
    1332            0 :             .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
    1333            0 :             .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
    1334            0 :             .Available = false;
    1335            0 :         state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
    1336            0 :             .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
    1337            0 :             .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
    1338            0 :             .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
    1339            0 :             .ON = false;
    1340              : 
    1341              :         // Dedicated Heat Recovery Water To Water Heat Pump Control.
    1342              :         // Assume there are two companion machines, one leads for cooling the return chilled water, the other leads for heating the return hot
    1343              :         // water When one side leads, the other gets favorable heat addition/extraction it is just not controlled to meet a setpoint Assume these
    1344              :         // are on the secondary loops.  Need to decide if it runs and which of cooling or heating companion coils gets to lead.
    1345              :         //
    1346              :         // Step 1. get the mass flow rates of the returns.  both must be non-zero for the WWHP to run
    1347            0 :         int inletChWReturnNodeNum = state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
    1348            0 :                                         .LoopSide(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopSideNum)
    1349            0 :                                         .Branch(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.branchNum)
    1350            0 :                                         .Comp(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.compNum)
    1351            0 :                                         .NodeNumIn;
    1352            0 :         int inletHWReturnNodeNum = state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
    1353            0 :                                        .LoopSide(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopSideNum)
    1354            0 :                                        .Branch(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.branchNum)
    1355            0 :                                        .Comp(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.compNum)
    1356            0 :                                        .NodeNumIn;
    1357            0 :         Real64 CW_RetMdot = state.dataLoopNodes->Node(inletChWReturnNodeNum).MassFlowRate;
    1358            0 :         Real64 HW_RetMdot = state.dataLoopNodes->Node(inletHWReturnNodeNum).MassFlowRate;
    1359              : 
    1360            0 :         bool flowInEach = false;
    1361              :         // need flow in both returns.
    1362            0 :         if (CW_RetMdot <= HVAC::SmallWaterVolFlow || HW_RetMdot <= HVAC::SmallWaterVolFlow) {
    1363            0 :             flowInEach = false;
    1364              :         } else {
    1365            0 :             flowInEach = true;
    1366              :         }
    1367              : 
    1368              :         // step 2. calculate the loads to adjust the
    1369              :         // returns to hit the associated setpoints at their current mass flow
    1370              :         Real64 const CpCW =
    1371            0 :             state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.sourceSidePlantLoc.loopNum)
    1372            0 :                 .glycol->getSpecificHeat(state, state.dataLoopNodes->Node(inletChWReturnNodeNum).Temp, "EvaluateChillerHeaterChangeoverOpScheme");
    1373              :         Real64 CW_Qdot =
    1374            0 :             CW_RetMdot * CpCW *
    1375            0 :             (this->Setpoint.SecCW - state.dataLoopNodes->Node(inletChWReturnNodeNum).Temp); // power = Mdot Cp Delta T, cooling load is negative
    1376              :         Real64 const CpHW =
    1377            0 :             state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.sourceSidePlantLoc.loopNum)
    1378            0 :                 .glycol->getSpecificHeat(state, state.dataLoopNodes->Node(inletHWReturnNodeNum).Temp, "EvaluateChillerHeaterChangeoverOpScheme");
    1379            0 :         Real64 HW_Qdot = HW_RetMdot * CpHW * (this->Setpoint.SecHW - state.dataLoopNodes->Node(inletHWReturnNodeNum).Temp); // power = Mdot Cp Delta T
    1380              : 
    1381              :         // store for reporting
    1382            0 :         this->Report.SecondaryPlantCoolingLoad = CW_Qdot;
    1383            0 :         this->Report.SecondaryPlantHeatingLoad = HW_Qdot;
    1384              : 
    1385              :         // step 3 decide if Dedicated HR is on and which leads based
    1386            0 :         bool CoolLedNeed = false;
    1387            0 :         bool HeatLedNeed = false;
    1388              : 
    1389            0 :         if (this->PlantOps.AirSourcePlantHeatingOnly && (CW_Qdot < DataPrecisionGlobals::constant_minusone * HVAC::SmallLoad) && flowInEach) {
    1390              :             // polled building loads are heating only, but secondary ChW plant has some cooling load and there is mass flow in each. So turn dedicated
    1391              :             // HR on in cooling lead mode
    1392            0 :             CoolLedNeed = true;
    1393              :         }
    1394              : 
    1395            0 :         if (this->PlantOps.AirSourcePlantCoolingOnly && (HW_Qdot > HVAC::SmallLoad) && flowInEach) {
    1396              :             // polled building loads are cooling only, but secondary HW plant has some heating load and there is mass flow in each. So turn dedicated
    1397              :             // HR on in heating lead mode
    1398            0 :             HeatLedNeed = true;
    1399              :         }
    1400              : 
    1401            0 :         if (this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling && this->PlantOps.SimultaneousHeatingCoolingWithHeatingDominant &&
    1402              :             flowInEach) {
    1403              :             // polled building loads are simultaneous with heating dominating and there is mass flow in each, So turn
    1404              :             // dedicated HR on in heating lead mode
    1405            0 :             HeatLedNeed = true;
    1406              :         }
    1407              : 
    1408            0 :         if (this->PlantOps.AirSourcePlantSimultaneousHeatingAndCooling && this->PlantOps.SimultaneousHeatingCoolingWithCoolingDominant &&
    1409              :             flowInEach) {
    1410              :             // polled building loads are simultaneous with cooling dominating and there is mass flow in each, So turn
    1411              :             // dedicated HR on in cooling lead mode
    1412            0 :             CoolLedNeed = true;
    1413              :         }
    1414              : 
    1415              :         //  step 4. check that there is sufficient flow in source side for chosen leader to avoid runaway plant conditions on source side
    1416              :         //  if not, see if other side could run beneficially as leader and switch to it if so
    1417              :         // Real64 FlowImbalanceRatioThreshold = 10.0; // TODO, check with TRANE engineering about WWHP operating limits wrt to relative flows (real
    1418              :         //                                          // systems have a pumped sided arm flow situation and do not have low flow problems)
    1419              : 
    1420              :         // if (CoolLedNeed) {
    1421              :         //    if (CW_RetMdot / HW_RetMdot > FlowImbalanceRatioThreshold) { // insufficient flow in source side relative to load side
    1422              :         //        CoolLedNeed = false;
    1423              :         //        // if (HW_Qdot > 1.0) {
    1424              :         //        //    HeatLedNeed = true;
    1425              :         //        //}
    1426              :         //    }
    1427              :         //}
    1428              :         // if (HeatLedNeed) {
    1429              :         //    if (HW_RetMdot / CW_RetMdot > FlowImbalanceRatioThreshold) { // insufficient flow in source side relative to load side
    1430              :         //        HeatLedNeed = false;
    1431              :         //        // if (CW_Qdot < -1.0) {
    1432              :         //        //    CoolLedNeed = true;
    1433              :         //        //}
    1434              :         //    }
    1435              :         //}
    1436              : 
    1437            0 :         this->Report.DedicHR_OpMode = 0;
    1438            0 :         if (CoolLedNeed) {
    1439            0 :             this->Report.DedicHR_OpMode = 2;
    1440              :             // turn ON load side of this water to water heat pump
    1441            0 :             state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
    1442            0 :                 .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
    1443            0 :                 .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
    1444            0 :                 .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
    1445            0 :                 .Available = true;
    1446            0 :             state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
    1447            0 :                 .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
    1448            0 :                 .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
    1449            0 :                 .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
    1450            0 :                 .ON = true;
    1451              : 
    1452            0 :             state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
    1453            0 :                 .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
    1454            0 :                 .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
    1455            0 :                 .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
    1456            0 :                 .CurOpSchemeType = this->Type;
    1457              : 
    1458            0 :             state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
    1459            0 :                 .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
    1460            0 :                 .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
    1461            0 :                 .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
    1462            0 :                 .MyLoad = CW_Qdot; // cooling load is negative
    1463              : 
    1464            0 :             int OutletChWReturnNodeNum = state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)
    1465            0 :                                              .LoopSide(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopSideNum)
    1466            0 :                                              .Branch(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.branchNum)
    1467            0 :                                              .Comp(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.compNum)
    1468            0 :                                              .NodeNumOut;
    1469            0 :             state.dataLoopNodes->Node(OutletChWReturnNodeNum).TempSetPoint = this->Setpoint.SecCW;
    1470            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum).TempSetPointNodeNum)
    1471            0 :                 .TempSetPoint = this->Setpoint.SecCW;
    1472              : 
    1473            0 :             if (this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum ==
    1474            0 :                 SecondaryPlantLoopIndicesBeingSupervised(this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum)) {
    1475              :                 // search for HX on this loop and place setpoint on outlet
    1476            0 :                 for (int HXnum = 1; HXnum <= this->PlantOps.numPlantHXs; ++HXnum) {
    1477            0 :                     if (this->PlantHXComps(HXnum).loopNum == this->DedicatedHR_CoolingPLHP.loadSidePlantLoc.loopNum) {
    1478            0 :                         int outletnode = state.dataPlnt->PlantLoop(this->PlantHXComps(HXnum).loopNum)
    1479            0 :                                              .LoopSide(this->PlantHXComps(HXnum).loopSideNum)
    1480            0 :                                              .Branch(this->PlantHXComps(HXnum).branchNum)
    1481            0 :                                              .Comp(this->PlantHXComps(HXnum).compNum)
    1482            0 :                                              .NodeNumOut;
    1483            0 :                         state.dataLoopNodes->Node(outletnode).TempSetPoint = this->Setpoint.SecCW;
    1484              :                     }
    1485              :                 }
    1486              :             }
    1487              : 
    1488            0 :         } else if (HeatLedNeed) {
    1489            0 :             this->Report.DedicHR_OpMode = 1;
    1490              :             // turn load side of this water to water heat pump
    1491            0 :             state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
    1492            0 :                 .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
    1493            0 :                 .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
    1494            0 :                 .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
    1495            0 :                 .Available = true;
    1496            0 :             state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
    1497            0 :                 .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
    1498            0 :                 .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
    1499            0 :                 .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
    1500            0 :                 .ON = true;
    1501            0 :             state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
    1502            0 :                 .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
    1503            0 :                 .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
    1504            0 :                 .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
    1505            0 :                 .CurOpSchemeType = this->Type;
    1506            0 :             state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
    1507            0 :                 .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
    1508            0 :                 .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
    1509            0 :                 .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
    1510            0 :                 .MyLoad = HW_Qdot;
    1511              : 
    1512            0 :             int OutletHWReturnNodeNum = state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)
    1513            0 :                                             .LoopSide(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopSideNum)
    1514            0 :                                             .Branch(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.branchNum)
    1515            0 :                                             .Comp(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.compNum)
    1516            0 :                                             .NodeNumOut;
    1517              : 
    1518            0 :             state.dataLoopNodes->Node(OutletHWReturnNodeNum).TempSetPoint = this->Setpoint.SecHW;
    1519            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum).TempSetPointNodeNum)
    1520            0 :                 .TempSetPoint = this->Setpoint.SecHW;
    1521              : 
    1522            0 :             if (this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum ==
    1523            0 :                 SecondaryPlantLoopIndicesBeingSupervised(this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum)) {
    1524              :                 // search for HX on this loop and place setpoint on outlet
    1525            0 :                 for (int HXnum = 1; HXnum <= this->PlantOps.numPlantHXs; ++HXnum) {
    1526            0 :                     if (this->PlantHXComps(HXnum).loopNum == this->DedicatedHR_HeatingPLHP.loadSidePlantLoc.loopNum) {
    1527            0 :                         int outletnode = state.dataPlnt->PlantLoop(this->PlantHXComps(HXnum).loopNum)
    1528            0 :                                              .LoopSide(this->PlantHXComps(HXnum).loopSideNum)
    1529            0 :                                              .Branch(this->PlantHXComps(HXnum).branchNum)
    1530            0 :                                              .Comp(this->PlantHXComps(HXnum).compNum)
    1531            0 :                                              .NodeNumOut;
    1532            0 :                         state.dataLoopNodes->Node(outletnode).TempSetPoint = min(this->Setpoint.SecHW, this->DetermineHWSetpointOARest(state));
    1533              :                     }
    1534              :                 }
    1535              :             }
    1536              :         }
    1537              :     }
    1538              : 
    1539           11 :     void ChillerHeaterSupervisoryOperationData::ProcessAndSetAuxilBoiler(EnergyPlusData &state)
    1540              :     {
    1541              :         // Check for boiler used as auxiliary or supplemental
    1542              :         // Assume boilers are in-line on supply side outlet branch, typically on secondary loop but may be on primary loop
    1543           11 :         this->Report.BoilerAux_OpMode = 0;
    1544           11 :         if (this->PlantOps.numBoilers <= 0) return;
    1545              : 
    1546              :         // first initialize them to be off
    1547            0 :         if (this->PlantOps.numBoilers > 0) {
    1548            0 :             for (int BoilerNum = 1; BoilerNum <= this->PlantOps.numBoilers; ++BoilerNum) {
    1549            0 :                 state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
    1550            0 :                     .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
    1551            0 :                     .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
    1552            0 :                     .Comp(this->PlantBoilerComps(BoilerNum).compNum)
    1553            0 :                     .Available = false;
    1554            0 :                 state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
    1555            0 :                     .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
    1556            0 :                     .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
    1557            0 :                     .Comp(this->PlantBoilerComps(BoilerNum).compNum)
    1558            0 :                     .ON = false;
    1559            0 :                 state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
    1560            0 :                     .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
    1561            0 :                     .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
    1562            0 :                     .Comp(this->PlantBoilerComps(BoilerNum).compNum)
    1563            0 :                     .MyLoad = 0.0;
    1564              :             }
    1565              :         }
    1566              : 
    1567            0 :         if (this->PlantOps.numBoilers > 0) {
    1568              :             // Boilers will run if outdoor air temperature is too low and there is flow in HW return loop
    1569              : 
    1570            0 :             bool LowOAAuxiliaryNeeded = false;
    1571            0 :             if (state.dataEnvrn->OutDryBulbTemp < this->TempReset.LowOutdoorTemp) {
    1572            0 :                 LowOAAuxiliaryNeeded = true;
    1573              :             }
    1574            0 :             for (int BoilerNum = 1; BoilerNum <= this->PlantOps.numBoilers; ++BoilerNum) {
    1575              :                 // determine if primary or secondary setpoint in use
    1576            0 :                 Real64 HWsetpt = 0.0;
    1577            0 :                 if (this->SecondaryPlantLoopIndicesBeingSupervised(this->PlantBoilerComps(BoilerNum).loopNum) >
    1578              :                     0) { // appears to be on secondary loop, supplemental boiler
    1579            0 :                     HWsetpt = min(this->Setpoint.SecHW,
    1580              :                                   DetermineHWSetpointOARest(
    1581              :                                       state)); // Assume if OA reset is lower than setting for secondary HW loop, then use the lower of the two
    1582              :                 } else {                       // primary loop, auxiliary boiler
    1583            0 :                     HWsetpt = DetermineHWSetpointOARest(state);
    1584              :                 }
    1585              : 
    1586            0 :                 HWsetpt = HWsetpt - this->TempReset.BoilerTemperatureOffset;
    1587              : 
    1588              :                 // check inlet temperature
    1589            0 :                 int inletBoilerNodeNum = state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
    1590            0 :                                              .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
    1591            0 :                                              .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
    1592            0 :                                              .Comp(this->PlantBoilerComps(BoilerNum).compNum)
    1593            0 :                                              .NodeNumIn;
    1594            0 :                 Real64 Tin = state.dataLoopNodes->Node(inletBoilerNodeNum).Temp;
    1595            0 :                 Real64 Mdot = state.dataLoopNodes->Node(inletBoilerNodeNum).MassFlowRate;
    1596              : 
    1597            0 :                 Real64 const CpHW = state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
    1598            0 :                                         .glycol->getSpecificHeat(state, Tin, "ChillerHeaterSupervisoryOperationData::ProcessAndSetAuxilBoiler");
    1599            0 :                 Real64 LoadToSetpoint = max(0.0, Mdot * CpHW * (HWsetpt - Tin));
    1600            0 :                 int pltSizNum = state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum).PlantSizNum;
    1601              :                 Real64 const thresholdPlantLoad =
    1602            0 :                     0.001 * state.dataSize->PlantSizData(pltSizNum).DesCapacity; // model an operating threshold at 0.1% of loop capacity, only run if
    1603              :                                                                                  // larger than that
    1604              : 
    1605            0 :                 if (((LoadToSetpoint > thresholdPlantLoad) &&
    1606            0 :                      ((this->Report.AirSourcePlant_OpMode == 0) ||
    1607            0 :                       LowOAAuxiliaryNeeded)) || // run boiler if there is any heating load and also heatpumps are off or too cold outside
    1608            0 :                     ((LoadToSetpoint > thresholdPlantLoad) &&
    1609            0 :                      (this->Report.AirSourcePlant_OpMode ==
    1610              :                       2))) { // run boiler if there is a somewhat significant heating load and heat pumps in cooling only mode
    1611              : 
    1612            0 :                     state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
    1613            0 :                         .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
    1614            0 :                         .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
    1615            0 :                         .Comp(this->PlantBoilerComps(BoilerNum).compNum)
    1616            0 :                         .Available = true;
    1617            0 :                     state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
    1618            0 :                         .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
    1619            0 :                         .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
    1620            0 :                         .Comp(this->PlantBoilerComps(BoilerNum).compNum)
    1621            0 :                         .ON = true;
    1622            0 :                     state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
    1623            0 :                         .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
    1624            0 :                         .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
    1625            0 :                         .Comp(this->PlantBoilerComps(BoilerNum).compNum)
    1626            0 :                         .CurOpSchemeType = this->Type;
    1627              :                     // boilers don't really have setpoint control mode, so set value for myLoad
    1628            0 :                     state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
    1629            0 :                         .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
    1630            0 :                         .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
    1631            0 :                         .Comp(this->PlantBoilerComps(BoilerNum).compNum)
    1632            0 :                         .MyLoad = LoadToSetpoint;
    1633            0 :                     int OutletBoilerNodeNum = state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
    1634            0 :                                                   .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
    1635            0 :                                                   .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
    1636            0 :                                                   .Comp(this->PlantBoilerComps(BoilerNum).compNum)
    1637            0 :                                                   .NodeNumOut;
    1638            0 :                     state.dataLoopNodes->Node(OutletBoilerNodeNum).TempSetPoint = HWsetpt;
    1639            0 :                     state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum).TempSetPointNodeNum).TempSetPoint =
    1640              :                         HWsetpt;
    1641            0 :                     this->Report.BoilerAux_OpMode = 1;
    1642            0 :                 } else { // still apply the setpoint, but don't turn on
    1643            0 :                     int OutletBoilerNodeNum = state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum)
    1644            0 :                                                   .LoopSide(this->PlantBoilerComps(BoilerNum).loopSideNum)
    1645            0 :                                                   .Branch(this->PlantBoilerComps(BoilerNum).branchNum)
    1646            0 :                                                   .Comp(this->PlantBoilerComps(BoilerNum).compNum)
    1647            0 :                                                   .NodeNumOut;
    1648            0 :                     state.dataLoopNodes->Node(OutletBoilerNodeNum).TempSetPoint = HWsetpt;
    1649            0 :                     state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->PlantBoilerComps(BoilerNum).loopNum).TempSetPointNodeNum).TempSetPoint =
    1650              :                         HWsetpt;
    1651              :                 }
    1652              :             }
    1653              :         }
    1654              :     }
    1655              : 
    1656           15 :     Real64 ChillerHeaterSupervisoryOperationData::DetermineHWSetpointOARest(EnergyPlusData &state)
    1657              :     {
    1658              :         // algorithm from calcSetPointLinInt
    1659           15 :         Real64 HWSetpoint = 0.0;
    1660              : 
    1661           15 :         if ((this->TempReset.LowOutdoorTemp == this->TempReset.BackupLowOutdoorTemp) &&
    1662           15 :             (this->Setpoint.PrimHW_Low == this->Setpoint.PrimHW_BackupLow)) { // no second-stage reset scheme
    1663              : 
    1664           15 :             if (this->TempReset.LowOutdoorTemp < this->TempReset.HighOutdoorTemp) {
    1665           15 :                 if (state.dataEnvrn->OutDryBulbTemp <= this->TempReset.LowOutdoorTemp) {
    1666           15 :                     HWSetpoint = this->Setpoint.PrimHW_Low;
    1667            0 :                 } else if (state.dataEnvrn->OutDryBulbTemp >= this->TempReset.HighOutdoorTemp) {
    1668            0 :                     HWSetpoint = this->Setpoint.PrimHW_High;
    1669              :                 } else {
    1670            0 :                     HWSetpoint = this->Setpoint.PrimHW_Low - ((state.dataEnvrn->OutDryBulbTemp - this->TempReset.LowOutdoorTemp) /
    1671            0 :                                                               (this->TempReset.HighOutdoorTemp - this->TempReset.LowOutdoorTemp)) *
    1672            0 :                                                                  (this->Setpoint.PrimHW_Low - this->Setpoint.PrimHW_High);
    1673            0 :                     HWSetpoint = min(HWSetpoint, this->Setpoint.PrimHW_High); // don't extrapolate, hold at high limit of primary HW
    1674              :                 }
    1675              : 
    1676              :             } else {
    1677            0 :                 HWSetpoint = 0.5 * (this->Setpoint.PrimHW_Low + this->Setpoint.PrimHW_High);
    1678              :             }
    1679              :         } else { // apply two stage reset scheme
    1680            0 :             if ((this->TempReset.LowOutdoorTemp < this->TempReset.HighOutdoorTemp) &&
    1681            0 :                 (this->TempReset.BackupLowOutdoorTemp < this->TempReset.LowOutdoorTemp)) { // expected configuration
    1682              : 
    1683            0 :                 if (state.dataEnvrn->OutDryBulbTemp <= this->TempReset.BackupLowOutdoorTemp) {
    1684            0 :                     HWSetpoint = this->Setpoint.PrimHW_BackupLow;
    1685            0 :                 } else if (state.dataEnvrn->OutDryBulbTemp >= this->TempReset.HighOutdoorTemp) {
    1686            0 :                     HWSetpoint = this->Setpoint.PrimHW_High;
    1687            0 :                 } else if ((state.dataEnvrn->OutDryBulbTemp >= this->TempReset.LowOutdoorTemp) &&
    1688            0 :                            (state.dataEnvrn->OutDryBulbTemp < this->TempReset.HighOutdoorTemp)) { // first stage for Heat pump reset down
    1689            0 :                     HWSetpoint = this->Setpoint.PrimHW_Low - ((state.dataEnvrn->OutDryBulbTemp - this->TempReset.LowOutdoorTemp) /
    1690            0 :                                                               (this->TempReset.HighOutdoorTemp - this->TempReset.LowOutdoorTemp)) *
    1691            0 :                                                                  (this->Setpoint.PrimHW_Low - this->Setpoint.PrimHW_High);
    1692            0 :                     HWSetpoint = min(HWSetpoint, this->Setpoint.PrimHW_High); // don't extrapolate, hold at high limit of primary HW
    1693            0 :                 } else if ((state.dataEnvrn->OutDryBulbTemp > this->TempReset.BackupLowOutdoorTemp) &&
    1694            0 :                            (state.dataEnvrn->OutDryBulbTemp < this->TempReset.LowOutdoorTemp)) { // second stage for backup boiler reset up
    1695            0 :                     HWSetpoint = this->Setpoint.PrimHW_BackupLow - ((state.dataEnvrn->OutDryBulbTemp - this->TempReset.BackupLowOutdoorTemp) /
    1696            0 :                                                                     (this->TempReset.LowOutdoorTemp - this->TempReset.BackupLowOutdoorTemp)) *
    1697            0 :                                                                        (this->Setpoint.PrimHW_BackupLow - this->Setpoint.PrimHW_Low);
    1698            0 :                     HWSetpoint = min(HWSetpoint, this->Setpoint.PrimHW_BackupLow); // don't extrapolate
    1699            0 :                     HWSetpoint = max(HWSetpoint, this->Setpoint.PrimHW_Low);       // don't extrapolate
    1700              :                 } else {
    1701              :                     // shouldn't get here, throw error?
    1702              :                 }
    1703              :             } else { // malformed input, take average of three setpoints
    1704            0 :                 HWSetpoint = (this->Setpoint.PrimHW_Low + this->Setpoint.PrimHW_High + this->Setpoint.PrimHW_BackupLow) / 3.0;
    1705              :             }
    1706              :         }
    1707           15 :         return HWSetpoint;
    1708              :     }
    1709              : 
    1710              : } // namespace DataPlant
    1711              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1