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
3 changes: 3 additions & 0 deletions src/energyplus/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ set(${target_name}_src
ForwardTranslator/ForwardTranslateThermalStorageIceDetailed.cpp
ForwardTranslator/ForwardTranslateThermalStorageChilledWaterStratified.cpp
ForwardTranslator/ForwardTranslateThermalZone.cpp
ForwardTranslator/ForwardTranslateThermochromicGlazing.cpp
ForwardTranslator/ForwardTranslateThermostatSetpointDualSetpoint.cpp
ForwardTranslator/ForwardTranslateTimestep.cpp
ForwardTranslator/ForwardTranslateUnitarySystemPerformanceMultispeed.cpp
Expand Down Expand Up @@ -632,6 +633,7 @@ set(${target_name}_src
ReverseTranslator/ReverseTranslateVersion.cpp
ReverseTranslator/ReverseTranslateWindowMaterialGas.cpp
ReverseTranslator/ReverseTranslateWindowMaterialGlazing.cpp
ReverseTranslator/ReverseTranslateWindowMaterialGlazingGroupThermochromic.cpp
ReverseTranslator/ReverseTranslateWindowMaterialSimpleGlazingSystem.cpp
ReverseTranslator/ReverseTranslateWindowPropertyFrameAndDivider.cpp
ReverseTranslator/ReverseTranslateWindowShadingControl.cpp
Expand Down Expand Up @@ -845,6 +847,7 @@ set(${target_name}_test_src
Test/TableLookup_GTest.cpp
Test/ThermalStorageChilledWaterStratified_GTest.cpp
Test/ThermalZone_GTest.cpp
Test/ThermochromicGlazing_GTest.cpp
Test/ThermostatSetpointDualSetpoint_GTest.cpp
Test/UnitarySystemPerformanceMultispeed_GTest.cpp
Test/WindowPropertyFrameAndDivider_GTest.cpp
Expand Down
3 changes: 2 additions & 1 deletion src/energyplus/ForwardTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3131,7 +3131,8 @@ namespace energyplus {
break;
}
case openstudio::IddObjectType::OS_WindowMaterial_GlazingGroup_Thermochromic: {
LOG(Warn, "OS_WindowMaterial_GlazingGroup_Thermochromic is not currently translated");
auto glazing = modelObject.cast<ThermochromicGlazing>();
retVal = translateThermochromicGlazing(glazing);
break;
}
case openstudio::IddObjectType::OS_WindowProperty_FrameAndDivider: {
Expand Down
3 changes: 3 additions & 0 deletions src/energyplus/ForwardTranslator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ namespace model {
class ThermalZone;
class ThermalStorageIceDetailed;
class ThermalStorageChilledWaterStratified;
class ThermochromicGlazing;
class ThermostatSetpointDualSetpoint;
class Timestep;
class UnitarySystemPerformanceMultispeed;
Expand Down Expand Up @@ -1522,6 +1523,8 @@ namespace energyplus {
// which is when fields on Sizing:Zone related to it are all defaulted (Implemeted in ForwardTranslateSizingZone)
boost::optional<std::string> zoneDSZADName(const model::ThermalZone& zone);

boost::optional<IdfObject> translateThermochromicGlazing(model::ThermochromicGlazing& modelObject);

boost::optional<IdfObject> translateThermostatSetpointDualSetpoint(model::ThermostatSetpointDualSetpoint& tsds);

boost::optional<IdfObject> translateTimestep(model::Timestep& modelObject);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/***********************************************************************************************************************
* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
* See also https://openstudio.net/license
***********************************************************************************************************************/

#include "../ForwardTranslator.hpp"
#include "../../model/Model.hpp"

#include "../../model/ThermochromicGlazing.hpp"

#include "../../utilities/math/FloatCompare.hpp"
#include "../../utilities/idf/IdfExtensibleGroup.hpp"
#include "../../utilities/idf/Workspace.hpp"

#include <utilities/idd/WindowMaterial_GlazingGroup_Thermochromic_FieldEnums.hxx>
#include <utilities/idd/IddEnums.hxx>

#include <algorithm> // For sort

using namespace openstudio::model;

namespace openstudio {

namespace energyplus {

boost::optional<IdfObject> ForwardTranslator::translateThermochromicGlazing(model::ThermochromicGlazing& modelObject) {

auto groups = modelObject.thermochromicGroups();
if (groups.empty()) {
LOG(Warn, "ThermochromicGlazing '" << modelObject.nameString() << "' has no ThermochromicGroups. Cannot translate.");
return boost::none;
}
// Instantiate an IdfObject of the class to store the values
IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::WindowMaterial_GlazingGroup_Thermochromic, modelObject);

// Sort by optical data temperature (ThermochromicGroup already has the operator< for this, but I'm making it clearer by using a lambda)
std::sort(groups.begin(), groups.end(),
[](const ThermochromicGroup& a, const ThermochromicGroup& b) { return a.opticalDataTemperature() < b.opticalDataTemperature(); });

auto first_thickness = groups.front().standardGlazing().thickness();

for (const auto& group : groups) {

IdfExtensibleGroup eg = idfObject.pushExtensibleGroup();
eg.setDouble(WindowMaterial_GlazingGroup_ThermochromicExtensibleFields::OpticalDataTemperature, group.opticalDataTemperature());
auto standardGlazing = group.standardGlazing();
if (boost::optional<IdfObject> wo_ = translateAndMapModelObject(standardGlazing)) {
eg.setString(WindowMaterial_GlazingGroup_ThermochromicExtensibleFields::WindowMaterialGlazingName, wo_->nameString());
}

// Check if the thickness is consistent across all groups
if (!openstudio::equal(group.standardGlazing().thickness(), first_thickness)) {
LOG(Warn, "ThermochromicGlazing '" << modelObject.nameString() << "' has inconsistent thicknesses across ThermochromicGroups. "
<< "Expected: " << first_thickness << ", found: " << group.standardGlazing().thickness());
}
}

return idfObject;
} // End of translate function

} // end namespace energyplus
} // end namespace openstudio
4 changes: 4 additions & 0 deletions src/energyplus/ReverseTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,10 @@ namespace energyplus {
modelObject = translateWindowMaterialGlazing(workspaceObject);
break;
}
case openstudio::IddObjectType::WindowMaterial_GlazingGroup_Thermochromic: {
modelObject = translateWindowMaterialGlazingGroupThermochromic(workspaceObject);
break;
}
case openstudio::IddObjectType::WindowMaterial_SimpleGlazingSystem: {
modelObject = translateWindowMaterialSimpleGlazingSystem(workspaceObject);
break;
Expand Down
2 changes: 2 additions & 0 deletions src/energyplus/ReverseTranslator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ namespace energyplus {

boost::optional<model::ModelObject> translateWindowMaterialGlazing(const WorkspaceObject& workspaceObject);

boost::optional<model::ModelObject> translateWindowMaterialGlazingGroupThermochromic(const WorkspaceObject& workspaceObject);

boost::optional<model::ModelObject> translateWindowMaterialSimpleGlazingSystem(const WorkspaceObject& workspaceObject);

boost::optional<model::ModelObject> translateWindowPropertyFrameAndDivider(const WorkspaceObject& workspaceObject);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ namespace energyplus {

openstudio::model::MaterialPropertyGlazingSpectralData glazingSpectralData(m_model);

// Name
if (boost::optional<std::string> name_ = workspaceObject.name()) {
glazingSpectralData.setName(name_.get());
}

// get extensible groups for spectral data fields
for (const IdfExtensibleGroup& idfGroup : workspaceObject.extensibleGroups()) {
auto workspaceGroup = idfGroup.cast<WorkspaceExtensibleGroup>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/***********************************************************************************************************************
* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
* See also https://openstudio.net/license
***********************************************************************************************************************/

#include "../ReverseTranslator.hpp"

#include "../../model/ThermochromicGlazing.hpp"
#include "../../model/StandardGlazing.hpp"
#include "../../model/StandardGlazing_Impl.hpp"

#include "../../utilities/idf/IdfExtensibleGroup.hpp"
#include "../../utilities/idf/WorkspaceExtensibleGroup.hpp"

#include <utilities/idd/WindowMaterial_GlazingGroup_Thermochromic_FieldEnums.hxx>
#include <utilities/idd/IddEnums.hxx>

using namespace openstudio::model;

namespace openstudio {

namespace energyplus {

boost::optional<ModelObject> ReverseTranslator::translateWindowMaterialGlazingGroupThermochromic(const WorkspaceObject& workspaceObject) {

openstudio::model::ThermochromicGlazing modelObject(m_model);

// Name
if (boost::optional<std::string> name_ = workspaceObject.name()) {
modelObject.setName(name_.get());
}

// Extensible groups
for (const IdfExtensibleGroup& eg : workspaceObject.extensibleGroups()) {
auto weg = eg.cast<WorkspaceExtensibleGroup>();

double opticalDataTemperature = 0.0;
if (auto opticalDataTemperature_ = weg.getDouble(WindowMaterial_GlazingGroup_ThermochromicExtensibleFields::OpticalDataTemperature)) {
opticalDataTemperature = *opticalDataTemperature_;
} else {
LOG(Warn, "Extensible group " << eg.groupIndex() << "(0-indexed) has an opticalDataTemperature, but it's a required field. Assuming zero");
}

if (boost::optional<WorkspaceObject> wo_ =
weg.getTarget(WindowMaterial_GlazingGroup_ThermochromicExtensibleFields::WindowMaterialGlazingName)) {
if (boost::optional<ModelObject> mo_ = translateAndMapWorkspaceObject(*wo_)) {
if (boost::optional<StandardGlazing> standardGlazing_ = mo_->optionalCast<StandardGlazing>()) {
modelObject.addThermochromicGroup(*standardGlazing_, opticalDataTemperature);
} else {
LOG(Warn, "Extensible group " << eg.groupIndex()
<< "(0-indexed) has a wrong type for WindowMaterialGlazingName, expected StandardGlazing, got "
<< mo_->briefDescription());
}
} else {
LOG(Warn, "Could not translate WindowMaterialGlazingName for Extensible group " << eg.groupIndex());
}
} else {
LOG(Warn, "Extensible group " << eg.groupIndex() << "(0-indexed) is missed the WindowMaterialGlazingName field, skipping group");
}
}

return modelObject;
} // End of translate function

} // end namespace energyplus
} // end namespace openstudio
143 changes: 143 additions & 0 deletions src/energyplus/Test/ThermochromicGlazing_GTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/***********************************************************************************************************************
* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
* See also https://openstudio.net/license
***********************************************************************************************************************/

#include <gtest/gtest.h>
#include "EnergyPlusFixture.hpp"

#include "../ForwardTranslator.hpp"
#include "../ReverseTranslator.hpp"

#include "../../model/ThermochromicGlazing.hpp"
#include "../../model/ThermochromicGlazing_Impl.hpp"

#include "../../model/Model.hpp"
#include "../../model/Construction.hpp"
#include "../../model/Space.hpp"
#include "../../model/StandardGlazing.hpp"
#include "../../model/StandardGlazing_Impl.hpp"
#include "../../model/Surface.hpp"
#include "../../model/SubSurface.hpp"
#include "../../model/ThermalZone.hpp"

#include "../../utilities/geometry/Point3d.hpp"
#include "../../utilities/idf/Workspace.hpp"
#include "../../utilities/idf/IdfObject.hpp"
#include "../../utilities/idf/WorkspaceObject.hpp"
#include "../../utilities/idf/IdfExtensibleGroup.hpp"
#include "../../utilities/idf/WorkspaceExtensibleGroup.hpp"

// E+ FieldEnums
#include <utilities/idd/IddEnums.hxx>
#include <utilities/idd/IddFactory.hxx>
#include <utilities/idd/WindowMaterial_GlazingGroup_Thermochromic_FieldEnums.hxx>
#include <utilities/idd/WindowMaterial_Glazing_FieldEnums.hxx>

using namespace openstudio::energyplus;
using namespace openstudio::model;
using namespace openstudio;

TEST_F(EnergyPlusFixture, ForwardTranslator_WindowMaterialGlazingGroupThermochromic) {

ForwardTranslator ft;

Model m;

ThermalZone tz(m);
Space space(m);
EXPECT_TRUE(space.setThermalZone(tz));

const std::vector<Point3d> sPoints{
{0, 2, 0},
{0, 0, 0},
{2, 0, 0},
{2, 2, 0},
};
Surface surface(sPoints, m);
surface.setName("Surface");
surface.setSpace(space);

const std::vector<Point3d> ssPoints = {
{0, 1, 0},
{0, 0, 0},
{1, 0, 0},
{1, 1, 0},
};

SubSurface subSurface(ssPoints, m);
subSurface.setName("SubSurface");
subSurface.setSurface(surface);

Construction construction(m);
subSurface.setConstruction(construction);

ThermochromicGlazing thermochromicGlazing(m);
thermochromicGlazing.setName("My WindowMaterialGlazingGroupThermochromic");

// Not assigned to a Construction, not translated
{
// Assigned to a Surface
Workspace w = ft.translateModel(m);

EXPECT_EQ(1, w.getObjectsByType(IddObjectType::FenestrationSurface_Detailed).size());
EXPECT_EQ(1, w.getObjectsByType(IddObjectType::Construction).size());
EXPECT_EQ(0, w.getObjectsByType(IddObjectType::WindowMaterial_GlazingGroup_Thermochromic).size());
EXPECT_EQ(0, w.getObjectsByType(IddObjectType::WindowMaterial_Glazing).size());
}

construction.insertLayer(0, thermochromicGlazing);

// Assigned to a Construction, but no extensible groups, not translated
{
Workspace w = ft.translateModel(m);

EXPECT_EQ(1, w.getObjectsByType(IddObjectType::FenestrationSurface_Detailed).size());
EXPECT_EQ(1, w.getObjectsByType(IddObjectType::Construction).size());
EXPECT_EQ(0, w.getObjectsByType(IddObjectType::WindowMaterial_GlazingGroup_Thermochromic).size());
EXPECT_EQ(0, w.getObjectsByType(IddObjectType::WindowMaterial_Glazing).size());
}

// Create 5 groups
for (int i = 1; i <= 5; ++i) {
StandardGlazing standardGlazing(m);
standardGlazing.setName("StandardGlazing" + std::to_string(i));

double optionalDataTemperature = 10.00 * (i - 1);

if (i % 2 == 0) {
EXPECT_TRUE(thermochromicGlazing.addThermochromicGroup(standardGlazing, optionalDataTemperature));
} else {
ThermochromicGroup group(standardGlazing, optionalDataTemperature);
EXPECT_TRUE(thermochromicGlazing.addThermochromicGroup(group));
}
EXPECT_EQ(i, thermochromicGlazing.numberofThermochromicGroups());
}
EXPECT_EQ(5, thermochromicGlazing.numberofThermochromicGroups());

std::vector<ThermochromicGroup> groups = thermochromicGlazing.thermochromicGroups();

{
Workspace w = ft.translateModel(m);

EXPECT_EQ(1, w.getObjectsByType(IddObjectType::FenestrationSurface_Detailed).size());
EXPECT_EQ(1, w.getObjectsByType(IddObjectType::Construction).size());
EXPECT_EQ(1, w.getObjectsByType(IddObjectType::WindowMaterial_GlazingGroup_Thermochromic).size());
EXPECT_EQ(5, w.getObjectsByType(IddObjectType::WindowMaterial_Glazing).size());

std::vector<WorkspaceObject> wos = w.getObjectsByType(IddObjectType::WindowMaterial_GlazingGroup_Thermochromic);
ASSERT_EQ(1, wos.size());
const auto& wo = wos.front();
EXPECT_EQ(thermochromicGlazing.nameString(), wo.nameString());

ASSERT_EQ(5, wo.numExtensibleGroups());
for (const auto& idf_eg : wo.extensibleGroups()) {
const auto& group = groups[idf_eg.groupIndex()];

EXPECT_EQ(group.opticalDataTemperature(),
idf_eg.getDouble(WindowMaterial_GlazingGroup_ThermochromicExtensibleFields::OpticalDataTemperature).get());
EXPECT_EQ(group.standardGlazing().nameString(),
idf_eg.getString(WindowMaterial_GlazingGroup_ThermochromicExtensibleFields::WindowMaterialGlazingName).get());
}
}
}
1 change: 1 addition & 0 deletions src/model/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2355,6 +2355,7 @@ set(${target_name}_test_src
test/ThermalZone_GTest.cpp
test/ThermalStorageIceDetailed_GTest.cpp
test/ThermalStorageChilledWaterStratified_GTest.cpp
test/ThermochromicGlazing_GTest.cpp
test/TemperingValve_GTest.cpp
test/ThreeJSForwardTranslator_GTest.cpp
test/ThreeJSReverseTranslator_GTest.cpp
Expand Down
10 changes: 10 additions & 0 deletions src/model/ModelResources.i
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ class HeatExchangerDesiccantBalancedFlow;
}
};

%extend openstudio::model::ThermochromicGroup {
// Use the overloaded operator<< for string representation
std::string __str__() {
std::ostringstream os;
os << *$self;
return os.str();
}
};

MODELOBJECT_TEMPLATES(ScheduleType)
MODELOBJECT_TEMPLATES(ScheduleInterval);
MODELOBJECT_TEMPLATES(ScheduleFixedInterval);
Expand Down Expand Up @@ -137,6 +146,7 @@ MODELOBJECT_TEMPLATES(SimpleGlazing);
MODELOBJECT_TEMPLATES(StandardGlazing);
MODELOBJECT_TEMPLATES(StandardOpaqueMaterial);
MODELOBJECT_TEMPLATES(ThermochromicGlazing);
MODELOBJECT_TEMPLATES(ThermochromicGroup); // helper for extensible fields for ThermochromicGlazing
MODELOBJECT_TEMPLATES(StandardsInformationMaterial);
MODELOBJECT_TEMPLATES(ConstructionBase);
MODELOBJECT_TEMPLATES(LayeredConstruction);
Expand Down
Loading
Loading