Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct Use of Incorrect Index for VRF Cooling #10679

Merged
merged 6 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 54 additions & 42 deletions src/EnergyPlus/HVACVariableRefrigerantFlow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7921,50 +7921,27 @@ void SizeVRF(EnergyPlusData &state, int const VRFTUNum)
}

// initialize capacity sizing variables: cooling
SizingMethod = CoolingCapacitySizing;
// capacity sizing methods (HeatingDesignCapacity, CapacityPerFloorArea, FractionOfAutosizedCoolingCapacity, and
// FractionOfAutosizedHeatingCapacity )
int CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod;
EqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
if (CapSizingMethod == CoolingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
if (CapSizingMethod == HeatingDesignCapacity) {
if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity > 0.0) {
EqSizing.CoolingCapacity = true;
EqSizing.DesCoolingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
}
} else if (CapSizingMethod == CapacityPerFloorArea) {
EqSizing.CoolingCapacity = true;
EqSizing.DesCoolingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity *
state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
state.dataSize->DataScalableCapSizingON = true;
} else if (CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
state.dataSize->DataFracOfAutosizedCoolingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
state.dataSize->DataScalableCapSizingON = true;
}
}
initCapSizingVars(state,
CoolingCapacitySizing,
state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod,
EqSizing.SizingMethod(SizingMethod),
state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity,
EqSizing.CoolingCapacity,
EqSizing.DesCoolingLoad,
state.dataSize->DataScalableCapSizingON,
state.dataSize->DataFracOfAutosizedCoolingCapacity);

// initialize capacity sizing variables: heating
SizingMethod = HeatingCapacitySizing;
CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod;
EqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
if (CapSizingMethod == HeatingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
if (CapSizingMethod == HeatingDesignCapacity) {
if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity > 0.0) {
EqSizing.HeatingCapacity = true;
EqSizing.DesHeatingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
}
} else if (CapSizingMethod == CapacityPerFloorArea) {
EqSizing.HeatingCapacity = true;
EqSizing.DesHeatingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity *
state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
state.dataSize->DataScalableCapSizingON = true;
} else if (CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
state.dataSize->DataFracOfAutosizedHeatingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
state.dataSize->DataScalableCapSizingON = true;
}
}
initCapSizingVars(state,
HeatingCapacitySizing,
state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod,
EqSizing.SizingMethod(SizingMethod),
state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity,
EqSizing.HeatingCapacity,
EqSizing.DesHeatingLoad,
state.dataSize->DataScalableCapSizingON,
state.dataSize->DataFracOfAutosizedHeatingCapacity);

Copy link
Contributor

Choose a reason for hiding this comment

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

This will certainly avoid the cut-n-paste errors that caused this issue. Is there a chance that the other 12 parent objects will get this change (I searched for FractionOfAutosizedCoolingCapacity)? Or at the very least a new issue opened?

The remaining discussion is for future use.

Now to think outside the box even further... What is really needed is for this "scaling" code to be moved to the sizer class so it's in 1 place. So that each parent does not need this overhead. All the sizer code would need to know is state.dataHVACVarRefFlow->VRFTU(VRFTUNum).HVACSizingIndex. That is, of course, for another day. That said, maybe the arguments could be shortened to pass only the HVACSizingIndex? and a key?

initSizingVars(state, sizingMethod, HVACSizingIndex) 

where sizingMethod = CoolingAirFlowSizing, HeatingAirFlowSizing, CoolingCapacitySizing, or HeatingCapacitySizing (did I miss anything?). Maybe that's too much to ask for this issue but it's good to be thinking in that direction (for the sake of moving this to the sizing routines). In this future code I still want to be able to call the sizing like this (maybe with an HVACSizingIndex argument?)

sizingCoolingAirFlow.size(state, TempSize, errorsFound)

but let the sizer handle the scaling. If I were calling CoolingAirFlowSizing I could look up the "cooling air flow" methods on the HVACSizing object because I already know I am sizing cooling air flow. Or set up all scalable sizing in the base class and each sizer uses what is relevant. This was considered when the sizer method was first developed but I decided to punt. Here's a hook, and then see the bottom of initializeWithinEP where this was initially started and then abandoned:

