Skip to content

Commit

Permalink
Solution to CondFD Flux Imbalance
Browse files Browse the repository at this point in the history
It was determined that the outside surface flux was wrong for a multi-year simulation.  Testing and comparing two output variables that should be almost identical showed than when the IsRain flag was true that things were way off.  This is because the one variable was not being calculated properly.  As a result, there were flux inconsistencies.  The fix corrects this problem and eliminates the inconsistency.  A unit test is also included in this commit.
  • Loading branch information
RKStrand committed Sep 16, 2023
1 parent 8134ee0 commit 135fd37
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 62 deletions.
2 changes: 2 additions & 0 deletions src/EnergyPlus/HeatBalFiniteDiffManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2609,6 +2609,8 @@ namespace HeatBalFiniteDiffManager {
interNodeFlux - sourceFlux +
surfaceFD.CpDelXRhoS2(node) * (surfaceFD.TDT(node) - surfaceFD.TDpriortimestep(node)) / state.dataGlobal->TimeStepZoneSec;
}
if (state.dataEnvrn->IsRain)
state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(Surf) = -surfaceFD.QDreport(1); // Update the outside flux if it is raining
}

void adjustPropertiesForPhaseChange(EnergyPlusData &state,
Expand Down
163 changes: 101 additions & 62 deletions tst/EnergyPlus/unit/HeatBalFiniteDiffManager.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
// EnergyPlus Headers
#include <EnergyPlus/Construction.hh>
#include <EnergyPlus/Data/EnergyPlusData.hh>
#include <EnergyPlus/DataEnvironment.hh>
#include <EnergyPlus/DataHeatBalSurface.hh>
#include <EnergyPlus/HeatBalFiniteDiffManager.hh>
#include <EnergyPlus/HeatBalanceManager.hh>
Expand All @@ -70,69 +71,90 @@ TEST_F(EnergyPlusFixture, HeatBalFiniteDiffManager_CalcNodeHeatFluxTest)
{
auto &SurfaceFD = state->dataHeatBalFiniteDiffMgr->SurfaceFD;
int constexpr numNodes(4);
Real64 constexpr allowedTolerance = 0.0001;
int nodeNum(0);
SurfaceFD.allocate(1);
int constexpr SurfNum(1);
SurfaceFD(SurfNum).QDreport.allocate(numNodes + 1);
SurfaceFD(SurfNum).TDpriortimestep.allocate(numNodes + 1);
SurfaceFD(SurfNum).TDT.allocate(numNodes + 1);
SurfaceFD(SurfNum).CpDelXRhoS1.allocate(numNodes + 1);
SurfaceFD(SurfNum).CpDelXRhoS2.allocate(numNodes + 1);
auto &surfFD = SurfaceFD(SurfNum);
surfFD.QDreport.allocate(numNodes + 1);
surfFD.TDpriortimestep.allocate(numNodes + 1);
surfFD.TDT.allocate(numNodes + 1);
surfFD.CpDelXRhoS1.allocate(numNodes + 1);
surfFD.CpDelXRhoS2.allocate(numNodes + 1);
state->dataHeatBalSurf->SurfOpaqInsFaceCondFlux.allocate(1);
state->dataHeatBalSurf->SurfOpaqOutFaceCondFlux.allocate(1);
state->dataGlobal->TimeStepZoneSec = 600.0;

Real64 expectedResult1(0.0);
Real64 expectedResult2(0.0);
Real64 expectedResult3(0.0);
Real64 expectedResult4(0.0);
Real64 expectedResult5(0.0);
Real64 expectedResultO(1.0);

// Steady-state case
state->dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = 100.0;
nodeNum = 1;
SurfaceFD(SurfNum).TDpriortimestep(nodeNum) = 20.0;
SurfaceFD(SurfNum).TDT(nodeNum) = 20.0;
SurfaceFD(SurfNum).CpDelXRhoS1(nodeNum) = 1000.0;
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) = 2000.0;
surfFD.TDpriortimestep(nodeNum) = 20.0;
surfFD.TDT(nodeNum) = 20.0;
surfFD.CpDelXRhoS1(nodeNum) = 1000.0;
surfFD.CpDelXRhoS2(nodeNum) = 2000.0;
expectedResult1 = state->dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum);

