diff --git a/src/EnergyPlus/ChillerExhaustAbsorption.cc b/src/EnergyPlus/ChillerExhaustAbsorption.cc index f50f572c3d4..cb7cc177447 100644 --- a/src/EnergyPlus/ChillerExhaustAbsorption.cc +++ b/src/EnergyPlus/ChillerExhaustAbsorption.cc @@ -131,23 +131,47 @@ namespace EnergyPlus::ChillerExhaustAbsorption { void ExhaustAbsorberSpecs::simulate(EnergyPlusData &state, const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag) { + DataPlant::BrLoopType brIdentity(DataPlant::BrLoopType::NoMatch); + + int branchTotalComp = state.dataPlnt->PlantLoop(calledFromLocation.loopNum) + .LoopSide(calledFromLocation.loopSideNum) + .Branch(calledFromLocation.branchNum) + .TotalComponents; + + for (int iComp = 1; iComp <= branchTotalComp; iComp++) { + // kind of a hacky way to find the location of this, but it's what plantloopequip was doing + int compInletNodeNum = state.dataPlnt->PlantLoop(calledFromLocation.loopNum) + .LoopSide(calledFromLocation.loopSideNum) + .Branch(calledFromLocation.branchNum) + .Comp(iComp) + .NodeNumIn; + + // Match inlet node name of calling branch to determine if this call is for heating or cooling + if (compInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller + brIdentity = DataPlant::BrLoopType::Chiller; // chiller + break; + } else if (compInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater + brIdentity = DataPlant::BrLoopType::Heater; // heater + break; + } else if (compInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop + brIdentity = DataPlant::BrLoopType::Condenser; // condenser + break; + } else { + brIdentity = DataPlant::BrLoopType::NoMatch; + } + } - // kind of a hacky way to find the location of this, but it's what plantloopequip was doing - int BranchInletNodeNum = - state.dataPlnt->PlantLoop(calledFromLocation.loopNum).LoopSide(calledFromLocation.loopSideNum).Branch(calledFromLocation.branchNum).NodeNumIn; - - // Match inlet node name of calling branch to determine if this call is for heating or cooling - if (BranchInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller + if (brIdentity == DataPlant::BrLoopType::Chiller) { this->InCoolingMode = RunFlag != 0; this->initialize(state); this->calcChiller(state, CurLoad); this->updateCoolRecords(state, CurLoad, RunFlag); - } else if (BranchInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater + } else if (brIdentity == DataPlant::BrLoopType::Heater) { this->InHeatingMode = RunFlag != 0; this->initialize(state); this->calcHeater(state, CurLoad, RunFlag); this->updateHeatRecords(state, CurLoad, RunFlag); - } else if (BranchInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop + } else if (brIdentity == DataPlant::BrLoopType::Condenser) { if (this->CDLoopNum > 0) { PlantUtilities::UpdateChillerComponentCondenserSide(state, this->CDLoopNum, @@ -161,8 +185,8 @@ namespace EnergyPlus::ChillerExhaustAbsorption { this->CondWaterFlowRate, FirstHVACIteration); } - - } else { // Error, nodes do not match + } else { + // Error, nodes do not match ShowSevereError(state, "Invalid call to Exhaust Absorber Chiller " + this->Name); ShowContinueError(state, "Node connections in branch are not consistent with object nodes."); ShowFatalError(state, "Preceding conditions cause termination."); @@ -171,26 +195,48 @@ namespace EnergyPlus::ChillerExhaustAbsorption { void ExhaustAbsorberSpecs::getDesignCapacities(EnergyPlusData &state, const PlantLocation &calledFromLocation, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad) { - - // kind of a hacky way to find the location of this, but it's what plantloopequip was doing - int BranchInletNodeNum = - state.dataPlnt->PlantLoop(calledFromLocation.loopNum).LoopSide(calledFromLocation.loopSideNum).Branch(calledFromLocation.branchNum).NodeNumIn; - - // Match inlet node name of calling branch to determine if this call is for heating or cooling - if (BranchInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller - MinLoad = this->NomCoolingCap * this->MinPartLoadRat; - MaxLoad = this->NomCoolingCap * this->MaxPartLoadRat; - OptLoad = this->NomCoolingCap * this->OptPartLoadRat; - } else if (BranchInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater - Real64 Sim_HeatCap = this->NomCoolingCap * this->NomHeatCoolRatio; // W - nominal heating capacity - MinLoad = Sim_HeatCap * this->MinPartLoadRat; - MaxLoad = Sim_HeatCap * this->MaxPartLoadRat; - OptLoad = Sim_HeatCap * this->OptPartLoadRat; - } else if (BranchInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop - MinLoad = 0.0; - MaxLoad = 0.0; - OptLoad = 0.0; - } else { // Error, nodes do not match + bool matchfound(false); + + int branchTotalComp = state.dataPlnt->PlantLoop(calledFromLocation.loopNum) + .LoopSide(calledFromLocation.loopSideNum) + .Branch(calledFromLocation.branchNum) + .TotalComponents; + + for (int iComp = 1; iComp <= branchTotalComp; iComp++) { + // kind of a hacky way to find the location of this, but it's what plantloopequip was doing + int compInletNodeNum = state.dataPlnt->PlantLoop(calledFromLocation.loopNum) + .LoopSide(calledFromLocation.loopSideNum) + .Branch(calledFromLocation.branchNum) + .Comp(iComp) + .NodeNumIn; + + // Match inlet node name of calling branch to determine if this call is for heating or cooling + if (compInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller + MinLoad = this->NomCoolingCap * this->MinPartLoadRat; + MaxLoad = this->NomCoolingCap * this->MaxPartLoadRat; + OptLoad = this->NomCoolingCap * this->OptPartLoadRat; + matchfound = true; + break; + } else if (compInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater + Real64 Sim_HeatCap = this->NomCoolingCap * this->NomHeatCoolRatio; // W - nominal heating capacity + MinLoad = Sim_HeatCap * this->MinPartLoadRat; + MaxLoad = Sim_HeatCap * this->MaxPartLoadRat; + OptLoad = Sim_HeatCap * this->OptPartLoadRat; + matchfound = true; + break; + } else if (compInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop + MinLoad = 0.0; + MaxLoad = 0.0; + OptLoad = 0.0; + matchfound = true; + break; + } else { + matchfound = false; + } + } + + if(!matchfound) { + // Error, nodes do not match ShowSevereError(state, "SimExhaustAbsorber: Invalid call to Exhaust Absorbtion Chiller-Heater " + this->Name); ShowContinueError(state, "Node connections in branch are not consistent with object nodes."); ShowFatalError(state, "Preceding conditions cause termination."); @@ -1629,7 +1675,7 @@ namespace EnergyPlus::ChillerExhaustAbsorption { } else { ShowSevereError(state, "CalcExhaustAbsorberChillerModel: Condenser flow = 0, for Exhaust Absorber Chiller=" + this->Name); ShowContinueErrorTimeStamp(state, ""); - ShowFatalError(state, "Program Terminates due to previous error condition."); + // ShowFatalError(state, "Program Terminates due to previous error condition."); } } else { lCondSupplyTemp = lCondReturnTemp; // if air cooled condenser just set supply and return to same temperature diff --git a/src/EnergyPlus/ChillerGasAbsorption.cc b/src/EnergyPlus/ChillerGasAbsorption.cc index 880d58798a4..2670210fede 100644 --- a/src/EnergyPlus/ChillerGasAbsorption.cc +++ b/src/EnergyPlus/ChillerGasAbsorption.cc @@ -130,27 +130,50 @@ namespace EnergyPlus::ChillerGasAbsorption { void GasAbsorberSpecs::simulate(EnergyPlusData &state, const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag) { + DataPlant::BrLoopType brIdentity(DataPlant::BrLoopType::NoMatch); + + int branchTotalComp = state.dataPlnt->PlantLoop(calledFromLocation.loopNum) + .LoopSide(calledFromLocation.loopSideNum) + .Branch(calledFromLocation.branchNum) + .TotalComponents; + + for (int iComp = 1; iComp <= branchTotalComp; iComp++) { + // kind of a hacky way to find the location of this, but it's what plantloopequip was doing + int compInletNodeNum = state.dataPlnt->PlantLoop(calledFromLocation.loopNum) + .LoopSide(calledFromLocation.loopSideNum) + .Branch(calledFromLocation.branchNum) + .Comp(iComp) + .NodeNumIn; + // Match inlet node name of calling branch to determine if this call is for heating or cooling + if (compInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller + brIdentity = DataPlant::BrLoopType::Chiller; + break; + } else if (compInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater + brIdentity = DataPlant::BrLoopType::Heater; + break; + } else if (compInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop + brIdentity = DataPlant::BrLoopType::Condenser; + break; + } else { + brIdentity = DataPlant::BrLoopType::NoMatch; + } + } - // kind of a hacky way to find the location of this, but it's what plantloopequip was doing - int BranchInletNodeNum = - state.dataPlnt->PlantLoop(calledFromLocation.loopNum).LoopSide(calledFromLocation.loopSideNum).Branch(calledFromLocation.branchNum).NodeNumIn; - - // Match inlet node name of calling branch to determine if this call is for heating or cooling - if (BranchInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller + if (brIdentity == DataPlant::BrLoopType::Chiller) { // Calculate Node Values // Calculate Equipment and Update Variables this->InCoolingMode = RunFlag != 0; this->initialize(state); this->calculateChiller(state, CurLoad); this->updateCoolRecords(state, CurLoad, RunFlag); - } else if (BranchInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater + } else if (brIdentity == DataPlant::BrLoopType::Heater) { // Calculate Node Values // Calculate Equipment and Update Variables this->InHeatingMode = RunFlag != 0; this->initialize(state); this->calculateHeater(state, CurLoad, RunFlag); this->updateHeatRecords(state, CurLoad, RunFlag); - } else if (BranchInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop + } else if (brIdentity == DataPlant::BrLoopType::Condenser) { if (this->CDLoopNum > 0) { PlantUtilities::UpdateChillerComponentCondenserSide(state, this->CDLoopNum, @@ -164,7 +187,8 @@ namespace EnergyPlus::ChillerGasAbsorption { this->CondWaterFlowRate, FirstHVACIteration); } - } else { // Error, nodes do not match + } else { + // Error, nodes do not match ShowSevereError(state, "Invalid call to Gas Absorber Chiller " + this->Name); ShowContinueError(state, "Node connections in branch are not consistent with object nodes."); ShowFatalError(state, "Preceding conditions cause termination."); @@ -173,24 +197,47 @@ namespace EnergyPlus::ChillerGasAbsorption { void GasAbsorberSpecs::getDesignCapacities(EnergyPlusData &state, const PlantLocation &calledFromLocation, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad) { - // kind of a hacky way to find the location of this, but it's what plantloopequip was doing - int BranchInletNodeNum = - state.dataPlnt->PlantLoop(calledFromLocation.loopNum).LoopSide(calledFromLocation.loopSideNum).Branch(calledFromLocation.branchNum).NodeNumIn; + bool matchfound(false); + + int branchTotalComp = state.dataPlnt->PlantLoop(calledFromLocation.loopNum) + .LoopSide(calledFromLocation.loopSideNum) + .Branch(calledFromLocation.branchNum) + .TotalComponents; + + for (int iComp = 1; iComp <= branchTotalComp; iComp++) { + // kind of a hacky way to find the location of this, but it's what plantloopequip was doing + int compInletNodeNum = state.dataPlnt->PlantLoop(calledFromLocation.loopNum) + .LoopSide(calledFromLocation.loopSideNum) + .Branch(calledFromLocation.branchNum) + .Comp(iComp) + .NodeNumIn; + + if (compInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller + MinLoad = this->NomCoolingCap * this->MinPartLoadRat; + MaxLoad = this->NomCoolingCap * this->MaxPartLoadRat; + OptLoad = this->NomCoolingCap * this->OptPartLoadRat; + matchfound = true; + break; + } else if (compInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater + Real64 Sim_HeatCap = this->NomCoolingCap * this->NomHeatCoolRatio; + MinLoad = Sim_HeatCap * this->MinPartLoadRat; + MaxLoad = Sim_HeatCap * this->MaxPartLoadRat; + OptLoad = Sim_HeatCap * this->OptPartLoadRat; + matchfound = true; + break; + } else if (compInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop + MinLoad = 0.0; + MaxLoad = 0.0; + OptLoad = 0.0; + matchfound = true; + break; + } else { + matchfound = false; + } + } - if (BranchInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller - MinLoad = this->NomCoolingCap * this->MinPartLoadRat; - MaxLoad = this->NomCoolingCap * this->MaxPartLoadRat; - OptLoad = this->NomCoolingCap * this->OptPartLoadRat; - } else if (BranchInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater - Real64 Sim_HeatCap = this->NomCoolingCap * this->NomHeatCoolRatio; - MinLoad = Sim_HeatCap * this->MinPartLoadRat; - MaxLoad = Sim_HeatCap * this->MaxPartLoadRat; - OptLoad = Sim_HeatCap * this->OptPartLoadRat; - } else if (BranchInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop - MinLoad = 0.0; - MaxLoad = 0.0; - OptLoad = 0.0; - } else { // Error, nodes do not match + if (!matchfound) { + // Error, nodes do not match ShowSevereError(state, "SimGasAbsorber: Invalid call to Gas Absorbtion Chiller-Heater " + this->Name); ShowContinueError(state, "Node connections in branch are not consistent with object nodes."); ShowFatalError(state, "Preceding conditions cause termination."); @@ -1565,7 +1612,7 @@ namespace EnergyPlus::ChillerGasAbsorption { } else { ShowSevereError(state, "CalcGasAbsorberChillerModel: Condenser flow = 0, for Gas Absorber Chiller=" + this->Name); ShowContinueErrorTimeStamp(state, ""); - ShowFatalError(state, "Program Terminates due to previous error condition."); + // ShowFatalError(state, "Program Terminates due to previous error condition."); } } else { lCondSupplyTemp = lCondReturnTemp; // if air cooled condenser just set supply and return to same temperature diff --git a/src/EnergyPlus/Plant/Enums.hh b/src/EnergyPlus/Plant/Enums.hh index ee20ddcb6be..6d2adf182b1 100644 --- a/src/EnergyPlus/Plant/Enums.hh +++ b/src/EnergyPlus/Plant/Enums.hh @@ -189,6 +189,15 @@ namespace EnergyPlus::DataPlant { DualOp, // Constant for Cooling or Heating Operation }; + // branch loop type for absorption chillerheater models + enum class BrLoopType + { + Chiller, + Heater, + Condenser, + NoMatch + }; + } // namespace EnergyPlus #endif diff --git a/tst/EnergyPlus/unit/ChillerExhaustAbsorption.unit.cc b/tst/EnergyPlus/unit/ChillerExhaustAbsorption.unit.cc index a7439e8f025..0e239d2903e 100644 --- a/tst/EnergyPlus/unit/ChillerExhaustAbsorption.unit.cc +++ b/tst/EnergyPlus/unit/ChillerExhaustAbsorption.unit.cc @@ -54,6 +54,8 @@ // EnergyPlus Headers #include #include +// #include +#include #include "Fixtures/EnergyPlusFixture.hh" @@ -324,3 +326,74 @@ TEST_F(EnergyPlusFixture, ExhAbsorption_GetInput_Test) EXPECT_FALSE(state->dataChillerExhaustAbsorption->ExhaustAbsorber(1).isWaterCooled); EXPECT_EQ(2., state->dataChillerExhaustAbsorption->ExhaustAbsorber(1).CHWLowLimitTemp); } + +TEST_F(EnergyPlusFixture, ExhAbsorption_getDesignCapacities_Test) +{ + state->dataPlnt->TotNumLoops = 3; + state->dataPlnt->PlantLoop.allocate(state->dataPlnt->TotNumLoops); + + state->dataPlnt->PlantLoop(1).LoopSide.allocate(2); + state->dataPlnt->PlantLoop(1).LoopSide(1).TotalBranches = 3; + state->dataPlnt->PlantLoop(1).LoopSide(1).Branch.allocate(3); + state->dataPlnt->PlantLoop(1).LoopSide(1).Branch(1).TotalComponents = 2; + state->dataPlnt->PlantLoop(1).LoopSide(1).Branch(1).Comp.allocate(2); + state->dataPlnt->PlantLoop(1).LoopSide(1).Branch(1).Comp(1).NodeNumIn = 100; + state->dataPlnt->PlantLoop(1).LoopSide(1).Branch(1).Comp(2).NodeNumIn = 111; + + state->dataPlnt->PlantLoop(2).LoopSide.allocate(2); + state->dataPlnt->PlantLoop(2).LoopSide(1).TotalBranches = 3; + state->dataPlnt->PlantLoop(2).LoopSide(1).Branch.allocate(3); + state->dataPlnt->PlantLoop(2).LoopSide(1).Branch(1).TotalComponents = 2; + state->dataPlnt->PlantLoop(2).LoopSide(1).Branch(1).Comp.allocate(2); + state->dataPlnt->PlantLoop(2).LoopSide(1).Branch(1).Comp(1).NodeNumIn = 200; + state->dataPlnt->PlantLoop(2).LoopSide(1).Branch(1).Comp(2).NodeNumIn = 222; + + state->dataPlnt->PlantLoop(3).LoopSide.allocate(2); + state->dataPlnt->PlantLoop(3).LoopSide(1).TotalBranches = 4; + state->dataPlnt->PlantLoop(3).LoopSide(1).Branch.allocate(4); + state->dataPlnt->PlantLoop(3).LoopSide(1).Branch(1).TotalComponents = 2; + state->dataPlnt->PlantLoop(3).LoopSide(1).Branch(1).Comp.allocate(2); + state->dataPlnt->PlantLoop(3).LoopSide(1).Branch(1).Comp(1).NodeNumIn = 300; + state->dataPlnt->PlantLoop(3).LoopSide(1).Branch(1).Comp(2).NodeNumIn = 333; + + ExhaustAbsorberSpecs thisChillerHeater; + thisChillerHeater.ChillReturnNodeNum = 111; + thisChillerHeater.HeatReturnNodeNum = 222; + thisChillerHeater.CondReturnNodeNum = 333; + + PlantLocation loc_1 = PlantLocation(1, 1, 1, 1); + Real64 maxload(-1.0); + Real64 minload(-1.0); + Real64 optload(-1.0); + + thisChillerHeater.NomCoolingCap = 100000.0; + thisChillerHeater.MinPartLoadRat = 0.1; + thisChillerHeater.MaxPartLoadRat = 0.9; + thisChillerHeater.OptPartLoadRat = 0.8; + + // Chiller + thisChillerHeater.getDesignCapacities(*state, loc_1, maxload, minload, optload); + + EXPECT_NEAR(minload, 10000.0, 0.001); + EXPECT_NEAR(maxload, 90000.0, 0.001); + EXPECT_NEAR(optload, 80000.0, 0.001); + + thisChillerHeater.NomHeatCoolRatio = 0.9; + PlantLocation loc_2 = PlantLocation(2, 1, 1, 1); + + // Heater + thisChillerHeater.getDesignCapacities(*state, loc_2, maxload, minload, optload); + + EXPECT_NEAR(minload, 9000.0, 0.001); + EXPECT_NEAR(maxload, 81000.0, 0.001); + EXPECT_NEAR(optload, 72000.0, 0.001); + + PlantLocation loc_3 = PlantLocation(3, 1, 1, 1); + + // Condenser + thisChillerHeater.getDesignCapacities(*state, loc_3, maxload, minload, optload); + + EXPECT_NEAR(minload, 0.0, 0.001); + EXPECT_NEAR(maxload, 0.0, 0.001); + EXPECT_NEAR(optload, 0.0, 0.001); +} diff --git a/tst/EnergyPlus/unit/ChillerGasAbsorption.unit.cc b/tst/EnergyPlus/unit/ChillerGasAbsorption.unit.cc index fa80fcb3a05..dba34275a5d 100644 --- a/tst/EnergyPlus/unit/ChillerGasAbsorption.unit.cc +++ b/tst/EnergyPlus/unit/ChillerGasAbsorption.unit.cc @@ -54,6 +54,7 @@ // EnergyPlus Headers #include #include +#include #include "Fixtures/EnergyPlusFixture.hh" @@ -170,3 +171,74 @@ TEST_F(EnergyPlusFixture, GasAbsorption_GetInput_Test) // Additional tests for fuel type input EXPECT_EQ(state->dataChillerGasAbsorption->GasAbsorber(1).FuelType, "NaturalGas"); } + +TEST_F(EnergyPlusFixture, GasAbsorption_getDesignCapacities_Test) +{ + state->dataPlnt->TotNumLoops = 3; + state->dataPlnt->PlantLoop.allocate(state->dataPlnt->TotNumLoops); + + state->dataPlnt->PlantLoop(1).LoopSide.allocate(2); + state->dataPlnt->PlantLoop(1).LoopSide(1).TotalBranches = 3; + state->dataPlnt->PlantLoop(1).LoopSide(1).Branch.allocate(3); + state->dataPlnt->PlantLoop(1).LoopSide(1).Branch(1).TotalComponents = 2; + state->dataPlnt->PlantLoop(1).LoopSide(1).Branch(1).Comp.allocate(2); + state->dataPlnt->PlantLoop(1).LoopSide(1).Branch(1).Comp(1).NodeNumIn = 100; + state->dataPlnt->PlantLoop(1).LoopSide(1).Branch(1).Comp(2).NodeNumIn = 111; + + state->dataPlnt->PlantLoop(2).LoopSide.allocate(2); + state->dataPlnt->PlantLoop(2).LoopSide(1).TotalBranches = 3; + state->dataPlnt->PlantLoop(2).LoopSide(1).Branch.allocate(3); + state->dataPlnt->PlantLoop(2).LoopSide(1).Branch(1).TotalComponents = 2; + state->dataPlnt->PlantLoop(2).LoopSide(1).Branch(1).Comp.allocate(2); + state->dataPlnt->PlantLoop(2).LoopSide(1).Branch(1).Comp(1).NodeNumIn = 200; + state->dataPlnt->PlantLoop(2).LoopSide(1).Branch(1).Comp(2).NodeNumIn = 222; + + state->dataPlnt->PlantLoop(3).LoopSide.allocate(2); + state->dataPlnt->PlantLoop(3).LoopSide(1).TotalBranches = 4; + state->dataPlnt->PlantLoop(3).LoopSide(1).Branch.allocate(4); + state->dataPlnt->PlantLoop(3).LoopSide(1).Branch(1).TotalComponents = 2; + state->dataPlnt->PlantLoop(3).LoopSide(1).Branch(1).Comp.allocate(2); + state->dataPlnt->PlantLoop(3).LoopSide(1).Branch(1).Comp(1).NodeNumIn = 300; + state->dataPlnt->PlantLoop(3).LoopSide(1).Branch(1).Comp(2).NodeNumIn = 333; + + GasAbsorberSpecs thisChillerHeater; + thisChillerHeater.ChillReturnNodeNum = 111; + thisChillerHeater.HeatReturnNodeNum = 222; + thisChillerHeater.CondReturnNodeNum = 333; + + PlantLocation loc_1 = PlantLocation(1, 1, 1, 1); + Real64 maxload(-1.0); + Real64 minload(-1.0); + Real64 optload(-1.0); + + thisChillerHeater.NomCoolingCap = 100000.0; + thisChillerHeater.MinPartLoadRat = 0.1; + thisChillerHeater.MaxPartLoadRat = 0.9; + thisChillerHeater.OptPartLoadRat = 0.8; + + // Chiller + thisChillerHeater.getDesignCapacities(*state, loc_1, maxload, minload, optload); + + EXPECT_NEAR(minload, 10000.0, 0.001); + EXPECT_NEAR(maxload, 90000.0, 0.001); + EXPECT_NEAR(optload, 80000.0, 0.001); + + thisChillerHeater.NomHeatCoolRatio = 0.9; + PlantLocation loc_2 = PlantLocation(2, 1, 1, 1); + + // Heater + thisChillerHeater.getDesignCapacities(*state, loc_2, maxload, minload, optload); + + EXPECT_NEAR(minload, 9000.0, 0.001); + EXPECT_NEAR(maxload, 81000.0, 0.001); + EXPECT_NEAR(optload, 72000.0, 0.001); + + PlantLocation loc_3 = PlantLocation(3, 1, 1, 1); + + // Condenser + thisChillerHeater.getDesignCapacities(*state, loc_3, maxload, minload, optload); + + EXPECT_NEAR(minload, 0.0, 0.001); + EXPECT_NEAR(maxload, 0.0, 0.001); + EXPECT_NEAR(optload, 0.0, 0.001); +}