Skip to content

Commit

Permalink
Merge pull request #10816 from NREL/10814-DOAS-vector-issue
Browse files Browse the repository at this point in the history
Corrects crash in DOAS fan sizing
  • Loading branch information
Myoldmopar authored Jan 9, 2025
2 parents 61aaa70 + d357c9f commit c0a6271
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 59 deletions.
2 changes: 0 additions & 2 deletions src/EnergyPlus/AirLoopHVACDOAS.cc
Original file line number Diff line number Diff line change
Expand Up @@ -982,13 +982,11 @@ namespace AirLoopHVACDOAS {
this->GetDesignDayConditions(state);

if (this->m_FanIndex > 0 && this->m_FanTypeNum == SimAirServingZones::CompType::Fan_System_Object) {
state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate = sizingMassFlow / state.dataEnvrn->StdRhoAir;
state.dataLoopNodes->Node(this->m_FanInletNodeNum).MassFlowRateMaxAvail = sizingMassFlow;
state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMaxAvail = sizingMassFlow;
state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMax = sizingMassFlow;
}
if (this->m_FanIndex > 0 && this->m_FanTypeNum == SimAirServingZones::CompType::Fan_ComponentModel) {
state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate = sizingMassFlow / state.dataEnvrn->StdRhoAir;
state.dataFans->fans(this->m_FanIndex)->minAirFlowRate = 0.0;
state.dataFans->fans(this->m_FanIndex)->maxAirMassFlowRate = sizingMassFlow;
state.dataLoopNodes->Node(this->m_FanInletNodeNum).MassFlowRateMaxAvail = sizingMassFlow;
Expand Down
159 changes: 102 additions & 57 deletions src/EnergyPlus/Autosizing/SystemAirFlowSizing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -777,13 +777,38 @@ Real64 SystemAirFlowSizer::size(EnergyPlusData &state, Real64 _originalValue, bo
}

} else {
auto &sysSizPeakDDNum = state.dataSize->SysSizPeakDDNum(this->curSysNum);

if (this->airLoopSysFlag) {
auto const &unitarysysEqSizing = this->unitarySysEqSizing(this->curSysNum);
if (unitarysysEqSizing.CoolingAirFlow && unitarysysEqSizing.HeatingAirFlow) {
this->autoSizedValue = std::max(unitarysysEqSizing.CoolingAirVolFlow, unitarysysEqSizing.HeatingAirVolFlow);
if (this->autoSizedValue == unitarysysEqSizing.CoolingAirVolFlow) {
if (this->curOASysNum > 0) {
// should a parent object ever override DOAS or OASystem flow rate (e.g., using oaSysEqSizing().AirVolFlow)?
if (outsideAirSys(this->curOASysNum).AirLoopDOASNum > -1) {
this->autoSizedValue =
this->airloopDOAS[outsideAirSys(this->curOASysNum).AirLoopDOASNum].SizingMassFlow / state.dataEnvrn->StdRhoAir;
} else {
switch (this->curDuctType) {
case HVAC::AirDuctType::Cooling: {
this->autoSizedValue = this->finalSysSizing(this->curSysNum).DesCoolVolFlow;
} break;
case HVAC::AirDuctType::Heating: {
this->autoSizedValue = this->finalSysSizing(this->curSysNum).DesHeatVolFlow;
} break;
case HVAC::AirDuctType::Main:
case HVAC::AirDuctType::Other:
default: {
this->autoSizedValue = this->finalSysSizing(this->curSysNum).DesMainVolFlow;
} break;
}
if (this->autoSizedValue == this->finalSysSizing(this->curSysNum).DesHeatVolFlow) {
if (this->finalSysSizing(this->curSysNum).HeatDDNum > 0 &&
this->finalSysSizing(this->curSysNum).HeatDDNum <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(this->finalSysSizing(this->curSysNum).HeatDDNum);
DDNameFanPeak = desDayInput.Title;
dateTimeFanPeak = format("{}/{} {}",
desDayInput.Month,
desDayInput.DayOfMonth,
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, this->finalSysSizing(this->curSysNum).SysHeatAirTimeStepPk));
}
} else if (this->autoSizedValue == this->finalSysSizing(this->curSysNum).DesCoolVolFlow) {
auto &sysSizPeakDDNum = state.dataSize->SysSizPeakDDNum(this->curSysNum);
if (sysSizPeakDDNum.CoolFlowPeakDD > 0 && sysSizPeakDDNum.CoolFlowPeakDD <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(sysSizPeakDDNum.CoolFlowPeakDD);
DDNameFanPeak = desDayInput.Title;
Expand All @@ -793,8 +818,51 @@ Real64 SystemAirFlowSizer::size(EnergyPlusData &state, Real64 _originalValue, bo
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, sysSizPeakDDNum.TimeStepAtCoolFlowPk(sysSizPeakDDNum.CoolFlowPeakDD)));
}
}
}
} else {
auto &sysSizPeakDDNum = state.dataSize->SysSizPeakDDNum(this->curSysNum);

if (this->airLoopSysFlag) {
auto const &unitarysysEqSizing = this->unitarySysEqSizing(this->curSysNum);
if (unitarysysEqSizing.CoolingAirFlow && unitarysysEqSizing.HeatingAirFlow) {
this->autoSizedValue = std::max(unitarysysEqSizing.CoolingAirVolFlow, unitarysysEqSizing.HeatingAirVolFlow);
if (this->autoSizedValue == unitarysysEqSizing.CoolingAirVolFlow) {
if (sysSizPeakDDNum.CoolFlowPeakDD > 0 && sysSizPeakDDNum.CoolFlowPeakDD <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(sysSizPeakDDNum.CoolFlowPeakDD);
DDNameFanPeak = desDayInput.Title;
dateTimeFanPeak = format("{}/{} {}",
desDayInput.Month,
desDayInput.DayOfMonth,
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, sysSizPeakDDNum.TimeStepAtCoolFlowPk(sysSizPeakDDNum.CoolFlowPeakDD)));
}

} else if (this->autoSizedValue == unitarysysEqSizing.HeatingAirVolFlow) {
} else if (this->autoSizedValue == unitarysysEqSizing.HeatingAirVolFlow) {
if (this->finalSysSizing(this->curSysNum).HeatDDNum > 0 &&
this->finalSysSizing(this->curSysNum).HeatDDNum <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(this->finalSysSizing(this->curSysNum).HeatDDNum);
DDNameFanPeak = desDayInput.Title;
dateTimeFanPeak = format("{}/{} {}",
desDayInput.Month,
desDayInput.DayOfMonth,
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, this->finalSysSizing(this->curSysNum).SysHeatAirTimeStepPk));
}
}
} else if (unitarysysEqSizing.CoolingAirFlow) {
this->autoSizedValue = unitarysysEqSizing.CoolingAirVolFlow;
if (sysSizPeakDDNum.CoolFlowPeakDD > 0 && sysSizPeakDDNum.CoolFlowPeakDD <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(sysSizPeakDDNum.CoolFlowPeakDD);
DDNameFanPeak = state.dataWeather->DesDayInput(sysSizPeakDDNum.CoolFlowPeakDD).Title;
dateTimeFanPeak = format("{}/{} {}",
desDayInput.Month,
desDayInput.DayOfMonth,
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, sysSizPeakDDNum.TimeStepAtCoolFlowPk(sysSizPeakDDNum.CoolFlowPeakDD)));
}
} else if (unitarysysEqSizing.HeatingAirFlow) {
this->autoSizedValue = unitarysysEqSizing.HeatingAirVolFlow;
if (this->finalSysSizing(this->curSysNum).HeatDDNum > 0 &&
this->finalSysSizing(this->curSysNum).HeatDDNum <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(this->finalSysSizing(this->curSysNum).HeatDDNum);
Expand All @@ -805,31 +873,32 @@ Real64 SystemAirFlowSizer::size(EnergyPlusData &state, Real64 _originalValue, bo
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, this->finalSysSizing(this->curSysNum).SysHeatAirTimeStepPk));
}
}
} else if (unitarysysEqSizing.CoolingAirFlow) {
this->autoSizedValue = unitarysysEqSizing.CoolingAirVolFlow;
if (sysSizPeakDDNum.CoolFlowPeakDD > 0 && sysSizPeakDDNum.CoolFlowPeakDD <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(sysSizPeakDDNum.CoolFlowPeakDD);
DDNameFanPeak = state.dataWeather->DesDayInput(sysSizPeakDDNum.CoolFlowPeakDD).Title;
dateTimeFanPeak = format("{}/{} {}",
desDayInput.Month,
desDayInput.DayOfMonth,
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, sysSizPeakDDNum.TimeStepAtCoolFlowPk(sysSizPeakDDNum.CoolFlowPeakDD)));
}
} else if (unitarysysEqSizing.HeatingAirFlow) {
this->autoSizedValue = unitarysysEqSizing.HeatingAirVolFlow;
if (this->finalSysSizing(this->curSysNum).HeatDDNum > 0 &&
this->finalSysSizing(this->curSysNum).HeatDDNum <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(this->finalSysSizing(this->curSysNum).HeatDDNum);
DDNameFanPeak = desDayInput.Title;
dateTimeFanPeak = format("{}/{} {}",
desDayInput.Month,
desDayInput.DayOfMonth,
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, this->finalSysSizing(this->curSysNum).SysHeatAirTimeStepPk));
}

} else {
this->autoSizedValue = this->finalSysSizing(this->curSysNum).DesMainVolFlow;
if (this->autoSizedValue == this->finalSysSizing(this->curSysNum).DesHeatVolFlow) {
if (this->finalSysSizing(this->curSysNum).HeatDDNum > 0 &&
this->finalSysSizing(this->curSysNum).HeatDDNum <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(this->finalSysSizing(this->curSysNum).HeatDDNum);
DDNameFanPeak = desDayInput.Title;
dateTimeFanPeak = format("{}/{} {}",
desDayInput.Month,
desDayInput.DayOfMonth,
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, this->finalSysSizing(this->curSysNum).SysHeatAirTimeStepPk));
}
} else if (this->autoSizedValue == this->finalSysSizing(this->curSysNum).DesCoolVolFlow) {
if (sysSizPeakDDNum.CoolFlowPeakDD > 0 && sysSizPeakDDNum.CoolFlowPeakDD <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(sysSizPeakDDNum.CoolFlowPeakDD);
DDNameFanPeak = desDayInput.Title;
dateTimeFanPeak = format("{}/{} {}",
desDayInput.Month,
desDayInput.DayOfMonth,
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, sysSizPeakDDNum.TimeStepAtCoolFlowPk(sysSizPeakDDNum.CoolFlowPeakDD)));
}
}
}
} else {
this->autoSizedValue = this->finalSysSizing(this->curSysNum).DesMainVolFlow;
if (this->autoSizedValue == this->finalSysSizing(this->curSysNum).DesHeatVolFlow) {
Expand All @@ -855,32 +924,8 @@ Real64 SystemAirFlowSizer::size(EnergyPlusData &state, Real64 _originalValue, bo
}
}
}
} else {
this->autoSizedValue = this->finalSysSizing(this->curSysNum).DesMainVolFlow;
if (this->autoSizedValue == this->finalSysSizing(this->curSysNum).DesHeatVolFlow) {
if (this->finalSysSizing(this->curSysNum).HeatDDNum > 0 &&
this->finalSysSizing(this->curSysNum).HeatDDNum <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(this->finalSysSizing(this->curSysNum).HeatDDNum);
DDNameFanPeak = desDayInput.Title;
dateTimeFanPeak = format("{}/{} {}",
desDayInput.Month,
desDayInput.DayOfMonth,
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, this->finalSysSizing(this->curSysNum).SysHeatAirTimeStepPk));
}
} else if (this->autoSizedValue == this->finalSysSizing(this->curSysNum).DesCoolVolFlow) {
if (sysSizPeakDDNum.CoolFlowPeakDD > 0 && sysSizPeakDDNum.CoolFlowPeakDD <= state.dataEnvrn->TotDesDays) {
auto &desDayInput = state.dataWeather->DesDayInput(sysSizPeakDDNum.CoolFlowPeakDD);
DDNameFanPeak = desDayInput.Title;
dateTimeFanPeak = format("{}/{} {}",
desDayInput.Month,
desDayInput.DayOfMonth,
state.dataRptCoilSelection->coilSelectionReportObj->getTimeText(
state, sysSizPeakDDNum.TimeStepAtCoolFlowPk(sysSizPeakDDNum.CoolFlowPeakDD)));
}
}
if (this->dataFractionUsedForSizing > 0.0) this->autoSizedValue = this->autoSizedValue * this->dataFractionUsedForSizing;
}
if (this->dataFractionUsedForSizing > 0.0) this->autoSizedValue = this->autoSizedValue * this->dataFractionUsedForSizing;
}
}
} else if (this->dataNonZoneNonAirloopValue > 0) {
Expand Down
19 changes: 19 additions & 0 deletions tst/EnergyPlus/unit/Autosizing/SystemAirFlowSizing.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,25 @@ TEST_F(AutoSizingFixture, SystemAirFlowSizingGauntlet)
eiooutput = std::string(" Component Sizing Information, Coil:Heating:Water, MyWaterCoil, Design Size Maximum Flow Rate [m3/s], 3.50000\n"
" Component Sizing Information, Coil:Heating:Water, MyWaterCoil, User-Specified Maximum Flow Rate [m3/s], 2.20000\n");
EXPECT_TRUE(compare_eio_stream(eiooutput, true));

// Test 58 - DOAS fan air flow rate autosizing
state->dataSize->HRFlowSizingFlag = false;
state->dataSize->CurOASysNum = 1;
state->dataAirLoop->OutsideAirSys(1).AirLoopDOASNum = 0;
AirLoopHVACDOAS::AirLoopDOAS thisDOAS;
state->dataAirLoopHVACDOAS->airloopDOAS.push_back(thisDOAS);
// use 0.53 m3/s multiplied by StdRhoAir = 1.2
state->dataAirLoopHVACDOAS->airloopDOAS[state->dataAirLoop->OutsideAirSys(1).AirLoopDOASNum].SizingMassFlow = 0.53 * 1.2;
inputValue = DataSizing::AutoSize;

// do sizing
sizer.wasAutoSized = false;
printFlag = true;
sizer.initializeWithinEP(*this->state, "Fan:SystemModel", "MyDOASFan", printFlag, routineName);
sizedValue = sizer.size(*this->state, inputValue, errorsFound);
EXPECT_ENUM_EQ(AutoSizingResultType::NoError, sizer.errorType); // cumulative of previous calls
EXPECT_TRUE(sizer.wasAutoSized);
EXPECT_NEAR(0.53, sizedValue, 0.01); // auto-sized value
}

} // namespace EnergyPlus

3 comments on commit c0a6271

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

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

develop (Myoldmopar) - x86_64-Linux-Ubuntu-24.04-gcc-13.3: OK (2919 of 2919 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

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

develop (Myoldmopar) - x86_64-Linux-Ubuntu-24.04-gcc-13.3-UnitTestsCoverage-RelWithDebInfo: OK (2101 of 2101 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

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

develop (Myoldmopar) - x86_64-Linux-Ubuntu-24.04-gcc-13.3-IntegrationCoverage-RelWithDebInfo: OK (801 of 801 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

Please sign in to comment.