Skip to content
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
80 changes: 45 additions & 35 deletions src/EnergyPlus/HybridEvapCoolingModel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

  1. is this redundant?, 2) is Mvent > 0 possible if StepIns.MinimumOA = 0? and 3) does it hurt to calculate PLVentRatio each time step?

     if (StepIns.MinimumOA > 0) {
         VentilationRequested = true;
     }
    

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 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.

Copy link
Copy Markdown
Collaborator

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?

Copy link
Copy Markdown
Collaborator

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.

}
PartRuntimeFraction = PLVentRatio;

if (SensibleRoomORZone > 0) {
if (CoolingRequested && SensibleRoomORZone > 0) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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;
}
Expand Down Expand Up @@ -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;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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(
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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; //

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I guess we don't need to assert(false) here since these are the only four valid options?


if (Conditioning_load_met && Humidification_load_met) {
// store best performing mode
Expand All @@ -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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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.

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.

Correct, that was the reasoning.

}
if (store_best_attempt) {
Expand Down Expand Up @@ -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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not sure why the change, but I assume it's fine.

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.

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
Expand Down
4 changes: 2 additions & 2 deletions tst/EnergyPlus/unit/UnitaryHybridAirConditioner.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ TEST_F(EnergyPlusFixture, Test_UnitaryHybridAirConditioner_Unittest)
EXPECT_EQ(modenumber, 4); // Ventilation Mode
EXPECT_NEAR(Tsa, Tosa, 1.0);
EXPECT_NEAR(Msa, DesignMinVR, 0.001);
EXPECT_GT(Electricpower, 4000 / NormalizationDivisor * MinFlowFraction);
EXPECT_LT(Electricpower, 5000 / NormalizationDivisor);
EXPECT_GT(Electricpower, 3000 / NormalizationDivisor * MinFlowFraction);
EXPECT_LT(Electricpower, 4000 / NormalizationDivisor);

// check fan heat calculation in supply air stream if not included in lookup tables
thisUnitary.FanHeatGain = true;
Expand Down
Loading