nodeNum = 2;
SurfaceFD(SurfNum).TDpriortimestep(nodeNum) = 22.0;
SurfaceFD(SurfNum).TDT(nodeNum) = 22.0;
SurfaceFD(SurfNum).CpDelXRhoS1(nodeNum) = 1000.0;
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) = 2000.0;
surfFD.TDpriortimestep(nodeNum) = 22.0;
surfFD.TDT(nodeNum) = 22.0;
surfFD.CpDelXRhoS1(nodeNum) = 1000.0;
surfFD.CpDelXRhoS2(nodeNum) = 2000.0;
expectedResult2 = state->dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum);

nodeNum = 3;
SurfaceFD(SurfNum).TDpriortimestep(nodeNum) = 23.0;
SurfaceFD(SurfNum).TDT(nodeNum) = 23.0;
SurfaceFD(SurfNum).CpDelXRhoS1(nodeNum) = 1000.0;
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) = 2000.0;
surfFD.TDpriortimestep(nodeNum) = 23.0;
surfFD.TDT(nodeNum) = 23.0;
surfFD.CpDelXRhoS1(nodeNum) = 1000.0;
surfFD.CpDelXRhoS2(nodeNum) = 2000.0;
expectedResult3 = state->dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum);

nodeNum = 4;
SurfaceFD(SurfNum).TDpriortimestep(nodeNum) = 26.0;
SurfaceFD(SurfNum).TDT(nodeNum) = 26.0;
SurfaceFD(SurfNum).CpDelXRhoS1(nodeNum) = 1000.0;
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) = 2000.0;
surfFD.TDpriortimestep(nodeNum) = 26.0;
surfFD.TDT(nodeNum) = 26.0;
surfFD.CpDelXRhoS1(nodeNum) = 1000.0;
surfFD.CpDelXRhoS2(nodeNum) = 2000.0;
expectedResult4 = state->dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum);

nodeNum = 5;
SurfaceFD(SurfNum).TDpriortimestep(nodeNum) = 27.0;
SurfaceFD(SurfNum).TDT(nodeNum) = 27.0;
SurfaceFD(SurfNum).CpDelXRhoS1(nodeNum) = 1000.0;
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) = 2000.0;
surfFD.TDpriortimestep(nodeNum) = 27.0;
surfFD.TDT(nodeNum) = 27.0;
surfFD.CpDelXRhoS1(nodeNum) = 1000.0;
surfFD.CpDelXRhoS2(nodeNum) = 2000.0;
expectedResult5 = state->dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum);

state->dataEnvrn->IsRain = false;
state->dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = 77.0;
expectedResultO = 77.0;

CalcNodeHeatFlux(*state, SurfNum, numNodes);
EXPECT_NEAR(surfFD.QDreport(1), expectedResult1, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(2), expectedResult2, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(3), expectedResult3, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(4), expectedResult4, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(5), expectedResult5, allowedTolerance);
EXPECT_NEAR(state->dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum), expectedResultO, allowedTolerance);

state->dataEnvrn->IsRain = true;
state->dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = 77.0;
expectedResultO = -state->dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum);

CalcNodeHeatFlux(*state, SurfNum, numNodes);
EXPECT_NEAR(SurfaceFD(SurfNum).QDreport(1), expectedResult1, 0.0001);
EXPECT_NEAR(SurfaceFD(SurfNum).QDreport(2), expectedResult2, 0.0001);
EXPECT_NEAR(SurfaceFD(SurfNum).QDreport(3), expectedResult3, 0.0001);
EXPECT_NEAR(SurfaceFD(SurfNum).QDreport(4), expectedResult4, 0.0001);
EXPECT_NEAR(SurfaceFD(SurfNum).QDreport(5), expectedResult5, 0.0001);
EXPECT_NEAR(surfFD.QDreport(1), expectedResult1, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(2), expectedResult2, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(3), expectedResult3, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(4), expectedResult4, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(5), expectedResult5, allowedTolerance);
EXPECT_NEAR(state->dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum), expectedResultO, allowedTolerance);