void BaseSizerWithScalableInputs::setHVACSizingIndexData(int const index)
{
    this->zoneHVACSizingIndex = index;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rraustad I like your line of thinking here. It would be really nice if this could be standardized across the various models that do this and your thoughts and expertise here are clearly very valuable.

I took a quick look at the various other occurrences in the code using a search for FractionOfAutosizedCoolingCapacity like you did. It seems like there are maybe a couple of cases where the code at first glance at least looks fairly similar to what existed here before the fix was implemented. However, there are other cases where additional steps are being taken. The question is then: how do we accommodate that and still get something that avoids the duplication of code across numerous instances. I really would like to see that happen, but I'm also not sure how that would work at this time. I wonder if that is why you "punted" as you said in your comment?

From my perspective, I am glad that my "value add" to the code here got this conversation started (or restarted?) and might yield other improvements to the code. It would have been easy to just change the one line and move on, but I thought it made more sense to also come up with something that avoids the problem. However, given my relatively low level of experience with the VRF and sizing code, I'm not sure that I'd be the most efficient person to handle anything beyond this. So, I think my vote would be to not attempt to bump the complexity of this up and do more changes here but to definitely open up a new issue that includes your comments here.

Thoughts? Any of the other flagged reviewers want to offer their opinions here?

Copy link
Contributor

Choose a reason for hiding this comment

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

@RKStrand I'm fine with leaving this as-is. I punted because the sizing functions were enough work on their own without adding in the rewriting and associated testing of scalable sizing in the zone equipment. I did leave the hook in as a starting place for this "sizable" refactor.

} else {
// no scalable sizing method has been specified. Sizing proceeds using the method
// specified in the zoneHVAC object
Expand Down Expand Up @@ -8856,6 +8833,41 @@ void SizeVRF(EnergyPlusData &state, int const VRFTUNum)
state.dataSize->DataScalableCapSizingON = false;
}

void initCapSizingVars(EnergyPlusData &state,
int sizingMethod,
int capSizingMethod,
int &eqSizingMethod,
Real64 scaledCapacity,
bool &modeCapacity,
Real64 &designLoad,
bool &scalableCapSizingOn,
Real64 &fracOfAutosizedCapacity)
{
using namespace DataSizing;
using HVAC::CoolingCapacitySizing;
using HVAC::HeatingCapacitySizing;

eqSizingMethod = capSizingMethod;
if (capSizingMethod == CoolingDesignCapacity || capSizingMethod == HeatingDesignCapacity || capSizingMethod == CapacityPerFloorArea ||
capSizingMethod == FractionOfAutosizedCoolingCapacity || capSizingMethod == FractionOfAutosizedHeatingCapacity) {
if ((capSizingMethod == CoolingDesignCapacity && sizingMethod == CoolingCapacitySizing) ||
(capSizingMethod == HeatingDesignCapacity && sizingMethod == HeatingCapacitySizing)) {
if (scaledCapacity > 0.0) {
modeCapacity = true;
designLoad = scaledCapacity;
}
} else if (capSizingMethod == CapacityPerFloorArea) {
modeCapacity = true;
designLoad = scaledCapacity * state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
scalableCapSizingOn = true;
} else if ((capSizingMethod == FractionOfAutosizedCoolingCapacity && sizingMethod == CoolingCapacitySizing) ||
(capSizingMethod == FractionOfAutosizedHeatingCapacity && sizingMethod == HeatingCapacitySizing)) {
fracOfAutosizedCapacity = scaledCapacity;
scalableCapSizingOn = true;
}
}
}

