LCOV - code coverage report
Current view: top level - EnergyPlus - ChillerElectricASHRAE205.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 535 785 68.2 %
Date: 2023-01-17 19:17:23 Functions: 14 15 93.3 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <cassert>
      50             : #include <cmath>
      51             : #include <string>
      52             : 
      53             : // ObjexxFCL Headers
      54             : #include <ObjexxFCL/Fmath.hh>
      55             : 
      56             : // EnergyPlus Headers
      57             : #include "rs0001_factory.h"
      58             : #include <EnergyPlus/Autosizing/All_Simple_Sizing.hh>
      59             : #include <EnergyPlus/BranchNodeConnections.hh>
      60             : #include <EnergyPlus/ChillerElectricASHRAE205.hh>
      61             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      62             : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
      63             : #include <EnergyPlus/DataEnvironment.hh>
      64             : #include <EnergyPlus/DataHVACGlobals.hh>
      65             : #include <EnergyPlus/DataHeatBalance.hh>
      66             : #include <EnergyPlus/DataIPShortCuts.hh>
      67             : #include <EnergyPlus/DataLoopNode.hh>
      68             : #include <EnergyPlus/DataSizing.hh>
      69             : #include <EnergyPlus/DataSystemVariables.hh>
      70             : #include <EnergyPlus/EMSManager.hh>
      71             : #include <EnergyPlus/FaultsManager.hh>
      72             : #include <EnergyPlus/FluidProperties.hh>
      73             : #include <EnergyPlus/General.hh>
      74             : #include <EnergyPlus/GeneralRoutines.hh>
      75             : #include <EnergyPlus/GlobalNames.hh>
      76             : #include <EnergyPlus/HeatBalanceInternalHeatGains.hh>
      77             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      78             : #include <EnergyPlus/NodeInputManager.hh>
      79             : #include <EnergyPlus/OutAirNodeManager.hh>
      80             : #include <EnergyPlus/OutputProcessor.hh>
      81             : #include <EnergyPlus/OutputReportPredefined.hh>
      82             : #include <EnergyPlus/Plant/DataPlant.hh>
      83             : #include <EnergyPlus/Plant/PlantLocation.hh>
      84             : #include <EnergyPlus/PlantUtilities.hh>
      85             : #include <EnergyPlus/ScheduleManager.hh>
      86             : #include <EnergyPlus/UtilityRoutines.hh>
      87             : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      88             : 
      89             : namespace EnergyPlus::ChillerElectricASHRAE205 {
      90             : 
      91             : constexpr std::array<std::string_view, static_cast<int>(AmbientTempIndicator::Num) - 1> AmbientTempNamesUC{
      92             :     "SCHEDULE",
      93             :     "ZONE",
      94             :     "OUTDOORS",
      95             : };
      96             : 
      97        2313 : std::map<std::string, Btwxt::Method> InterpMethods = // NOLINT(cert-err58-cpp)
      98        1542 :     {{"LINEAR", Btwxt::Method::LINEAR}, {"CUBIC", Btwxt::Method::CUBIC}};
      99             : 
     100           0 : void tk205ErrCallback(tk205::MsgSeverity message_type, const std::string &message, void *context_ptr)
     101             : {
     102           0 :     std::pair<EnergyPlusData *, std::string> contextPair = *(std::pair<EnergyPlusData *, std::string> *)context_ptr;
     103           0 :     std::string fullMessage = contextPair.second + ": " + message;
     104           0 :     if (message_type == tk205::MsgSeverity::ERR_205) {
     105           0 :         ShowSevereError(*contextPair.first, fullMessage);
     106           0 :         ShowFatalError(*contextPair.first, "libtk205: Errors discovered, program terminates.");
     107             :     } else {
     108           0 :         if (message_type == tk205::MsgSeverity::WARN_205) {
     109           0 :             ShowWarningError(*contextPair.first, fullMessage);
     110           0 :         } else if (message_type == tk205::MsgSeverity::INFO_205) {
     111           0 :             ShowMessage(*contextPair.first, fullMessage);
     112             :         } else {
     113           0 :             ShowMessage(*contextPair.first, fullMessage);
     114             :         }
     115             :     }
     116           0 : }
     117             : 
     118           3 : void getChillerASHRAE205Input(EnergyPlusData &state)
     119             : {
     120             :     static constexpr std::string_view RoutineName("getChillerASHRAE205Input: "); // include trailing blank space
     121             : 
     122             :     using namespace tk205;
     123           3 :     RSInstanceFactory::register_factory("RS0001", std::make_shared<RS0001Factory>());
     124             : 
     125           3 :     bool ErrorsFound{false};
     126             : 
     127           3 :     state.dataIPShortCut->cCurrentModuleObject = ChillerElectricASHRAE205::ASHRAE205ChillerSpecs::ObjectType;
     128           3 :     auto &ip = state.dataInputProcessing->inputProcessor;
     129           3 :     int numElectric205Chillers = ip->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
     130             : 
     131           3 :     if (numElectric205Chillers <= 0) {
     132           0 :         ShowSevereError(state, format("No {} equipment specified in input file", state.dataIPShortCut->cCurrentModuleObject));
     133           0 :         ErrorsFound = true;
     134             :     }
     135             : 
     136           3 :     state.dataChillerElectricASHRAE205->Electric205Chiller.allocate(numElectric205Chillers);
     137             : 
     138           6 :     auto const ChillerInstances = ip->epJSON.find(state.dataIPShortCut->cCurrentModuleObject).value();
     139           3 :     int ChillerNum{0};
     140           3 :     auto const &objectSchemaProps = ip->getObjectSchemaProps(state, state.dataIPShortCut->cCurrentModuleObject);
     141           8 :     for (auto &instance : ChillerInstances.items()) {
     142           5 :         auto const &fields = instance.value();
     143           5 :         auto const &thisObjectName = instance.key();
     144           5 :         GlobalNames::VerifyUniqueChillerName(
     145          10 :             state, state.dataIPShortCut->cCurrentModuleObject, thisObjectName, ErrorsFound, state.dataIPShortCut->cCurrentModuleObject + " Name");
     146             : 
     147           5 :         ++ChillerNum;
     148           5 :         auto &thisChiller = state.dataChillerElectricASHRAE205->Electric205Chiller(ChillerNum);
     149           5 :         thisChiller.Name = UtilityRoutines::MakeUPPERCase(thisObjectName);
     150           5 :         ip->markObjectAsUsed(state.dataIPShortCut->cCurrentModuleObject, thisObjectName);
     151             : 
     152          10 :         std::string const rep_file_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "representation_file_name");
     153          10 :         fs::path rep_file_path = DataSystemVariables::CheckForActualFilePath(state, fs::path(rep_file_name), std::string(RoutineName));
     154           5 :         if (rep_file_path.empty()) {
     155           0 :             ErrorsFound = true;
     156             :             // Given that several of the following expressions require the representation file to be present, we'll just throw a fatal here.
     157             :             // The ErrorsFound flag is still set to true here so that in the future, if we defer the fatal until later in this routine, it will still
     158             :             // be set The CheckForActualFilePath function emits some nice information to the ERR file, so we just need a simple fatal here
     159           0 :             ShowFatalError(state, "Program terminates due to the missing ASHRAE 205 RS0001 representation file.");
     160             :         }
     161          10 :         std::pair<EnergyPlusData *, std::string> callbackPair{&state,
     162          10 :                                                               format("{} \"{}\"", state.dataIPShortCut->cCurrentModuleObject, thisObjectName)};
     163           5 :         tk205::set_error_handler(tk205ErrCallback, &callbackPair);
     164           5 :         Btwxt::LOG_LEVEL = static_cast<int>(Btwxt::MsgLevel::MSG_WARN);
     165           5 :         thisChiller.Representation =
     166          10 :             std::dynamic_pointer_cast<tk205::rs0001_ns::RS0001>(RSInstanceFactory::create("RS0001", rep_file_path.string().c_str()));
     167           5 :         if (nullptr == thisChiller.Representation) {
     168           0 :             ShowSevereError(state, format("{} is not an instance of an ASHRAE205 Chiller.", rep_file_path.string()));
     169           0 :             ErrorsFound = true;
     170             :         }
     171           5 :         thisChiller.InterpolationType =
     172          10 :             InterpMethods[UtilityRoutines::MakeUPPERCase(ip->getAlphaFieldValue(fields, objectSchemaProps, "performance_interpolation_method"))];
     173             : 
     174          10 :         const auto compressorSequence = thisChiller.Representation->performance.performance_map_cooling.grid_variables.compressor_sequence_number;
     175             :         // minmax_element is sound but perhaps overkill; as sequence numbers are required by A205 to be in ascending order
     176          10 :         const auto minmaxSequenceNum = std::minmax_element(compressorSequence.begin(), compressorSequence.end());
     177           5 :         thisChiller.MinSequenceNumber = *(minmaxSequenceNum.first);
     178           5 :         thisChiller.MaxSequenceNumber = *(minmaxSequenceNum.second);
     179             : 
     180           5 :         if (fields.count("rated_capacity")) {
     181           0 :             ShowWarningError(state, format("{}{}=\"{}\"", std::string{RoutineName}, state.dataIPShortCut->cCurrentModuleObject, thisChiller.Name));
     182           0 :             ShowContinueError(state, "Rated Capacity field is not yet supported for ASHRAE 205 representations.");
     183             :         }
     184             : 
     185           5 :         thisChiller.RefCap = 0.0;               // ip->getRealFieldValue(fields, objectSchemaProps, "rated_capacity");
     186           5 :         thisChiller.RefCapWasAutoSized = false; // for now
     187             : 
     188             :         //        if (thisChiller.RefCap == DataSizing::AutoSize) {
     189             :         //            thisChiller.RefCapWasAutoSized = true;
     190             :         //        }
     191             :         //        if (thisChiller.RefCap == 0.0) {
     192             :         //            ShowSevereError(
     193             :         //                state, format("{}{}=\"{}\"",std::string{RoutineName},state.dataIPShortCut->cCurrentModuleObject,thisChiller.Name);
     194             :         //            ShowContinueError(state, format("Invalid {}={:.2R}", "Rated Capacity", thisChiller.RefCap));
     195             :         //            ErrorsFound = true;
     196             :         //        }
     197             : 
     198          10 :         std::string const evap_inlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "chilled_water_inlet_node_name");
     199          10 :         std::string const evap_outlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "chilled_water_outlet_node_name");
     200           5 :         if (evap_inlet_node_name.empty() || evap_outlet_node_name.empty()) {
     201           0 :             ShowSevereError(state, format("{}{}=\"{}\"", std::string{RoutineName}, state.dataIPShortCut->cCurrentModuleObject, thisChiller.Name));
     202           0 :             ShowContinueError(state, "Evaporator Inlet or Outlet Node Name is blank.");
     203           0 :             ErrorsFound = true;
     204             :         }
     205           5 :         thisChiller.EvapInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     206             :                                                                            evap_inlet_node_name,
     207             :                                                                            ErrorsFound,
     208             :                                                                            DataLoopNode::ConnectionObjectType::ChillerElectricASHRAE205,
     209             :                                                                            thisChiller.Name,
     210             :                                                                            DataLoopNode::NodeFluidType::Water,
     211             :                                                                            DataLoopNode::ConnectionType::Inlet,
     212             :                                                                            NodeInputManager::CompFluidStream::Primary,
     213           5 :                                                                            DataLoopNode::ObjectIsNotParent);
     214           5 :         thisChiller.EvapOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     215             :                                                                             evap_outlet_node_name,
     216             :                                                                             ErrorsFound,
     217             :                                                                             DataLoopNode::ConnectionObjectType::ChillerElectricASHRAE205,
     218             :                                                                             thisChiller.Name,
     219             :                                                                             DataLoopNode::NodeFluidType::Water,
     220             :                                                                             DataLoopNode::ConnectionType::Outlet,
     221             :                                                                             NodeInputManager::CompFluidStream::Primary,
     222           5 :                                                                             DataLoopNode::ObjectIsNotParent);
     223          10 :         BranchNodeConnections::TestCompSet(
     224           5 :             state, state.dataIPShortCut->cCurrentModuleObject, thisChiller.Name, evap_inlet_node_name, evap_outlet_node_name, "Chilled Water Nodes");
     225             : 
     226           5 :         thisChiller.CondenserType = DataPlant::CondenserType::WaterCooled;
     227             : 
     228          10 :         std::string const cond_inlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "condenser_inlet_node_name");
     229          10 :         std::string const cond_outlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "condenser_outlet_node_name");
     230           5 :         if (cond_inlet_node_name.empty() || cond_outlet_node_name.empty()) {
     231           0 :             ShowSevereError(state, format("{}{}=\"{}\"", std::string{RoutineName}, state.dataIPShortCut->cCurrentModuleObject, thisChiller.Name));
     232           0 :             ShowContinueError(state, "Condenser Inlet or Outlet Node Name is blank.");
     233           0 :             ErrorsFound = true;
     234             :         }
     235           5 :         thisChiller.CondInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     236             :                                                                            cond_inlet_node_name,
     237             :                                                                            ErrorsFound,
     238             :                                                                            DataLoopNode::ConnectionObjectType::ChillerElectricASHRAE205,
     239             :                                                                            thisChiller.Name,
     240             :                                                                            DataLoopNode::NodeFluidType::Water,
     241             :                                                                            DataLoopNode::ConnectionType::Inlet,
     242             :                                                                            NodeInputManager::CompFluidStream::Secondary,
     243           5 :                                                                            DataLoopNode::ObjectIsNotParent);
     244             : 
     245           5 :         thisChiller.CondOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     246             :                                                                             cond_outlet_node_name,
     247             :                                                                             ErrorsFound,
     248             :                                                                             DataLoopNode::ConnectionObjectType::ChillerElectricASHRAE205,
     249             :                                                                             thisChiller.Name,
     250             :                                                                             DataLoopNode::NodeFluidType::Water,
     251             :                                                                             DataLoopNode::ConnectionType::Outlet,
     252             :                                                                             NodeInputManager::CompFluidStream::Secondary,
     253           5 :                                                                             DataLoopNode::ObjectIsNotParent);
     254             : 
     255          10 :         BranchNodeConnections::TestCompSet(state,
     256           5 :                                            state.dataIPShortCut->cCurrentModuleObject,
     257             :                                            thisChiller.Name,
     258             :                                            cond_inlet_node_name,
     259             :                                            cond_outlet_node_name,
     260             :                                            "Condenser Water Nodes");
     261             : 
     262           5 :         thisChiller.FlowMode = static_cast<DataPlant::FlowMode>(
     263          10 :             getEnumerationValue(DataPlant::FlowModeNamesUC, ip->getAlphaFieldValue(fields, objectSchemaProps, "chiller_flow_mode")));
     264             : 
     265           5 :         if (thisChiller.FlowMode == DataPlant::FlowMode::Invalid) {
     266           0 :             ShowSevereError(state, format("{}{}=\"{}\"", std::string{RoutineName}, state.dataIPShortCut->cCurrentModuleObject, thisObjectName));
     267           0 :             ShowContinueError(state, "Invalid Chiller Flow Mode = " + fields.at("chiller_flow_mode").get<std::string>());
     268           0 :             ShowContinueError(state, "Available choices are ConstantFlow, NotModulated, or LeavingSetpointModulated");
     269           0 :             ShowContinueError(state, "Flow mode NotModulated is assumed and the simulation continues.");
     270           0 :             thisChiller.FlowMode = DataPlant::FlowMode::NotModulated;
     271             :         };
     272             : 
     273           5 :         thisChiller.SizFac = fields.at("sizing_factor").get<Real64>();
     274           5 :         if (thisChiller.SizFac <= 0.0) {
     275           0 :             thisChiller.SizFac = 1.0;
     276             :         }
     277             : 
     278             :         {
     279          10 :             auto tmpFlowRate = fields.at("chilled_water_maximum_requested_flow_rate");
     280           5 :             if (tmpFlowRate == "Autosize") {
     281           0 :                 thisChiller.EvapVolFlowRate = DataSizing::AutoSize;
     282           0 :                 thisChiller.EvapVolFlowRateWasAutoSized = true;
     283             :             } else {
     284           5 :                 thisChiller.EvapVolFlowRate = tmpFlowRate.get<Real64>();
     285             :             }
     286             :         }
     287             :         {
     288          10 :             auto tmpFlowRate = fields.at("condenser_maximum_requested_flow_rate");
     289           5 :             if (tmpFlowRate == "Autosize") {
     290           0 :                 thisChiller.CondVolFlowRate = DataSizing::AutoSize;
     291           0 :                 thisChiller.CondVolFlowRateWasAutoSized = true;
     292             :             } else {
     293           5 :                 thisChiller.CondVolFlowRate = tmpFlowRate.get<Real64>();
     294             :             }
     295             :         }
     296             : 
     297          10 :         thisChiller.AmbientTempType = static_cast<AmbientTempIndicator>(getEnumerationValue(
     298          15 :             AmbientTempNamesUC, UtilityRoutines::MakeUPPERCase(ip->getAlphaFieldValue(fields, objectSchemaProps, "ambient_temperature_indicator"))));
     299           5 :         switch (thisChiller.AmbientTempType) {
     300           0 :         case AmbientTempIndicator::Schedule: {
     301           0 :             std::string const ambient_temp_schedule = ip->getAlphaFieldValue(fields, objectSchemaProps, "ambient_temperature_schedule");
     302           0 :             thisChiller.AmbientTempSchedule = ScheduleManager::GetScheduleIndex(state, ambient_temp_schedule);
     303           0 :             if (thisChiller.AmbientTempSchedule == 0) {
     304           0 :                 ShowSevereError(state,
     305           0 :                                 format("{} = {}:  Ambient Temperature Schedule not found = {}",
     306           0 :                                        state.dataIPShortCut->cCurrentModuleObject,
     307             :                                        thisObjectName,
     308           0 :                                        ambient_temp_schedule));
     309           0 :                 ErrorsFound = true;
     310             :             }
     311             : 
     312           0 :             break;
     313             :         }
     314           5 :         case AmbientTempIndicator::TempZone: {
     315          10 :             std::string const ambient_temp_zone_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "ambient_temperature_zone_name");
     316           5 :             thisChiller.AmbientTempZone = UtilityRoutines::FindItemInList(ambient_temp_zone_name, state.dataHeatBal->Zone);
     317           5 :             if (thisChiller.AmbientTempZone == 0) {
     318           0 :                 ShowSevereError(state,
     319           0 :                                 format("{} = {}:  Ambient Temperature Zone not found = {}",
     320           0 :                                        state.dataIPShortCut->cCurrentModuleObject,
     321             :                                        thisObjectName,
     322           0 :                                        ambient_temp_zone_name));
     323           0 :                 ErrorsFound = true;
     324             :             } else {
     325           5 :                 SetupZoneInternalGain(state,
     326             :                                       thisChiller.AmbientTempZone,
     327             :                                       thisChiller.Name,
     328             :                                       DataHeatBalance::IntGainType::ElectricEquipment,
     329             :                                       &thisChiller.AmbientZoneGain);
     330             :             }
     331           5 :             break;
     332             :         }
     333           0 :         case AmbientTempIndicator::OutsideAir: {
     334             :             std::string const ambient_temp_outdoor_node =
     335           0 :                 ip->getAlphaFieldValue(fields, objectSchemaProps, "ambient_temperature_outdoor_air_node_name");
     336           0 :             thisChiller.AmbientTempOutsideAirNode = NodeInputManager::GetOnlySingleNode(state,
     337             :                                                                                         ambient_temp_outdoor_node,
     338             :                                                                                         ErrorsFound,
     339             :                                                                                         DataLoopNode::ConnectionObjectType::ChillerElectricASHRAE205,
     340             :                                                                                         thisChiller.Name,
     341             :                                                                                         DataLoopNode::NodeFluidType::Air,
     342             :                                                                                         DataLoopNode::ConnectionType::OutsideAirReference,
     343             :                                                                                         NodeInputManager::CompFluidStream::Primary,
     344           0 :                                                                                         DataLoopNode::ObjectIsNotParent);
     345           0 :             if (fields.count("ambient_temperature_outdoor_air_node_name")) {
     346           0 :                 if (!OutAirNodeManager::CheckOutAirNodeNumber(state, thisChiller.AmbientTempOutsideAirNode)) {
     347           0 :                     ShowSevereError(state,
     348           0 :                                     format("{} = {}: Outdoor Air Node not on OutdoorAir:NodeList or OutdoorAir:Node",
     349           0 :                                            state.dataIPShortCut->cCurrentModuleObject,
     350           0 :                                            thisObjectName));
     351           0 :                     ShowContinueError(state, format("...Referenced Node Name={}", ambient_temp_outdoor_node));
     352           0 :                     ErrorsFound = true;
     353             :                 }
     354             :             } else {
     355           0 :                 ShowSevereError(state, format("{} = {}", state.dataIPShortCut->cCurrentModuleObject, ambient_temp_outdoor_node));
     356           0 :                 ShowContinueError(state, "An Ambient Outdoor Air Node name must be used when the Ambient Temperature Indicator is Outdoors.");
     357           0 :                 ErrorsFound = true;
     358             :             }
     359             : 
     360           0 :             break;
     361             :         }
     362           0 :         default: {
     363           0 :             ShowSevereError(state,
     364           0 :                             format("{} = {}:  Invalid Ambient Temperature Indicator entered={}",
     365           0 :                                    state.dataIPShortCut->cCurrentModuleObject,
     366             :                                    thisObjectName,
     367           0 :                                    ip->getAlphaFieldValue(fields, objectSchemaProps, "ambient_temperature_indicator")));
     368           0 :             ShowContinueError(state, " Valid entries are SCHEDULE, ZONE, and OUTDOORS.");
     369           0 :             ErrorsFound = true;
     370           0 :             break;
     371             :         }
     372             :         }
     373             :         // end Ambient temperature
     374          10 :         std::string const oil_cooler_inlet_node = ip->getAlphaFieldValue(fields, objectSchemaProps, "oil_cooler_inlet_node_name");
     375          10 :         std::string const oil_cooler_outlet_node = ip->getAlphaFieldValue(fields, objectSchemaProps, "oil_cooler_outlet_node_name");
     376           5 :         if (!oil_cooler_inlet_node.empty() && !oil_cooler_outlet_node.empty()) {
     377           2 :             thisChiller.OilCoolerInletNode = NodeInputManager::GetOnlySingleNode(state,
     378             :                                                                                  oil_cooler_inlet_node,
     379             :                                                                                  ErrorsFound,
     380             :                                                                                  DataLoopNode::ConnectionObjectType::ChillerElectricASHRAE205,
     381             :                                                                                  thisChiller.Name,
     382             :                                                                                  DataLoopNode::NodeFluidType::Water,
     383             :                                                                                  DataLoopNode::ConnectionType::Inlet,
     384             :                                                                                  NodeInputManager::CompFluidStream::Tertiary,
     385           2 :                                                                                  DataLoopNode::ObjectIsNotParent);
     386           2 :             thisChiller.OilCoolerOutletNode = NodeInputManager::GetOnlySingleNode(state,
     387             :                                                                                   oil_cooler_outlet_node,
     388             :                                                                                   ErrorsFound,
     389             :                                                                                   DataLoopNode::ConnectionObjectType::ChillerElectricASHRAE205,
     390             :                                                                                   thisChiller.Name,
     391             :                                                                                   DataLoopNode::NodeFluidType::Water,
     392             :                                                                                   DataLoopNode::ConnectionType::Outlet,
     393             :                                                                                   NodeInputManager::CompFluidStream::Tertiary,
     394           2 :                                                                                   DataLoopNode::ObjectIsNotParent);
     395           4 :             BranchNodeConnections::TestCompSet(state,
     396           2 :                                                state.dataIPShortCut->cCurrentModuleObject,
     397             :                                                thisChiller.Name,
     398             :                                                oil_cooler_inlet_node,
     399             :                                                oil_cooler_outlet_node,
     400             :                                                "Oil Cooler Water Nodes");
     401             :         }
     402          10 :         std::string const aux_heat_inlet_node = ip->getAlphaFieldValue(fields, objectSchemaProps, "auxiliary_inlet_node_name");
     403          10 :         std::string const aux_heat_outlet_node = ip->getAlphaFieldValue(fields, objectSchemaProps, "auxiliary_outlet_node_name");
     404           5 :         if (!aux_heat_inlet_node.empty() && !aux_heat_outlet_node.empty()) {
     405             : 
     406           2 :             thisChiller.AuxiliaryHeatInletNode = NodeInputManager::GetOnlySingleNode(state,
     407             :                                                                                      aux_heat_inlet_node,
     408             :                                                                                      ErrorsFound,
     409             :                                                                                      DataLoopNode::ConnectionObjectType::ChillerElectricASHRAE205,
     410             :                                                                                      thisChiller.Name,
     411             :                                                                                      DataLoopNode::NodeFluidType::Water,
     412             :                                                                                      DataLoopNode::ConnectionType::Inlet,
     413             :                                                                                      NodeInputManager::CompFluidStream::Quaternary,
     414           2 :                                                                                      DataLoopNode::ObjectIsNotParent);
     415           2 :             thisChiller.AuxiliaryHeatOutletNode = NodeInputManager::GetOnlySingleNode(state,
     416             :                                                                                       aux_heat_outlet_node,
     417             :                                                                                       ErrorsFound,
     418             :                                                                                       DataLoopNode::ConnectionObjectType::ChillerElectricASHRAE205,
     419             :                                                                                       thisChiller.Name,
     420             :                                                                                       DataLoopNode::NodeFluidType::Water,
     421             :                                                                                       DataLoopNode::ConnectionType::Outlet,
     422             :                                                                                       NodeInputManager::CompFluidStream::Quaternary,
     423           2 :                                                                                       DataLoopNode::ObjectIsNotParent);
     424           4 :             BranchNodeConnections::TestCompSet(state,
     425           2 :                                                state.dataIPShortCut->cCurrentModuleObject,
     426             :                                                thisChiller.Name,
     427             :                                                aux_heat_inlet_node,
     428             :                                                aux_heat_outlet_node,
     429             :                                                "Auxiliary Water Nodes");
     430             :         }
     431             : 
     432             :         // TODO: When implemented, add ...WasAutoSized variables
     433           5 :         if (fields.count("oil_cooler_design_flow_rate")) {
     434           2 :             thisChiller.OilCoolerVolFlowRate = fields.at("oil_cooler_design_flow_rate").get<Real64>();
     435             :         }
     436           5 :         if (fields.count("auxiliary_equipment_design_flow_rate")) {
     437           0 :             thisChiller.AuxiliaryVolFlowRate = fields.at("auxiliary_equipment_design_flow_rate").get<Real64>();
     438             :         }
     439             : 
     440           5 :         if (fields.count("end_use_subcategory")) {
     441           0 :             thisChiller.EndUseSubcategory = ip->getAlphaFieldValue(fields, objectSchemaProps, "end_use_subcategory");
     442             :         } else {
     443           5 :             thisChiller.EndUseSubcategory = "General";
     444             :         }
     445             :         // Set reference conditions
     446           5 :         thisChiller.TempRefCondIn = 29.44;
     447           5 :         thisChiller.TempRefEvapOut = 6.67;
     448             :     }
     449             : 
     450           3 :     if (ErrorsFound) {
     451           0 :         ShowFatalError(state, format("Errors found in processing input for {}", state.dataIPShortCut->cCurrentModuleObject));
     452             :     }
     453           3 : }
     454             : 
     455          14 : ASHRAE205ChillerSpecs *ASHRAE205ChillerSpecs::factory(EnergyPlusData &state, std::string const &objectName)
     456             : {
     457          14 :     if (state.dataChillerElectricASHRAE205->getInputFlag) {
     458           3 :         getChillerASHRAE205Input(state);
     459           3 :         state.dataChillerElectricASHRAE205->getInputFlag = false;
     460             :     }
     461          20 :     for (auto &obj : state.dataChillerElectricASHRAE205->Electric205Chiller) {
     462          20 :         if (obj.Name == objectName) {
     463          14 :             return &obj;
     464             :         }
     465             :     }
     466             :     // If we didn't find it, fatal
     467             :     ShowFatalError(state, "ASHRAE205ChillerSpecs::factory: Error getting inputs for object named: " + objectName); // LCOV_EXCL_LINE
     468             :     return nullptr;                                                                                                // LCOV_EXCL_LINE
     469             : }
     470             : 
     471           5 : void ASHRAE205ChillerSpecs::oneTimeInit_new(EnergyPlusData &state)
     472             : {
     473             :     // This function is called from GetPlantInput
     474             :     // Locate the chillers on the plant loops for later usage
     475           5 :     bool errFlag{false};
     476           5 :     PlantUtilities::ScanPlantLoopsForObject(
     477             :         state, this->Name, DataPlant::PlantEquipmentType::Chiller_ElectricASHRAE205, this->CWPlantLoc, errFlag, _, _, _, this->EvapInletNodeNum, _);
     478           5 :     if (this->CondenserType != DataPlant::CondenserType::AirCooled) {
     479           5 :         PlantUtilities::ScanPlantLoopsForObject(state,
     480             :                                                 this->Name,
     481             :                                                 DataPlant::PlantEquipmentType::Chiller_ElectricASHRAE205,
     482             :                                                 this->CDPlantLoc,
     483             :                                                 errFlag,
     484             :                                                 _,
     485             :                                                 _,
     486             :                                                 _,
     487             :                                                 this->CondInletNodeNum,
     488             :                                                 _);
     489           5 :         PlantUtilities::InterConnectTwoPlantLoopSides(
     490             :             state, this->CWPlantLoc, this->CDPlantLoc, DataPlant::PlantEquipmentType::Chiller_ElectricASHRAE205, true);
     491             :     }
     492           5 :     if (this->OilCoolerInletNode) {
     493           2 :         PlantUtilities::ScanPlantLoopsForObject(state,
     494             :                                                 this->Name,
     495             :                                                 DataPlant::PlantEquipmentType::Chiller_ElectricASHRAE205,
     496             :                                                 this->OCPlantLoc,
     497             :                                                 errFlag,
     498             :                                                 _,
     499             :                                                 _,
     500             :                                                 _,
     501             :                                                 this->OilCoolerInletNode,
     502             :                                                 _);
     503             :     }
     504           5 :     if (this->AuxiliaryHeatInletNode) {
     505           2 :         PlantUtilities::ScanPlantLoopsForObject(state,
     506             :                                                 this->Name,
     507             :                                                 DataPlant::PlantEquipmentType::Chiller_ElectricASHRAE205,
     508             :                                                 this->AHPlantLoc,
     509             :                                                 errFlag,
     510             :                                                 _,
     511             :                                                 _,
     512             :                                                 _,
     513             :                                                 this->AuxiliaryHeatInletNode,
     514             :                                                 _);
     515             :     }
     516             : #if 0  // If and when heat recovery is implemented, uncomment
     517             :         if (this->HeatRecActive) {
     518             :             PlantUtilities::ScanPlantLoopsForObject(state,
     519             :                                                     this->Name,
     520             :                                                     DataPlant::PlantEquipmentType::Chiller_ElectricASHRAE205,
     521             :                                                     this->HRPlantLoc,
     522             :                                                     errFlag,
     523             :                                                     _,
     524             :                                                     _,
     525             :                                                     _,
     526             :                                                     this->HeatRecInletNodeNum,
     527             :                                                     _);
     528             :             PlantUtilities::InterConnectTwoPlantLoopSides(
     529             :                     state, this->CWPlantLoc, this->HRPlantLoc, DataPlant::PlantEquipmentType::Chiller_ElectricASHRAE205, true);
     530             :         }
     531             : 
     532             :         if ((this->CondenserType != DataPlant::CondenserType::AirCooled) && (this->HeatRecActive)) {
     533             :             PlantUtilities::InterConnectTwoPlantLoopSides(
     534             :                     state, this->CDPlantLoc, this->HRPlantLoc, DataPlant::PlantEquipmentType::Chiller_ElectricASHRAE205, false);
     535             :         }
     536             : #endif // #if 0
     537             : 
     538           5 :     if (errFlag) {
     539           0 :         ShowFatalError(state, "InitElecASHRAE205Chiller: Program terminated due to previous condition(s).");
     540             :     }
     541             : 
     542           5 :     if (this->FlowMode == DataPlant::FlowMode::Constant) {
     543             :         // reset flow priority
     544           4 :         DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).FlowPriority = DataPlant::LoopFlowStatus::NeedyIfLoopOn;
     545             :     }
     546             : 
     547           1 :     else if (this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) {
     548             :         // reset flow priority
     549           0 :         DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).FlowPriority = DataPlant::LoopFlowStatus::NeedyIfLoopOn;
     550             :         // check if setpoint on outlet node
     551           0 :         if ((state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue) &&
     552           0 :             (state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi == DataLoopNode::SensedNodeFlagValue)) {
     553           0 :             if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
     554           0 :                 if (!this->ModulatedFlowErrDone) {
     555           0 :                     ShowWarningError(state, format("Missing temperature setpoint for LeavingSetpointModulated mode chiller named {}", this->Name));
     556           0 :                     ShowContinueError(
     557             :                         state, "  A temperature setpoint is needed at the outlet node of a chiller in variable flow mode, use a SetpointManager");
     558           0 :                     ShowContinueError(state, "  The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
     559           0 :                     this->ModulatedFlowErrDone = true;
     560             :                 }
     561             :             } else {
     562             :                 // need call to EMS to check node
     563           0 :                 bool fatalError = false; // but not really fatal yet, but should be.
     564           0 :                 EMSManager::CheckIfNodeSetPointManagedByEMS(
     565             :                     state, this->EvapOutletNodeNum, EMSManager::SPControlType::TemperatureSetPoint, fatalError);
     566           0 :                 state.dataLoopNodes->NodeSetpointCheck(this->EvapOutletNodeNum).needsSetpointChecking = false;
     567           0 :                 if (fatalError) {
     568           0 :                     if (!this->ModulatedFlowErrDone) {
     569           0 :                         ShowWarningError(state,
     570           0 :                                          format("Missing temperature setpoint for LeavingSetpointModulated mode chiller named {}", this->Name));
     571           0 :                         ShowContinueError(state,
     572             :                                           "  A temperature setpoint is needed at the outlet node of a chiller evaporator in variable flow mode");
     573           0 :                         ShowContinueError(state, "  use a Setpoint Manager to establish a setpoint at the chiller evaporator outlet node ");
     574           0 :                         ShowContinueError(state, "  or use an EMS actuator to establish a setpoint at the outlet node ");
     575           0 :                         ShowContinueError(state, "  The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
     576           0 :                         this->ModulatedFlowErrDone = true;
     577             :                     }
     578             :                 }
     579             :             }
     580           0 :             this->ModulatedFlowSetToLoop = true;
     581           0 :             state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint =
     582           0 :                 state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
     583           0 :             state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi =
     584           0 :                 state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPointHi;
     585             :         }
     586             :     }
     587             : 
     588           5 :     this->setOutputVariables(state);
     589           5 : }
     590             : 
     591      252475 : void ASHRAE205ChillerSpecs::initialize(EnergyPlusData &state, bool const RunFlag, Real64 const MyLoad)
     592             : {
     593             :     static constexpr std::string_view RoutineName("ASHRAE205ChillerSpecs::initialize");
     594             : 
     595      252475 :     switch (this->AmbientTempType) {
     596           0 :     case AmbientTempIndicator::Schedule: {
     597           0 :         this->AmbientTemp = ScheduleManager::GetCurrentScheduleValue(state, this->AmbientTempSchedule);
     598           0 :         break;
     599             :     }
     600      252475 :     case AmbientTempIndicator::TempZone: {
     601      252475 :         this->AmbientTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->AmbientTempZone).MAT;
     602      252475 :         break;
     603             :     }
     604           0 :     case AmbientTempIndicator::OutsideAir: {
     605           0 :         this->AmbientTemp = state.dataLoopNodes->Node(this->AmbientTempOutsideAirNode).Temp;
     606           0 :         break;
     607             :     }
     608           0 :     default:
     609           0 :         break;
     610             :     }
     611             : 
     612      252475 :     this->EquipFlowCtrl = DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).FlowCtrl;
     613             : 
     614      252475 :     if (this->MyEnvrnFlag && state.dataGlobal->BeginEnvrnFlag && (state.dataPlnt->PlantFirstSizesOkayToFinalize)) {
     615        1910 :         Real64 rho = FluidProperties::GetDensityGlycol(state,
     616         955 :                                                        state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidName,
     617             :                                                        DataGlobalConstants::CWInitConvTemp,
     618         955 :                                                        state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidIndex,
     619         955 :                                                        RoutineName);
     620             : 
     621         955 :         this->EvapMassFlowRateMax = rho * this->EvapVolFlowRate;
     622         955 :         PlantUtilities::InitComponentNodes(state, 0.0, this->EvapMassFlowRateMax, this->EvapInletNodeNum, this->EvapOutletNodeNum);
     623             : 
     624         955 :         if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
     625        1910 :             rho = FluidProperties::GetDensityGlycol(state,
     626         955 :                                                     state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).FluidName,
     627             :                                                     this->TempRefCondIn,
     628         955 :                                                     state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).FluidIndex,
     629             :                                                     RoutineName);
     630         955 :             this->CondMassFlowRateMax = rho * this->CondVolFlowRate;
     631         955 :             PlantUtilities::InitComponentNodes(state, 0.0, this->CondMassFlowRateMax, this->CondInletNodeNum, this->CondOutletNodeNum);
     632         955 :             state.dataLoopNodes->Node(this->CondInletNodeNum).Temp = this->TempRefCondIn;
     633             :         }
     634             :         // Set mass flow rates at Oil Cooler and Aux Equipment nodes
     635         955 :         if (this->OilCoolerInletNode) {
     636         852 :             Real64 rho_oil_cooler = FluidProperties::GetDensityGlycol(state,
     637         426 :                                                                       state.dataPlnt->PlantLoop(this->OCPlantLoc.loopNum).FluidName,
     638             :                                                                       DataGlobalConstants::InitConvTemp,
     639         426 :                                                                       state.dataPlnt->PlantLoop(this->OCPlantLoc.loopNum).FluidIndex,
     640         426 :                                                                       RoutineName);
     641         426 :             this->OilCoolerMassFlowRate = rho_oil_cooler * this->OilCoolerVolFlowRate;
     642         426 :             PlantUtilities::InitComponentNodes(state, 0.0, this->OilCoolerMassFlowRate, this->OilCoolerInletNode, this->OilCoolerOutletNode);
     643             :         }
     644         955 :         if (this->AuxiliaryHeatInletNode) {
     645         852 :             Real64 rho_aux = FluidProperties::GetDensityGlycol(state,
     646         426 :                                                                state.dataPlnt->PlantLoop(this->AHPlantLoc.loopNum).FluidName,
     647             :                                                                DataGlobalConstants::InitConvTemp,
     648         426 :                                                                state.dataPlnt->PlantLoop(this->AHPlantLoc.loopNum).FluidIndex,
     649         426 :                                                                RoutineName);
     650         426 :             this->AuxiliaryMassFlowRate = rho_aux * this->AuxiliaryVolFlowRate;
     651         426 :             PlantUtilities::InitComponentNodes(state, 0.0, this->AuxiliaryMassFlowRate, this->AuxiliaryHeatInletNode, this->AuxiliaryHeatOutletNode);
     652             :         }
     653             :     }
     654      252475 :     if (!state.dataGlobal->BeginEnvrnFlag) {
     655      251440 :         this->MyEnvrnFlag = true;
     656             :     }
     657             : 
     658      252475 :     if ((this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) && this->ModulatedFlowSetToLoop) {
     659             :         // see ReformulatedEIR or EIR Chiller for origin of the following
     660           0 :         state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint =
     661           0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
     662           0 :         state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi =
     663           0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPointHi;
     664             :     }
     665             : 
     666      252475 :     Real64 mdot = ((std::abs(MyLoad) > 0.0) && RunFlag) ? this->EvapMassFlowRateMax : 0.0;
     667      252475 :     Real64 mdotCond = ((std::abs(MyLoad) > 0.0) && RunFlag) ? this->CondMassFlowRateMax : 0.0;
     668             : 
     669      252475 :     PlantUtilities::SetComponentFlowRate(state, mdot, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
     670             : 
     671      252475 :     if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
     672      252475 :         PlantUtilities::SetComponentFlowRate(state, mdotCond, this->CondInletNodeNum, this->CondOutletNodeNum, this->CDPlantLoc);
     673             :     }
     674             : 
     675             :     // Set component flow rates for Oil Cooler and Aux equipment
     676      252475 :     if (this->OilCoolerInletNode) {
     677      111572 :         PlantUtilities::SetComponentFlowRate(
     678             :             state, this->OilCoolerMassFlowRate, this->OilCoolerInletNode, this->OilCoolerOutletNode, this->OCPlantLoc);
     679             :     }
     680      252475 :     if (this->AuxiliaryHeatInletNode) {
     681      111572 :         PlantUtilities::SetComponentFlowRate(
     682             :             state, this->AuxiliaryMassFlowRate, this->AuxiliaryHeatInletNode, this->AuxiliaryHeatOutletNode, this->AHPlantLoc);
     683             :     }
     684             :     // Recalculate volumetric flow rates from component mass flow rates if necessary
     685             : 
     686             : #if 0  // Revisit when heat recovery implemented
     687             :        // Initialize heat recovery flow rates at node
     688             :         if (this->HeatRecActive) {
     689             : 
     690             :             // check if inlet limit active and if exceeded.
     691             :             bool HeatRecRunFlag = RunFlag;
     692             :             if (this->HeatRecInletLimitSchedNum > 0) {
     693             :                 Real64 HeatRecHighInletLimit = ScheduleManager::GetCurrentScheduleValue(state, this->HeatRecInletLimitSchedNum);
     694             :                 if (state.dataLoopNodes->Node(this->HeatRecInletNodeNum).Temp > HeatRecHighInletLimit) { // shut down heat recovery
     695             :                     HeatRecRunFlag = false;
     696             :                 } else {
     697             :                     HeatRecRunFlag = RunFlag;
     698             :                 }
     699             :             }
     700             : 
     701             :             mdot = HeatRecRunFlag ? this->DesignHeatRecMassFlowRate : 0.0;
     702             : 
     703             :             PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatRecInletNodeNum, this->HeatRecOutletNodeNum, this->HRPlantLoc);
     704             :         }
     705             : #endif // if 0
     706      252475 : }
     707             : 
     708          25 : void ASHRAE205ChillerSpecs::size([[maybe_unused]] EnergyPlusData &state)
     709             : {
     710             :     static constexpr std::string_view RoutineName("SizeElectricASHRAE205Chiller");
     711             : 
     712          25 :     bool ErrorsFound = false;
     713          25 :     Real64 tmpNomCap{0.0};
     714          25 :     Real64 tmpEvapVolFlowRate = this->EvapVolFlowRate;
     715          25 :     Real64 tmpCondVolFlowRate = this->CondVolFlowRate;
     716             : 
     717             :     // Size evaporator flow rate
     718             :     // find the appropriate Plant Sizing object
     719          25 :     int PltSizNum = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).PlantSizNum;
     720             : 
     721          25 :     if (PltSizNum > 0) {
     722          20 :         if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= DataHVACGlobals::SmallWaterVolFlow) {
     723          12 :             tmpEvapVolFlowRate = state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate * this->SizFac;
     724             :         } else {
     725           8 :             if (this->EvapVolFlowRateWasAutoSized) tmpEvapVolFlowRate = 0.0;
     726             :         }
     727          20 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     728           4 :             if (this->EvapVolFlowRateWasAutoSized) {
     729           0 :                 this->EvapVolFlowRate = tmpEvapVolFlowRate;
     730           0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     731           0 :                     BaseSizer::reportSizerOutput(
     732           0 :                         state, this->ObjectType, this->Name, "Design Size Chilled Water Maximum Requested Flow Rate [m3/s]", tmpEvapVolFlowRate);
     733             :                 }
     734           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
     735           0 :                     BaseSizer::reportSizerOutput(state,
     736             :                                                  this->ObjectType,
     737             :                                                  this->Name,
     738             :                                                  "Initial Design Size Chilled Water Maximum Requested Flow Rate [m3/s]",
     739           0 :                                                  tmpEvapVolFlowRate);
     740             :                 }
     741             :             } else { // Hard-size with sizing data
     742           4 :                 if (this->EvapVolFlowRate > 0.0 && tmpEvapVolFlowRate > 0.0) {
     743           4 :                     Real64 EvapVolFlowRateUser = this->EvapVolFlowRate;
     744           4 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     745           8 :                         BaseSizer::reportSizerOutput(state,
     746             :                                                      this->ObjectType,
     747             :                                                      this->Name,
     748             :                                                      "Design Size Chilled Water Maximum Requested Flow Rate [m3/s]",
     749             :                                                      tmpEvapVolFlowRate,
     750             :                                                      "User-Specified Chilled Water Maximum Requested Flow Rate [m3/s]",
     751           4 :                                                      EvapVolFlowRateUser);
     752           4 :                         if (state.dataGlobal->DisplayExtraWarnings) {
     753           0 :                             if ((std::abs(tmpEvapVolFlowRate - EvapVolFlowRateUser) / EvapVolFlowRateUser) >
     754           0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
     755           0 :                                 ShowMessage(state, format("{}: Potential issue with equipment sizing for {}", RoutineName, this->Name));
     756           0 :                                 ShowContinueError(
     757           0 :                                     state, format("User-Specified Chilled Water Maximum Requested Flow Rate of {:.5R} [m3/s]", EvapVolFlowRateUser));
     758           0 :                                 ShowContinueError(state,
     759           0 :                                                   format("differs from Design Size Chilled Water Maximum Requested Flow Rate of {:.5R} [m3/s]",
     760           0 :                                                          tmpEvapVolFlowRate));
     761           0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
     762           0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
     763             :                             }
     764             :                         }
     765             :                     }
     766           4 :                     tmpEvapVolFlowRate = EvapVolFlowRateUser;
     767             :                 }
     768             :             }
     769             :         }
     770             :     } else {
     771           5 :         if (this->EvapVolFlowRateWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     772           0 :             ShowSevereError(state, "Autosizing of Electric Chiller evap flow rate requires a loop Sizing:Plant object");
     773           0 :             ShowContinueError(state, "Occurs in Electric Chiller object=" + this->Name);
     774           0 :             ErrorsFound = true;
     775             :         }
     776           5 :         if (!this->EvapVolFlowRateWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && (this->EvapVolFlowRate > 0.0)) {
     777           2 :             BaseSizer::reportSizerOutput(
     778           1 :                 state, this->ObjectType, this->Name, "User-Specified Chilled Water Maximum Requested Flow Rate [m3/s]", this->EvapVolFlowRate);
     779             :         }
     780             :     }
     781             : 
     782          25 :     PlantUtilities::RegisterPlantCompDesignFlow(state, this->EvapInletNodeNum, tmpEvapVolFlowRate);
     783             : 
     784             :     // Size condenser flow rate
     785          25 :     int PltSizCondNum = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).PlantSizNum; // Change for air-cooled when it's supported
     786          25 :     if (PltSizCondNum > 0 && PltSizNum > 0) {
     787          20 :         if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= DataHVACGlobals::SmallWaterVolFlow && tmpNomCap > 0.0) {
     788             : 
     789           0 :             Real64 rho = FluidProperties::GetDensityGlycol(state,
     790           0 :                                                            state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).FluidName,
     791             :                                                            DataGlobalConstants::CWInitConvTemp,
     792           0 :                                                            state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).FluidIndex,
     793           0 :                                                            RoutineName);
     794           0 :             Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
     795           0 :                                                                state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).FluidName,
     796             :                                                                this->TempRefCondIn,
     797           0 :                                                                state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).FluidIndex,
     798           0 :                                                                RoutineName);
     799           0 :             tmpCondVolFlowRate = tmpNomCap * (1.0 + (1.0 / this->RefCOP) * this->CompPowerToCondenserFrac) /
     800           0 :                                  (state.dataSize->PlantSizData(PltSizCondNum).DeltaT * Cp * rho);
     801             : 
     802             :         } else {
     803          20 :             if (this->CondVolFlowRateWasAutoSized) tmpCondVolFlowRate = 0.0;
     804             :         }
     805          20 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     806           4 :             if (this->CondVolFlowRateWasAutoSized) {
     807           0 :                 this->CondVolFlowRate = tmpCondVolFlowRate;
     808           0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     809           0 :                     BaseSizer::reportSizerOutput(
     810           0 :                         state, this->ObjectType, this->Name, "Design Size Condenser Maximum Requested Flow Rate [m3/s]", tmpCondVolFlowRate);
     811             :                 }
     812           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
     813           0 :                     BaseSizer::reportSizerOutput(
     814           0 :                         state, this->ObjectType, this->Name, "Initial Design Size Condenser Maximum Requested Flow Rate [m3/s]", tmpCondVolFlowRate);
     815             :                 }
     816             :             } else {
     817           4 :                 if (this->CondVolFlowRate > 0.0 && tmpCondVolFlowRate > 0.0) {
     818           4 :                     Real64 CondVolFlowRateUser = this->CondVolFlowRate;
     819           4 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     820           8 :                         BaseSizer::reportSizerOutput(state,
     821             :                                                      this->ObjectType,
     822             :                                                      this->Name,
     823             :                                                      "Design Size Condenser Maximum Requested Flow Rate [m3/s]",
     824             :                                                      tmpCondVolFlowRate,
     825             :                                                      "User-Specified Condenser Maximum Requested Flow Rate [m3/s]",
     826           4 :                                                      CondVolFlowRateUser);
     827           4 :                         if (state.dataGlobal->DisplayExtraWarnings) {
     828           0 :                             if ((std::abs(tmpCondVolFlowRate - CondVolFlowRateUser) / CondVolFlowRateUser) >
     829           0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
     830           0 :                                 ShowMessage(state, format("{}: Potential issue with equipment sizing for {}", RoutineName, this->Name));
     831           0 :                                 ShowContinueError(
     832           0 :                                     state, format("User-Specified Condenser Maximum Requested Flow Rate of {:.5R} [m3/s]", CondVolFlowRateUser));
     833           0 :                                 ShowContinueError(
     834             :                                     state,
     835           0 :                                     format("differs from Design Size Condenser Maximum Requested Flow Rate of {:.5R} [m3/s]", tmpCondVolFlowRate));
     836           0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
     837           0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
     838             :                             }
     839             :                         }
     840             :                     }
     841           4 :                     tmpCondVolFlowRate = CondVolFlowRateUser;
     842             :                 }
     843             :             }
     844          20 :         }
     845             :     } else {
     846           5 :         if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
     847             : 
     848           5 :             if (this->CondVolFlowRateWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     849           0 :                 ShowSevereError(state, "Autosizing of Electric ASHRAE 205 Chiller condenser fluid flow rate requires a condenser");
     850           0 :                 ShowContinueError(state, "loop Sizing:Plant object");
     851           0 :                 ShowContinueError(state, "Occurs in Electric ASHRAE 205 Chiller object=" + this->Name);
     852           0 :                 ErrorsFound = true;
     853             :             }
     854           5 :             if (!this->CondVolFlowRateWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && (this->CondVolFlowRate > 0.0)) {
     855           2 :                 BaseSizer::reportSizerOutput(
     856           1 :                     state, this->ObjectType, this->Name, "User-Specified Condenser Maximum Requested Flow Rate [m3/s]", this->CondVolFlowRate);
     857             :             }
     858             : 
     859             :         } else {
     860             : 
     861             :             // Auto size condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
     862           0 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     863           0 :                 std::string_view CompType =
     864             :                     DataPlant::PlantEquipTypeNames[static_cast<int>(DataPlant::PlantEquipmentType::Chiller_ElectricASHRAE205)];
     865           0 :                 state.dataSize->DataConstantUsedForSizing = this->RefCap;
     866           0 :                 state.dataSize->DataFractionUsedForSizing = 0.000114;
     867           0 :                 Real64 TempSize = this->CondVolFlowRate;
     868           0 :                 bool bPRINT = true; // TRUE if sizing is reported to output (eio)
     869           0 :                 AutoCalculateSizer sizerCondAirFlow;
     870           0 :                 std::string stringOverride = "Condenser Maximum Requested Flow Rate  [m3/s]";
     871           0 :                 if (state.dataGlobal->isEpJSON) stringOverride = "condenser_maximum_requested_flow_rate [m3/s]";
     872           0 :                 sizerCondAirFlow.overrideSizingString(stringOverride);
     873           0 :                 sizerCondAirFlow.initializeWithinEP(state, CompType, this->Name, bPRINT, RoutineName);
     874           0 :                 this->CondVolFlowRate = sizerCondAirFlow.size(state, TempSize, ErrorsFound);
     875             :             }
     876             :         }
     877             :     }
     878             : 
     879             :     // save the reference condenser water volumetric flow rate for use by the condenser water loop sizing algorithms
     880          25 :     PlantUtilities::RegisterPlantCompDesignFlow(state, this->CondInletNodeNum, tmpCondVolFlowRate);
     881             : 
     882             :     // Calculate design evaporator capacity (eventually add autosize here too)
     883             : 
     884             :     // TODO: Determine actual rated flow rates instead of design flow rates
     885          50 :     this->RefCap = this->Representation->performance.performance_map_cooling
     886          50 :                        .calculate_performance(this->EvapVolFlowRate,
     887          25 :                                               this->TempRefEvapOut + DataGlobalConstants::KelvinConv,
     888             :                                               this->CondVolFlowRate,
     889          25 :                                               this->TempRefCondIn + DataGlobalConstants::KelvinConv,
     890          25 :                                               this->MaxSequenceNumber,
     891         100 :                                               this->InterpolationType)
     892          25 :                        .net_evaporator_capacity;
     893             : 
     894          25 :     if (PltSizNum > 0) {
     895          20 :         if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= DataHVACGlobals::SmallWaterVolFlow) {
     896          24 :             Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
     897          12 :                                                                state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidName,
     898             :                                                                DataGlobalConstants::CWInitConvTemp,
     899          12 :                                                                state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidIndex,
     900          12 :                                                                RoutineName);
     901             : 
     902          24 :             Real64 rho = FluidProperties::GetDensityGlycol(state,
     903          12 :                                                            state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidName,
     904             :                                                            DataGlobalConstants::CWInitConvTemp,
     905          12 :                                                            state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidIndex,
     906          12 :                                                            RoutineName);
     907          12 :             tmpNomCap = Cp * rho * state.dataSize->PlantSizData(PltSizNum).DeltaT * tmpEvapVolFlowRate;
     908             :         } else {
     909           8 :             tmpNomCap = 0.0;
     910             :         }
     911          20 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     912           4 :             if (this->RefCapWasAutoSized) {
     913           0 :                 this->RefCap = tmpNomCap;
     914           0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     915           0 :                     BaseSizer::reportSizerOutput(state, this->ObjectType, this->Name, "Design Size Rated Capacity [W]", tmpNomCap);
     916             :                 }
     917           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
     918           0 :                     BaseSizer::reportSizerOutput(state, this->ObjectType, this->Name, "Initial Design Size Rated Capacity [W]", tmpNomCap);
     919             :                 }
     920             :             } else { // Hard-sized with sizing data
     921           4 :                 if (this->RefCap > 0.0 && tmpNomCap > 0.0) {
     922           4 :                     Real64 RefCapUser = this->RefCap;
     923           4 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     924           8 :                         BaseSizer::reportSizerOutput(state,
     925             :                                                      this->ObjectType,
     926             :                                                      this->Name,
     927             :                                                      "Design Size Rated Capacity [W]",
     928             :                                                      tmpNomCap,
     929             :                                                      "User-Specified Rated Capacity [W]",
     930           4 :                                                      RefCapUser);
     931           4 :                         if (state.dataGlobal->DisplayExtraWarnings) {
     932           0 :                             if ((std::abs(tmpNomCap - RefCapUser) / RefCapUser) > state.dataSize->AutoVsHardSizingThreshold) {
     933           0 :                                 ShowMessage(state, format("{}: Potential issue with equipment sizing for {}", RoutineName, this->Name));
     934           0 :                                 ShowContinueError(state, format("User-Specified Rated Capacity of {:.2R} [W]", RefCapUser));
     935           0 :                                 ShowContinueError(state, format("differs from Design Size Rated Capacity of {:.2R} [W]", tmpNomCap));
     936           0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
     937           0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
     938             :                             }
     939             :                         }
     940             :                     }
     941           4 :                     tmpNomCap = RefCapUser;
     942             :                 }
     943             :             }
     944             :         }
     945             :     } else {
     946           5 :         if (this->RefCapWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     947           0 :             ShowSevereError(state, "Autosizing of Electric Chiller reference capacity requires a loop Sizing:Plant object");
     948           0 :             ShowContinueError(state, "Occurs in Electric Chiller object=" + this->Name);
     949           0 :             ErrorsFound = true;
     950             :         }
     951           5 :         if (!this->RefCapWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && (this->RefCap > 0.0)) { // Hard-sized with no sizing data
     952           1 :             BaseSizer::reportSizerOutput(state, this->ObjectType, this->Name, "User-Specified Rated Capacity [W]", this->RefCap);
     953             :         }
     954             :     }
     955             : 
     956          25 :     if (this->OilCoolerInletNode) {
     957          10 :         PlantUtilities::RegisterPlantCompDesignFlow(state, this->OilCoolerInletNode, this->OilCoolerVolFlowRate);
     958             :     }
     959             : 
     960          25 :     if (this->AuxiliaryHeatInletNode) {
     961          10 :         PlantUtilities::RegisterPlantCompDesignFlow(state, this->AuxiliaryHeatInletNode, this->AuxiliaryVolFlowRate);
     962             :     }
     963             : 
     964          25 :     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     965             :         // create predefined report
     966           5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechType, this->Name, this->ObjectType);
     967           5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomEff, this->Name, this->RefCOP);
     968           5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomCap, this->Name, this->RefCap);
     969             :     }
     970             : 
     971          25 :     if (ErrorsFound) {
     972           0 :         ShowFatalError(state, "Preceding sizing errors cause program termination");
     973             :     }
     974          25 : }
     975             : 
     976           5 : void ASHRAE205ChillerSpecs::setOutputVariables(EnergyPlusData &state)
     977             : {
     978          10 :     SetupOutputVariable(state,
     979             :                         "Chiller Part Load Ratio",
     980             :                         OutputProcessor::Unit::None,
     981             :                         this->ChillerPartLoadRatio,
     982             :                         OutputProcessor::SOVTimeStepType::System,
     983             :                         OutputProcessor::SOVStoreType::Average,
     984           5 :                         this->Name);
     985             : 
     986          10 :     SetupOutputVariable(state,
     987             :                         "Chiller Cycling Ratio",
     988             :                         OutputProcessor::Unit::None,
     989             :                         this->ChillerCyclingRatio,
     990             :                         OutputProcessor::SOVTimeStepType::System,
     991             :                         OutputProcessor::SOVStoreType::Average,
     992           5 :                         this->Name);
     993             : 
     994          10 :     SetupOutputVariable(state,
     995             :                         "Minimum Part Load Ratio",
     996             :                         OutputProcessor::Unit::None,
     997             :                         this->MinPartLoadRat,
     998             :                         OutputProcessor::SOVTimeStepType::System,
     999             :                         OutputProcessor::SOVStoreType::Average,
    1000           5 :                         this->Name);
    1001             : 
    1002          10 :     SetupOutputVariable(state,
    1003             :                         "Chiller Electricity Rate",
    1004             :                         OutputProcessor::Unit::W,
    1005             :                         this->Power,
    1006             :                         OutputProcessor::SOVTimeStepType::System,
    1007             :                         OutputProcessor::SOVStoreType::Average,
    1008           5 :                         this->Name);
    1009             : 
    1010          10 :     SetupOutputVariable(state,
    1011             :                         "Chiller Electricity Energy",
    1012             :                         OutputProcessor::Unit::J,
    1013             :                         this->Energy,
    1014             :                         OutputProcessor::SOVTimeStepType::System,
    1015             :                         OutputProcessor::SOVStoreType::Summed,
    1016             :                         this->Name,
    1017             :                         _,
    1018             :                         "ELECTRICITY",
    1019             :                         "Cooling",
    1020             :                         this->EndUseSubcategory,
    1021           5 :                         "Plant");
    1022             : 
    1023          10 :     SetupOutputVariable(state,
    1024             :                         "Chiller Evaporator Cooling Rate",
    1025             :                         OutputProcessor::Unit::W,
    1026             :                         this->QEvaporator,
    1027             :                         OutputProcessor::SOVTimeStepType::System,
    1028             :                         OutputProcessor::SOVStoreType::Average,
    1029           5 :                         this->Name);
    1030             : 
    1031          10 :     SetupOutputVariable(state,
    1032             :                         "Chiller Evaporator Cooling Energy",
    1033             :                         OutputProcessor::Unit::J,
    1034             :                         this->EvapEnergy,
    1035             :                         OutputProcessor::SOVTimeStepType::System,
    1036             :                         OutputProcessor::SOVStoreType::Summed,
    1037             :                         this->Name,
    1038             :                         _,
    1039             :                         "ENERGYTRANSFER",
    1040             :                         "CHILLERS",
    1041             :                         _,
    1042           5 :                         "Plant");
    1043             : 
    1044          10 :     SetupOutputVariable(state,
    1045             :                         "Chiller Evaporator Inlet Temperature",
    1046             :                         OutputProcessor::Unit::C,
    1047             :                         this->EvapInletTemp,
    1048             :                         OutputProcessor::SOVTimeStepType::System,
    1049             :                         OutputProcessor::SOVStoreType::Average,
    1050           5 :                         this->Name);
    1051             : 
    1052          10 :     SetupOutputVariable(state,
    1053             :                         "Chiller Evaporator Outlet Temperature",
    1054             :                         OutputProcessor::Unit::C,
    1055             :                         this->EvapOutletTemp,
    1056             :                         OutputProcessor::SOVTimeStepType::System,
    1057             :                         OutputProcessor::SOVStoreType::Average,
    1058           5 :                         this->Name);
    1059             : 
    1060          10 :     SetupOutputVariable(state,
    1061             :                         "Chiller Evaporator Mass Flow Rate",
    1062             :                         OutputProcessor::Unit::kg_s,
    1063             :                         this->EvapMassFlowRate,
    1064             :                         OutputProcessor::SOVTimeStepType::System,
    1065             :                         OutputProcessor::SOVStoreType::Average,
    1066           5 :                         this->Name);
    1067             : 
    1068          10 :     SetupOutputVariable(state,
    1069             :                         "Chiller Condenser Heat Transfer Rate",
    1070             :                         OutputProcessor::Unit::W,
    1071             :                         this->QCondenser,
    1072             :                         OutputProcessor::SOVTimeStepType::System,
    1073             :                         OutputProcessor::SOVStoreType::Average,
    1074           5 :                         this->Name);
    1075             : 
    1076          10 :     SetupOutputVariable(state,
    1077             :                         "Chiller Condenser Heat Transfer Energy",
    1078             :                         OutputProcessor::Unit::J,
    1079             :                         this->CondEnergy,
    1080             :                         OutputProcessor::SOVTimeStepType::System,
    1081             :                         OutputProcessor::SOVStoreType::Summed,
    1082             :                         this->Name,
    1083             :                         _,
    1084             :                         "ENERGYTRANSFER",
    1085             :                         "HEATREJECTION",
    1086             :                         _,
    1087           5 :                         "Plant");
    1088             : 
    1089          10 :     SetupOutputVariable(state,
    1090             :                         "Chiller COP",
    1091             :                         OutputProcessor::Unit::W_W,
    1092             :                         this->ActualCOP,
    1093             :                         OutputProcessor::SOVTimeStepType::System,
    1094             :                         OutputProcessor::SOVStoreType::Average,
    1095           5 :                         this->Name);
    1096             : 
    1097          10 :     SetupOutputVariable(state,
    1098             :                         "Chiller Condenser Inlet Temperature",
    1099             :                         OutputProcessor::Unit::C,
    1100             :                         this->CondInletTemp,
    1101             :                         OutputProcessor::SOVTimeStepType::System,
    1102             :                         OutputProcessor::SOVStoreType::Average,
    1103           5 :                         this->Name);
    1104             : 
    1105          10 :     SetupOutputVariable(state,
    1106             :                         "Chiller Condenser Outlet Temperature",
    1107             :                         OutputProcessor::Unit::C,
    1108             :                         this->CondOutletTemp,
    1109             :                         OutputProcessor::SOVTimeStepType::System,
    1110             :                         OutputProcessor::SOVStoreType::Average,
    1111           5 :                         this->Name);
    1112             : 
    1113          10 :     SetupOutputVariable(state,
    1114             :                         "Chiller Condenser Mass Flow Rate",
    1115             :                         OutputProcessor::Unit::kg_s,
    1116             :                         this->CondMassFlowRate,
    1117             :                         OutputProcessor::SOVTimeStepType::System,
    1118             :                         OutputProcessor::SOVStoreType::Average,
    1119           5 :                         this->Name);
    1120             : 
    1121          10 :     SetupOutputVariable(state,
    1122             :                         "Chiller Effective Heat Rejection Temperature",
    1123             :                         OutputProcessor::Unit::C,
    1124             :                         this->ChillerCondAvgTemp,
    1125             :                         OutputProcessor::SOVTimeStepType::System,
    1126             :                         OutputProcessor::SOVStoreType::Average,
    1127           5 :                         this->Name);
    1128             : 
    1129          10 :     SetupOutputVariable(state,
    1130             :                         "Chiller Zone Heat Gain Rate",
    1131             :                         OutputProcessor::Unit::W,
    1132             :                         this->AmbientZoneGain,
    1133             :                         OutputProcessor::SOVTimeStepType::System,
    1134             :                         OutputProcessor::SOVStoreType::Average,
    1135           5 :                         this->Name);
    1136             : 
    1137          10 :     SetupOutputVariable(state,
    1138             :                         "Chiller Zone Heat Gain Energy",
    1139             :                         OutputProcessor::Unit::J,
    1140             :                         this->AmbientZoneGainEnergy,
    1141             :                         OutputProcessor::SOVTimeStepType::System,
    1142             :                         OutputProcessor::SOVStoreType::Summed,
    1143           5 :                         this->Name);
    1144             : 
    1145          10 :     SetupOutputVariable(state,
    1146             :                         "Oil Cooler Heat Transfer Rate",
    1147             :                         OutputProcessor::Unit::W,
    1148             :                         this->QOilCooler,
    1149             :                         OutputProcessor::SOVTimeStepType::System,
    1150             :                         OutputProcessor::SOVStoreType::Average,
    1151           5 :                         this->Name);
    1152             : 
    1153          10 :     SetupOutputVariable(state,
    1154             :                         "Oil Cooler Heat Transfer Energy",
    1155             :                         OutputProcessor::Unit::J,
    1156             :                         this->OilCoolerEnergy,
    1157             :                         OutputProcessor::SOVTimeStepType::System,
    1158             :                         OutputProcessor::SOVStoreType::Summed,
    1159           5 :                         this->Name);
    1160             : 
    1161          10 :     SetupOutputVariable(state,
    1162             :                         "Auxiliary Heat Transfer Rate",
    1163             :                         OutputProcessor::Unit::W,
    1164             :                         this->QAuxiliary,
    1165             :                         OutputProcessor::SOVTimeStepType::System,
    1166             :                         OutputProcessor::SOVStoreType::Average,
    1167           5 :                         this->Name);
    1168             : 
    1169          10 :     SetupOutputVariable(state,
    1170             :                         "Auxiliary Heat Transfer Energy",
    1171             :                         OutputProcessor::Unit::J,
    1172             :                         this->AuxiliaryEnergy,
    1173             :                         OutputProcessor::SOVTimeStepType::System,
    1174             :                         OutputProcessor::SOVStoreType::Summed,
    1175           5 :                         this->Name);
    1176           5 : }
    1177             : 
    1178       74828 : void ASHRAE205ChillerSpecs::findEvaporatorMassFlowRate(EnergyPlusData &state, Real64 &load, Real64 Cp)
    1179             : {
    1180             :     static constexpr std::string_view RoutineName("ASHRAE205ChillerSpecs::findEvaporatorMassFlowRate");
    1181       74828 :     const int PlantLoopNum = this->CWPlantLoc.loopNum;
    1182       74828 :     const DataPlant::LoopSideLocation LoopSideNum = this->CWPlantLoc.loopSideNum;
    1183       74828 :     const int BranchNum = this->CWPlantLoc.branchNum;
    1184       74828 :     const int CompNum = this->CWPlantLoc.compNum;
    1185             : 
    1186             :     // If FlowLock is False (0), the chiller sets the plant loop mdot
    1187             :     // If FlowLock is True (1),  the new resolved plant loop mdot is used
    1188       74828 :     if (state.dataPlnt->PlantLoop(PlantLoopNum).LoopSide(LoopSideNum).FlowLock == DataPlant::FlowLock::Unlocked) {
    1189       37390 :         this->PossibleSubcooling = !(state.dataPlnt->PlantLoop(PlantLoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(CompNum).CurOpSchemeType ==
    1190             :                                      DataPlant::OpScheme::CompSetPtBased);
    1191             : 
    1192       37390 :         Real64 evapDeltaTemp(0.0); // Evaporator temperature difference [C]
    1193             : 
    1194             :         // Either set the flow to the Constant value or calculate the flow for the variable volume case
    1195       37390 :         if ((this->FlowMode == DataPlant::FlowMode::Constant) || (this->FlowMode == DataPlant::FlowMode::NotModulated)) {
    1196             :             // Set the evaporator mass flow rate to design
    1197             :             // Start by assuming max (design) flow
    1198       37390 :             this->EvapMassFlowRate = this->EvapMassFlowRateMax;
    1199             :             // Use PlantUtilities::SetComponentFlowRate to decide actual flow
    1200       37390 :             PlantUtilities::SetComponentFlowRate(state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
    1201       37390 :             if (this->EvapMassFlowRate != 0.0) {
    1202       37390 :                 evapDeltaTemp = std::abs(load) / this->EvapMassFlowRate / Cp; // MyLoad = net evaporator capacity, QEvaporator
    1203             :             } else {
    1204           0 :                 evapDeltaTemp = 0.0;
    1205             :             }
    1206       37390 :             this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - evapDeltaTemp;
    1207           0 :         } else if (this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) {
    1208           0 :             switch (state.dataPlnt->PlantLoop(PlantLoopNum).LoopDemandCalcScheme) {
    1209           0 :             case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1210             :                 // Calculate the Delta Temp from the inlet temp to the chiller outlet setpoint
    1211           0 :                 evapDeltaTemp =
    1212           0 :                     state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint;
    1213           0 :             } break;
    1214           0 :             case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1215           0 :                 evapDeltaTemp =
    1216           0 :                     state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi;
    1217           0 :             } break;
    1218           0 :             default: {
    1219           0 :                 assert(false);
    1220             :             } break;
    1221             :             }
    1222             : 
    1223           0 :             if (evapDeltaTemp != 0) {
    1224           0 :                 this->EvapMassFlowRate = max(0.0, (std::abs(load) / Cp / evapDeltaTemp));
    1225           0 :                 if ((this->EvapMassFlowRate - this->EvapMassFlowRateMax) > DataBranchAirLoopPlant::MassFlowTolerance) this->PossibleSubcooling = true;
    1226             :                 // Check to see if the Maximum is exceeded, if so set to maximum
    1227           0 :                 this->EvapMassFlowRate = min(this->EvapMassFlowRateMax, this->EvapMassFlowRate);
    1228             :                 // Use PlantUtilities::SetComponentFlowRate to decide actual flow
    1229           0 :                 PlantUtilities::SetComponentFlowRate(
    1230             :                     state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
    1231             :                 // Should we recalculate this with the corrected setpoint?
    1232           0 :                 switch (state.dataPlnt->PlantLoop(PlantLoopNum).LoopDemandCalcScheme) {
    1233           0 :                 case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1234           0 :                     this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint;
    1235           0 :                 } break;
    1236           0 :                 case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1237           0 :                     this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi;
    1238           0 :                 } break;
    1239           0 :                 default:
    1240           0 :                     break;
    1241             :                 }
    1242             :             } else {
    1243             :                 // Try to request zero flow
    1244           0 :                 this->EvapMassFlowRate = 0.0;
    1245             :                 // Use PlantUtilities::SetComponentFlowRate to decide actual flow
    1246           0 :                 PlantUtilities::SetComponentFlowRate(
    1247             :                     state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
    1248             :                 // No deltaT since component is not running
    1249           0 :                 this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    1250           0 :                 this->QEvaporator = 0.0;
    1251             :                 // PartLoadRat = 0.0;
    1252           0 :                 this->ChillerPartLoadRatio = 0.0;
    1253             : 
    1254           0 :                 if (this->DeltaTErrCount < 1 && !state.dataGlobal->WarmupFlag) {
    1255           0 :                     ++this->DeltaTErrCount;
    1256           0 :                     ShowWarningError(state, "Evaporator DeltaTemp = 0 in mass flow calculation (Tevapin = Tevapout setpoint temp).");
    1257           0 :                     ShowContinueErrorTimeStamp(state, "");
    1258           0 :                 } else if (!state.dataGlobal->WarmupFlag) {
    1259           0 :                     ++this->ChillerCapFTError;
    1260           0 :                     ShowRecurringWarningErrorAtEnd(
    1261             :                         state,
    1262           0 :                         format("{} \"{}\": Evaporator DeltaTemp = 0 in mass flow calculation warning continues...", this->ObjectType, this->Name),
    1263             :                         this->DeltaTErrCountIndex,
    1264             :                         evapDeltaTemp,
    1265             :                         evapDeltaTemp);
    1266             :                 }
    1267             :             }
    1268             :         }
    1269             :     } else { // If FlowLock is True
    1270       37438 :         this->EvapMassFlowRate = state.dataLoopNodes->Node(this->EvapInletNodeNum).MassFlowRate;
    1271       37438 :         PlantUtilities::SetComponentFlowRate(state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
    1272             :         //       Some other component set the flow to 0. No reason to continue with calculations.
    1273       37438 :         if (this->EvapMassFlowRate == 0.0) {
    1274           0 :             load = 0.0;
    1275           0 :             return;
    1276             :         }
    1277             :     } // This is the end of the FlowLock Block
    1278             : 
    1279      149656 :     const Real64 rho = FluidProperties::GetDensityGlycol(state,
    1280       74828 :                                                          state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidName,
    1281             :                                                          DataGlobalConstants::CWInitConvTemp,
    1282       74828 :                                                          state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidIndex,
    1283       74828 :                                                          RoutineName);
    1284             : 
    1285       74828 :     this->EvapVolFlowRate = this->EvapMassFlowRate / rho;
    1286             : }
    1287             : 
    1288      252405 : void ASHRAE205ChillerSpecs::calculate(EnergyPlusData &state, Real64 &MyLoad, bool const RunFlag)
    1289             : {
    1290             :     static constexpr std::string_view RoutineName("CalcElecASHRAE205ChillerModel");
    1291      252405 :     this->ChillerPartLoadRatio = 0.0;
    1292      252405 :     this->ChillerCyclingRatio = 1.0;
    1293      252405 :     this->ChillerFalseLoadRate = 0.0;
    1294      252405 :     this->EvapMassFlowRate = 0.0;
    1295      252405 :     this->CondMassFlowRate = 0.0;
    1296      252405 :     this->Power = 0.0;
    1297      252405 :     this->QCondenser = 0.0;
    1298      252405 :     this->QEvaporator = 0.0;
    1299      252405 :     this->QOilCooler = 0.0;
    1300      252405 :     this->QAuxiliary = 0.0;
    1301      252405 :     int PlantLoopNum = this->CWPlantLoc.loopNum;
    1302      252405 :     DataPlant::LoopSideLocation LoopSideNum = this->CWPlantLoc.loopSideNum;
    1303      252405 :     int BranchNum = this->CWPlantLoc.branchNum;
    1304      252405 :     int CompNum = this->CWPlantLoc.compNum;
    1305             : 
    1306             :     // Set module-level chiller evaporator and condenser inlet temperature variables
    1307             :     // using prior time step's temperature
    1308      252405 :     Real64 condInletTemp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    1309      252405 :     this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp;
    1310             : 
    1311             :     // If no loop demand or chiller OFF, return
    1312             :     // If chiller load is 0 or chiller is not running then leave the subroutine. Before leaving
    1313             :     //  if the component control is SERIESACTIVE we set the component flow to inlet flow so that
    1314             :     //  flow resolver will not shut down the branch
    1315             : 
    1316             :     // Calculate performance for standby (only used when off or cycling)
    1317             :     Real64 standbyPower =
    1318      252405 :         this->Representation->performance.performance_map_standby.calculate_performance(this->AmbientTemp, this->InterpolationType).input_power;
    1319      252405 :     if (MyLoad >= 0 || !RunFlag) {
    1320      195178 :         if (this->EquipFlowCtrl == DataBranchAirLoopPlant::ControlType::SeriesActive ||
    1321       18093 :             state.dataPlnt->PlantLoop(PlantLoopNum).LoopSide(LoopSideNum).FlowLock == DataPlant::FlowLock::Locked) {
    1322      168036 :             this->EvapMassFlowRate = state.dataLoopNodes->Node(this->EvapInletNodeNum).MassFlowRate;
    1323             :         }
    1324      177085 :         if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    1325      177085 :             if (DataPlant::CompData::getPlantComponent(state, this->CDPlantLoc).FlowCtrl == DataBranchAirLoopPlant::ControlType::SeriesActive) {
    1326           0 :                 this->CondMassFlowRate = state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate;
    1327             :             }
    1328             :         }
    1329      177085 :         this->Power = standbyPower;
    1330      177085 :         this->AmbientZoneGain = standbyPower;
    1331      354694 :         return;
    1332             :     }
    1333             : 
    1334             : // Revisit
    1335             : #if 0
    1336             :         //        // If there is a fault of chiller fouling
    1337             : //        if (this->FaultyChillerFoulingFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    1338             : //            (!state.dataGlobal->KickOffSimulation)) {
    1339             : //            int FaultIndex = this->FaultyChillerFoulingIndex;
    1340             : //            Real64 NomCap_ff = ChillerRefCap;
    1341             : //            Real64 ReferenceCOP_ff = ReferenceCOP;
    1342             : //
    1343             : //            // calculate the Faulty Chiller Fouling Factor using fault information
    1344             : //            this->FaultyChillerFoulingFactor = state.dataFaultsMgr->FaultsChillerFouling(FaultIndex).CalFoulingFactor(state);
    1345             : //
    1346             : //            // update the Chiller nominal capacity and COP at faulty cases
    1347             : //            ChillerRefCap = NomCap_ff * this->FaultyChillerFoulingFactor;
    1348             : //            ReferenceCOP = ReferenceCOP_ff * this->FaultyChillerFoulingFactor;
    1349             : //        }
    1350             : #endif // 0
    1351             : 
    1352             :     // Set mass flow rates
    1353       75320 :     if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    1354       75320 :         this->CondMassFlowRate = this->CondMassFlowRateMax;
    1355       75320 :         PlantUtilities::SetComponentFlowRate(state, this->CondMassFlowRate, this->CondInletNodeNum, this->CondOutletNodeNum, this->CDPlantLoc);
    1356       75320 :         PlantUtilities::PullCompInterconnectTrigger(
    1357             :             state, this->CWPlantLoc, this->CondMassFlowIndex, this->CDPlantLoc, DataPlant::CriteriaType::MassFlowRate, this->CondMassFlowRate);
    1358             : 
    1359       75320 :         if (this->CondMassFlowRate < DataBranchAirLoopPlant::MassFlowTolerance) return;
    1360             :     }
    1361       74844 :     Real64 EvapOutletTempSetPoint(0.0); // Evaporator outlet temperature setpoint [C]
    1362       74844 :     switch (state.dataPlnt->PlantLoop(PlantLoopNum).LoopDemandCalcScheme) {
    1363       74844 :     case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1364      224532 :         if ((this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) ||
    1365       74844 :             (state.dataPlnt->PlantLoop(PlantLoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(CompNum).CurOpSchemeType ==
    1366      149688 :              DataPlant::OpScheme::CompSetPtBased) ||
    1367       74844 :             (state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint != DataLoopNode::SensedNodeFlagValue)) {
    1368             :             // there will be a valid setpoint on outlet
    1369           0 :             EvapOutletTempSetPoint = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint;
    1370             :         } else { // use plant loop overall setpoint
    1371       74844 :             EvapOutletTempSetPoint = state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(PlantLoopNum).TempSetPointNodeNum).TempSetPoint;
    1372             :         }
    1373       74844 :     } break;
    1374           0 :     case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1375           0 :         if ((this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) ||
    1376           0 :             (state.dataPlnt->PlantLoop(PlantLoopNum).LoopSide(LoopSideNum).Branch(BranchNum).Comp(CompNum).CurOpSchemeType ==
    1377           0 :              DataPlant::OpScheme::CompSetPtBased) ||
    1378           0 :             (state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi != DataLoopNode::SensedNodeFlagValue)) {
    1379             :             // there will be a valid setpoint on outlet
    1380           0 :             EvapOutletTempSetPoint = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi;
    1381             :         } else { // use plant loop overall setpoint
    1382           0 :             EvapOutletTempSetPoint = state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(PlantLoopNum).TempSetPointNodeNum).TempSetPointHi;
    1383             :         }
    1384           0 :     } break;
    1385           0 :     default: {
    1386           0 :         assert(false);
    1387             :     } break;
    1388             :     }
    1389             : // Revisit
    1390             : #if 0
    1391             :         //        // If there is a fault of Chiller SWT Sensor
    1392             : //        if (this->FaultyChillerSWTFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation)) {
    1393             : //            int FaultIndex = this->FaultyChillerSWTIndex;
    1394             : //            Real64 EvapOutletTempSetPoint_ff = EvapOutletTempSetPoint;
    1395             : //
    1396             : //            // calculate the sensor offset using fault information
    1397             : //            this->FaultyChillerSWTOffset = state.dataFaultsMgr->FaultsChillerSWTSensor(FaultIndex).CalFaultOffsetAct(state);
    1398             : //            // update the EvapOutletTempSetPoint
    1399             : //            EvapOutletTempSetPoint =
    1400             : //                    max(this->TempLowLimitEvapOut,
    1401             : //                        min(state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp, EvapOutletTempSetPoint_ff - this->FaultyChillerSWTOffset));
    1402             : //            this->FaultyChillerSWTOffset = EvapOutletTempSetPoint_ff - EvapOutletTempSetPoint;
    1403             : //        }
    1404             : #endif // 0
    1405             :        // When implemented, TODO: correct temperature if using heat recovery
    1406             : 
    1407       74844 :     this->EvapMassFlowRate = state.dataLoopNodes->Node(this->EvapInletNodeNum).MassFlowRate;
    1408             :     // If some other component set the flow to 0, no reason to continue with calculations.
    1409       74844 :     if (this->EvapMassFlowRate == 0.0) {
    1410          48 :         MyLoad = 0.0;
    1411          48 :         return;
    1412             :     }
    1413             : 
    1414      224388 :     Real64 CpEvap = FluidProperties::GetSpecificHeatGlycol(state,
    1415       74796 :                                                            state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidName,
    1416       74796 :                                                            state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp,
    1417       74796 :                                                            state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidIndex,
    1418       74796 :                                                            RoutineName);
    1419             : 
    1420             :     // Calculate mass flow rate based on MyLoad (TODO: then adjust it after determining if chiller can meet the load)
    1421       74796 :     this->findEvaporatorMassFlowRate(state, MyLoad, CpEvap);
    1422             : 
    1423             :     // Available chiller capacity is capacity at the highest sequence number; i.e. max chiller capacity
    1424       74796 :     const Real64 maximumChillerCap = this->Representation->performance.performance_map_cooling
    1425      149592 :                                          .calculate_performance(this->EvapVolFlowRate,
    1426       74796 :                                                                 this->EvapOutletTemp + DataGlobalConstants::KelvinConv,
    1427             :                                                                 this->CondVolFlowRate,
    1428       74796 :                                                                 this->CondInletTemp + DataGlobalConstants::KelvinConv,
    1429       74796 :                                                                 this->MaxSequenceNumber,
    1430      299184 :                                                                 this->InterpolationType)
    1431       74796 :                                          .net_evaporator_capacity;
    1432       74796 :     const Real64 minimumChillerCap = this->Representation->performance.performance_map_cooling
    1433      149592 :                                          .calculate_performance(this->EvapVolFlowRate,
    1434       74796 :                                                                 this->EvapOutletTemp + DataGlobalConstants::KelvinConv,
    1435             :                                                                 this->CondVolFlowRate,
    1436       74796 :                                                                 this->CondInletTemp + DataGlobalConstants::KelvinConv,
    1437       74796 :                                                                 this->MinSequenceNumber,
    1438      299184 :                                                                 this->InterpolationType)
    1439       74796 :                                          .net_evaporator_capacity;
    1440             :     // Part load ratio based on load and available chiller capacity; cap at max P.L.R. (can be >1)
    1441       74796 :     this->ChillerPartLoadRatio = (maximumChillerCap > 0) ? max(0.0, std::abs(MyLoad) / maximumChillerCap) : 0.0;
    1442             :     // Minimum capacity ratio, under which cycling occurs
    1443       74796 :     this->MinPartLoadRat = (maximumChillerCap > 0) ? minimumChillerCap / maximumChillerCap : 0.0;
    1444       74796 :     Real64 partLoadSeqNum{0.};
    1445             : 
    1446             :     // Chiller may be operating in one of three modes: cycling, modulating, or full capacity
    1447       74796 :     if (this->ChillerPartLoadRatio < this->MinPartLoadRat) // Cycling
    1448             :     {
    1449        7229 :         this->ChillerCyclingRatio = this->ChillerPartLoadRatio / this->MinPartLoadRat;
    1450        7229 :         partLoadSeqNum = this->MinSequenceNumber;
    1451       67567 :     } else if (this->ChillerPartLoadRatio < 1.0) // Modulating
    1452             :     {
    1453             :         // Use performance map to find the fractional sequence number (which most closely matches our part load)
    1454       67535 :         Real64 constexpr accuracy{0.0001};
    1455       67535 :         int constexpr maxIter{500};
    1456       67535 :         int solFla{0};
    1457     1823445 :         auto f = [MyLoad, this](Real64 partLoadSeqNum) {
    1458      405210 :             this->QEvaporator = this->Representation->performance.performance_map_cooling
    1459      405210 :                                     .calculate_performance(this->EvapVolFlowRate,
    1460      202605 :                                                            this->EvapOutletTemp + DataGlobalConstants::KelvinConv,
    1461             :                                                            this->CondVolFlowRate,
    1462      202605 :                                                            this->CondInletTemp + DataGlobalConstants::KelvinConv,
    1463             :                                                            partLoadSeqNum,
    1464     1215630 :                                                            this->InterpolationType)
    1465      202605 :                                     .net_evaporator_capacity;
    1466      405210 :             return std::abs(MyLoad) - this->QEvaporator;
    1467       67535 :         };
    1468             :         // Iteratively calculate this->QEvaporator by modulating partLoadSeqNum, ending at Q_Evaporator(partLoadSeqNum)
    1469       67535 :         General::SolveRoot(state, accuracy, maxIter, solFla, partLoadSeqNum, f, this->MinSequenceNumber, this->MaxSequenceNumber);
    1470             :     } else // Full capacity: std::abs(MyLoad) > this->QEvaporator
    1471             :     {
    1472          32 :         this->QEvaporator = maximumChillerCap;
    1473          32 :         partLoadSeqNum = this->MaxSequenceNumber;
    1474             :         // SolveRoot stuff for eventual flow rate (can always calculate Ts if you have MFR and capacity)
    1475             :         // recursion? Revisit.
    1476          32 :         findEvaporatorMassFlowRate(state, this->QEvaporator, CpEvap);
    1477             :         // if MFR changes, recalculate chiller capacity.
    1478             :         // repeat until load <= capacity
    1479             :     }
    1480             : 
    1481             :     // Use performance map to get the rest of results at new sequence number
    1482             :     auto lookupVariablesCooling =
    1483       74796 :         this->Representation->performance.performance_map_cooling.calculate_performance(this->EvapVolFlowRate,
    1484       74796 :                                                                                         this->EvapOutletTemp + DataGlobalConstants::KelvinConv,
    1485             :                                                                                         this->CondVolFlowRate,
    1486       74796 :                                                                                         this->CondInletTemp + DataGlobalConstants::KelvinConv,
    1487             :                                                                                         partLoadSeqNum,
    1488      224388 :                                                                                         this->InterpolationType);
    1489       74796 :     this->QEvaporator = lookupVariablesCooling.net_evaporator_capacity * this->ChillerCyclingRatio;
    1490             : 
    1491       74796 :     auto evapDeltaTemp = this->QEvaporator / this->EvapMassFlowRate / CpEvap;
    1492       74796 :     this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - evapDeltaTemp;
    1493             : 
    1494             :     // TODO: Revisit fault
    1495             : #if 0
    1496             :         // If there is a fault of Chiller SWT Sensor
    1497             :         if (this->FaultyChillerSWTFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    1498             :             (!state.dataGlobal->KickOffSimulation) && (this->EvapMassFlowRate > 0)) {
    1499             :             // calculate directly affected variables at faulty case: EvapOutletTemp, EvapMassFlowRate, QEvaporator
    1500             :             int FaultIndex = this->FaultyChillerSWTIndex;
    1501             :             bool VarFlowFlag = false;
    1502             :             state.dataFaultsMgr->FaultsChillerSWTSensor(FaultIndex)
    1503             :                     .CalFaultChillerSWT(VarFlowFlag,
    1504             :                                         this->FaultyChillerSWTOffset,
    1505             :                                         Cp,
    1506             :                                         state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp,
    1507             :                                         this->EvapOutletTemp,
    1508             :                                         this->EvapMassFlowRate,
    1509             :                                         this->QEvaporator);
    1510             :             // update corresponding variables at faulty case
    1511             :         }
    1512             : #endif // 0
    1513             : 
    1514       74796 :     auto cd = this->Representation->performance.cycling_degradation_coefficient;
    1515       74796 :     Real64 cyclingFactor{(1.0 - cd) + (cd * this->ChillerCyclingRatio)};
    1516       74796 :     Real64 runtimeFactor{this->ChillerCyclingRatio / cyclingFactor};
    1517       74796 :     this->Power = lookupVariablesCooling.input_power * runtimeFactor + ((1 - this->ChillerCyclingRatio) * standbyPower);
    1518       74796 :     this->QCondenser = lookupVariablesCooling.net_condenser_capacity * this->ChillerCyclingRatio;
    1519       74796 :     this->QOilCooler = lookupVariablesCooling.oil_cooler_heat;
    1520       74796 :     this->QAuxiliary = lookupVariablesCooling.auxiliary_heat;
    1521       74796 :     Real64 QExternallyCooled{0.0};
    1522       74796 :     if (this->OilCoolerInletNode) {
    1523       32536 :         QExternallyCooled += this->QOilCooler;
    1524             :     }
    1525       74796 :     if (this->AuxiliaryHeatInletNode) {
    1526       32536 :         QExternallyCooled += this->QAuxiliary;
    1527             :     }
    1528             :     // Energy balance on the chiller system gives the amount of heat lost to the ambient zone
    1529       74796 :     this->AmbientZoneGain = this->QEvaporator + this->Power - (this->QCondenser + QExternallyCooled);
    1530             : 
    1531      149592 :     Real64 CpCond = FluidProperties::GetSpecificHeatGlycol(state,
    1532       74796 :                                                            state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).FluidName,
    1533             :                                                            condInletTemp,
    1534       74796 :                                                            state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).FluidIndex,
    1535       74796 :                                                            RoutineName);
    1536       74796 :     this->CondOutletTemp = this->QCondenser / this->CondMassFlowRate / CpCond + condInletTemp;
    1537             : 
    1538             :     // Oil cooler and Auxiliary Heat delta-T calculations
    1539       74796 :     if (this->OilCoolerInletNode) {
    1540       32536 :         auto oilCoolerDeltaTemp{0.0};
    1541       32536 :         PlantUtilities::SetComponentFlowRate(
    1542             :             state, this->OilCoolerMassFlowRate, this->OilCoolerInletNode, this->OilCoolerOutletNode, this->OCPlantLoc);
    1543             : 
    1544       97608 :         Real64 CpOilCooler = FluidProperties::GetSpecificHeatGlycol(state,
    1545       32536 :                                                                     state.dataPlnt->PlantLoop(this->OCPlantLoc.loopNum).FluidName,
    1546       32536 :                                                                     state.dataLoopNodes->Node(this->OilCoolerInletNode).Temp,
    1547       32536 :                                                                     state.dataPlnt->PlantLoop(this->OCPlantLoc.loopNum).FluidIndex,
    1548       32536 :                                                                     RoutineName);
    1549             : 
    1550       32536 :         if (this->OilCoolerMassFlowRate != 0.0) {
    1551           0 :             oilCoolerDeltaTemp = this->QOilCooler / (this->OilCoolerMassFlowRate * CpOilCooler);
    1552             :         } else {
    1553       32536 :             oilCoolerDeltaTemp = 0.0;
    1554             :         }
    1555       32536 :         state.dataLoopNodes->Node(this->OilCoolerOutletNode).Temp = state.dataLoopNodes->Node(this->OilCoolerInletNode).Temp - oilCoolerDeltaTemp;
    1556             :     }
    1557       74796 :     if (this->AuxiliaryHeatInletNode) {
    1558       32536 :         auto auxiliaryDeltaTemp{0.0};
    1559       32536 :         PlantUtilities::SetComponentFlowRate(
    1560             :             state, this->AuxiliaryMassFlowRate, this->AuxiliaryHeatInletNode, this->AuxiliaryHeatOutletNode, this->AHPlantLoc);
    1561             : 
    1562       97608 :         Real64 CpAux = FluidProperties::GetSpecificHeatGlycol(state,
    1563       32536 :                                                               state.dataPlnt->PlantLoop(this->AHPlantLoc.loopNum).FluidName,
    1564       32536 :                                                               state.dataLoopNodes->Node(this->AuxiliaryHeatInletNode).Temp,
    1565       32536 :                                                               state.dataPlnt->PlantLoop(this->AHPlantLoc.loopNum).FluidIndex,
    1566       32536 :                                                               RoutineName);
    1567             : 
    1568       32536 :         if (this->AuxiliaryMassFlowRate != 0.0) {
    1569           0 :             auxiliaryDeltaTemp = this->QAuxiliary / (this->AuxiliaryMassFlowRate * CpAux);
    1570             :         } else {
    1571       32536 :             auxiliaryDeltaTemp = 0.0;
    1572             :         }
    1573       32536 :         state.dataLoopNodes->Node(this->AuxiliaryHeatOutletNode).Temp =
    1574       32536 :             state.dataLoopNodes->Node(this->AuxiliaryHeatInletNode).Temp - auxiliaryDeltaTemp;
    1575             :     }
    1576             : }
    1577             : 
    1578      252405 : void ASHRAE205ChillerSpecs::update(EnergyPlusData &state, Real64 const MyLoad, bool const RunFlag)
    1579             : {
    1580      252405 :     if (MyLoad >= 0.0 || !RunFlag) { // Chiller not running so pass inlet states to outlet states
    1581             :         // Set node temperatures
    1582      177133 :         state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    1583      177133 :         state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    1584      177133 :         if (this->OilCoolerInletNode) {
    1585       78764 :             state.dataLoopNodes->Node(this->OilCoolerOutletNode).Temp = state.dataLoopNodes->Node(this->OilCoolerInletNode).Temp;
    1586             :         }
    1587      177133 :         if (this->AuxiliaryHeatInletNode) {
    1588       78764 :             state.dataLoopNodes->Node(this->AuxiliaryHeatOutletNode).Temp = state.dataLoopNodes->Node(this->AuxiliaryHeatInletNode).Temp;
    1589             :         }
    1590             : 
    1591      177133 :         this->ChillerPartLoadRatio = 0.0;
    1592      177133 :         this->ChillerCyclingRatio = 0.0;
    1593      177133 :         this->ChillerFalseLoadRate = 0.0;
    1594      177133 :         this->ChillerFalseLoad = 0.0;
    1595      177133 :         this->QEvaporator = 0.0;
    1596      177133 :         this->QCondenser = 0.0;
    1597      177133 :         this->Energy = 0.0;
    1598      177133 :         this->EvapEnergy = 0.0;
    1599      177133 :         this->CondEnergy = 0.0;
    1600      177133 :         this->QOilCooler = 0.0;
    1601      177133 :         this->QAuxiliary = 0.0;
    1602      177133 :         this->OilCoolerEnergy = 0.0;
    1603      177133 :         this->AuxiliaryEnergy = 0.0;
    1604      177133 :         this->EvapInletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    1605      177133 :         this->CondInletTemp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    1606      177133 :         this->CondOutletTemp = state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp;
    1607      177133 :         this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp;
    1608      177133 :         this->ActualCOP = 0.0;
    1609             : 
    1610             :     } else { // Chiller is running, so pass calculated values
    1611             :         // Set node temperatures
    1612       75272 :         state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp = this->EvapOutletTemp;
    1613       75272 :         state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp = this->CondOutletTemp;
    1614             :         // Set node flow rates;  for these load based models
    1615             :         // assume that sufficient evaporator flow rate is available
    1616       75272 :         this->EvapEnergy = this->QEvaporator * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
    1617       75272 :         this->CondEnergy = this->QCondenser * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
    1618       75272 :         this->OilCoolerEnergy = this->QOilCooler * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
    1619       75272 :         this->AuxiliaryEnergy = this->QAuxiliary * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
    1620       75272 :         this->EvapInletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    1621       75272 :         this->CondInletTemp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    1622       75272 :         this->CondOutletTemp = state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp;
    1623       75272 :         if (this->Power != 0.0) {
    1624       74796 :             this->ActualCOP = this->QEvaporator / this->Power;
    1625             :         } else {
    1626         476 :             this->ActualCOP = 0.0;
    1627             :         }
    1628             :     }
    1629             : 
    1630             :     // Calculate in case of standby power
    1631      252405 :     this->AmbientZoneGainEnergy = this->AmbientZoneGain * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
    1632      252405 :     this->Energy = this->Power * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
    1633      252405 : }
    1634             : 
    1635      501738 : void ASHRAE205ChillerSpecs::simulate(
    1636             :     EnergyPlusData &state, const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag)
    1637             : {
    1638      501738 :     if (calledFromLocation.loopNum == this->CWPlantLoc.loopNum) {
    1639      252405 :         this->initialize(state, RunFlag, CurLoad);
    1640      252405 :         this->calculate(state, CurLoad, RunFlag);
    1641      252405 :         this->update(state, CurLoad, RunFlag);
    1642      249333 :     } else if (calledFromLocation.loopNum == this->CDPlantLoc.loopNum) {
    1643      137793 :         DataPlant::LoopSideLocation LoopSide = this->CDPlantLoc.loopSideNum;
    1644      275586 :         PlantUtilities::UpdateChillerComponentCondenserSide(state,
    1645      137793 :                                                             calledFromLocation.loopNum,
    1646             :                                                             LoopSide,
    1647             :                                                             DataPlant::PlantEquipmentType::Chiller_ElectricASHRAE205,
    1648             :                                                             this->CondInletNodeNum,
    1649             :                                                             this->CondOutletNodeNum,
    1650             :                                                             this->QCondenser,
    1651             :                                                             this->CondInletTemp,
    1652             :                                                             this->CondOutletTemp,
    1653             :                                                             this->CondMassFlowRate,
    1654             :                                                             FirstHVACIteration);
    1655             :     }
    1656      501738 : }
    1657             : 
    1658          70 : void ASHRAE205ChillerSpecs::getDesignCapacities(
    1659             :     [[maybe_unused]] EnergyPlusData &state, const PlantLocation &calledFromLocation, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad)
    1660             : {
    1661          70 :     if (calledFromLocation.loopNum == this->CWPlantLoc.loopNum) {
    1662          50 :         MinLoad = this->Representation->performance.performance_map_cooling
    1663          50 :                       .calculate_performance(this->EvapVolFlowRate,
    1664          25 :                                              this->TempRefEvapOut + DataGlobalConstants::KelvinConv,
    1665             :                                              this->CondVolFlowRate,
    1666          25 :                                              this->TempRefCondIn + DataGlobalConstants::KelvinConv,
    1667          25 :                                              this->MinSequenceNumber,
    1668         100 :                                              this->InterpolationType)
    1669          25 :                       .net_evaporator_capacity;
    1670          25 :         MaxLoad = this->RefCap;
    1671          25 :         OptLoad = MaxLoad;
    1672             :     } else {
    1673          45 :         MinLoad = 0.0;
    1674          45 :         MaxLoad = 0.0;
    1675          45 :         OptLoad = 0.0;
    1676             :     }
    1677          70 : }
    1678             : 
    1679        2313 : } // namespace EnergyPlus::ChillerElectricASHRAE205

Generated by: LCOV version 1.13