Skip to content

Commit

Permalink
Apply changes to ReformulatedEIR chiller and remove dedicated input f…
Browse files Browse the repository at this point in the history
…or dT.
  • Loading branch information
lymereJ committed Jun 2, 2024
1 parent eddc95d commit 426036c
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 68 deletions.
49 changes: 39 additions & 10 deletions idd/Energy+.idd.in
Original file line number Diff line number Diff line change
Expand Up @@ -73383,21 +73383,13 @@ Chiller:Electric:EIR,
\note PLR is the chilled water plant loop part load ratio (actual/design)
\type object-list
\object-list UnivariateFunctions
N19, \field Temperature Difference Across Condenser
\type real
\units C
\minimum 2.0
\default 15.0
\note The temperature difference across the condenser. This input is used to calculate the condenser flow
\note request.This input is only used when "Condenser Flow Control" is set to
\note "ModulatedDeltaTemperature".
A20, \field Temperature Difference Across Condenser Schedule Name
\note A schedule that defines the temperature difference across the condenser. This input is used to
\note calculate the condenser flow. This input is only used when "Condenser Flow Control" is set to
\note "ModulatedDeltaTemperature".
\type object-list
\object-list ScheduleNames
N20; \field Condenser Minimum Flow Fraction
N19; \field Condenser Minimum Flow Fraction
\note This input corresponds to the minimum flow fraction to be simulated. The minimum condenser flow
\note corresponds to this fraction multiplied by the maximum condenser flow rate. This input is only used
\note when the "Condenser Flow Control" input is set to "ModulatedChillerPLR", "ModulatedLoopPLR" or
Expand Down Expand Up @@ -73595,11 +73587,48 @@ Chiller:Electric:ReformulatedEIR,
\note Using this triggers a model more suited to series bundle and chillers with higher temperature heat recovery
\note If this field is not used, the bundles are modeled as being in parallel
\type node
A15; \field End-Use Subcategory
A15, \field End-Use Subcategory
\note Any text may be used here to categorize the end-uses in the ABUPS End Uses by Subcategory table.
\type alpha
\retaincase
\default General
A16, \field Condenser Flow Control
\note Select the chiller condenser flow request mode. With "ConstantFlow" a chiller will always request
\note its maximum condenser flow rate. With "ModulatedChillerPLR" the condenser flow request corresponds
\note to the chiller part load ratio multiplied by the chiller maximum condenser flow rate. With
\note "ModulatedLoopPLR" the chiller will request a flow rate that is function of the chilled water
\note loop's part load ratio, see the "Condenser Loop Flow Rate Fraction Function of Loop Part Load Ratio
\note Curve Name" input. With "ModulatedDeltaTemperature" the chiller will request the flow rate required to meet
\note the condenser loop load based on the condenser leaving fluid temperature and a reference temperature,
\note see the "Temperature Difference Across Condenser" and "Temperature Difference Across Condenser Schedule
\note Name" input.
\note Use "ConstantFlow" when modeling a constant flow condenser plant loop, choose one of the other inputs
\note when modeling a variable flow condenser plant loop.
\key ConstantFlow
\key ModulatedChillerPLR
\key ModulatedLoopPLR
\key ModulatedDeltaTemperature
\default ConstantFlow
A17, \field Condenser Loop Flow Rate Fraction Function of Loop Part Load Ratio Curve Name
\note Condenser loop flow rate fraction as a function of loop part load ratio
\note CWFR = C * PLR + D
\note Where:
\note CWFR is the condenser water flow fraction (actual/design)
\note C and D are coefficients, see "Optimizing Design & Control Of Chilled Water Plants, Part 5", S. Taylor, ASHRAE Journal June 2012
\note PLR is the chilled water plant loop part load ratio (actual/design)
\type object-list
\object-list UnivariateFunctions
A19, \field Temperature Difference Across Condenser Schedule Name
\note A schedule that defines the temperature difference across the condenser. This input is used to
\note calculate the condenser flow. This input is only used when "Condenser Flow Control" is set to
\note "ModulatedDeltaTemperature".
\type object-list
\object-list ScheduleNames
N16; \field Condenser Minimum Flow Fraction
\note This input corresponds to the minimum flow fraction to be simulated. The minimum condenser flow
\note corresponds to this fraction multiplied by the maximum condenser flow rate. This input is only used
\note when the "Condenser Flow Control" input is set to "ModulatedChillerPLR", "ModulatedLoopPLR" or
\note "ModulatedDeltaTemperature".

Chiller:Electric,
\min-fields 27
Expand Down
17 changes: 1 addition & 16 deletions src/EnergyPlus/ChillerElectricEIR.cc
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ void GetElectricEIRChillerInput(EnergyPlusData &state)
if (thisChiller.CondenserFlowControl == DataPlant::CondenserFlowControl::Invalid) {
ShowSevereError(state,
format("{}{}=\"{}\",", RoutineName, state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(10), state.dataIPShortCut->cAlphaArgs(10)));
ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(17), state.dataIPShortCut->cAlphaArgs(17)));
ShowContinueError(state, "Available choices are ConstantFlow, ModulatedChillerPLR, ModulatedLoopPLR, or ModulatedDeltaTemperature");
ShowContinueError(state, "Flow mode ConstantFlow is assumed and the simulation continues.");
thisChiller.CondenserFlowControl = DataPlant::CondenserFlowControl::ConstantFlow;
Expand All @@ -685,12 +685,6 @@ void GetElectricEIRChillerInput(EnergyPlusData &state)
ErrorsFound = true;
}

