-
Notifications
You must be signed in to change notification settings - Fork 480
ZoneHVAC:HybridUnitaryHVAC - Check for ventilation setting before defaulting to standby #11642
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
Changes from all 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 |
|---|---|---|
|
|
@@ -1078,30 +1078,28 @@ namespace HybridEvapCoolingModel { | |
| Real64 PLHumidRatio, PLDehumidRatio, PLVentRatio, PLSensibleCoolingRatio, PLSensibleHeatingRatio, PartRuntimeFraction; | ||
| PLHumidRatio = PLDehumidRatio = PLVentRatio = PLSensibleCoolingRatio = PLSensibleHeatingRatio = 0; | ||
|
|
||
| if (Mvent > 0) { | ||
| if (VentilationRequested && Mvent > 0) { | ||
| PLVentRatio = MinOA_Msa / Mvent; | ||
| } | ||
| PartRuntimeFraction = PLVentRatio; | ||
|
|
||
| if (SensibleRoomORZone > 0) { | ||
| if (CoolingRequested && SensibleRoomORZone > 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. This seems like a reasonable guard. |
||
| PLSensibleCoolingRatio = std::abs(RequestedCoolingLoad) / std::abs(SensibleRoomORZone); | ||
| } | ||
| if (PLSensibleCoolingRatio > PartRuntimeFraction) { | ||
| PartRuntimeFraction = PLSensibleCoolingRatio; | ||
| } | ||
|
|
||
| if (SensibleRoomORZone < 0) { | ||
| if (HeatingRequested && SensibleRoomORZone < 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. Same here. |
||
| PLSensibleHeatingRatio = std::abs(RequestedHeatingLoad) / std::abs(SensibleRoomORZone); | ||
| } | ||
|
|
||
| if (PLSensibleHeatingRatio > PartRuntimeFraction) { | ||
| PartRuntimeFraction = PLSensibleHeatingRatio; | ||
| } | ||
|
|
||
| if (RequestedDehumidificationLoad > 0) { | ||
| PLDehumidRatio = std::abs(RequestedDehumidificationLoad) / std::abs(LatentRoomORZone); | ||
| } | ||
|
|
||
| if (PLDehumidRatio > PartRuntimeFraction) { | ||
| PartRuntimeFraction = PLDehumidRatio; | ||
| } | ||
|
|
@@ -1193,13 +1191,15 @@ namespace HybridEvapCoolingModel { | |
| bool DidWeMeetLoad = false; | ||
| bool DidWeMeetHumidification = false; | ||
| bool DidWePartlyMeetLoad = false; | ||
| bool DidWeMeetVentilation = false; | ||
| Real64 OptimalSetting_RunFractionTotalFuel = IMPLAUSIBLE_POWER; | ||
| Real64 Tma; | ||
| Real64 Wma; | ||
| Real64 Hsa; | ||
| Real64 Hma; | ||
| Real64 PreviousMaxiumConditioningOutput = 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. Spelling correction. OK. |
||
| Real64 PreviousMaxiumHumidOrDehumidOutput = 0; | ||
| Real64 PreviousMaximumConditioningOutput = 0; | ||
| Real64 PreviousMaximumHumidOrDehumidOutput = 0; | ||
| Real64 PreviousMaximumSupplyFanElectricPower = IMPLAUSIBLE_POWER; | ||
| std::string ObjectID = Name.c_str(); | ||
| if (StepIns.RHosa > 1) { | ||
| ShowSevereError( | ||
|
|
@@ -1328,11 +1328,8 @@ namespace HybridEvapCoolingModel { | |
| CandidateSetting.Unscaled_Supply_Air_Mass_Flow_Rate = UnscaledMsa; | ||
| CandidateSetting.ScaledSupply_Air_Mass_Flow_Rate = ScaledMsa; | ||
|
|
||
| // If no load is requested but ventilation is required, set the supply air mass flow rate to the minimum of the | ||
| // required ventilation flow rate and the maximum supply air flow rate | ||
| if (!CoolingRequested && !HeatingRequested && !DehumidificationRequested && !HumidificationRequested) { | ||
| CandidateSetting.ScaledSupply_Air_Mass_Flow_Rate = | ||
| min(MinOA_Msa, CandidateSetting.ScaledSupply_Air_Mass_Flow_Rate); | ||
| // If no load is requested but ventilation is required, set the supply air temp to the outside air temp | ||
| // add fan heat if not included in lookup tables for supply air stream | ||
| Tsa = StepIns.Tosa + FanHeatTemp; | ||
| } | ||
|
|
@@ -1453,33 +1450,32 @@ namespace HybridEvapCoolingModel { | |
| thisSetting.oMode.CalculateCurveVal(state, StepIns.Tosa, Wosa, StepIns.Tra, Wra, UnscaledMsa, OSAF, WATER_USE); | ||
|
|
||
| // Calculate partload fraction required to meet all requirements | ||
| // Fraction can be above 1 meaning its not able to do it completely in a time step | ||
| Real64 PartRuntimeFraction = CalculatePartRuntimeFraction(MinOA_Msa, | ||
| thisSetting.Supply_Air_Ventilation_Volume * state.dataEnvrn->StdRhoAir, | ||
| StepIns.RequestedCoolingLoad, | ||
| StepIns.RequestedHeatingLoad, | ||
| SensibleRoomORZone, | ||
| StepIns.ZoneDehumidificationLoad, | ||
| StepIns.ZoneMoistureLoad, | ||
| latentRoomORZone); | ||
| thisSetting.Runtime_Fraction = CalculatePartRuntimeFraction(MinOA_Msa, | ||
| thisSetting.Supply_Air_Ventilation_Volume * state.dataEnvrn->StdRhoAir, | ||
| StepIns.RequestedCoolingLoad, | ||
| StepIns.RequestedHeatingLoad, | ||
| SensibleRoomORZone, | ||
| StepIns.ZoneDehumidificationLoad, | ||
| StepIns.ZoneMoistureLoad, | ||
| latentRoomORZone); | ||
|
|
||
| Real64 RunFractionTotalFuel; | ||
| switch (ObjectiveFunction) { | ||
| default: | ||
| case ObjectiveFunctionType::ElectricityUse: | ||
| RunFractionTotalFuel = thisSetting.ElectricalPower * PartRuntimeFraction; | ||
| RunFractionTotalFuel = (thisSetting.ElectricalPower * thisSetting.Runtime_Fraction) + | ||
| (thisSetting.SupplyFanElectricPower * thisSetting.Runtime_Fraction); | ||
|
Comment on lines
+1466
to
+1467
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 like that these are tied to the actual settings now. |
||
| break; | ||
| case ObjectiveFunctionType::SecondFuelUse: | ||
| RunFractionTotalFuel = thisSetting.SecondaryFuelConsumptionRate * PartRuntimeFraction; | ||
| RunFractionTotalFuel = thisSetting.SecondaryFuelConsumptionRate * thisSetting.Runtime_Fraction; | ||
| break; | ||
| case ObjectiveFunctionType::ThirdFuelUse: | ||
| RunFractionTotalFuel = thisSetting.ThirdFuelConsumptionRate * PartRuntimeFraction; | ||
| RunFractionTotalFuel = thisSetting.ThirdFuelConsumptionRate * thisSetting.Runtime_Fraction; | ||
| break; | ||
| case ObjectiveFunctionType::WaterUse: | ||
| RunFractionTotalFuel = thisSetting.WaterConsumptionRate * PartRuntimeFraction; | ||
| RunFractionTotalFuel = thisSetting.WaterConsumptionRate * thisSetting.Runtime_Fraction; | ||
| break; | ||
| } | ||
| thisSetting.Runtime_Fraction = PartRuntimeFraction; // | ||
|
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 guess we don't need to |
||
|
|
||
| if (Conditioning_load_met && Humidification_load_met) { | ||
| // store best performing mode | ||
|
|
@@ -1495,24 +1491,33 @@ namespace HybridEvapCoolingModel { | |
|
|
||
| if (Conditioning_load_met) { | ||
| DidWeMeetLoad = true; | ||
| if (HumidificationRequested && (latentRoomORZone < PreviousMaxiumHumidOrDehumidOutput)) { | ||
| if (HumidificationRequested && (latentRoomORZone < PreviousMaximumHumidOrDehumidOutput)) { | ||
| store_best_attempt = true; | ||
| } | ||
| if (DehumidificationRequested && (latentRoomORZone > PreviousMaxiumHumidOrDehumidOutput)) { | ||
| if (DehumidificationRequested && (latentRoomORZone > PreviousMaximumHumidOrDehumidOutput)) { | ||
| store_best_attempt = true; | ||
| } | ||
| if (store_best_attempt) { | ||
| PreviousMaxiumHumidOrDehumidOutput = latentRoomORZone; | ||
| PreviousMaximumHumidOrDehumidOutput = latentRoomORZone; | ||
| } | ||
| } else { | ||
| if (CoolingRequested && (SensibleRoomORZone > PreviousMaxiumConditioningOutput)) { | ||
| if (CoolingRequested && (SensibleRoomORZone > PreviousMaximumConditioningOutput)) { | ||
| store_best_attempt = true; | ||
| } | ||
| if (HeatingRequested && (SensibleRoomORZone < PreviousMaxiumConditioningOutput)) { | ||
| if (HeatingRequested && (SensibleRoomORZone < PreviousMaximumConditioningOutput)) { | ||
| store_best_attempt = true; | ||
| } | ||
| if (store_best_attempt) { | ||
| PreviousMaxiumConditioningOutput = SensibleRoomORZone; | ||
| PreviousMaximumConditioningOutput = SensibleRoomORZone; | ||
| } else if (VentilationRequested && !DidWePartlyMeetLoad) { | ||
| // If no load is requested but ventilation is required, find the setting that uses the least supply fan power. | ||
| // Note that settings that meet partial load still take priority, so use logic separate from store_best_attempt. | ||
| Real64 RunFractionSupplyFanElectricPower = thisSetting.SupplyFanElectricPower * thisSetting.Runtime_Fraction; | ||
| if (RunFractionSupplyFanElectricPower < PreviousMaximumSupplyFanElectricPower) { | ||
| PreviousMaximumSupplyFanElectricPower = RunFractionSupplyFanElectricPower; | ||
| OptimalSetting = thisSetting; | ||
| DidWeMeetVentilation = true; | ||
| } | ||
| } | ||
|
Comment on lines
+1512
to
1521
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 guess the reasoning is that if we're only requiring ventilation, we should minimize the fan power, and not necessarily the specified objective function, which could be fuel or water. Is that correct? I think I can agree with that, if true.
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. Correct, that was the reasoning. |
||
| } | ||
| if (store_best_attempt) { | ||
|
|
@@ -1542,25 +1547,30 @@ namespace HybridEvapCoolingModel { | |
| ErrorCode = 0; | ||
| // save the optimal setting in the | ||
| CurrentOperatingSettings[0] = OptimalSetting; | ||
| PrimaryMode = OptimalSetting.Mode; | ||
| PrimaryModeRuntimeFraction = OptimalSetting.Runtime_Fraction; | ||
| oStandBy.Runtime_Fraction = (1 - PrimaryModeRuntimeFraction); | ||
| if (oStandBy.Runtime_Fraction < 0) { | ||
| oStandBy.Runtime_Fraction = 0; | ||
| } | ||
| CurrentOperatingSettings[1] = oStandBy; | ||
| } else { | ||
| // if we partly met the load then do the best we can and run full out in that optimal setting. | ||
| if (DidWePartlyMeetLoad) { | ||
| // if we partly met the load or met the ventilation then do the best we can | ||
| if (DidWePartlyMeetLoad || DidWeMeetVentilation) { | ||
| ErrorCode = 0; | ||
| count_DidWeNotMeetLoad++; | ||
| if (OptimalSetting.ElectricalPower == IMPLAUSIBLE_POWER) { | ||
| ShowWarningError(state, "Model was not able to provide cooling for a time step, called in HybridEvapCooling:dostep"); | ||
| OptimalSetting.ElectricalPower = 0; | ||
| } | ||
| OptimalSetting.Runtime_Fraction = 1; | ||
| CurrentOperatingSettings[0] = OptimalSetting; | ||
| PrimaryMode = OptimalSetting.Mode; | ||
| PrimaryModeRuntimeFraction = 1; | ||
| PrimaryModeRuntimeFraction = OptimalSetting.Runtime_Fraction; | ||
| oStandBy.Runtime_Fraction = (1 - PrimaryModeRuntimeFraction); | ||
| if (oStandBy.Runtime_Fraction < 0) { | ||
| oStandBy.Runtime_Fraction = 0; | ||
| } | ||
| CurrentOperatingSettings[1] = oStandBy; | ||
| } | ||
|
Comment on lines
+1568
to
1574
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. Looks OK to me. |
||
| // if we didn't even partially meet the load make sure the operational settings are just the standby mode. | ||
| else { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -748,7 +748,7 @@ | |
| 1, !- Mode 4 Minimum Outdoor Air Fraction | ||
| 1, !- Mode 4 Maximum Outdoor Air Fraction | ||
| 0.7039, !- Mode 4 Minimum Supply Air Mass Flow Rate Ratio | ||
| 0.957, !- Mode 4 Maximum Supply Air Mass Flow Rate Ratio | ||
| 1, !- Mode 4 Maximum Supply Air Mass Flow Rate Ratio | ||
|
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. Not sure why the change, but I assume it's fine.
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. One of the unit tests was failing to find this mode because the ventilation ratio wasn't high enough. This small change seemed to fix it without breaking anything else and I didn't have to rework that section of the unit test. |
||
| Mode5_Heat, !- Mode 5 Name | ||
| Mode5_TSA_lookup, !- Mode 5 Supply Air Temperature Lookup Table Name | ||
| Mode5_wSA_lookup, !- Mode 5 Supply Air Humidity Ratio Lookup Table Name | ||
|
|
||
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.
is this redundant?, 2) is Mvent > 0 possible if StepIns.MinimumOA = 0? and 3) does it hurt to calculate PLVentRatio each time step?
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 it will be common, but yes, Mvent > 0 is possible when StepIns.MinimumOA is 0. Checking for VentilationRequested might be a little redundant, but I figured it was better to skip a division when we know the result is 0.
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.
Anything else on this point @rraustad?
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.
Nothing else. I think this meets the objective.