-
Notifications
You must be signed in to change notification settings - Fork 472
Fix heating and cooling runtime fraction for AirLoopHVAC:UnitarySystem for airflow network simulations
#11491
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
base: develop
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -140,6 +140,15 @@ namespace UnitarySystems { | |
| return; | ||
| } | ||
|
|
||
| // Save the current AFN coil runtime fraction for comparison with the one calculated below | ||
| Real64 refAFNLoopHeatingCoilMaxRTF(0.0); | ||
| Real64 refAFNLoopCoolingCoilMaxRTF(0.0); | ||
| if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP && | ||
| this->m_sysType != SysType::PackagedWSHP && AirLoopNum > 0) { | ||
| refAFNLoopHeatingCoilMaxRTF = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF; | ||
| refAFNLoopCoolingCoilMaxRTF = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF; | ||
| } | ||
|
|
||
| // MassFlowRateMaxAvail issues are impeding non-VAV air loop equipment by limiting air flow | ||
| // temporarily open up flow limits while simulating, and then set this same value at the INLET after this parent has simulated | ||
| Real64 tempMassFlowRateMaxAvail = state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail; | ||
|
|
@@ -160,6 +169,128 @@ namespace UnitarySystems { | |
| // Report the current output | ||
| this->reportUnitarySystem(state, AirLoopNum); | ||
|
|
||
| // Get the actual maximum RTF for AFN simulations | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar changes as for #11367. We save the RTFs at the system level instead of at the coil level and make the determination here, that way we can also include the supplemental heating coil. |
||
| if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP && | ||
| this->m_sysType != SysType::PackagedWSHP && AirLoopNum > 0) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there may be a problem with these conditionals. The first is that we should move away from checking for the "Packaged" sysType because it was added to reduce diffs. These special considerations should be removed slowly and will cause little diffs so should probably be done 1 at a time. What is important here is that this is a system level object. Not zone equipment, OA sys equipment, or in a ZoneHVAC:OutdoorAirUnit object. The second is that This conditional would be the same as: except the snag that this system could be called from MixedAir and be part of an outdoor air system. You could probably use this to capture a system object (air loop equipment): I am not positive that AFN would not include OA systems here but if so then CurOASysNum==0 would not be needed (I think it's needed).
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, thanks. I was following the existing pattern. Should these mods be done as a follow up PR, or should I include them here?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just include them here. This is a small change that also gets rid of some "Packaged" sysType checks.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made the changes. |
||
| Real64 heatingCoilRTF = 0.0; | ||
| Real64 coolingCoilRTF = 0.0; | ||
| Real64 suppHeatingCoilRTF = 0.0; | ||
| bool errorFound(false); | ||
| switch (this->m_HeatingCoilType_Num) { | ||
| case HVAC::Coil_HeatingGasOrOtherFuel: | ||
| case HVAC::Coil_HeatingElectric: | ||
| case HVAC::Coil_HeatingDesuperheater: | ||
| case HVAC::Coil_HeatingElectric_MultiStage: | ||
| case HVAC::Coil_HeatingGas_MultiStage: { | ||
| if (this->m_HeatingCoilIndex > 0) { | ||
| heatingCoilRTF = state.dataHeatingCoils->HeatingCoil(this->m_HeatingCoilIndex).RTF; | ||
| } | ||
| } break; | ||
| case HVAC::CoilDX_HeatingEmpirical: | ||
| case HVAC::CoilDX_MultiSpeedHeating: { | ||
| if (this->m_HeatingCoilIndex > 0) { | ||
| heatingCoilRTF = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).HeatingCoilRuntimeFraction; | ||
| } | ||
| } break; | ||
| case HVAC::Coil_HeatingWaterToAirHPSimple: { | ||
| if (this->m_HeatingCoilIndex > 0) { | ||
| heatingCoilRTF = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_HeatingCoilIndex).RunFrac; | ||
| } | ||
| } break; | ||
| case HVAC::Coil_HeatingWaterToAirHP: { | ||
| if (this->m_HeatingCoilIndex > 0) { | ||
| heatingCoilRTF = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_HeatingCoilIndex).RunFrac; | ||
| } | ||
| } break; | ||
| case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: | ||
| case HVAC::Coil_HeatingAirToAirVariableSpeed: { | ||
| if (this->m_HeatingCoilIndex > 0) { | ||
| heatingCoilRTF = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).RunFrac; | ||
| } | ||
| } break; | ||
| case HVAC::Coil_HeatingSteam: | ||
| case HVAC::Coil_HeatingWater: | ||
| case HVAC::Coil_UserDefined: { | ||
| heatingCoilRTF = 1.0; | ||
| } break; | ||
| default:; | ||
| } | ||
| if (errorFound) { | ||
| ShowSevereError(state, EnergyPlus::format("The index of \"{}\" is not found", this->m_HeatingCoilName)); | ||
| ShowContinueError(state, EnergyPlus::format("...occurs for {}", this->m_HeatingCoilName)); | ||
| errorFound = false; | ||
| } | ||
| switch (this->m_SuppHeatCoilType_Num) { | ||
| case HVAC::Coil_HeatingGasOrOtherFuel: | ||
| case HVAC::Coil_HeatingElectric: | ||
| case HVAC::Coil_HeatingDesuperheater: | ||
| case HVAC::Coil_HeatingElectric_MultiStage: { | ||
| if (this->m_SuppHeatCoilIndex > 0) { | ||
| suppHeatingCoilRTF = state.dataHeatingCoils->HeatingCoil(this->m_SuppHeatCoilIndex).RTF; | ||
| } | ||
| } break; | ||
| case HVAC::Coil_HeatingSteam: | ||
| case HVAC::Coil_HeatingWater: | ||
| case HVAC::Coil_UserDefined: { | ||
| heatingCoilRTF = 1.0; | ||
| } break; | ||
| default:; | ||
| } | ||
| if (errorFound) { | ||
| ShowSevereError(state, EnergyPlus::format("The index of \"{}\" is not found", this->m_SuppHeatCoilName)); | ||
| ShowContinueError(state, EnergyPlus::format("...occurs for {}", this->m_SuppHeatCoilName)); | ||
| errorFound = false; | ||
| } | ||
| state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = | ||
| max(refAFNLoopHeatingCoilMaxRTF, heatingCoilRTF, suppHeatingCoilRTF); | ||
|
|
||
| switch (this->m_CoolingCoilType_Num) { | ||
| case HVAC::CoilDX_Cooling: { | ||
| if (this->m_CoolingCoilIndex > 0) { | ||
| coolingCoilRTF = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].coolingCoilRuntimeFraction; | ||
| } | ||
| } break; | ||
| case HVAC::CoilDX_CoolingSingleSpeed: | ||
| case HVAC::CoilDX_MultiSpeedCooling: | ||
| case HVAC::CoilDX_CoolingTwoSpeed: | ||
| case HVAC::CoilDX_CoolingTwoStageWHumControl: { | ||
| if (this->m_CoolingCoilIndex > 0) { | ||
| coolingCoilRTF = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).CoolingCoilRuntimeFraction; | ||
| } | ||
| } break; | ||
| case HVAC::CoilDX_PackagedThermalStorageCooling: { | ||
| if (this->m_CoolingCoilIndex > 0) { | ||
| coolingCoilRTF = state.dataPackagedThermalStorageCoil->TESCoil(this->m_CoolingCoilIndex).RuntimeFraction; | ||
| } | ||
| } break; | ||
| case HVAC::Coil_CoolingWaterToAirHPSimple: { | ||
| if (this->m_CoolingCoilIndex > 0) { | ||
| coolingCoilRTF = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_CoolingCoilIndex).RunFrac; | ||
| } | ||
| } break; | ||
| case HVAC::Coil_CoolingWaterToAirHP: { | ||
| if (this->m_CoolingCoilIndex > 0) { | ||
| coolingCoilRTF = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_CoolingCoilIndex).RunFrac; | ||
| } | ||
| } break; | ||
| case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: | ||
| case HVAC::Coil_CoolingAirToAirVariableSpeed: { | ||
| if (this->m_CoolingCoilIndex > 0) { | ||
| coolingCoilRTF = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).RunFrac; | ||
| } | ||
| } break; | ||
| case HVAC::Coil_CoolingWater: | ||
| case HVAC::Coil_CoolingWaterDetailed: | ||
| case HVAC::Coil_UserDefined: | ||
| case HVAC::CoilDX_CoolingHXAssisted: | ||
| case HVAC::CoilWater_CoolingHXAssisted: { | ||
| coolingCoilRTF = 1.0; | ||
| } break; | ||
| default:; | ||
| } | ||
| state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = max(refAFNLoopCoolingCoilMaxRTF, coolingCoilRTF); | ||
| } | ||
|
|
||
| // CoolActive = false; // set in call from ZoneEquipmentManager | ||
| if (this->m_CoolingPartLoadFrac * double(CompressorOn) > 0.0) { | ||
| CoolActive = true; | ||
|
|
@@ -14597,17 +14728,6 @@ namespace UnitarySystems { | |
| int CompIndex = this->m_HeatingCoilIndex; | ||
| HVAC::FanOp fanOp = this->m_FanOpMode; | ||
| Real64 DesOutTemp = this->m_DesiredOutletTemp; | ||
|
|
||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These were only applied when the system is controller to a setpoint. The propose changes apply to both load-based and setpoint control. |
||
| Real64 LoopHeatingCoilMaxRTFSave = 0.0; | ||
| Real64 LoopDXCoilMaxRTFSave = 0.0; | ||
| if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP && | ||
| this->m_sysType != SysType::PackagedWSHP) { | ||
| LoopHeatingCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF; | ||
| state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0; | ||
| LoopDXCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF; | ||
| state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = 0.0; | ||
| } | ||
|
|
||
| Real64 PartLoadFrac = 0.0; | ||
| Real64 SpeedRatio = 0.0; | ||
| Real64 CycRatio = 0.0; | ||
|
|
@@ -15233,14 +15353,6 @@ namespace UnitarySystems { | |
| this->m_HeatingCycRatio = CycRatio; | ||
| HeatCoilLoad = ReqOutput; | ||
|
|
||
| if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP && | ||
| this->m_sysType != SysType::PackagedWSHP) { | ||
| state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = | ||
| max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave); | ||
| state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = | ||
| max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave); | ||
| } | ||
|
|
||
| if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) { | ||
| mdot = PartLoadFrac * this->MaxHeatCoilFluidFlow; | ||
| PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc); | ||
|
|
@@ -15283,17 +15395,6 @@ namespace UnitarySystems { | |
| Real64 DesOutTemp = this->m_DesiredOutletTemp; | ||
| std::string_view CompName = this->m_SuppHeatCoilName; | ||
|
|
||
| Real64 LoopHeatingCoilMaxRTFSave = 0.0; | ||
| Real64 LoopDXCoilMaxRTFSave = 0.0; | ||
| if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP && | ||
| this->m_sysType != SysType::PackagedWSHP) { | ||
| auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum); | ||
| LoopHeatingCoilMaxRTFSave = afnInfo.AFNLoopHeatingCoilMaxRTF; | ||
| afnInfo.AFNLoopHeatingCoilMaxRTF = 0.0; | ||
| LoopDXCoilMaxRTFSave = afnInfo.AFNLoopDXCoilRTF; | ||
| afnInfo.AFNLoopDXCoilRTF = 0.0; | ||
| } | ||
|
|
||
| // IF there is a fault of coil SAT Sensor | ||
| if (this->m_FaultyCoilSATFlag) { | ||
| // calculate the sensor offset using fault information | ||
|
|
@@ -15646,14 +15747,6 @@ namespace UnitarySystems { | |
| } // IF SENSIBLE LOAD | ||
| } // IF((GetCurrentScheduleValue(state, UnitarySystem(UnitarySysNum)%m_SysAvailSchedPtr) > 0.0d0) .AND. & | ||
|
|
||
| // LoopHeatingCoilMaxRTF used for AirflowNetwork gets set in child components (gas and fuel) | ||
| if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP && | ||
| this->m_sysType != SysType::PackagedWSHP) { | ||
| auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum); | ||
| afnInfo.AFNLoopHeatingCoilMaxRTF = max(afnInfo.AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave); | ||
| afnInfo.AFNLoopDXCoilRTF = max(afnInfo.AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave); | ||
| } | ||
|
|
||
| if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) { | ||
| mdot = PartLoadFrac * this->m_MaxSuppCoilFluidFlow; | ||
| PlantUtilities::SetComponentFlowRate( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you just move these last 2 lines down inside of the block below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so because I think this needs to happen before
controlUnitarySystemtoSPorcontrolUnitarySystemtoLoadare called.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Because these same AFN variables are set in the child. In this parent there can be 2 heating coils so the larger RTF should be used and calling the control functions will set AFNLoopHeatingCoilMaxRTF to the RTF of the last coil called.