if (NumNums > 18) {
thisChiller.CondDT = state.dataIPShortCut->rNumericArgs(19);
} else {
thisChiller.CondDT = 0.0;
}

if (NumAlphas > 18) {
if (!state.dataIPShortCut->lAlphaFieldBlanks(19)) {
thisChiller.CondDTScheduleNum = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(19));
Expand Down Expand Up @@ -2418,15 +2412,6 @@ void ElectricEIRChillerSpecs::calculate(EnergyPlusData &state, Real64 &MyLoad, b
PlantUtilities::SetComponentFlowRate(state, this->CondMassFlowRate, this->CondInletNodeNum, this->CondOutletNodeNum, this->CDPlantLoc);
PlantUtilities::PullCompInterconnectTrigger(
state, this->CWPlantLoc, this->CondMassFlowIndex, this->CDPlantLoc, DataPlant::CriteriaType::MassFlowRate, this->CondMassFlowRate);

if (this->CondMassFlowRate < DataBranchAirLoopPlant::MassFlowTolerance) {
if (this->EvapMassFlowRate < DataBranchAirLoopPlant::MassFlowTolerance) {
// Use PlantUtilities::SetComponentFlowRate to decide actual flow
PlantUtilities::SetComponentFlowRate(
state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
}
return;
}
}

if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
Expand Down
119 changes: 117 additions & 2 deletions src/EnergyPlus/ChillerReformulatedEIR.cc
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,59 @@ void GetElecReformEIRChillerInput(EnergyPlusData &state)
} else {
thisChiller.EndUseSubcategory = "General";
}

if (NumAlphas > 15) {
thisChiller.CondenserFlowControl = static_cast<DataPlant::CondenserFlowControl>(
getEnumValue(DataPlant::CondenserFlowControlNamesUC, state.dataIPShortCut->cAlphaArgs(16)));
} else {
thisChiller.CondenserFlowControl = DataPlant::CondenserFlowControl::ConstantFlow;
}

if (thisChiller.CondenserFlowControl == DataPlant::CondenserFlowControl::Invalid) {
ShowSevereError(state,
format("{}{}=\"{}\",", RoutineName, state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(16), state.dataIPShortCut->cAlphaArgs(16)));
ShowContinueError(state, "Available choices are ConstantFlow, ModulatedChillerPLR, ModulatedLoopPLR, or ModulatedDeltaTemperature");
ShowContinueError(state, "Flow mode ConstantFlow is assumed and the simulation continues.");
thisChiller.CondenserFlowControl = DataPlant::CondenserFlowControl::ConstantFlow;
ErrorsFound = true;
};

if (NumAlphas > 16) {
thisChiller.ChillerCondLoopFlowFLoopPLRIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(17));
} else {
thisChiller.ChillerCondLoopFlowFLoopPLRIndex = 0;
}
if ((thisChiller.ChillerCondLoopFlowFLoopPLRIndex == 0) &&
(thisChiller.CondenserFlowControl == DataPlant::CondenserFlowControl::ModulatedLoopPLR)) {
ShowSevereError(state,
format("{}{} \"{}\"", RoutineName, state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(17), state.dataIPShortCut->cAlphaArgs(17)));
ErrorsFound = true;
}

if (NumAlphas > 17) {
if (!state.dataIPShortCut->lAlphaFieldBlanks(18)) {
thisChiller.CondDTScheduleNum = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(18));
if (thisChiller.CondDTScheduleNum == 0) {
ShowSevereError(
state, format("{}{}=\"{}\"", RoutineName, state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
ShowContinueError(state,
format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(18), state.dataIPShortCut->cAlphaArgs(18)));
ErrorsFound = true;
}
} else {
thisChiller.CondDTScheduleNum = 0;
}
} else {
thisChiller.CondDTScheduleNum = 0;
}

if (NumNums > 16) {
thisChiller.MinCondFlowRatio = state.dataIPShortCut->rNumericArgs(17);
} else {
thisChiller.MinCondFlowRatio = 0.2;
}
}