// Reset
SurfaceFD(SurfNum).QDreport = 0.0;
surfFD.QDreport = 0.0;
expectedResult1 = 0.0;
expectedResult2 = 0.0;
expectedResult3 = 0.0;
Expand All @@ -144,50 +166,67 @@ TEST_F(EnergyPlusFixture, HeatBalFiniteDiffManager_CalcNodeHeatFluxTest)
state->dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = -200.0;

nodeNum = 5;
SurfaceFD(SurfNum).TDpriortimestep(nodeNum) = 27.5;
SurfaceFD(SurfNum).TDT(nodeNum) = 27.0;
SurfaceFD(SurfNum).CpDelXRhoS1(nodeNum) = 0.0;
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) = 0.0;
surfFD.TDpriortimestep(nodeNum) = 27.5;
surfFD.TDT(nodeNum) = 27.0;
surfFD.CpDelXRhoS1(nodeNum) = 0.0;
surfFD.CpDelXRhoS2(nodeNum) = 0.0;
expectedResult5 = state->dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum);

nodeNum = 4;
SurfaceFD(SurfNum).TDpriortimestep(nodeNum) = 26.0;
SurfaceFD(SurfNum).TDT(nodeNum) = 26.0;
SurfaceFD(SurfNum).CpDelXRhoS1(nodeNum) = 0.0;
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) = 2000.0;
surfFD.TDpriortimestep(nodeNum) = 26.0;
surfFD.TDT(nodeNum) = 26.0;
surfFD.CpDelXRhoS1(nodeNum) = 0.0;
surfFD.CpDelXRhoS2(nodeNum) = 2000.0;
expectedResult4 = expectedResult5; // r-layer with zero heat capacity, so flux passes through

nodeNum = 3;
SurfaceFD(SurfNum).TDpriortimestep(nodeNum) = 23.0;
SurfaceFD(SurfNum).TDT(nodeNum) = 23.0;
SurfaceFD(SurfNum).CpDelXRhoS1(nodeNum) = 1000.0;
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) = 2000.0;
surfFD.TDpriortimestep(nodeNum) = 23.0;
surfFD.TDT(nodeNum) = 23.0;
surfFD.CpDelXRhoS1(nodeNum) = 1000.0;
surfFD.CpDelXRhoS2(nodeNum) = 2000.0;
expectedResult3 = expectedResult4; // no change in temperature at nodes 4 and 3, so flux passes through

nodeNum = 2;
SurfaceFD(SurfNum).TDpriortimestep(nodeNum) = 22.2;
SurfaceFD(SurfNum).TDT(nodeNum) = 22.0;
SurfaceFD(SurfNum).CpDelXRhoS1(nodeNum) = 1000.0;
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) = 2000.0;
expectedResult2 = expectedResult3 + (SurfaceFD(SurfNum).TDT(nodeNum) - SurfaceFD(SurfNum).TDpriortimestep(nodeNum)) *
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) / state->dataGlobal->TimeStepZoneSec;
surfFD.TDpriortimestep(nodeNum) = 22.2;
surfFD.TDT(nodeNum) = 22.0;
surfFD.CpDelXRhoS1(nodeNum) = 1000.0;
surfFD.CpDelXRhoS2(nodeNum) = 2000.0;
expectedResult2 =
expectedResult3 + (surfFD.TDT(nodeNum) - surfFD.TDpriortimestep(nodeNum)) * surfFD.CpDelXRhoS2(nodeNum) / state->dataGlobal->TimeStepZoneSec;