void VRFCondenserEquipment::SizeVRFCondenser(EnergyPlusData &state)
{

Expand Down
10 changes: 10 additions & 0 deletions src/EnergyPlus/HVACVariableRefrigerantFlow.hh
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,16 @@ namespace HVACVariableRefrigerantFlow {

void SizeVRF(EnergyPlusData &state, int const VRFTUNum);

void initCapSizingVars(EnergyPlusData &state,
int sizingMethod,
int capSizingMethod,
int &eqSizingMethod,
Real64 scaledCapacity,
bool &modeCapacity,
Real64 &designLoad,
bool &scalableCapSizingOn,
Real64 &fracOfAutosizedCapacity);

void SimVRF(EnergyPlusData &state,
int VRFTUNum,
bool FirstHVACIteration,
Expand Down
30 changes: 28 additions & 2 deletions testfiles/VariableRefrigerantFlow_5Zone.idf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
! VariableRefrigerantFlow_5Zone.idf
! Basic file description: 1 story building divided into 4 exterior and one interior conditioned zones and return plenum.
!
! Highlights: Varible Refrigerant Flow AC system
! Highlights: Variable Refrigerant Flow AC system
!
! Simulation Location/Run: Miami Intl Ap FL USA TMY3 722020, 2 design days, 2 run periods,
!
Expand Down Expand Up @@ -519,11 +519,37 @@
20, !- Zone Terminal Unit Off Parasitic Electric Energy Use {W}
, !- Rated Heating Capacity Sizing Ratio {W/W}
TU1-NightCycleManagerList, !- Availability Manager List Name
, !- Design Specification ZoneHVAC Sizing Object Name
VRFSizingRules1, !- Design Specification ZoneHVAC Sizing Object Name
, !- Supplemental Heating Coil Object Type
, !- Supplemental Heating Coil Name
; !- Maximum Supply Air Temperature from Supplemental Heater {C}

DesignSpecification:ZoneHVAC:Sizing,
VRFSizingRules1, !- Name
SupplyAirFlowRate, !- Cooling Supply Air Flow Rate Method
autosize, !- Cooling Supply Air Flow Rate {m3/s}
, !- Cooling Supply Air Flow Rate Per Floor Area {m3/s-m2}
, !- Cooling Fraction of Autosized Cooling Supply Air Flow Rate
, !- Cooling Supply Air Flow Rate Per Unit Cooling Capacity {m3/s-W}
SupplyAirFlowRate, !- No Load Supply Air Flow Rate Method
0.0, !- No Load Supply Air Flow Rate {m3/s}
, !- No Load Supply Air Flow Rate Per Floor Area {m3/s-m2}
, !- No Load Fraction of Cooling Supply Air Flow Rate
, !- No Load Fraction of Heating Supply Air Flow Rate
SupplyAirFlowRate, !- Heating Supply Air Flow Rate Method
autosize, !- Heating Supply Air Flow Rate {m3/s}
, !- Heating Supply Air Flow Rate Per Floor Area {m3/s-m2}
, !- Heating Fraction of Heating Supply Air Flow Rate
, !- Heating Supply Air Flow Rate Per Unit Heating Capacity {m3/s-W}
CoolingDesignCapacity, !- Cooling Design Capacity Method
autosize, !- Cooling Design Capacity {W}
, !- Cooling Design Capacity Per Floor Area {W/m2}
, !- Fraction of Autosized Cooling Design Capacity
CapacityPerFloorArea, !- Heating Design Capacity Method
, !- Heating Design Capacity {W}
156.89549, !- Heating Design Capacity Per Floor Area {W/m2}
; !- Fraction of Autosized Heating Design Capacity

AvailabilityManagerAssignmentList,
TU1-NightCycleManagerList, !- Name
AvailabilityManager:NightCycle, !- Availability Manager 1 Object Type
Expand Down
2 changes: 1 addition & 1 deletion testfiles/VariableRefrigerantFlow_5Zone_wAirloop.idf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
! VariableRefrigerantFlow_5Zone.idf
! Basic file description: 1 story building divided into 4 exterior and one interior conditioned zones and return plenum.
!
! Highlights: Varible Refrigerant Flow AC system
! Highlights: Variable Refrigerant Flow AC system
!
! Simulation Location/Run: Miami Intl Ap FL USA TMY3 722020, 2 design days, 2 run periods,
!
Expand Down
200 changes: 200 additions & 0 deletions tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25525,4 +25525,204 @@ TEST_F(EnergyPlusFixture, VRFTest_TU_HeatRecoveryCheck)
EXPECT_FALSE(state->dataHVACVarRefFlow->VRF(vrf3).HeatRecoveryUsed);
}

TEST_F(EnergyPlusFixture, VRFTest_initCapSizingVars)
{
// Test for #10638
using namespace DataSizing;
using HVAC::AutoCalculateSizing;
using HVAC::CoolingCapacitySizing;
using HVAC::HeatingCapacitySizing;

int testSizingMethod;
int testCapSizingMethod;
int testEqSizingMethod;
Real64 testScaledCapacity;
bool testModeCapacity;
Real64 testDesignLoad;
bool testScalableCapSizingOn;
Real64 testFracOfAutosizedCapacity;
Real64 allowedTolerance = 0.0001;
int expectedEqSizingMethod;
Real64 expectedScaledCapacity;
Real64 expectedDesignLoad;
Real64 expectedFracOfAutosizedCapacity;

state->dataSize->DataZoneNumber = 1;
state->dataHeatBal->Zone.allocate(1);
state->dataHeatBal->Zone(1).FloorArea = 2.0;

// Test 1: no valid sizing chosen--nothing changes from what things are previously set to
testSizingMethod = AutoCalculateSizing;
testCapSizingMethod = None;
testEqSizingMethod = -1;
testScaledCapacity = 12.0;
testModeCapacity = false;
testDesignLoad = 123.0;
testScalableCapSizingOn = false;
testFracOfAutosizedCapacity = 1234.0;
expectedScaledCapacity = 12.0;
expectedDesignLoad = 123.0;
expectedFracOfAutosizedCapacity = 1234.0;
initCapSizingVars(*state,
testSizingMethod,
testCapSizingMethod,
testEqSizingMethod,
testScaledCapacity,
testModeCapacity,
testDesignLoad,
testScalableCapSizingOn,
testFracOfAutosizedCapacity);
EXPECT_FALSE(testModeCapacity);
EXPECT_FALSE(testScalableCapSizingOn);
EXPECT_EQ(testEqSizingMethod, None);
EXPECT_NEAR(testScaledCapacity, expectedScaledCapacity, allowedTolerance);
EXPECT_NEAR(testDesignLoad, expectedDesignLoad, allowedTolerance);
EXPECT_NEAR(testFracOfAutosizedCapacity, expectedFracOfAutosizedCapacity, allowedTolerance);

// Test 2a: CoolingCapacitySizing with CoolingDesignCapacity--set ModeCapacity to true and DesignLoad to ScaledCapacity
testSizingMethod = CoolingCapacitySizing;
testCapSizingMethod = CoolingDesignCapacity;
testEqSizingMethod = -1;
testScaledCapacity = 12.0;
testModeCapacity = false;
testDesignLoad = 123.0;
testScalableCapSizingOn = false;
testFracOfAutosizedCapacity = 1234.0;
expectedScaledCapacity = 12.0;
expectedDesignLoad = 12.0;
expectedFracOfAutosizedCapacity = 1234.0;
expectedEqSizingMethod = CoolingDesignCapacity;
initCapSizingVars(*state,
testSizingMethod,
testCapSizingMethod,
testEqSizingMethod,
testScaledCapacity,
testModeCapacity,
testDesignLoad,
testScalableCapSizingOn,
testFracOfAutosizedCapacity);
EXPECT_TRUE(testModeCapacity);
EXPECT_FALSE(testScalableCapSizingOn);
EXPECT_EQ(testEqSizingMethod, expectedEqSizingMethod);
EXPECT_NEAR(testScaledCapacity, expectedScaledCapacity, allowedTolerance);
EXPECT_NEAR(testDesignLoad, expectedDesignLoad, allowedTolerance);
EXPECT_NEAR(testFracOfAutosizedCapacity, expectedFracOfAutosizedCapacity, allowedTolerance);

// Test 2b: HeatingCapacitySizing with HeatingDesignCapacity--set ModeCapacity to true and DesignLoad to ScaledCapacity
testSizingMethod = HeatingCapacitySizing;
testCapSizingMethod = HeatingDesignCapacity;
testEqSizingMethod = -1;
testScaledCapacity = 12.0;
testModeCapacity = false;
testDesignLoad = 123.0;
testScalableCapSizingOn = false;
testFracOfAutosizedCapacity = 1234.0;
expectedScaledCapacity = 12.0;
expectedDesignLoad = 12.0;
expectedFracOfAutosizedCapacity = 1234.0;
expectedEqSizingMethod = HeatingDesignCapacity;
initCapSizingVars(*state,
testSizingMethod,
testCapSizingMethod,
testEqSizingMethod,
testScaledCapacity,
testModeCapacity,
testDesignLoad,
testScalableCapSizingOn,
testFracOfAutosizedCapacity);
EXPECT_TRUE(testModeCapacity);
EXPECT_FALSE(testScalableCapSizingOn);
EXPECT_EQ(testEqSizingMethod, expectedEqSizingMethod);
EXPECT_NEAR(testScaledCapacity, expectedScaledCapacity, allowedTolerance);
EXPECT_NEAR(testDesignLoad, expectedDesignLoad, allowedTolerance);
EXPECT_NEAR(testFracOfAutosizedCapacity, expectedFracOfAutosizedCapacity, allowedTolerance);

// Test 3: CapacityPerFloorArea (both heating and cooling are the same)--set ModeCapacity and scalable to true and DesignLoad to ScaledCapacity
testSizingMethod = HeatingCapacitySizing;
testCapSizingMethod = CapacityPerFloorArea;
testEqSizingMethod = -1;
testScaledCapacity = 12.0;
testModeCapacity = false;
testDesignLoad = 123.0;
testScalableCapSizingOn = false;
testFracOfAutosizedCapacity = 1234.0;
expectedScaledCapacity = 12.0;
expectedDesignLoad = 24.0;
expectedFracOfAutosizedCapacity = 1234.0;
expectedEqSizingMethod = CapacityPerFloorArea;
initCapSizingVars(*state,
testSizingMethod,
testCapSizingMethod,
testEqSizingMethod,
testScaledCapacity,
testModeCapacity,
testDesignLoad,
testScalableCapSizingOn,
testFracOfAutosizedCapacity);
EXPECT_TRUE(testModeCapacity);
EXPECT_TRUE(testScalableCapSizingOn);
EXPECT_EQ(testEqSizingMethod, expectedEqSizingMethod);
EXPECT_NEAR(testScaledCapacity, expectedScaledCapacity, allowedTolerance);
EXPECT_NEAR(testDesignLoad, expectedDesignLoad, allowedTolerance);
EXPECT_NEAR(testFracOfAutosizedCapacity, expectedFracOfAutosizedCapacity, allowedTolerance);

// Test 4a: CoolingCapacitySizing with FractionOfAutosizedCoolingCapacity--set ModeCapacity to true and DesignLoad to ScaledCapacity
testSizingMethod = CoolingCapacitySizing;
testCapSizingMethod = FractionOfAutosizedCoolingCapacity;
testEqSizingMethod = -1;
testScaledCapacity = 12.0;
testModeCapacity = false;
testDesignLoad = 123.0;
testScalableCapSizingOn = false;
testFracOfAutosizedCapacity = 1234.0;
expectedScaledCapacity = 12.0;
expectedDesignLoad = 123.0;
expectedFracOfAutosizedCapacity = 12.0;
expectedEqSizingMethod = FractionOfAutosizedCoolingCapacity;
initCapSizingVars(*state,
testSizingMethod,
testCapSizingMethod,
testEqSizingMethod,
testScaledCapacity,
testModeCapacity,
testDesignLoad,
testScalableCapSizingOn,
testFracOfAutosizedCapacity);
EXPECT_FALSE(testModeCapacity);
EXPECT_TRUE(testScalableCapSizingOn);
EXPECT_EQ(testEqSizingMethod, expectedEqSizingMethod);
EXPECT_NEAR(testScaledCapacity, expectedScaledCapacity, allowedTolerance);
EXPECT_NEAR(testDesignLoad, expectedDesignLoad, allowedTolerance);
EXPECT_NEAR(testFracOfAutosizedCapacity, expectedFracOfAutosizedCapacity, allowedTolerance);

// Test 4b: HeatingCapacitySizing with FractionOfAutosizedHeatingCapacity--set ModeCapacity to true and DesignLoad to ScaledCapacity
testSizingMethod = HeatingCapacitySizing;
testCapSizingMethod = FractionOfAutosizedHeatingCapacity;
testEqSizingMethod = -1;
testScaledCapacity = 12.0;
testModeCapacity = false;
testDesignLoad = 123.0;
testScalableCapSizingOn = false;
testFracOfAutosizedCapacity = 1234.0;
expectedScaledCapacity = 12.0;
expectedDesignLoad = 123.0;
expectedFracOfAutosizedCapacity = 12.0;
expectedEqSizingMethod = FractionOfAutosizedHeatingCapacity;
initCapSizingVars(*state,
testSizingMethod,
testCapSizingMethod,
testEqSizingMethod,
testScaledCapacity,
testModeCapacity,
testDesignLoad,
testScalableCapSizingOn,
testFracOfAutosizedCapacity);
EXPECT_FALSE(testModeCapacity);
EXPECT_TRUE(testScalableCapSizingOn);
EXPECT_EQ(testEqSizingMethod, expectedEqSizingMethod);
EXPECT_NEAR(testScaledCapacity, expectedScaledCapacity, allowedTolerance);
EXPECT_NEAR(testDesignLoad, expectedDesignLoad, allowedTolerance);
EXPECT_NEAR(testFracOfAutosizedCapacity, expectedFracOfAutosizedCapacity, allowedTolerance);
}

} // end of namespace EnergyPlus
Loading