Skip to content
Open
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
162 changes: 84 additions & 78 deletions src/EnergyPlus/SZVAVModel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,6 @@ namespace SZVAVModel {
HVAC::CompressorOp const CompressorONFlag)
{

UnitarySystems::UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[SysIndex];

int constexpr MaxIter(100); // maximum number of iterations
int SolFlag(0); // return flag from RegulaFalsi for sensible load
std::string MessagePrefix; // label for warning reporting
Expand All @@ -603,6 +601,7 @@ namespace SZVAVModel {
int coilAirOutletNode(0);
Real64 HeatCoilLoad(0.0);
Real64 SupHeaterLoad(0.0);
Real64 iterWaterAirOrNot(0.0);

Real64 TempSensOutput; // iterative sensible capacity [W]
Real64 TempLatOutput; // iterative latent capacity [W]
Expand Down Expand Up @@ -722,34 +721,34 @@ namespace SZVAVModel {
if (SZVAVModel.MaxCoolCoilFluidFlow > 0.0) {
SZVAVModel.CoolCoilWaterFlowRatio = maxCoilFluidFlow / SZVAVModel.MaxCoolCoilFluidFlow;
}
thisSys.calcUnitarySystemToLoad(state,
AirLoopNum,
FirstHVACIteration,
PartLoadRatio,
0.0,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
HeatCoilLoad,
SupHeaterLoad,
CompressorONFlag);
SZVAVModel.calcUnitarySystemToLoad(state,
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure why this change was required but the debugger showed me these were different (i.e., using thisSys vs SZVAVModel, which are both references to the same unitarySytsem. At line 711 above, where SZVAVModel.FanPartLoadRatio = 0.0, that code DID change FanPartLoadRatio in the SZVAVModel reference but DID NOT change FanPartLoadRatio in the thisSys reference. I know, it's a conundrum. This is the reason for this change, this needs to reference the right system.

AirLoopNum,
FirstHVACIteration,
PartLoadRatio,
0.0,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
HeatCoilLoad,
SupHeaterLoad,
CompressorONFlag);
} else {
if (SZVAVModel.MaxHeatCoilFluidFlow > 0.0) {
SZVAVModel.HeatCoilWaterFlowRatio = maxCoilFluidFlow / SZVAVModel.MaxHeatCoilFluidFlow;
}
thisSys.calcUnitarySystemToLoad(state,
AirLoopNum,
FirstHVACIteration,
0.0,
PartLoadRatio,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
ZoneLoad,
SupHeaterLoad,
CompressorONFlag);
SZVAVModel.calcUnitarySystemToLoad(state,
AirLoopNum,
FirstHVACIteration,
0.0,
PartLoadRatio,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
ZoneLoad,
SupHeaterLoad,
CompressorONFlag);
}

coilActive = std::abs(state.dataLoopNodes->Node(coilAirInletNode).Temp - state.dataLoopNodes->Node(coilAirOutletNode).Temp) > 0;
Expand All @@ -764,6 +763,7 @@ namespace SZVAVModel {
}

if ((CoolingLoad && TempSensOutput < ZoneLoad) || (HeatingLoad && TempSensOutput > ZoneLoad)) { // low speed fan can meet load
// don't iterate on air flow in region 1 using iterWaterAirOrNot = 0.0 as default
auto fR1 = [&state,
SysIndex,
FirstHVACIteration,
Expand All @@ -776,6 +776,7 @@ namespace SZVAVModel {
maxCoilFluidFlow,
minAirMassFlow,
maxAirMassFlow,
iterWaterAirOrNot,
CoolingLoad](Real64 const PartLoadRatio) {
return UnitarySystems::UnitarySys::calcUnitarySystemWaterFlowResidual(state,
PartLoadRatio, // coil part load ratio
Expand All @@ -792,7 +793,7 @@ namespace SZVAVModel {
0.0,
maxAirMassFlow,
CoolingLoad,
1.0);
iterWaterAirOrNot);
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This was another subtle but necessary change. This residual function has 2 choices for adjusting air and water flow rates. If the load is in Region 1 or 3 (iterWaterAirOrNot = 0) then the air flow is constant and the compressor speed or water flow rate changes to meet the load. When in region 2 (iterWaterAirOrNot = 1), both change. See the figure in the PR description for clarity or just ask me. Feel free to suggest a different variable name.

};
General::SolveRoot(state, 0.001, MaxIter, SolFlag, PartLoadRatio, fR1, 0.0, 1.0);
if (SolFlag < 0) {
Expand All @@ -814,6 +815,7 @@ namespace SZVAVModel {

if ((CoolingLoad && boundaryLoadMet < ZoneLoad) || (HeatingLoad && boundaryLoadMet > ZoneLoad)) { // in Region 2 of figure

iterWaterAirOrNot = 1.0; // iterate on air and/or water flow in region 2
outletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
minHumRat = state.dataLoopNodes->Node(SZVAVModel.NodeNumOfControlledZone).HumRat;
if (outletTemp < ZoneTemp) {
Expand All @@ -836,6 +838,7 @@ namespace SZVAVModel {
lowSpeedFanRatio,
AirMassFlow,
maxAirMassFlow,
iterWaterAirOrNot,
CoolingLoad,
maxCoilFluidFlow](Real64 const PartLoadRatio) {
return UnitarySystems::UnitarySys::calcUnitarySystemWaterFlowResidual(state,
Expand All @@ -853,7 +856,7 @@ namespace SZVAVModel {
0.0,
maxAirMassFlow,
CoolingLoad,
1.0);
iterWaterAirOrNot);
};
General::SolveRoot(state, 0.001, MaxIter, SolFlag, PartLoadRatio, fR2, 0.0, 1.0);
if (SolFlag == -2 && ((CoolingLoad && SZVAVModel.m_CoolingSpeedNum < SZVAVModel.m_NumOfSpeedCooling) ||
Expand Down Expand Up @@ -885,6 +888,7 @@ namespace SZVAVModel {
lowSpeedFanRatio,
AirMassFlow,
maxAirMassFlow,
iterWaterAirOrNot,
CoolingLoad,
maxCoilFluidFlow](Real64 const PartLoadRatio) {
return UnitarySystems::UnitarySys::calcUnitarySystemWaterFlowResidual(state,
Expand All @@ -902,7 +906,7 @@ namespace SZVAVModel {
0.0,
maxAirMassFlow,
CoolingLoad,
1.0);
iterWaterAirOrNot);
};
General::SolveRoot(state, 0.001, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
if (SolFlag > 0) {
Expand Down Expand Up @@ -930,34 +934,34 @@ namespace SZVAVModel {
if (SZVAVModel.MaxCoolCoilFluidFlow > 0.0) {
SZVAVModel.CoolCoilWaterFlowRatio = maxCoilFluidFlow / SZVAVModel.MaxCoolCoilFluidFlow;
}
thisSys.calcUnitarySystemToLoad(state,
AirLoopNum,
FirstHVACIteration,
PartLoadRatio,
0.0,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
HeatCoilLoad,
SupHeaterLoad,
CompressorONFlag);
SZVAVModel.calcUnitarySystemToLoad(state,
AirLoopNum,
FirstHVACIteration,
PartLoadRatio,
0.0,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
HeatCoilLoad,
SupHeaterLoad,
CompressorONFlag);
} else {
if (SZVAVModel.MaxHeatCoilFluidFlow > 0.0) {
SZVAVModel.HeatCoilWaterFlowRatio = maxCoilFluidFlow / SZVAVModel.MaxHeatCoilFluidFlow;
}
thisSys.calcUnitarySystemToLoad(state,
AirLoopNum,
FirstHVACIteration,
0.0,
PartLoadRatio,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
ZoneLoad,
SupHeaterLoad,
CompressorONFlag);
SZVAVModel.calcUnitarySystemToLoad(state,
AirLoopNum,
FirstHVACIteration,
0.0,
PartLoadRatio,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
ZoneLoad,
SupHeaterLoad,
CompressorONFlag);
}

coilActive = std::abs(state.dataLoopNodes->Node(coilAirInletNode).Temp - state.dataLoopNodes->Node(coilAirOutletNode).Temp) > 0;
Expand All @@ -975,6 +979,7 @@ namespace SZVAVModel {
return; // system cannot meet load, leave at max capacity
}

iterWaterAirOrNot = 0.0; // don't iterate on air flow in region 3
// otherwise iterate on load
auto fR3 = [&state,
SysIndex,
Expand All @@ -987,6 +992,7 @@ namespace SZVAVModel {
lowSpeedFanRatio,
maxCoilFluidFlow,
maxAirMassFlow,
iterWaterAirOrNot,
CoolingLoad](Real64 const PartLoadRatio) {
return UnitarySystems::UnitarySys::calcUnitarySystemWaterFlowResidual(state,
PartLoadRatio, // coil part load ratio
Expand All @@ -1003,7 +1009,7 @@ namespace SZVAVModel {
0.0,
maxAirMassFlow,
CoolingLoad,
1.0);
iterWaterAirOrNot);
};
General::SolveRoot(state, 0.001, MaxIter, SolFlag, PartLoadRatio, fR3, 0.0, 1.0);
// Par[12] = maxAirMassFlow; // operating air flow rate, minAirMassFlow indicates low speed air flow rate,
Expand All @@ -1027,31 +1033,31 @@ namespace SZVAVModel {
if (SolFlag == -1) {
// get capacity for warning
if (CoolingLoad) { // Function CalcUnitarySystemToLoad, 4th and 5th arguments are CoolPLR and HeatPLR
thisSys.calcUnitarySystemToLoad(state,
AirLoopNum,
FirstHVACIteration,
PartLoadRatio,
0.0,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
HeatCoilLoad,
SupHeaterLoad,
CompressorONFlag);
SZVAVModel.calcUnitarySystemToLoad(state,
AirLoopNum,
FirstHVACIteration,
PartLoadRatio,
0.0,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
HeatCoilLoad,
SupHeaterLoad,
CompressorONFlag);
} else {
thisSys.calcUnitarySystemToLoad(state,
AirLoopNum,
FirstHVACIteration,
0.0,
PartLoadRatio,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
ZoneLoad,
SupHeaterLoad,
CompressorONFlag);
SZVAVModel.calcUnitarySystemToLoad(state,
AirLoopNum,
FirstHVACIteration,
0.0,
PartLoadRatio,
OnOffAirFlowRatio,
TempSensOutput,
TempLatOutput,
HXUnitOn,
ZoneLoad,
SupHeaterLoad,
CompressorONFlag);
}

if (std::abs(TempSensOutput - ZoneLoad) * SZVAVModel.ControlZoneMassFlowFrac >
Expand Down
12 changes: 9 additions & 3 deletions src/EnergyPlus/UnitarySystem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16955,20 +16955,26 @@ namespace UnitarySystems {
} else {
SATempTarget = par13_SATempTarget;
}
bool iterateOnAirOnly = (par16_IterationMethod > 1.0);
bool modulateAirFlow = (par16_IterationMethod > 0.0);

bool HXUnitOn = true;

if (iterateOnAirOnly) {
if (modulateAirFlow) {
// in Region 2

// set air flow rate bounded by low speed and high speed air flow rates
state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot * (lowSpeedRatio + (PartLoadRatio * (1.0 - lowSpeedRatio)));
state.dataLoopNodes->Node(AirControlNode).MassFlowRate = systemMaxAirFlowRate * (lowSpeedRatio + (PartLoadRatio * (1.0 - lowSpeedRatio)));
// FanPartLoadRatio is used to pass info over to function SetAverageAirFlow since air and coil PLR are disassociated in the model
// FanPartLoadRatio is a report variable that is updated (overwritten) in ReportUnitarySystem
thisSys.FanPartLoadRatio = PartLoadRatio;
// if( WaterControlNode > 0 ) Node( WaterControlNode ).MassFlowRate = highWaterMdot;
if (WaterControlNode > 0) {
Real64 waterMdot = highWaterMdot * PartLoadRatio;
state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = waterMdot;
}

} else {
// in Region 1 or 3 where air flow is constant and water flow or compressor is modulated to meet the load

state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot;
if (lowSpeedRatio != 1.0) {
Expand Down
Loading
Loading