Skip to content

Commit

Permalink
Support and calculate temperatures of sealed forced-ventilation gaps,…
Browse files Browse the repository at this point in the history
… that is, forced-ventilation gaps sandwiched between solids
  • Loading branch information
simon-wacker committed Nov 18, 2022
1 parent 7dc4422 commit 156b5e0
Show file tree
Hide file tree
Showing 5 changed files with 419 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/Tarcog/src/IGU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,22 @@ namespace Tarcog
}
if(std::dynamic_pointer_cast<CIGUGapLayer>(t_Layer) != nullptr)
{
auto gap = std::dynamic_pointer_cast<CIGUGapLayer>(t_Layer);
if(std::dynamic_pointer_cast<CIGUShadeLayer>(t_Layer->getPreviousLayer())
!= nullptr)
{
auto newLayer = std::make_shared<CIGUVentilatedGapLayer>(gap);
replaceLayer(std::dynamic_pointer_cast<CIGUGapLayer>(t_Layer), newLayer);
}
else if(gap->isVentilationForced()
&& std::dynamic_pointer_cast<CIGUSolidLayer>(t_Layer->getPreviousLayer())
!= nullptr
&& std::dynamic_pointer_cast<CIGUShadeLayer>(t_Layer->getPreviousLayer())
== nullptr
&& std::dynamic_pointer_cast<CIGUSolidLayer>(t_Layer->getNextLayer())
!= nullptr
&& std::dynamic_pointer_cast<CIGUShadeLayer>(t_Layer->getNextLayer())
== nullptr)
{
auto newLayer = std::make_shared<CIGUVentilatedGapLayer>(
std::dynamic_pointer_cast<CIGUGapLayer>(t_Layer));
Expand Down
73 changes: 73 additions & 0 deletions src/Tarcog/src/IGUVentilatedGapLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
#include <cassert>
#include <stdexcept>

#include "BaseShade.hpp"
#include "TarcogConstants.hpp"
#include "IGUVentilatedGapLayer.hpp"
#include "WCEGases.hpp"
#include "WCECommon.hpp"

using FenestrationCommon::Side;

namespace Tarcog
{
Expand Down Expand Up @@ -155,10 +159,79 @@ namespace Tarcog
CIGUGapLayer::calculateConvectionOrConductionFlow();
if(!isCalculated())
{
if(isVentilationForced() && m_NextLayer != nullptr && m_PreviousLayer != nullptr
&& std::dynamic_pointer_cast<CIGUSolidLayer>(m_PreviousLayer) != nullptr
&& std::dynamic_pointer_cast<CIGUShadeLayer>(m_PreviousLayer) == nullptr
&& std::dynamic_pointer_cast<CIGUSolidLayer>(m_NextLayer) != nullptr
&& std::dynamic_pointer_cast<CIGUShadeLayer>(m_NextLayer) == nullptr)
{
auto previousSolidLayer =
std::dynamic_pointer_cast<CIGUSolidLayer>(m_PreviousLayer);
auto nextSolidLayer = std::dynamic_pointer_cast<CIGUSolidLayer>(m_NextLayer);
calcSealedForcedVentilationGapTemperatures(previousSolidLayer, nextSolidLayer);
}
ventilatedFlow();
}
}

void CIGUVentilatedGapLayer::calcSealedForcedVentilationGapTemperatures(
std::shared_ptr<CIGUSolidLayer> t_PreviousLayer,
std::shared_ptr<CIGUSolidLayer> t_NextLayer)
{
// Inspired by `CIGUShadeLayer::calcEdgeShadeFlow`
double TgapOut = layerTemperature();
double RelaxationParameter = IterationConstants::RELAXATION_PARAMETER_AIRFLOW;
bool converged = false;
size_t iterationStep = 0;

double tempGap = layerTemperature();
ForcedVentilation forcedVentilation = getForcedVentilation();
setFlowSpeed(forcedVentilation.Speed);
// m_AirSpeed = forcedVentilation.Speed;
double tempPreviousLayer = t_PreviousLayer->getTemperature(Side::Back);
while(!converged)
{
double TavGap = averageTemperature();
// TODO Calling `betaCoeff` results in an infinite recursion
// because it calls `calculateLayerHeatFlow`. I do not believe
// that the latter call is required because we set `m_AirSpeed`
// above. Are all other properties also set? What about
// `m_ConductiveConvectiveCoeff`?
// TODO If `beta` and `TavGap` do not change during the
// loop, then extract them.
double beta = exp(-m_Height / characteristicHeight());
double alpha = 1 - beta;

double TgapOutOld = TgapOut;

TgapOut = alpha * TavGap + beta * tempPreviousLayer;

setFlowTemperatures(tempPreviousLayer, TgapOut);
// m_inTemperature = tempPreviousLayer;
// m_outTemperature = TgapOut;

tempGap = layerTemperature();

TgapOut = RelaxationParameter * tempGap + (1 - RelaxationParameter) * TgapOutOld;

converged = std::abs(TgapOut - TgapOutOld)
< IterationConstants::CONVERGENCE_TOLERANCE_AIRFLOW;

++iterationStep;
if(iterationStep > IterationConstants::NUMBER_OF_STEPS)
{
RelaxationParameter -= IterationConstants::RELAXATION_PARAMETER_AIRFLOW_STEP;
iterationStep = 0;
if(RelaxationParameter == IterationConstants::RELAXATION_PARAMETER_AIRFLOW_MIN)
{
converged = true;
throw std::runtime_error("Airflow iterations fail to converge. "
"Maximum number of iteration steps reached.");
}
}
}
}

double CIGUVentilatedGapLayer::characteristicHeight()
{
const auto aProperties = m_Gas.getGasProperties();
Expand Down
4 changes: 4 additions & 0 deletions src/Tarcog/src/IGUVentilatedGapLayer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <memory>

#include "BaseShade.hpp"
#include "WCEGases.hpp"
#include "IGUGapLayer.hpp"

Expand Down Expand Up @@ -41,6 +42,9 @@ namespace Tarcog
double characteristicHeight();
double calcImpedance(double t_A) const;
void ventilatedFlow();
void calcSealedForcedVentilationGapTemperatures(
std::shared_ptr<CIGUSolidLayer> t_PreviousLayer,
std::shared_ptr<CIGUSolidLayer> t_NextLayer);

std::shared_ptr<CIGUGapLayer> m_Layer;
Gases::CGas m_ReferenceGas;
Expand Down
164 changes: 164 additions & 0 deletions src/Tarcog/tst/units/GapLayerSealedForcedVentilation.unit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include <memory>
#include <gtest/gtest.h>

#include "WCETarcog.hpp"

class TestGapLayerSealedForcedVentilation : public testing::Test
{
private:
std::shared_ptr<Tarcog::ISO15099::CSingleSystem> m_TarcogSystem;

protected:
void SetUp() override
{
/////////////////////////////////////////////////////////
// Outdoor
/////////////////////////////////////////////////////////
auto airTemperature = 255.15; // Kelvins
auto airSpeed = 5.5; // meters per second
auto tSky = 255.15; // Kelvins
auto solarRadiation = 0.0;

auto Outdoor = Tarcog::ISO15099::Environments::outdoor(
airTemperature, airSpeed, solarRadiation, tSky, Tarcog::ISO15099::SkyModel::AllSpecified);
ASSERT_TRUE(Outdoor != nullptr);
Outdoor->setHCoeffModel(Tarcog::ISO15099::BoundaryConditionsCoeffModel::CalculateH);

/////////////////////////////////////////////////////////
/// Indoor
/////////////////////////////////////////////////////////

auto roomTemperature = 295.15;

auto Indoor = Tarcog::ISO15099::Environments::indoor(roomTemperature);
ASSERT_TRUE(Indoor != nullptr);

// IGU
auto solidLayerThickness = 0.005715; // [m]
auto solidLayerConductance = 1.0;

auto solidLayer1 =
Tarcog::ISO15099::Layers::solid(solidLayerThickness, solidLayerConductance);
ASSERT_TRUE(solidLayer1 != nullptr);

auto solidLayer2 =
Tarcog::ISO15099::Layers::solid(solidLayerThickness, solidLayerConductance);
ASSERT_TRUE(solidLayer2 != nullptr);

auto gapThickness = 0.0127;
auto gapAirSpeed = 0.5;
Tarcog::ISO15099::ForcedVentilation forcedVentilation = {gapAirSpeed};
auto gap = Tarcog::ISO15099::Layers::forcedVentilationGap(gapThickness, forcedVentilation);
ASSERT_TRUE(gap != nullptr);

double windowWidth = 1;
double windowHeight = 1;
Tarcog::ISO15099::CIGU aIGU(windowWidth, windowHeight);
aIGU.addLayers({solidLayer1, gap, solidLayer2});

/////////////////////////////////////////////////////////
/// System
/////////////////////////////////////////////////////////
m_TarcogSystem = std::make_shared<Tarcog::ISO15099::CSingleSystem>(aIGU, Indoor, Outdoor);
ASSERT_TRUE(m_TarcogSystem != nullptr);

m_TarcogSystem->solve();
}

public:
std::shared_ptr<Tarcog::ISO15099::CIGUSolidLayer> GetSolidLayer1() const
{
auto solidLayer = m_TarcogSystem->getSolidLayers()[0];
assert(std::dynamic_pointer_cast<Tarcog::ISO15099::CIGUSolidLayer>(solidLayer) != nullptr);
return std::dynamic_pointer_cast<Tarcog::ISO15099::CIGUSolidLayer>(solidLayer);
};

std::shared_ptr<Tarcog::ISO15099::CIGUVentilatedGapLayer> GetGap() const
{
auto gap = m_TarcogSystem->getGapLayers()[0];
assert(std::dynamic_pointer_cast<Tarcog::ISO15099::CIGUVentilatedGapLayer>(gap) != nullptr);
return std::dynamic_pointer_cast<Tarcog::ISO15099::CIGUVentilatedGapLayer>(gap);
};

std::shared_ptr<Tarcog::ISO15099::CIGUSolidLayer> GetSolidLayer2() const
{
auto solidLayer = m_TarcogSystem->getSolidLayers()[1];
assert(std::dynamic_pointer_cast<Tarcog::ISO15099::CIGUSolidLayer>(solidLayer) != nullptr);
return std::dynamic_pointer_cast<Tarcog::ISO15099::CIGUSolidLayer>(solidLayer);
};
};

TEST_F(TestGapLayerSealedForcedVentilation, GainEnergy)
{
SCOPED_TRACE("Begin Test: Test Ventilated Gap Layer - Gain Energy");

auto aLayer = GetGap();

// Airflow iterations are set to 1e-4 and it cannot exceed that precision

ASSERT_TRUE(aLayer != nullptr);
auto gainEnergy = aLayer->getGainFlow();
EXPECT_NEAR(-57.193291279467125, gainEnergy, 1e-4);
}

TEST_F(TestGapLayerSealedForcedVentilation, Solid1Temperatures)
{
SCOPED_TRACE("Begin Test: Test Ventilated Gap Layer - Solid 1 Temperatures");

auto aLayer = GetSolidLayer1();

// Airflow iterations are set to 1e-4 and it cannot exceed that precision

ASSERT_TRUE(aLayer != nullptr);
auto frontTemperature = aLayer->getTemperature(FenestrationCommon::Side::Front);
auto backTemperature = aLayer->getTemperature(FenestrationCommon::Side::Back);
EXPECT_NEAR(257.88610911376719, frontTemperature, 1e-4);
EXPECT_NEAR(258.34294987245784, backTemperature, 1e-4);
}

TEST_F(TestGapLayerSealedForcedVentilation, GapTemperatures)
{
SCOPED_TRACE("Begin Test: Test Ventilated Gap Layer - Gap Temperatures");

auto aLayer = GetGap();

// Airflow iterations are set to 1e-4 and it cannot exceed that precision

ASSERT_TRUE(aLayer != nullptr);
auto frontTemperature = aLayer->getTemperature(FenestrationCommon::Side::Front);
auto backTemperature = aLayer->getTemperature(FenestrationCommon::Side::Back);
auto layerTemperature = aLayer->layerTemperature();
auto averageTemperature = aLayer->averageTemperature();
EXPECT_NEAR(258.34294987245784, frontTemperature, 1e-4);
EXPECT_NEAR(276.01222466583204, backTemperature, 1e-4);
EXPECT_NEAR(262.42249308270669, layerTemperature, 1e-4);
EXPECT_NEAR(267.17758726914496, averageTemperature, 1e-4);
}

TEST_F(TestGapLayerSealedForcedVentilation, Solid2Temperatures)
{
SCOPED_TRACE("Begin Test: Test Ventilated Gap Layer - Solid 2 Temperatures");

auto aLayer = GetSolidLayer2();

// Airflow iterations are set to 1e-4 and it cannot exceed that precision

ASSERT_TRUE(aLayer != nullptr);
auto frontTemperature = aLayer->getTemperature(FenestrationCommon::Side::Front);
auto backTemperature = aLayer->getTemperature(FenestrationCommon::Side::Back);
EXPECT_NEAR(276.01222466583204, frontTemperature, 1e-4);
EXPECT_NEAR(276.79592508330529, backTemperature, 1e-4);
}

TEST_F(TestGapLayerSealedForcedVentilation, AirflowReferencePoint)
{
SCOPED_TRACE("Begin Test: Test Ventilated Gap Layer - Airflow Reference Point");

auto aLayer = GetGap();

// Airflow iterations are set to 1e-4 and it cannot exceed that precision

ASSERT_TRUE(aLayer != nullptr);
auto airflowReferencePoint = aLayer->getAirflowReferencePoint(0.5);
EXPECT_NEAR(6911.4449859804226, airflowReferencePoint, 1e-4);
}
Loading

0 comments on commit 156b5e0

Please sign in to comment.