if (ErrorsFound) {
Expand Down Expand Up @@ -2076,8 +2129,7 @@ void ReformulatedEIRChillerSpecs::calculate(EnergyPlusData &state, Real64 &MyLoa
ReferenceCOP = ReferenceCOP_ff * this->FaultyChillerFoulingFactor;
}

// Set mass flow rates

// Set initial mass flow rates
if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
this->CondMassFlowRate = this->CondMassFlowRateMax;
PlantUtilities::SetComponentFlowRate(state, this->CondMassFlowRate, this->CondInletNodeNum, this->CondOutletNodeNum, this->CDPlantLoc);
Expand Down Expand Up @@ -2439,6 +2491,69 @@ void ReformulatedEIRChillerSpecs::calculate(EnergyPlusData &state, Real64 &MyLoa

this->QCondenser = this->Power * this->CompPowerToCondenserFrac + this->QEvaporator + this->ChillerFalseLoadRate;

// set condenser mass flow rate
if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
switch (this->CondenserFlowControl) {
case DataPlant::CondenserFlowControl::ConstantFlow: {
this->CondMassFlowRate = this->CondMassFlowRateMax;
} break;
case DataPlant::CondenserFlowControl::ModulatedChillerPLR: {
this->CondMassFlowRate = this->CondMassFlowRateMax * PartLoadRat;
} break;
case DataPlant::CondenserFlowControl::ModulatedLoopPLR: {
int PltSizNum = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).PlantSizNum;
int CondPltSizNum = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).PlantSizNum;
if (PltSizNum > 0 && CondPltSizNum > 0) {
Real64 chwLoopCap = state.dataSize->PlantSizData(PltSizNum).DesCapacity;
Real64 chwLoopDemand =
std::abs(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).LoopSide(this->CWPlantLoc.loopSideNum).UpdatedDemandToLoopSetPoint);
Real64 cwhLoopPLR = 0.0;
if (chwLoopDemand > 0) {
cwhLoopPLR = chwLoopDemand / chwLoopCap;
}
Real64 condWaterFlowFrac = Curve::CurveValue(state, this->ChillerCondLoopFlowFLoopPLRIndex, cwhLoopPLR);
Real64 cwLoopDesVolFlowRate = state.dataSize->PlantSizData(CondPltSizNum).DesVolFlowRate;
Real64 cwLoopVolFlowRate = condWaterFlowFrac * cwLoopDesVolFlowRate;
Real64 rho = FluidProperties::GetDensityGlycol(state,
state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).FluidName,
this->TempRefCondIn,
state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).FluidIndex,
RoutineName);
if (chwLoopDemand > 0) {
this->CondMassFlowRate = cwLoopVolFlowRate * rho * this->QEvaporator / chwLoopDemand;
} else {
this->CondMassFlowRate = 0.0;
}
} else {
ShowFatalError(state,
"CalcElectricEIRChillerModel: The ModulatedLoopPLR condenser flow control requires a Sizing:Plant object for "
"both loops connected to the condenser and evaporator of the chiller.");
}
} break;
case DataPlant::CondenserFlowControl::ModulatedDeltaTemperature: {
Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidName,
Constant::CWInitConvTemp,
state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).FluidIndex,
RoutineName);
Real64 condDT = 0.0;
if (this->CondDTScheduleNum > 0) {
condDT = ScheduleManager::GetCurrentScheduleValue(state, this->CondDTScheduleNum);
} else {
condDT = this->CondDT;
}
this->CondMassFlowRate = this->QCondenser / (Cp * condDT);
} break;
default: {
this->CondMassFlowRate = this->CondMassFlowRateMax;
} break;
}
this->CondMassFlowRate = max(min(this->CondMassFlowRate, this->CondMassFlowRateMax), this->MinCondFlowRatio * this->CondMassFlowRateMax);
PlantUtilities::SetComponentFlowRate(state, this->CondMassFlowRate, this->CondInletNodeNum, this->CondOutletNodeNum, this->CDPlantLoc);
PlantUtilities::PullCompInterconnectTrigger(
state, this->CWPlantLoc, this->CondMassFlowIndex, this->CDPlantLoc, DataPlant::CriteriaType::MassFlowRate, this->CondMassFlowRate);
}

// Currently only water cooled chillers are allowed for the reformulated EIR chiller model
if (this->CondMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
// If Heat Recovery specified for this vapor compression chiller, then Qcondenser will be adjusted by this subroutine
Expand Down
Loading

5 comments on commit 426036c

@nrel-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var_speed_cond_ctrl (lymereJ) - Win64-Windows-10-VisualStudio-16: OK (2784 of 2784 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var_speed_cond_ctrl (lymereJ) - x86_64-MacOS-10.18-clang-15.0.0: OK (3565 of 3572 tests passed, 299 test warnings)

Messages:\n

  • 303 tests had: AUD diffs.
  • 302 tests had: EIO diffs.
  • 27 tests had: Table small diffs.
  • 7 tests had: Table big diffs.

Failures:\n

regression Test Summary

  • Passed: 780
  • Failed: 7

Build Badge Test Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var_speed_cond_ctrl (lymereJ) - x86_64-Linux-Ubuntu-22.04-gcc-11.4: OK (3606 of 3613 tests passed, 300 test warnings)

Messages:\n

  • 304 tests had: AUD diffs.
  • 303 tests had: EIO diffs.
  • 27 tests had: Table small diffs.
  • 7 tests had: Table big diffs.

Failures:\n

regression Test Summary

  • Passed: 800
  • Failed: 7

Build Badge Test Badge

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var_speed_cond_ctrl (lymereJ) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-IntegrationCoverage-Debug: OK (791 of 791 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-2c
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var_speed_cond_ctrl (lymereJ) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-UnitTestsCoverage-Debug: OK (1996 of 1996 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

Please sign in to comment.