nodeNum = 1;
SurfaceFD(SurfNum).TDpriortimestep(nodeNum) = 20.1;
SurfaceFD(SurfNum).TDT(nodeNum) = 20.0;
SurfaceFD(SurfNum).CpDelXRhoS1(nodeNum) = 1000.0;
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) = 2000.0;
expectedResult1 = expectedResult2 + (SurfaceFD(SurfNum).TDT(nodeNum + 1) - SurfaceFD(SurfNum).TDpriortimestep(nodeNum + 1)) *
SurfaceFD(SurfNum).CpDelXRhoS1(nodeNum + 1) / state->dataGlobal->TimeStepZoneSec;
expectedResult1 = expectedResult1 + (SurfaceFD(SurfNum).TDT(nodeNum) - SurfaceFD(SurfNum).TDpriortimestep(nodeNum)) *
SurfaceFD(SurfNum).CpDelXRhoS2(nodeNum) / state->dataGlobal->TimeStepZoneSec;
surfFD.TDpriortimestep(nodeNum) = 20.1;
surfFD.TDT(nodeNum) = 20.0;
surfFD.CpDelXRhoS1(nodeNum) = 1000.0;
surfFD.CpDelXRhoS2(nodeNum) = 2000.0;
expectedResult1 = expectedResult2 + (surfFD.TDT(nodeNum + 1) - surfFD.TDpriortimestep(nodeNum + 1)) * surfFD.CpDelXRhoS1(nodeNum + 1) /
state->dataGlobal->TimeStepZoneSec;
expectedResult1 =
expectedResult1 + (surfFD.TDT(nodeNum) - surfFD.TDpriortimestep(nodeNum)) * surfFD.CpDelXRhoS2(nodeNum) / state->dataGlobal->TimeStepZoneSec;

state->dataEnvrn->IsRain = false;
state->dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = 123.0;
expectedResultO = 123.0;

CalcNodeHeatFlux(*state, SurfNum, numNodes);
EXPECT_NEAR(surfFD.QDreport(1), expectedResult1, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(2), expectedResult2, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(3), expectedResult3, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(4), expectedResult4, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(5), expectedResult5, allowedTolerance);
EXPECT_NEAR(state->dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum), expectedResultO, allowedTolerance);

state->dataEnvrn->IsRain = true;
state->dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = 123.0;
expectedResultO = -expectedResult1;

CalcNodeHeatFlux(*state, SurfNum, numNodes);
EXPECT_NEAR(SurfaceFD(SurfNum).QDreport(1), expectedResult1, 0.0001);
EXPECT_NEAR(SurfaceFD(SurfNum).QDreport(2), expectedResult2, 0.0001);
EXPECT_NEAR(SurfaceFD(SurfNum).QDreport(3), expectedResult3, 0.0001);
EXPECT_NEAR(SurfaceFD(SurfNum).QDreport(4), expectedResult4, 0.0001);
EXPECT_NEAR(SurfaceFD(SurfNum).QDreport(5), expectedResult5, 0.0001);
EXPECT_NEAR(surfFD.QDreport(1), expectedResult1, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(2), expectedResult2, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(3), expectedResult3, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(4), expectedResult4, allowedTolerance);
EXPECT_NEAR(surfFD.QDreport(5), expectedResult5, allowedTolerance);
EXPECT_NEAR(state->dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum), expectedResultO, allowedTolerance);
}

TEST_F(EnergyPlusFixture, HeatBalFiniteDiffManager_adjustPropertiesForPhaseChange)
Expand Down

5 comments on commit 135fd37

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

8234AccumulatingFluxImbalanceCondFD (RKStrand) - Win64-Windows-10-VisualStudio-16: OK (2731 of 2731 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-3
Copy link

Choose a reason for hiding this comment

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

8234AccumulatingFluxImbalanceCondFD (RKStrand) - x86_64-MacOS-10.17-clang-14.0.0: OK (3516 of 3516 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

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

8234AccumulatingFluxImbalanceCondFD (RKStrand) - x86_64-Linux-Ubuntu-22.04-gcc-11.4: OK (3557 of 3557 tests passed, 1 test warnings)

Messages:\n

  • 1 test had: Table small diffs.

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.

8234AccumulatingFluxImbalanceCondFD (RKStrand) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-UnitTestsCoverage-Debug: OK (1946 of 1946 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

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

8234AccumulatingFluxImbalanceCondFD (RKStrand) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-IntegrationCoverage-Debug: OK (788 of 788 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

Please sign in to comment.