From 691f6a769c961198eea09a030f51d191cc597447 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Fri, 4 Sep 2020 11:42:19 -0700 Subject: [PATCH 01/49] Store subsurface on shading control instead of shading control on subsurface. --- resources/model/OpenStudio.idd | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd index d86c67251a3..e57a6c5c1fd 100644 --- a/resources/model/OpenStudio.idd +++ b/resources/model/OpenStudio.idd @@ -5706,13 +5706,7 @@ OS:SubSurface, \minimum 0 \maximum 1 \default autocalculate - A7, \field Shading Control Name - \note enter the name of a WindowProperty:ShadingControl object - \note used for windows and glass doors only - \note If not specified, window or glass door has no shading (blind, roller shade, etc.) - \type object-list - \object-list WindowShadeControlNames - A8, \field Frame and Divider Name + A7, \field Frame and Divider Name \note Enter the name of a WindowProperty:FrameAndDivider object \note Used only for exterior windows (rectangular) and glass doors. \note Unused for triangular windows. @@ -5878,13 +5872,20 @@ OS:ShadingControl, \note Used only if Shading Type = InteriorBlind, ExteriorBlind or BetweenGlassBlind. \note Required if Type of Slat Angle Control for Blinds = ScheduledSlatAngle \note Schedule values should be degrees (0 minimum, 180 maximum) - N2 ; \field Setpoint 2 + N2 , \field Setpoint 2 \note W/m2 for solar-based controls, deg C for temperature-based controls. \note Used only as the second setpoint for the following two-setpoint control types: \note OnIfHighOutdoorAirTempAndHighSolarOnWindow, OnIfHighOutdoorAirTempAndHighHorizontalSolar, \note OnIfHighZoneAirTempAndHighSolarOnWindow, and OnIfHighZoneAirTempAndHighHorizontalSolar \type real \ip-units unknown + A12; \field Sub Surface Name + \required-field + \begin-extensible + \type object-list + \object-list GlazedExtSubSurfNames + \note When Multiple Surface Control Type is set to Sequential the shades will be deployed for the referenced surface objects in order. + \note When that field is set to Group the entire list is controlled simultaneously. OS:WindowProperty:FrameAndDivider, \memo Specifies the dimensions of a window frame, dividers, and reveal surfaces. From 71318ceceb329fdb715ab9df9fac525e14b86402 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Fri, 4 Sep 2020 11:42:47 -0700 Subject: [PATCH 02/49] Stub new methods for subsurface and shading control. --- src/model/ShadingControl.cpp | 40 +++++++++++++++++++++++++++++++ src/model/ShadingControl.hpp | 10 ++++++++ src/model/ShadingControl_Impl.hpp | 12 +++++++++- src/model/SubSurface.hpp | 2 +- src/model/SubSurface_Impl.hpp | 14 +++++++++++ 5 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index ecf9ea60b99..144bd9ecb6a 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -207,11 +207,31 @@ namespace detail { OS_ASSERT(test); } + unsigned int ShadingControl_Impl::numberofSubSurfaces() const { + + } + + bool ShadingControl_Impl::addSubSurface(const SubSurface& subSurface) { + + } + + bool ShadingControl_Impl::removeSubSurface(unsigned groupIndex) { + + } + + void ShadingControl_Impl::removeAllSubSurfaces() { + + } + std::vector ShadingControl_Impl::subSurfaces() const { return getObject().getModelObjectSources(); } + bool ShadingControl_Impl::addSubSurfaces(const std::vector &subSurfaces) { + + } + } // detail @@ -378,10 +398,30 @@ void ShadingControl::resetSetpoint(){ getImpl()->resetSetpoint(); } +unsigned int ShadingControl::numberofSubSurfaces() const { + +} + +bool ShadingControl::addSubSurface(const SubSurface& subSurface) { + +} + +void ShadingControl::removeSubSurface(int groupIndex) { + +} + +void ShadingControl::removeAllSubSurfaces() { + +} + std::vector ShadingControl::subSurfaces() const { return getImpl()->subSurfaces(); } +bool ShadingControl::addSubSurfaces(const std::vector &subSurfaces) { + +} + /// @cond ShadingControl::ShadingControl(std::shared_ptr impl) : ResourceObject(std::move(impl)) diff --git a/src/model/ShadingControl.hpp b/src/model/ShadingControl.hpp index efb9fd0c902..2c2557c637a 100644 --- a/src/model/ShadingControl.hpp +++ b/src/model/ShadingControl.hpp @@ -94,6 +94,8 @@ class MODEL_API ShadingControl : public ResourceObject { bool isSetpointDefaulted() const; + unsigned int numberofSubSurfaces() const; + //@} /** @name Setters */ //@{ @@ -119,8 +121,16 @@ class MODEL_API ShadingControl : public ResourceObject { /** @name Other */ //@{ + bool addSubSurface(const SubSurface& subSurface); + + bool removeSubSurface(unsigned groupIndex); + + void removeAllSubSurfaces(); + std::vector subSurfaces() const; + bool addSubSurfaces(const std::vector &subSurfaces); + //@} protected: /// @cond diff --git a/src/model/ShadingControl_Impl.hpp b/src/model/ShadingControl_Impl.hpp index 65b8f45c779..b5a95ec9b7b 100644 --- a/src/model/ShadingControl_Impl.hpp +++ b/src/model/ShadingControl_Impl.hpp @@ -92,6 +92,8 @@ namespace detail { bool isSetpointDefaulted() const; + unsigned int numberofSubSurfaces() const; + //@} /** @name Setters */ //@{ @@ -114,8 +116,16 @@ namespace detail { /** @name Other */ //@{ + bool addSubSurface(const SubSurface& subSurface); + + bool removeSubSurface(unsigned groupIndex); + + void removeAllSubSurfaces(); + std::vector subSurfaces() const; - + + bool addSubSurfaces(const std::vector &subSurfaces); + //@} protected: diff --git a/src/model/SubSurface.hpp b/src/model/SubSurface.hpp index 279bf8add54..d38b1951eb6 100644 --- a/src/model/SubSurface.hpp +++ b/src/model/SubSurface.hpp @@ -132,7 +132,7 @@ class MODEL_API SubSurface : public PlanarSurface { void resetWindowPropertyFrameAndDivider(); - bool setMultiplier(double multiplShadingControlier); + bool setMultiplier(double multiplier); void resetMultiplier(); diff --git a/src/model/SubSurface_Impl.hpp b/src/model/SubSurface_Impl.hpp index fa6640c400a..ecce02277a7 100644 --- a/src/model/SubSurface_Impl.hpp +++ b/src/model/SubSurface_Impl.hpp @@ -152,6 +152,12 @@ namespace detail { boost::optional shadingControl() const; + std::vector shadingControls(); + + ShadingControl getShadingControl(unsigned shadingControlIndex); + + unsigned int numberofShadingControls(); + bool allowWindowPropertyFrameAndDivider() const; boost::optional windowPropertyFrameAndDivider() const; @@ -186,6 +192,14 @@ namespace detail { void resetShadingControl(); + bool setShadingControls(const std::vector &shadingControls); + + bool insertShadingControl(unsigned shadingControlIndex, const ShadingControl &shadingControl); + + bool removeShadingControl(unsigned shadingControlIndex); + + bool removeAllShadingControls(); + bool setWindowPropertyFrameAndDivider(const WindowPropertyFrameAndDivider& windowPropertyFrameAndDivider); void resetWindowPropertyFrameAndDivider(); From f9df752b9640486095e23d249c501b4cdaabf4e1 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 8 Sep 2020 12:29:23 -0700 Subject: [PATCH 03/49] Start filling out methods for shading control. --- .../ForwardTranslateSubSurface.cpp | 2 - src/model/FoundationKiva.cpp | 2 +- src/model/ShadingControl.cpp | 100 +++++++++++++----- src/model/ShadingControl.hpp | 16 +-- src/model/ShadingControl_Impl.hpp | 16 +-- 5 files changed, 88 insertions(+), 48 deletions(-) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateSubSurface.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateSubSurface.cpp index 25be33be228..4836cb67a6d 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateSubSurface.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateSubSurface.cpp @@ -36,8 +36,6 @@ #include "../../model/Surface_Impl.hpp" #include "../../model/ConstructionBase.hpp" #include "../../model/ConstructionBase_Impl.hpp" -#include "../../model/ShadingControl.hpp" -#include "../../model/ShadingControl_Impl.hpp" #include "../../model/WindowPropertyFrameAndDivider.hpp" #include "../../model/WindowPropertyFrameAndDivider_Impl.hpp" #include "../../model/SurfacePropertyOtherSideCoefficients.hpp" diff --git a/src/model/FoundationKiva.cpp b/src/model/FoundationKiva.cpp index 19a8e6dfca7..143657d3064 100644 --- a/src/model/FoundationKiva.cpp +++ b/src/model/FoundationKiva.cpp @@ -663,7 +663,7 @@ void FoundationKiva::removeCustomBlock(int groupIndex) { } void FoundationKiva::removeAllCustomBlocks() { - return getImpl()->removeAllCustomBlocks(); + getImpl()->removeAllCustomBlocks(); } std::vector FoundationKiva::customBlocks() const { diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index 144bd9ecb6a..7884d095ac2 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -48,6 +48,8 @@ #include "Model.hpp" #include "Model_Impl.hpp" +#include "../utilities/idf/WorkspaceExtensibleGroup.hpp" + #include #include @@ -139,10 +141,34 @@ namespace detail { return result; } - bool ShadingControl_Impl::isSetpointDefaulted() const{ + bool ShadingControl_Impl::isSetpointDefaulted() const + { return isEmpty(OS_ShadingControlFields::Setpoint); } + std::vector ShadingControl_Impl::subSurfaces() const + { + std::vector result; + + std::vector groups = extensibleGroups(); + + for (const auto & group : groups) { + boost::optional wo = group.cast().getTarget(OS_ShadingControlExtensibleFields::SubSurfaceName); + boost::optional subsurface = wo->optionalCast(); + + if (subsurface) { + result.push_back(subsurface.get()); + } + } + + return result; + } + + unsigned int ShadingControl_Impl::numberofSubSurfaces() const + { + return numExtensibleGroups(); + } + bool ShadingControl_Impl::setShadingType(const std::string& shadingType) { return setString(OS_ShadingControlFields::ShadingType, shadingType); @@ -207,29 +233,45 @@ namespace detail { OS_ASSERT(test); } - unsigned int ShadingControl_Impl::numberofSubSurfaces() const { - - } - - bool ShadingControl_Impl::addSubSurface(const SubSurface& subSurface) { - - } - - bool ShadingControl_Impl::removeSubSurface(unsigned groupIndex) { - + bool ShadingControl_Impl::addSubSurface(const SubSurface& subSurface) + { + bool result; + + WorkspaceExtensibleGroup eg = getObject(); + bool subsurface = eg.setPointer(OS_ShadingControlExtensibleFields::SubSurfaceName, subSurface.handle()); + if (subsurface) { + result = true; + } else { + // Something went wrong + // So erase the new extensible group + getObject().eraseExtensibleGroup(eg.groupIndex()); + result = false; + } + result = true; + return result; } - void ShadingControl_Impl::removeAllSubSurfaces() { - + void ShadingControl_Impl::removeSubSurface(const SubSurface& subSurface) + { + for (unsigned i = 0; i < numberofSubSurfaces(); ++i) { + ModelExtensibleGroup group = getExtensibleGroup(i).cast(); + if (subSurface.handle() == group.getString(OS_ShadingControlExtensibleFields::SubSurfaceName)) { + getObject().eraseExtensibleGroup(i); + } + } } - std::vector ShadingControl_Impl::subSurfaces() const + bool ShadingControl_Impl::addSubSurfaces(const std::vector &subSurfaces) { - return getObject().getModelObjectSources(); + for (const SubSurface& subSurface : subSurfaces) { + addSubSurface(subSurface); + } + return true; } - bool ShadingControl_Impl::addSubSurfaces(const std::vector &subSurfaces) { - + void ShadingControl_Impl::removeAllSubSurfaces() + { + getObject.clearExtensibleGroups(); } } // detail @@ -398,28 +440,28 @@ void ShadingControl::resetSetpoint(){ getImpl()->resetSetpoint(); } -unsigned int ShadingControl::numberofSubSurfaces() const { - +std::vector ShadingControl::subSurfaces() const { + return getImpl()->subSurfaces(); } -bool ShadingControl::addSubSurface(const SubSurface& subSurface) { - +unsigned int ShadingControl::numberofSubSurfaces() const { + return getImpl()->numberofSubSurfaces(); } -void ShadingControl::removeSubSurface(int groupIndex) { - +bool ShadingControl::addSubSurface(const SubSurface& subSurface) { + return getImpl()->addSubSUrface(subSurface); } -void ShadingControl::removeAllSubSurfaces() { - +void ShadingControl::removeSubSurface(const SubSurface& subSurface) { + getImpl()->removeSubSurface(subSurface); } -std::vector ShadingControl::subSurfaces() const { - return getImpl()->subSurfaces(); +bool ShadingControl::addSubSurfaces(const std::vector &subSurfaces) { + return getImpl()->addSubSurfaces(subSurfaces); } -bool ShadingControl::addSubSurfaces(const std::vector &subSurfaces) { - +void ShadingControl::removeAllSubSurfaces() { + getImpl()->removeAllSubSurfaces(); } /// @cond diff --git a/src/model/ShadingControl.hpp b/src/model/ShadingControl.hpp index 2c2557c637a..9cc9af23c50 100644 --- a/src/model/ShadingControl.hpp +++ b/src/model/ShadingControl.hpp @@ -94,6 +94,8 @@ class MODEL_API ShadingControl : public ResourceObject { bool isSetpointDefaulted() const; + std::vector subSurfaces() const; + unsigned int numberofSubSurfaces() const; //@} @@ -117,19 +119,17 @@ class MODEL_API ShadingControl : public ResourceObject { void resetSetpoint(); - //@} - /** @name Other */ - //@{ - bool addSubSurface(const SubSurface& subSurface); - bool removeSubSurface(unsigned groupIndex); + void removeSubSurface(const SubSurface& subSurface); - void removeAllSubSurfaces(); + bool addSubSurfaces(const std::vector &subSurfaces); - std::vector subSurfaces() const; + void removeAllSubSurfaces(); - bool addSubSurfaces(const std::vector &subSurfaces); + //@} + /** @name Other */ + //@{ //@} protected: diff --git a/src/model/ShadingControl_Impl.hpp b/src/model/ShadingControl_Impl.hpp index b5a95ec9b7b..73ffdf13f6c 100644 --- a/src/model/ShadingControl_Impl.hpp +++ b/src/model/ShadingControl_Impl.hpp @@ -92,6 +92,8 @@ namespace detail { bool isSetpointDefaulted() const; + std::vector subSurfaces() const; + unsigned int numberofSubSurfaces() const; //@} @@ -112,19 +114,17 @@ namespace detail { void resetSetpoint(); - //@} - /** @name Other */ - //@{ - bool addSubSurface(const SubSurface& subSurface); - bool removeSubSurface(unsigned groupIndex); + void removeSubSurface(const SubSurface& subSurface); - void removeAllSubSurfaces(); + bool addSubSurfaces(const std::vector &subSurfaces); - std::vector subSurfaces() const; + void removeAllSubSurfaces(); - bool addSubSurfaces(const std::vector &subSurfaces); + //@} + /** @name Other */ + //@{ //@} protected: From 4c453f5a5384add48f619fd8fc9f0e1e991f663c Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 8 Sep 2020 12:29:37 -0700 Subject: [PATCH 04/49] Start filling out methods for sub surface. --- src/model/SubSurface.cpp | 83 +++++++++++++++++++++++++++++++---- src/model/SubSurface.hpp | 19 ++++++-- src/model/SubSurface_Impl.hpp | 14 +++--- 3 files changed, 97 insertions(+), 19 deletions(-) diff --git a/src/model/SubSurface.cpp b/src/model/SubSurface.cpp index 8034ba60c55..a22b1cf19a0 100644 --- a/src/model/SubSurface.cpp +++ b/src/model/SubSurface.cpp @@ -487,7 +487,24 @@ namespace detail { boost::optional SubSurface_Impl::shadingControl() const { - return getObject().getModelObjectTarget(OS_SubSurfaceFields::ShadingControlName); + if (numberofShadingControls() > 1) { + return boost::none; + } else { + return shadingControls()[0]; + } + } + + std::vector SubSurface_Impl::shadingControls() const + { + // TODO + // loop thru shading control objects + // loop thru extensible groups + // if group.handle() == this.handle(), add to list + } + + unsigned int SubSurface_Impl::numberofShadingControls() const + { + return shadingControls().size(); } bool SubSurface_Impl::allowWindowPropertyFrameAndDivider() const @@ -598,17 +615,37 @@ namespace detail { bool SubSurface_Impl::setShadingControl(const ShadingControl& shadingControl) { - bool result = false; - if (allowShadingControl()){ - result = setPointer(OS_SubSurfaceFields::ShadingControlName, shadingControl.handle()); - } - return result; + resetShadingControl(); + shadingControl.addSubSurface(this); } void SubSurface_Impl::resetShadingControl() { - bool result = setString(OS_SubSurfaceFields::ShadingControlName, ""); - OS_ASSERT(result); + removeAllShadingControls(); + } + + bool SubSurface_Impl::addShadingControl(const ShadingControl& shadingControl) + { + shadingControl.addSubSurface(this); + } + + bool SubSurface_Impl::addShadingControls(const std::vector &shadingControls) + { + for (const ShadingControl& shadingControl : shadingControls) { + shadingControl.addSubSurface(this); + } + } + + void SubSurface_Impl::removeShadingControl(const ShadingControl& shadingControl) + { + shadingControl.removeSubSurface(this); + } + + void SubSurface_Impl::removeAllShadingControls() + { + for (const ShadingControl& shadingControl : shadingControls()) { + shadingControl.removeSubSurface(this); + } } bool SubSurface_Impl::setWindowPropertyFrameAndDivider(const WindowPropertyFrameAndDivider& windowPropertyFrameAndDivider) @@ -1212,6 +1249,16 @@ boost::optional SubSurface::shadingControl() const return getImpl()->shadingControl(); } +std::vector SubSurface::shadingControls() const +{ + return getImpl()->shadingControls(); +} + +unsigned int SubSurface::numberofShadingControls() const { + return getImpl()->numberofShadingControls(); +} + + bool SubSurface::allowWindowPropertyFrameAndDivider() const { return getImpl()->allowWindowPropertyFrameAndDivider(); @@ -1298,6 +1345,26 @@ void SubSurface::resetShadingControl() { getImpl()->resetShadingControl(); } +bool SubSurface::addShadingControl(const ShadingControl& shadingControl) +{ + return getImpl()->addShadingControl(shadingControl); +} + +bool SubSurface::addShadingControls(const std::vector &shadingControls) +{ + return getImpl()->addShadingControls(shadingControls); +} + +void SubSurface::removeShadingControl(const ShadingControl& shadingControl) +{ + getImpl()->removeShadingControl(shadingControl); +} + +void SubSurface::removeAllShadingControls() +{ + getImpl()->removeAllShadingControls(); +} + bool SubSurface::setWindowPropertyFrameAndDivider(const WindowPropertyFrameAndDivider& windowPropertyFrameAndDivider) { return getImpl()->setWindowPropertyFrameAndDivider(windowPropertyFrameAndDivider); diff --git a/src/model/SubSurface.hpp b/src/model/SubSurface.hpp index d38b1951eb6..fb1b978a4d9 100644 --- a/src/model/SubSurface.hpp +++ b/src/model/SubSurface.hpp @@ -32,6 +32,7 @@ #include "ModelAPI.hpp" #include "PlanarSurface.hpp" +#include "../utilities/core/Deprecated.hpp" namespace openstudio { namespace model { @@ -92,7 +93,11 @@ class MODEL_API SubSurface : public PlanarSurface { bool allowShadingControl() const; - boost::optional shadingControl() const; + OS_DEPRECATED boost::optional shadingControl() const; + + std::vector shadingControls() const; + + unsigned int numberofShadingControls() const; bool allowWindowPropertyFrameAndDivider() const; @@ -124,9 +129,17 @@ class MODEL_API SubSurface : public PlanarSurface { void autocalculateViewFactortoGround(); - bool setShadingControl(const ShadingControl& shadingControl); + OS_DEPRECATED bool setShadingControl(const ShadingControl& shadingControl); + + OS_DEPRECATED void resetShadingControl(); + + bool addShadingControl(const ShadingControl& shadingControl); + + bool addShadingControls(const std::vector &shadingControls); + + void removeShadingControl(const ShadingControl& shadingControl); - void resetShadingControl(); + void removeAllShadingControls(); bool setWindowPropertyFrameAndDivider(const WindowPropertyFrameAndDivider& windowPropertyFrameAndDivider); diff --git a/src/model/SubSurface_Impl.hpp b/src/model/SubSurface_Impl.hpp index ecce02277a7..90f8c735bbe 100644 --- a/src/model/SubSurface_Impl.hpp +++ b/src/model/SubSurface_Impl.hpp @@ -152,11 +152,9 @@ namespace detail { boost::optional shadingControl() const; - std::vector shadingControls(); + std::vector shadingControls() const; - ShadingControl getShadingControl(unsigned shadingControlIndex); - - unsigned int numberofShadingControls(); + unsigned int numberofShadingControls() const; bool allowWindowPropertyFrameAndDivider() const; @@ -192,13 +190,13 @@ namespace detail { void resetShadingControl(); - bool setShadingControls(const std::vector &shadingControls); + bool addShadingControl(const ShadingControl& shadingControl); - bool insertShadingControl(unsigned shadingControlIndex, const ShadingControl &shadingControl); + bool addShadingControls(const std::vector &shadingControls); - bool removeShadingControl(unsigned shadingControlIndex); + void removeShadingControl(const ShadingControl& shadingControl); - bool removeAllShadingControls(); + void removeAllShadingControls(); bool setWindowPropertyFrameAndDivider(const WindowPropertyFrameAndDivider& windowPropertyFrameAndDivider); From 92fdd7b55f849549a43114933edaeea6981451e8 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 8 Sep 2020 13:28:52 -0700 Subject: [PATCH 05/49] Continue to fill out sub surface methods. --- src/model/SubSurface.cpp | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/model/SubSurface.cpp b/src/model/SubSurface.cpp index a22b1cf19a0..e4d7edd0b28 100644 --- a/src/model/SubSurface.cpp +++ b/src/model/SubSurface.cpp @@ -491,15 +491,25 @@ namespace detail { return boost::none; } else { return shadingControls()[0]; - } + } + return boost::none; } std::vector SubSurface_Impl::shadingControls() const { - // TODO - // loop thru shading control objects - // loop thru extensible groups - // if group.handle() == this.handle(), add to list + SubSurface thisSubSurface = getObject(); + + std::vector shadingControls; + + for (const ShadingControl& shadingControl : getObjectsByType(ShadingControl::iddObjectType())) { + for (const SubSurface& subSurface : shadingControl.subSurfaces()) { + if (subSurface.handle() == thisSubSurface.handle()) { + shadingControls.push_back(shadingControl); + } + } + } + + return shadingControls; } unsigned int SubSurface_Impl::numberofShadingControls() const @@ -615,8 +625,9 @@ namespace detail { bool SubSurface_Impl::setShadingControl(const ShadingControl& shadingControl) { + SubSurface thisSubSurface = getObject(); resetShadingControl(); - shadingControl.addSubSurface(this); + shadingControl.addSubSurface(thisSubSurface); } void SubSurface_Impl::resetShadingControl() @@ -626,25 +637,29 @@ namespace detail { bool SubSurface_Impl::addShadingControl(const ShadingControl& shadingControl) { - shadingControl.addSubSurface(this); + SubSurface thisSubSurface = getObject(); + shadingControl.addSubSurface(thisSubSurface); } bool SubSurface_Impl::addShadingControls(const std::vector &shadingControls) { + SubSurface thisSubSurface = getObject(); for (const ShadingControl& shadingControl : shadingControls) { - shadingControl.addSubSurface(this); + shadingControl.addSubSurface(thisSubSurface); } } void SubSurface_Impl::removeShadingControl(const ShadingControl& shadingControl) { - shadingControl.removeSubSurface(this); + SubSurface thisSubSurface = getObject(); + shadingControl.removeSubSurface(thisSubSurface); } - + void SubSurface_Impl::removeAllShadingControls() { + SubSurface thisSubSurface = getObject(); for (const ShadingControl& shadingControl : shadingControls()) { - shadingControl.removeSubSurface(this); + shadingControl.removeSubSurface(thisSubSurface); } } From f84e7104f39b0e395fba6a32e157a6ad5926d7ae Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 8 Sep 2020 14:24:38 -0700 Subject: [PATCH 06/49] Add new model test for sub surface. --- src/model/test/SubSurface_GTest.cpp | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/model/test/SubSurface_GTest.cpp b/src/model/test/SubSurface_GTest.cpp index 7a3692e9df1..f5a1ca0ae15 100644 --- a/src/model/test/SubSurface_GTest.cpp +++ b/src/model/test/SubSurface_GTest.cpp @@ -1205,3 +1205,45 @@ TEST_F(ModelFixture, SubSurface_SurfacePropertyOtherSideConditionsModel) Model model; SurfacePropertyOtherSideConditionsModel otherSideModel(model); } + +TEST_F(ModelFixture, SubSurface_ShadingControls) +} + std::vector vertices; + vertices.push_back(Point3d(0,0,1)); + vertices.push_back(Point3d(0,0,0)); + vertices.push_back(Point3d(1,0,0)); + vertices.push_back(Point3d(1,0,1)); + SubSurface subSurface(vertices, model); + + Blind blind1(model); + ShadingControl shadingControl1(blind1); + + Blind blind2(model); + ShadingControl shadingControl2(blind2); + + EXPECT_EQ(0, subSurface.numberofShadingControls()); + EXPECT_TRUE(subSurface.addShadingControl(shadingControl1)); + EXPECT_EQ(1, subSurface.numberofShadingControls()); + subSurface.removeShadingControl(shadingControl1); + EXPECT_EQ(0, subSurface.numberofShadingControls()); + + std::vector shadingControls; + shadingControls.push_back(shadingControl1); + shadingControls.push_back(shadingControl2); + EXPECT_TRUE(subSurface.addShadingControls(shadingControls)); + EXPECT_EQ(2, subSurface.numberofShadingControls()); + subSurface.removeAllShadingControls(); + EXPECT_EQ(0, subSurface.numberofShadingControls()); + + // Test deprecated methods + subSurface.addShadingControls(shadingControls); + EXPECT_EQ(2, subSurface.numberofShadingControls()); + EXPECT_FALSE(subSurface.shadingControl()); + EXPECT_TRUE(subSurface.setShadingControl(shadingControl1)); + EXPECT_EQ(1, subSurface.numberofShadingControls()); + EXPECT_TRUE(subSurface.shadingControl()); + EXPECT_TRUE(subSurface.addShadingControl(shadingControl2)); + EXPECT_EQ(2, subSurface.numberofShadingControls()); + subSurface.resetShadingControl(); + EXPECT_EQ(0, subSurface.numberofShadingControls()); +} From b282d03b4f2ae5e84a92f898f90b8681d792dc32 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 8 Sep 2020 14:24:49 -0700 Subject: [PATCH 07/49] Add new model test for shading control. --- src/model/test/ShadingControl_GTest.cpp | 40 +++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/model/test/ShadingControl_GTest.cpp b/src/model/test/ShadingControl_GTest.cpp index 48463147330..3a1a947269a 100644 --- a/src/model/test/ShadingControl_GTest.cpp +++ b/src/model/test/ShadingControl_GTest.cpp @@ -44,7 +44,7 @@ using namespace openstudio; using namespace openstudio::model; -TEST_F(ModelFixture,ShadingControl_Construction) { +TEST_F(ModelFixture, ShadingControl_Construction) { Model model; Construction construction(model); @@ -78,7 +78,6 @@ TEST_F(ModelFixture,ShadingControl_Construction) { EXPECT_EQ(construction.handle(), subSurface.shadingControl()->construction()->handle()); } - TEST_F(ModelFixture,ShadingControl_Material) { Model model; @@ -117,4 +116,39 @@ TEST_F(ModelFixture, ShadingControl_PurgeUnusedModelObjects) { model.purgeUnusedResourceObjects(); EXPECT_EQ(0, model.objects().size()); -} \ No newline at end of file +} + +TEST_F(ModelFixture, ShadingControl_SubSurfaces) { + Model model; + + Blind blind(model); + ShadingControl shadingControl(blind); + + std::vector vertices1; + vertices1.push_back(Point3d(0,0,1)); + vertices1.push_back(Point3d(0,0,0)); + vertices1.push_back(Point3d(1,0,0)); + vertices1.push_back(Point3d(1,0,1)); + SubSurface subSurface1(vertices1, model); + + std::vector vertices2; + vertices2.push_back(Point3d(0,0,1)); + vertices2.push_back(Point3d(0,0,0)); + vertices2.push_back(Point3d(1,0,0)); + vertices2.push_back(Point3d(1,0,1)); + SubSurface subSurface2(vertices2, model); + + EXPECT_EQ(0, shadingControl.numberofSubSurfaces()); + EXPECT_TRUE(shadingControl.addSubSurface(subSurface1)); + EXPECT_EQ(1, shadingControl.numberofSubSurfaces()); + shadingControl.removeSubSurface(subSurface1); + EXPECT_EQ(0, shadingControl.numberofSubSurfaces()); + + std::vector subSurfaces; + subSurfaces.push_back(subSurface1); + subSurfaces.push_back(subSurface2); + EXPECT_TRUE(shadingControl.addSubSurfaces(subSurfaces)); + EXPECT_EQ(2, shadingControl.numberofSubSurfaces()); + shadingControl.removeAllSubSurfaces(); + EXPECT_EQ(0, shadingControl.numberofSubSurfaces()); +} From b14c8f74312f7a9103f799a0e874d7d28ceeb6d2 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 8 Sep 2020 16:49:01 -0700 Subject: [PATCH 08/49] Clean up some model and test files. --- src/model/ShadingControl.cpp | 9 +++++---- src/model/SubSurface.cpp | 4 +++- src/model/test/SubSurface_GTest.cpp | 6 +++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index 7884d095ac2..bd634a34b75 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -47,6 +47,7 @@ #include "SubSurface_Impl.hpp" #include "Model.hpp" #include "Model_Impl.hpp" +#include "ModelExtensibleGroup.hpp" #include "../utilities/idf/WorkspaceExtensibleGroup.hpp" @@ -148,7 +149,7 @@ namespace detail { std::vector ShadingControl_Impl::subSurfaces() const { - std::vector result; + std::vector result; std::vector groups = extensibleGroups(); @@ -237,7 +238,7 @@ namespace detail { { bool result; - WorkspaceExtensibleGroup eg = getObject(); + WorkspaceExtensibleGroup eg = getObject().pushExtensibleGroup().cast(); bool subsurface = eg.setPointer(OS_ShadingControlExtensibleFields::SubSurfaceName, subSurface.handle()); if (subsurface) { result = true; @@ -255,7 +256,7 @@ namespace detail { { for (unsigned i = 0; i < numberofSubSurfaces(); ++i) { ModelExtensibleGroup group = getExtensibleGroup(i).cast(); - if (subSurface.handle() == group.getString(OS_ShadingControlExtensibleFields::SubSurfaceName)) { + if (std::to_string(*subSurface.handle()) == group.getString(OS_ShadingControlExtensibleFields::SubSurfaceName).get()) { getObject().eraseExtensibleGroup(i); } } @@ -449,7 +450,7 @@ unsigned int ShadingControl::numberofSubSurfaces() const { } bool ShadingControl::addSubSurface(const SubSurface& subSurface) { - return getImpl()->addSubSUrface(subSurface); + return getImpl()->addSubSurface(subSurface); } void ShadingControl::removeSubSurface(const SubSurface& subSurface) { diff --git a/src/model/SubSurface.cpp b/src/model/SubSurface.cpp index e4d7edd0b28..ffa56de28a3 100644 --- a/src/model/SubSurface.cpp +++ b/src/model/SubSurface.cpp @@ -501,7 +501,9 @@ namespace detail { std::vector shadingControls; - for (const ShadingControl& shadingControl : getObjectsByType(ShadingControl::iddObjectType())) { + for (const auto& object: thisSubSurface.model().getObjectsByType(ShadingControl::iddObjectType())) { + ModelObject modelObject = object.cast(); + ShadingControl shadingControl = modelObject.cast(); for (const SubSurface& subSurface : shadingControl.subSurfaces()) { if (subSurface.handle() == thisSubSurface.handle()) { shadingControls.push_back(shadingControl); diff --git a/src/model/test/SubSurface_GTest.cpp b/src/model/test/SubSurface_GTest.cpp index f5a1ca0ae15..62cb33a5793 100644 --- a/src/model/test/SubSurface_GTest.cpp +++ b/src/model/test/SubSurface_GTest.cpp @@ -46,6 +46,8 @@ #include "../DefaultConstructionSet.hpp" #include "../SurfacePropertyOtherSideCoefficients.hpp" #include "../SurfacePropertyOtherSideConditionsModel.hpp" +#include "../Blind.hpp" +#include "../ShadingControl.hpp" #include "../Model_Impl.hpp" #include "../../utilities/geometry/Geometry.hpp" @@ -1207,7 +1209,9 @@ TEST_F(ModelFixture, SubSurface_SurfacePropertyOtherSideConditionsModel) } TEST_F(ModelFixture, SubSurface_ShadingControls) -} +{ + Model model; + std::vector vertices; vertices.push_back(Point3d(0,0,1)); vertices.push_back(Point3d(0,0,0)); From afda1a1557a380f46ac4009836c75ad7336b421b Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 8 Sep 2020 16:49:33 -0700 Subject: [PATCH 09/49] Start a vt for sub surface and shading control. --- src/osversion/VersionTranslator.cpp | 45 +++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/osversion/VersionTranslator.cpp b/src/osversion/VersionTranslator.cpp index 922821a2a93..0372ddd6291 100644 --- a/src/osversion/VersionTranslator.cpp +++ b/src/osversion/VersionTranslator.cpp @@ -6281,6 +6281,51 @@ std::string VersionTranslator::update_3_0_1_to_3_1_0(const IdfFile& idf_3_0_1, c m_refactored.push_back( RefactoredObjectData(object, newObject) ); ss << newObject; } + } else if (iddname == "OS:ShadingControl") { + // get all subsurfaces + // loop thru subsurfaces + // check if shading control name equals this handle + // add extensible field with subsurface handle + // remove shading control name field from subsurface + auto iddObjectShadingControl = idd_3_1_0.getObject("OS:ShadingControl"); + IdfObject newShadingControl(iddObjectShadingControl.get()); + + for (size_t i = 0; i < object.numFields(); ++i) { + if ((value = object.getString(i))) { + newShadingControl.setString(i, value.get()); + } + } + + std::vector subSurfaces = idf_3_0_1.getObjectsByType(idf_3_0_1.iddFile().getObject("OS:SubSurface").get()); + for ( auto & subSurface : subSurfaces ) { + value = subSurface.getString(7); // Shading Control Name + if (value) { + if (value.get() == object.getString(0)) { + newShadingControl.setString(13, subSurface.getString(0).get()); + + auto iddObjectSubSurface = idd_3_1_0.getObject("OS:SubSurface"); + IdfObject newSubSurface(iddObjectSubSurface.get()); + + for (size_t i = 0; i < subSurface.numFields(); ++i) { + if ((value = subSurface.getString(i))) { + if (i < 7) { + newSubSurface.setString(i, value.get()); + } else if (i == 7) { // Shading Control Name + // no-op + } else { + newSubSurface.setString(i - 1, value.get()); + } + } + } + + m_refactored.push_back(RefactoredObjectData(subSurface, newSubSurface)); + ss << subSurface; + } + } + } + + m_refactored.push_back(RefactoredObjectData(object, newShadingControl)); + ss << newShadingControl; // Note: Would have needed to do UtilityCost:Tariff too, but not wrapped From 4ab931829a5ec94100a3489a23ab1c1710f43775 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Thu, 10 Sep 2020 10:04:07 -0700 Subject: [PATCH 10/49] Updates to source files after review. --- src/model/ShadingControl.cpp | 14 +++++--------- src/model/SubSurface.cpp | 32 +++++++++++++++++++++----------- src/model/SubSurface.hpp | 2 ++ 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index bd634a34b75..8e628d9d16c 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -150,18 +150,15 @@ namespace detail { std::vector ShadingControl_Impl::subSurfaces() const { std::vector result; - - std::vector groups = extensibleGroups(); - + auto groups = extensibleGroups(); for (const auto & group : groups) { boost::optional wo = group.cast().getTarget(OS_ShadingControlExtensibleFields::SubSurfaceName); - boost::optional subsurface = wo->optionalCast(); - - if (subsurface) { - result.push_back(subsurface.get()); + if (wo) { + if (auto subsurface = wo->optionalCast()) { + result.push_back(subsurface.get()); + } } } - return result; } @@ -248,7 +245,6 @@ namespace detail { getObject().eraseExtensibleGroup(eg.groupIndex()); result = false; } - result = true; return result; } diff --git a/src/model/SubSurface.cpp b/src/model/SubSurface.cpp index ffa56de28a3..c9c046d875d 100644 --- a/src/model/SubSurface.cpp +++ b/src/model/SubSurface.cpp @@ -487,12 +487,14 @@ namespace detail { boost::optional SubSurface_Impl::shadingControl() const { - if (numberofShadingControls() > 1) { - return boost::none; - } else { + if (numberofShadingControls() > 0) { + if (numberofShadingControls() > 1) { + LOG(Warn, briefDescription() << " has more than one ShadingControl attached, returning first."); + } return shadingControls()[0]; - } - return boost::none; + } else { + return boost::none; + } } std::vector SubSurface_Impl::shadingControls() const @@ -501,7 +503,7 @@ namespace detail { std::vector shadingControls; - for (const auto& object: thisSubSurface.model().getObjectsByType(ShadingControl::iddObjectType())) { + for (const auto& object: getObject().getModelObjectSources()) { ModelObject modelObject = object.cast(); ShadingControl shadingControl = modelObject.cast(); for (const SubSurface& subSurface : shadingControl.subSurfaces()) { @@ -627,9 +629,13 @@ namespace detail { bool SubSurface_Impl::setShadingControl(const ShadingControl& shadingControl) { - SubSurface thisSubSurface = getObject(); - resetShadingControl(); - shadingControl.addSubSurface(thisSubSurface); + bool result = false; + if (allowShadingControl()){ + SubSurface thisSubSurface = getObject(); + resetShadingControl(); + result = shadingControl.addSubSurface(thisSubSurface); + } + return result; } void SubSurface_Impl::resetShadingControl() @@ -639,8 +645,12 @@ namespace detail { bool SubSurface_Impl::addShadingControl(const ShadingControl& shadingControl) { - SubSurface thisSubSurface = getObject(); - shadingControl.addSubSurface(thisSubSurface); + bool result = false; + if (allowShadingControl()){ + SubSurface thisSubSurface = getObject(); + result = shadingControl.addSubSurface(thisSubSurface); + } + return result; } bool SubSurface_Impl::addShadingControls(const std::vector &shadingControls) diff --git a/src/model/SubSurface.hpp b/src/model/SubSurface.hpp index fb1b978a4d9..835ddf9d6e5 100644 --- a/src/model/SubSurface.hpp +++ b/src/model/SubSurface.hpp @@ -129,8 +129,10 @@ class MODEL_API SubSurface : public PlanarSurface { void autocalculateViewFactortoGround(); + // This method is deprecated, please use addShadingControl or **setShadingControls/addShadingControls**. This will remove this SubSurface from any shading control(s) it is on (`removeAllShadingControls()`) then will call `addShadingControl(shadingControl)` OS_DEPRECATED bool setShadingControl(const ShadingControl& shadingControl); + // Replaced with removeAllShadingControls OS_DEPRECATED void resetShadingControl(); bool addShadingControl(const ShadingControl& shadingControl); From 8b1664b0180deb0c968871de941645f96406b5e1 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 12:21:20 +0200 Subject: [PATCH 11/49] Make some changes to ShadingControl. --- src/model/ShadingControl.cpp | 162 ++++++++++++++++++++++++------ src/model/ShadingControl.hpp | 69 +++++++++++-- src/model/ShadingControl_Impl.hpp | 26 +++-- 3 files changed, 206 insertions(+), 51 deletions(-) diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index 8e628d9d16c..62d713427f8 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -147,26 +147,6 @@ namespace detail { return isEmpty(OS_ShadingControlFields::Setpoint); } - std::vector ShadingControl_Impl::subSurfaces() const - { - std::vector result; - auto groups = extensibleGroups(); - for (const auto & group : groups) { - boost::optional wo = group.cast().getTarget(OS_ShadingControlExtensibleFields::SubSurfaceName); - if (wo) { - if (auto subsurface = wo->optionalCast()) { - result.push_back(subsurface.get()); - } - } - } - return result; - } - - unsigned int ShadingControl_Impl::numberofSubSurfaces() const - { - return numExtensibleGroups(); - } - bool ShadingControl_Impl::setShadingType(const std::string& shadingType) { return setString(OS_ShadingControlFields::ShadingType, shadingType); @@ -231,6 +211,48 @@ namespace detail { OS_ASSERT(test); } + + + unsigned int ShadingControl_Impl::numberofSubSurfaces() const + { + return numExtensibleGroups(); + } + + std::vector ShadingControl_Impl::subSurfaces() const + { + std::vector result; + auto groups = extensibleGroups(); + for (const auto & group : groups) { + boost::optional wo = group.cast().getTarget(OS_ShadingControlExtensibleFields::SubSurfaceName); + if (wo) { + if (auto subsurface = wo->optionalCast()) { + result.push_back(subsurface.get()); + } + } + } + return result; + } + + boost::optional ShadingControl_Impl::subSurfaceIndex(const SubSurface& subSurface) const { + + boost::optional result; + + auto egs = castVector(extensibleGroups()); + auto h = openstudio::toString(subSurface.handle()); + auto it = std::find_if(egs.begin(), egs.end(), + [&](const WorkspaceExtensibleGroup& eg) { + return (eg.getField(OS_ShadingControlExtensibleFields::SubSurfaceName).get() == h); + }); + + // If found, we compute the index by using std::distance between the start of vector and the iterator returned by std::find_if + if (it != egs.end()) { + result = std::distance(egs.begin(), it) + 1; + } + + return result; + } + + bool ShadingControl_Impl::addSubSurface(const SubSurface& subSurface) { bool result; @@ -248,27 +270,85 @@ namespace detail { return result; } - void ShadingControl_Impl::removeSubSurface(const SubSurface& subSurface) + + bool ShadingControl_Impl::setSubSurfaceIndex(const SubSurface& subSurface, unsigned index) { - for (unsigned i = 0; i < numberofSubSurfaces(); ++i) { - ModelExtensibleGroup group = getExtensibleGroup(i).cast(); - if (std::to_string(*subSurface.handle()) == group.getString(OS_ShadingControlExtensibleFields::SubSurfaceName).get()) { - getObject().eraseExtensibleGroup(i); - } + boost::optional idx = subSurfaceIndex(subSurface); + if (!idx) { + LOG(Warn, "For " << briefDescription() << " cannot set the index of SubSurface " << subSurface.nameString() << " since it is not part of it."); + return false; + } + + // TODO: we could just set via string instead of doing a ton of typechecking below... + std::vector subSurfaceVector = subSurfaces(); + + if (index > subSurfaceVector.size()) { + LOG(Warn, "Requested a subSurface index of " << index << " to be assigned to " << subSurface.nameString() << ", but " + << briefDescription() << " only has " << subSurfaceVector.size() << " SubSurfaces, resetting to that."); + index = subSurfaceVector.size(); + } else if (index < 1) { + LOG(Warn, "Requested a subSurface index of " << index << " < 1 to be assigned to " << subSurface.briefDescription() << ", resetting to 1"); + index = 1; } + + subSurfaceVector.erase(subSurfaceVector.begin() + idx.get() - 1); // subSurfaceIndex is 1-indexed, and vector is 0-indexed + + subSurfaceVector.insert(subSurfaceVector.begin() + (index - 1), subSurface); + + return setSubSurfaces(subSurfaceVector); + } + + bool ShadingControl_Impl::addSubSurface(const SubSurface& subSurface, unsigned index) { + bool ok = addSubSurface(subSurface); + if (!ok) { + return false; + } + ok = setSubSurfaceIndex(subSurface, index); + return ok; } + + + bool ShadingControl_Impl::removeSubSurface(const SubSurface& subSurface) + { + boost::optional idx = subSurfaceIndex(subSurface); + if (!idx) { + LOG(Warn, "For " << briefDescription() << " cannot remove SubSurface " << subSurface.nameString() << " since it is not part of it."); + return false; + } + + return removeSubSurface(idx.get()); + } + + bool ShadingControl_Impl::removeSubSurface(unsigned index) { + bool result = false; + if ((index > 0) && (index <= numberofSubSurfaces())) { + getObject().eraseExtensibleGroup(index-1); + result = true; + } + return result; + } + + bool ShadingControl_Impl::addSubSurfaces(const std::vector &subSurfaces) { + bool ok = true; for (const SubSurface& subSurface : subSurfaces) { - addSubSurface(subSurface); + ok &= addSubSurface(subSurface); } - return true; + return ok;; } void ShadingControl_Impl::removeAllSubSurfaces() { - getObject.clearExtensibleGroups(); + clearExtensibleGroups(); + } + + + bool ShadingControl_Impl::setSubSurfaces(const std::vector &subSurfaces) + { + removeAllSubSurfaces(); + return addSubSurfaces(subSurfaces); } } // detail @@ -445,18 +525,38 @@ unsigned int ShadingControl::numberofSubSurfaces() const { return getImpl()->numberofSubSurfaces(); } +boost::optional ShadingControl::subSurfaceIndex(const SubSurface& subSurface) const { + return getImpl()->subSurfaceIndex(subSurface); +} + bool ShadingControl::addSubSurface(const SubSurface& subSurface) { return getImpl()->addSubSurface(subSurface); } -void ShadingControl::removeSubSurface(const SubSurface& subSurface) { - getImpl()->removeSubSurface(subSurface); +bool ShadingControl::addSubSurface(const SubSurface& subSurface, unsigned index) { + return getImpl()->addSubSurface(subSurface, index); +} + +bool ShadingControl::setSubSurfaceIndex(const SubSurface& subSurface, unsigned index) { + return getImpl()->setSubSurfaceIndex(subSurface, index); +} + +bool ShadingControl::removeSubSurface(unsigned index) { + return getImpl()->removeSubSurface(index); +} + +bool ShadingControl::removeSubSurface(const SubSurface& subSurface) { + return getImpl()->removeSubSurface(subSurface); } bool ShadingControl::addSubSurfaces(const std::vector &subSurfaces) { return getImpl()->addSubSurfaces(subSurfaces); } +bool ShadingControl::setSubSurfaces(const std::vector &subSurfaces) { + return getImpl()->setSubSurfaces(subSurfaces); +} + void ShadingControl::removeAllSubSurfaces() { getImpl()->removeAllSubSurfaces(); } diff --git a/src/model/ShadingControl.hpp b/src/model/ShadingControl.hpp index 9cc9af23c50..d71d6b2a53d 100644 --- a/src/model/ShadingControl.hpp +++ b/src/model/ShadingControl.hpp @@ -94,10 +94,6 @@ class MODEL_API ShadingControl : public ResourceObject { bool isSetpointDefaulted() const; - std::vector subSurfaces() const; - - unsigned int numberofSubSurfaces() const; - //@} /** @name Setters */ //@{ @@ -119,17 +115,72 @@ class MODEL_API ShadingControl : public ResourceObject { void resetSetpoint(); + //@} + /** @name Other */ + //@{ + + // Extensible: Surfaces + std::vector subSurfaces() const; + unsigned int numberofSubSurfaces() const; + + /* + * Get the index of a given SubSurface (1-indexed) + */ + boost::optional subSurfaceIndex(const SubSurface& subSurface) const; + + /* + * Add a new SubSurface at the end of all of the existing SubSurfaces + */ bool addSubSurface(const SubSurface& subSurface); - void removeSubSurface(const SubSurface& subSurface); + /* + * Add a new SubSurface to the list which a given index (1 to x). + * Internally calls addSubSurface then setSubSurfaceIndex, see remarks there + */ + bool addSubSurface(const SubSurface& subSurface, unsigned index); + + /* + * You can shuffle the priority of a given SubSurface after having added it + * If index is below 1, it's reset to 1. + * If index is greater than the number of SubSurfaces, will reset to last + */ + bool setSubSurfaceIndex(const SubSurface& subSurface, unsigned index); + + /* + * Remove the given SubSurface from this object's subsurfaces + */ + bool removeSubSurface(const SubSurface& subSurface); + + /* + * Remove the SubSurface at the given index (1-indexed) + */ + bool removeSubSurface(unsigned index); + + // Bulk operations + + /** + * Does not clear any subSurfaces already added, just calls calls addSubSurface for each + * It will return the global status, but will continue trying if there are problems + * (eg: if you make or a vector that has a subSurface from another model, the valid subSurfaces will be + * added indeed, but it'll eventually return false) + */ bool addSubSurfaces(const std::vector &subSurfaces); - void removeAllSubSurfaces(); - //@} - /** @name Other */ - //@{ + /* + * Set all SubSurfaces using a vector of SubSurface + * Internally calls removeAllSubSurfaces(), then addSubSurfaces + * It will return the global status, but will continue trying if there are problems + * (eg: if you make or a vector that has a subSurface from another model, the valid subSurface will be + * added indeed, but it'll eventually return false) + */ + bool setSubSurfaces(const std::vector &subSurfaces); + + /* + * Removes all SubSurfaces in this object + */ + void removeAllSubSurfaces(); //@} protected: diff --git a/src/model/ShadingControl_Impl.hpp b/src/model/ShadingControl_Impl.hpp index 73ffdf13f6c..c18657abc8c 100644 --- a/src/model/ShadingControl_Impl.hpp +++ b/src/model/ShadingControl_Impl.hpp @@ -92,10 +92,6 @@ namespace detail { bool isSetpointDefaulted() const; - std::vector subSurfaces() const; - - unsigned int numberofSubSurfaces() const; - //@} /** @name Setters */ //@{ @@ -114,18 +110,26 @@ namespace detail { void resetSetpoint(); - bool addSubSurface(const SubSurface& subSurface); + //@} + /** @name Other */ + //@{ - void removeSubSurface(const SubSurface& subSurface); + // Extensible: Surfaces + std::vector subSurfaces() const; + unsigned numberofSubSurfaces() const; + boost::optional subSurfaceIndex(const SubSurface& subSurface) const; + bool addSubSurface(const SubSurface& subSurface); + bool addSubSurface(const SubSurface& subSurface, unsigned index); + bool setSubSurfaceIndex(const SubSurface& subSurface, unsigned index); + bool removeSubSurface(const SubSurface& subSurface); + bool removeSubSurface(unsigned index); + // Bulk operations bool addSubSurfaces(const std::vector &subSurfaces); - + // Clears existing first, then bulk add + bool setSubSurfaces(const std::vector &subSurfaces); void removeAllSubSurfaces(); - //@} - /** @name Other */ - //@{ - //@} protected: From 3e236f1873ed64d90f203a15d97150d8f15d60bb Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 12:23:58 +0200 Subject: [PATCH 12/49] Remove the deprecated functions from the Impl API to fix compiler error --- src/model/SubSurface.cpp | 74 ++++++++++++++--------------------- src/model/SubSurface_Impl.hpp | 6 --- 2 files changed, 29 insertions(+), 51 deletions(-) diff --git a/src/model/SubSurface.cpp b/src/model/SubSurface.cpp index c9c046d875d..616fa454dc1 100644 --- a/src/model/SubSurface.cpp +++ b/src/model/SubSurface.cpp @@ -485,18 +485,6 @@ namespace detail { return result; } - boost::optional SubSurface_Impl::shadingControl() const - { - if (numberofShadingControls() > 0) { - if (numberofShadingControls() > 1) { - LOG(Warn, briefDescription() << " has more than one ShadingControl attached, returning first."); - } - return shadingControls()[0]; - } else { - return boost::none; - } - } - std::vector SubSurface_Impl::shadingControls() const { SubSurface thisSubSurface = getObject(); @@ -574,7 +562,7 @@ namespace detail { if (result){ if (!allowShadingControl()){ - this->resetShadingControl(); + this->removeAllShadingControls(); } if (!allowWindowPropertyFrameAndDivider()){ @@ -591,7 +579,7 @@ namespace detail { boost::optional adjacentSubSurface = this->adjacentSubSurface(); if (adjacentSubSurface){ adjacentSubSurface->setString(OS_SubSurfaceFields::SubSurfaceType, subSurfaceType); - adjacentSubSurface->resetShadingControl(); + adjacentSubSurface->removeAllShadingControls(); } } return result; @@ -627,22 +615,6 @@ namespace detail { OS_ASSERT(result); } - bool SubSurface_Impl::setShadingControl(const ShadingControl& shadingControl) - { - bool result = false; - if (allowShadingControl()){ - SubSurface thisSubSurface = getObject(); - resetShadingControl(); - result = shadingControl.addSubSurface(thisSubSurface); - } - return result; - } - - void SubSurface_Impl::resetShadingControl() - { - removeAllShadingControls(); - } - bool SubSurface_Impl::addShadingControl(const ShadingControl& shadingControl) { bool result = false; @@ -812,12 +784,12 @@ namespace detail { result = setPointer(OS_SubSurfaceFields::OutsideBoundaryConditionObject, subSurface.handle()); OS_ASSERT(result); - this->resetShadingControl(); + this->removeAllShadingControls(); if (!isSameSubSurface){ result = subSurface.setPointer(OS_SubSurfaceFields::OutsideBoundaryConditionObject, this->handle()); OS_ASSERT(result); - subSurface.resetShadingControl(); + subSurface.removeAllShadingControls(); } } } @@ -1271,11 +1243,6 @@ bool SubSurface::allowShadingControl() const return getImpl()->allowShadingControl(); } -boost::optional SubSurface::shadingControl() const -{ - return getImpl()->shadingControl(); -} - std::vector SubSurface::shadingControls() const { return getImpl()->shadingControls(); @@ -1364,14 +1331,6 @@ void SubSurface::autocalculateNumberofVertices() { getImpl()->autocalculateNumberofVertices(); } -bool SubSurface::setShadingControl(const ShadingControl& shadingControl) { - return getImpl()->setShadingControl(shadingControl); -} - -void SubSurface::resetShadingControl() { - getImpl()->resetShadingControl(); -} - bool SubSurface::addShadingControl(const ShadingControl& shadingControl) { return getImpl()->addShadingControl(shadingControl); @@ -1495,6 +1454,31 @@ boost::optional SubSurface::addDaylightingDeviceShelf() SubSurface::SubSurface(std::shared_ptr impl) : PlanarSurface(std::move(impl)) {} + +// DEPRECATED +boost::optional SubSurface::shadingControl() const +{ + boost::optional result; + auto scs = shadingControls(); + if (scs.size() >= 1) { + if (scs.size() > 1) { + LOG(Warn, briefDescription() << " has more than one ShadingControl and you're using a deprecated method. Use shadingControls() instead"); + } + result = scs[0]; + } + return result; +} + +// DEPRECATED +bool SubSurface::setShadingControl(const ShadingControl& shadingControl) { + removeAllShadingControls(); + return addShadingControl(shadingControl); +} + +// DEPRECATED +void SubSurface::resetShadingControl() { + removeAllShadingControls(); +} /// @endcond std::vector applySkylightPattern(const std::vector >& pattern, const std::vector& spaces, const boost::optional& construction) diff --git a/src/model/SubSurface_Impl.hpp b/src/model/SubSurface_Impl.hpp index 90f8c735bbe..625caf16f8d 100644 --- a/src/model/SubSurface_Impl.hpp +++ b/src/model/SubSurface_Impl.hpp @@ -150,8 +150,6 @@ namespace detail { bool allowShadingControl() const; - boost::optional shadingControl() const; - std::vector shadingControls() const; unsigned int numberofShadingControls() const; @@ -186,10 +184,6 @@ namespace detail { void autocalculateViewFactortoGround(); - bool setShadingControl(const ShadingControl& shadingControl); - - void resetShadingControl(); - bool addShadingControl(const ShadingControl& shadingControl); bool addShadingControls(const std::vector &shadingControls); From 2f008b37e04fd204eb759d0870051110647e6aee Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 12:35:22 +0200 Subject: [PATCH 13/49] const-correctness; ,no ABI break: cannot pass cosnt ShadingCOntrol& when we are mutating it. m --- src/model/SubSurface.cpp | 20 +++++++++++--------- src/model/SubSurface.hpp | 6 +++--- src/model/SubSurface_Impl.hpp | 6 +++--- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/model/SubSurface.cpp b/src/model/SubSurface.cpp index 616fa454dc1..83dd14ce774 100644 --- a/src/model/SubSurface.cpp +++ b/src/model/SubSurface.cpp @@ -615,7 +615,7 @@ namespace detail { OS_ASSERT(result); } - bool SubSurface_Impl::addShadingControl(const ShadingControl& shadingControl) + bool SubSurface_Impl::addShadingControl(ShadingControl& shadingControl) { bool result = false; if (allowShadingControl()){ @@ -625,15 +625,17 @@ namespace detail { return result; } - bool SubSurface_Impl::addShadingControls(const std::vector &shadingControls) + bool SubSurface_Impl::addShadingControls(std::vector& shadingControls) { + bool ok = true; SubSurface thisSubSurface = getObject(); - for (const ShadingControl& shadingControl : shadingControls) { - shadingControl.addSubSurface(thisSubSurface); + for (ShadingControl& shadingControl : shadingControls) { + ok &= shadingControl.addSubSurface(thisSubSurface); } + return ok; } - void SubSurface_Impl::removeShadingControl(const ShadingControl& shadingControl) + void SubSurface_Impl::removeShadingControl(ShadingControl& shadingControl) { SubSurface thisSubSurface = getObject(); shadingControl.removeSubSurface(thisSubSurface); @@ -642,7 +644,7 @@ namespace detail { void SubSurface_Impl::removeAllShadingControls() { SubSurface thisSubSurface = getObject(); - for (const ShadingControl& shadingControl : shadingControls()) { + for (ShadingControl& shadingControl : shadingControls()) { shadingControl.removeSubSurface(thisSubSurface); } } @@ -1331,17 +1333,17 @@ void SubSurface::autocalculateNumberofVertices() { getImpl()->autocalculateNumberofVertices(); } -bool SubSurface::addShadingControl(const ShadingControl& shadingControl) +bool SubSurface::addShadingControl(ShadingControl& shadingControl) { return getImpl()->addShadingControl(shadingControl); } -bool SubSurface::addShadingControls(const std::vector &shadingControls) +bool SubSurface::addShadingControls(std::vector& shadingControls) { return getImpl()->addShadingControls(shadingControls); } -void SubSurface::removeShadingControl(const ShadingControl& shadingControl) +void SubSurface::removeShadingControl(ShadingControl& shadingControl) { getImpl()->removeShadingControl(shadingControl); } diff --git a/src/model/SubSurface.hpp b/src/model/SubSurface.hpp index 835ddf9d6e5..b60543714fd 100644 --- a/src/model/SubSurface.hpp +++ b/src/model/SubSurface.hpp @@ -135,11 +135,11 @@ class MODEL_API SubSurface : public PlanarSurface { // Replaced with removeAllShadingControls OS_DEPRECATED void resetShadingControl(); - bool addShadingControl(const ShadingControl& shadingControl); + bool addShadingControl(ShadingControl& shadingControl); - bool addShadingControls(const std::vector &shadingControls); + bool addShadingControls(std::vector& shadingControls); - void removeShadingControl(const ShadingControl& shadingControl); + void removeShadingControl(ShadingControl& shadingControl); void removeAllShadingControls(); diff --git a/src/model/SubSurface_Impl.hpp b/src/model/SubSurface_Impl.hpp index 625caf16f8d..3a2bdd98d15 100644 --- a/src/model/SubSurface_Impl.hpp +++ b/src/model/SubSurface_Impl.hpp @@ -184,11 +184,11 @@ namespace detail { void autocalculateViewFactortoGround(); - bool addShadingControl(const ShadingControl& shadingControl); + bool addShadingControl(ShadingControl& shadingControl); - bool addShadingControls(const std::vector &shadingControls); + bool addShadingControls(std::vector& shadingControls); - void removeShadingControl(const ShadingControl& shadingControl); + void removeShadingControl(ShadingControl& shadingControl); void removeAllShadingControls(); From ff629b3704ce90fd3df53cc34240328fb248a44a Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 12:26:14 +0200 Subject: [PATCH 14/49] ABI break of now-deprecated function --- src/model/SubSurface.cpp | 2 +- src/model/SubSurface.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/model/SubSurface.cpp b/src/model/SubSurface.cpp index 83dd14ce774..73b0b6f37a4 100644 --- a/src/model/SubSurface.cpp +++ b/src/model/SubSurface.cpp @@ -1472,7 +1472,7 @@ boost::optional SubSurface::shadingControl() const } // DEPRECATED -bool SubSurface::setShadingControl(const ShadingControl& shadingControl) { +bool SubSurface::setShadingControl(ShadingControl& shadingControl) { removeAllShadingControls(); return addShadingControl(shadingControl); } diff --git a/src/model/SubSurface.hpp b/src/model/SubSurface.hpp index b60543714fd..db4bacfd220 100644 --- a/src/model/SubSurface.hpp +++ b/src/model/SubSurface.hpp @@ -130,7 +130,7 @@ class MODEL_API SubSurface : public PlanarSurface { void autocalculateViewFactortoGround(); // This method is deprecated, please use addShadingControl or **setShadingControls/addShadingControls**. This will remove this SubSurface from any shading control(s) it is on (`removeAllShadingControls()`) then will call `addShadingControl(shadingControl)` - OS_DEPRECATED bool setShadingControl(const ShadingControl& shadingControl); + OS_DEPRECATED bool setShadingControl(ShadingControl& shadingControl); // Replaced with removeAllShadingControls OS_DEPRECATED void resetShadingControl(); From 373d248c449f55a4a82e35fe7157e44d1193af1e Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 12:36:23 +0200 Subject: [PATCH 15/49] Update description --- src/model/SubSurface.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/model/SubSurface.hpp b/src/model/SubSurface.hpp index db4bacfd220..04b10f3e707 100644 --- a/src/model/SubSurface.hpp +++ b/src/model/SubSurface.hpp @@ -129,7 +129,8 @@ class MODEL_API SubSurface : public PlanarSurface { void autocalculateViewFactortoGround(); - // This method is deprecated, please use addShadingControl or **setShadingControls/addShadingControls**. This will remove this SubSurface from any shading control(s) it is on (`removeAllShadingControls()`) then will call `addShadingControl(shadingControl)` + // This method is deprecated, please use addShadingControl or addShadingControls. + // This will remove this SubSurface from any shading control(s) it is on (`removeAllShadingControls()`) then will call `addShadingControl(shadingControl)` OS_DEPRECATED bool setShadingControl(ShadingControl& shadingControl); // Replaced with removeAllShadingControls From 87820eee725e68e6be58d3803cd02547232a0470 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 12:45:23 +0200 Subject: [PATCH 16/49] Update FT to avoid error using deprecated. is this still needed? @joseph-robertson --- src/energyplus/ForwardTranslator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/energyplus/ForwardTranslator.cpp b/src/energyplus/ForwardTranslator.cpp index f2b5f288236..3cc7a818d93 100644 --- a/src/energyplus/ForwardTranslator.cpp +++ b/src/energyplus/ForwardTranslator.cpp @@ -447,6 +447,7 @@ Workspace ForwardTranslator::translateModelPrivate( model::Model & model, bool f } } + // TODO: Is this still needed? // ensure shading controls only reference windows in a single zone and determine control sequence number // DLM: ideally E+ would not need to know the zone, shading controls could work across zones std::vector shadingControls = model.getConcreteModelObjects(); @@ -479,7 +480,7 @@ Workspace ForwardTranslator::translateModelPrivate( model::Model & model, bool f thisZoneHandleSet.insert(zoneHandle); ShadingControl clone = shadingControl.clone(model).cast(); // assign clone to control subSurface - subSurface.setShadingControl(clone); + clone.addSubSurface(subSurface); auto it = zoneHandleToShadingControlVectorMap.find(zoneHandle); if (it == zoneHandleToShadingControlVectorMap.end()) { zoneHandleToShadingControlVectorMap.insert(std::make_pair(zoneHandle, std::vector())); From 5dd85a15216f73567fc52790654bc6fa78373652 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 12:58:05 +0200 Subject: [PATCH 17/49] Implement new MultipleSurfaceControlType field in Shading Control --- resources/model/OpenStudio.idd | 10 ++++++++- src/model/ShadingControl.cpp | 34 +++++++++++++++++++++++++++++++ src/model/ShadingControl.hpp | 6 ++++++ src/model/ShadingControl_Impl.hpp | 4 ++++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd index e57a6c5c1fd..df509327408 100644 --- a/resources/model/OpenStudio.idd +++ b/resources/model/OpenStudio.idd @@ -5879,7 +5879,15 @@ OS:ShadingControl, \note OnIfHighZoneAirTempAndHighSolarOnWindow, and OnIfHighZoneAirTempAndHighHorizontalSolar \type real \ip-units unknown - A12; \field Sub Surface Name + A12, \field Multiple Surface Control Type + \type choice + \key Sequential + \key Group + \required-field + \note When Sequential is used the list of fenestration surfaces are controlled individually in the order specified + \note When Group is used the entire list is controlled simultaneously and if glare control is needed the entire + \note group of window shades are deployed together a the same time + A13; \field Sub Surface Name \required-field \begin-extensible \type object-list diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index 62d713427f8..a8b1792f498 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -211,7 +211,17 @@ namespace detail { OS_ASSERT(test); } + std::string ShadingControl_Impl::multipleSurfaceControlType() const + { + boost::optional result = getString(OS_ShadingControlFields::MultipleSurfaceControlType, true); + OS_ASSERT(result); + return result.get(); + } + bool ShadingControl_Impl::setMultipleSurfaceControlType(const std::string& multipleSurfaceControlType) + { + return setString(OS_ShadingControlFields::MultipleSurfaceControlType, multipleSurfaceControlType); + } unsigned int ShadingControl_Impl::numberofSubSurfaces() const { @@ -414,6 +424,9 @@ ShadingControl::ShadingControl(const Construction& construction) bool test = this->setShadingType(position + type); OS_ASSERT(test); + test = setMultipleSurfaceControlType("Sequential"); // E+ IDD Default + OS_ASSERT(test); + test = this->setPointer(OS_ShadingControlFields::ConstructionwithShadingName, construction.handle()); OS_ASSERT(test); } @@ -439,6 +452,9 @@ ShadingControl::ShadingControl(const ShadingMaterial& shadingMaterial) bool test = this->setShadingType(type); OS_ASSERT(test); + test = setMultipleSurfaceControlType("Sequential"); // E+ IDD Default + OS_ASSERT(test); + test = this->setPointer(OS_ShadingControlFields::ShadingDeviceMaterialName, shadingMaterial.handle()); OS_ASSERT(test); } @@ -457,6 +473,11 @@ std::vector ShadingControl::shadingControlTypeValues() { OS_ShadingControlFields::ShadingControlType); } +std::vector ShadingControl::multipleSurfaceControlTypeValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), + OS_ShadingControlFields::MultipleSurfaceControlType); +} + boost::optional ShadingControl::construction() const { return getImpl()->construction(); } @@ -517,6 +538,19 @@ void ShadingControl::resetSetpoint(){ getImpl()->resetSetpoint(); } +std::string ShadingControl::multipleSurfaceControlType() const { + return getImpl()->multipleSurfaceControlType(); +} + + +bool ShadingControl::setMultipleSurfaceControlType(const std::string& multipleSurfaceControlType){ + return getImpl()->setMultipleSurfaceControlType(multipleSurfaceControlType); +} + + + +// Extensible Fields + std::vector ShadingControl::subSurfaces() const { return getImpl()->subSurfaces(); } diff --git a/src/model/ShadingControl.hpp b/src/model/ShadingControl.hpp index d71d6b2a53d..d278e8121ae 100644 --- a/src/model/ShadingControl.hpp +++ b/src/model/ShadingControl.hpp @@ -75,6 +75,8 @@ class MODEL_API ShadingControl : public ResourceObject { static std::vector shadingControlTypeValues(); + static std::vector multipleSurfaceControlTypeValues(); + /** @name Getters */ //@{ @@ -94,6 +96,8 @@ class MODEL_API ShadingControl : public ResourceObject { bool isSetpointDefaulted() const; + std::string multipleSurfaceControlType() const; + //@} /** @name Setters */ //@{ @@ -115,6 +119,8 @@ class MODEL_API ShadingControl : public ResourceObject { void resetSetpoint(); + bool setMultipleSurfaceControlType(const std::string& multipleSurfaceControlType); + //@} /** @name Other */ //@{ diff --git a/src/model/ShadingControl_Impl.hpp b/src/model/ShadingControl_Impl.hpp index c18657abc8c..061137ea488 100644 --- a/src/model/ShadingControl_Impl.hpp +++ b/src/model/ShadingControl_Impl.hpp @@ -92,6 +92,8 @@ namespace detail { bool isSetpointDefaulted() const; + std::string multipleSurfaceControlType() const; + //@} /** @name Setters */ //@{ @@ -110,6 +112,8 @@ namespace detail { void resetSetpoint(); + bool setMultipleSurfaceControlType(const std::string& multipleSurfaceControlType); + //@} /** @name Other */ //@{ From 6619cbf8c661e0eba23c0350714730c13ca48049 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 12:53:48 +0200 Subject: [PATCH 18/49] The Radiance Forward Translator also needs to be update. I'm just making a crude change for build to keep going @joseph-robertson --- src/radiance/ForwardTranslator.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/radiance/ForwardTranslator.cpp b/src/radiance/ForwardTranslator.cpp index 0698b708cd3..3520260f549 100644 --- a/src/radiance/ForwardTranslator.cpp +++ b/src/radiance/ForwardTranslator.cpp @@ -1214,7 +1214,12 @@ namespace radiance { continue; } - boost::optional shadingControl = subSurface.shadingControl(); + // TODO: This is going to need update! + boost::optional shadingControl; + auto scs = subSurface.shadingControls(); + if (!scs.empty()) { + shadingControl = scs[0]; + } // future support for mullion factor double visibleTransmittanceMultiplier = 1.0; From 3c610c1386bf2fdb5c69f394dab315617dc5f657 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 13:10:30 +0200 Subject: [PATCH 19/49] VT & FT for MultipleSurfaceControlType --- .../ForwardTranslator/ForwardTranslateShadingControl.cpp | 2 ++ src/osversion/VersionTranslator.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp index 4a805fa6328..479bfbed6d0 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp @@ -160,6 +160,8 @@ boost::optional ForwardTranslator::translateShadingControl(model::Sha //idfObject.setDouble(WindowShadingControlFields::Setpoint2, 0.0); + idfObject.setString(WindowShadingControlFields::MultipleSurfaceControlType, modelObject.multipleSurfaceControlType()); + idfObject.clearExtensibleGroups(); for (const SubSurface& subSurface : subSurfaces) { IdfExtensibleGroup group = idfObject.pushExtensibleGroup(); diff --git a/src/osversion/VersionTranslator.cpp b/src/osversion/VersionTranslator.cpp index 0372ddd6291..fa6fa63ed87 100644 --- a/src/osversion/VersionTranslator.cpp +++ b/src/osversion/VersionTranslator.cpp @@ -6296,6 +6296,9 @@ std::string VersionTranslator::update_3_0_1_to_3_1_0(const IdfFile& idf_3_0_1, c } } + // New field at end, before extensible, and I moved to E+ default to the Ctor and made it required, so need to set it here + newShadingControl.setString(13, "Sequential"); + std::vector subSurfaces = idf_3_0_1.getObjectsByType(idf_3_0_1.iddFile().getObject("OS:SubSurface").get()); for ( auto & subSurface : subSurfaces ) { value = subSurface.getString(7); // Shading Control Name From b682148068439b6017a71c762d515981c44d0b58 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 13:44:34 +0200 Subject: [PATCH 20/49] There's a problem with the extensibles [18] 3_1_0(main)> sc.addSubSurface(s) NameError: undefined local variable or method `s' for main:Object from (pry):16:in `__pry__' [19] 3_1_0(main)> sc.addSubSurface(ss) [openstudio.IdfExtensibleGroup] <2> This extensible group is invalid, and so does not have an index. RuntimeError: /home/julien/Software/Others/OpenStudio/src/utilities/idf/IdfExtensibleGroup.cpp@199 : This extensible group is invalid, and so does not have an index. from (pry):17:in `addSubSurface' --- resources/model/OpenStudio.idd | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd index df509327408..dda65fd06b3 100644 --- a/resources/model/OpenStudio.idd +++ b/resources/model/OpenStudio.idd @@ -5888,7 +5888,6 @@ OS:ShadingControl, \note When Group is used the entire list is controlled simultaneously and if glare control is needed the entire \note group of window shades are deployed together a the same time A13; \field Sub Surface Name - \required-field \begin-extensible \type object-list \object-list GlazedExtSubSurfNames From 85fdf12bc9d8c0f8f0dcb967150aa12b4c8f8626 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 13:50:39 +0200 Subject: [PATCH 21/49] Write a VT test and adjust VT: Always deal with OS:SubSurface, and prescan for speed. --- src/osversion/VersionTranslator.cpp | 78 +++++++++++-------- .../test/3_1_0/test_vt_ShadingControl.osm | 33 ++++++++ .../test/3_1_0/test_vt_ShadingControl.rb | 25 ++++++ .../test/VersionTranslator_GTest.cpp | 32 ++++++++ 4 files changed, 137 insertions(+), 31 deletions(-) create mode 100644 src/osversion/test/3_1_0/test_vt_ShadingControl.osm create mode 100644 src/osversion/test/3_1_0/test_vt_ShadingControl.rb diff --git a/src/osversion/VersionTranslator.cpp b/src/osversion/VersionTranslator.cpp index fa6fa63ed87..f144be5f313 100644 --- a/src/osversion/VersionTranslator.cpp +++ b/src/osversion/VersionTranslator.cpp @@ -5956,6 +5956,21 @@ std::string VersionTranslator::update_3_0_1_to_3_1_0(const IdfFile& idf_3_0_1, c }); +/***************************************************************************************************************************************************** +* Shading Control Refactor: pre-scan * +*****************************************************************************************************************************************************/ + + std::map shadingControlToSurfaceMap; + std::vector subSurfaces = idf_3_0_1.getObjectsByType(idf_3_0_1.iddFile().getObject("OS:SubSurface").get()); + for ( auto & subSurface : subSurfaces ) { + value = subSurface.getString(7); // Shading Control Name + if (value) { + // TEMP + LOG(Warn, value.get() << ": " << subSurface.getString(0).get()); + shadingControlToSurfaceMap[value.get()] = subSurface.getString(0).get(); + } + } + for (const IdfObject& object : idf_3_0_1.objects()) { auto iddname = object.iddObject().name(); @@ -6281,56 +6296,57 @@ std::string VersionTranslator::update_3_0_1_to_3_1_0(const IdfFile& idf_3_0_1, c m_refactored.push_back( RefactoredObjectData(object, newObject) ); ss << newObject; } + + // Note: Would have needed to do UtilityCost:Tariff for Fuel Type renames too, but not wrapped + } else if (iddname == "OS:ShadingControl") { // get all subsurfaces // loop thru subsurfaces // check if shading control name equals this handle // add extensible field with subsurface handle // remove shading control name field from subsurface - auto iddObjectShadingControl = idd_3_1_0.getObject("OS:ShadingControl"); - IdfObject newShadingControl(iddObjectShadingControl.get()); + auto iddObject = idd_3_1_0.getObject(iddname); + IdfObject newObject(iddObject.get()); for (size_t i = 0; i < object.numFields(); ++i) { if ((value = object.getString(i))) { - newShadingControl.setString(i, value.get()); + newObject.setString(i, value.get()); } } // New field at end, before extensible, and I moved to E+ default to the Ctor and made it required, so need to set it here - newShadingControl.setString(13, "Sequential"); + newObject.setString(13, "Sequential"); - std::vector subSurfaces = idf_3_0_1.getObjectsByType(idf_3_0_1.iddFile().getObject("OS:SubSurface").get()); - for ( auto & subSurface : subSurfaces ) { - value = subSurface.getString(7); // Shading Control Name - if (value) { - if (value.get() == object.getString(0)) { - newShadingControl.setString(13, subSurface.getString(0).get()); - - auto iddObjectSubSurface = idd_3_1_0.getObject("OS:SubSurface"); - IdfObject newSubSurface(iddObjectSubSurface.get()); - - for (size_t i = 0; i < subSurface.numFields(); ++i) { - if ((value = subSurface.getString(i))) { - if (i < 7) { - newSubSurface.setString(i, value.get()); - } else if (i == 7) { // Shading Control Name - // no-op - } else { - newSubSurface.setString(i - 1, value.get()); - } - } - } + // Add the SubSurface to the list if any + auto subSurfaceHandleIt = shadingControlToSurfaceMap.find(object.getString(0).get()); + if ( subSurfaceHandleIt != shadingControlToSurfaceMap.end() ) { + // TEMP + LOG(Warn, object.getString(0).get() << " maps to " << subSurfaceHandleIt->second); + newObject.pushExtensibleGroup(StringVector(1u, subSurfaceHandleIt->second)); + } - m_refactored.push_back(RefactoredObjectData(subSurface, newSubSurface)); - ss << subSurface; + m_refactored.push_back(RefactoredObjectData(object, newObject)); + ss << newObject; + + } else if (iddname == "OS:SubSurface") { + + auto iddObject = idd_3_1_0.getObject(iddname); + IdfObject newObject(iddObject.get()); + + for (size_t i = 0; i < object.numFields(); ++i) { + if ((value = object.getString(i))) { + if (i < 7) { + newObject.setString(i, value.get()); + } else if (i == 7) { // Shading Control Name + // no-op + } else { + newObject.setString(i - 1, value.get()); } } } - m_refactored.push_back(RefactoredObjectData(object, newShadingControl)); - ss << newShadingControl; - - // Note: Would have needed to do UtilityCost:Tariff too, but not wrapped + m_refactored.push_back(RefactoredObjectData(object, newObject)); + ss << newObject; // No-op } else { diff --git a/src/osversion/test/3_1_0/test_vt_ShadingControl.osm b/src/osversion/test/3_1_0/test_vt_ShadingControl.osm new file mode 100644 index 00000000000..0b7f79fa9e3 --- /dev/null +++ b/src/osversion/test/3_1_0/test_vt_ShadingControl.osm @@ -0,0 +1,33 @@ + +OS:Version, + {f2244246-9f10-476b-acb6-90ee026a1f9b}, !- Handle + 3.0.1; !- Version Identifier + +OS:SubSurface, + {e1cf7875-d26c-4ac9-ab87-b62eeb1f8c68}, !- Handle + SubSurface, !- Name + Skylight, !- Sub Surface Type + {8dc9f32d-e3da-4b0d-8061-ade751c81cda}, !- Construction Name + , !- Surface Name + , !- Outside Boundary Condition Object + 0.5, !- View Factor to Ground + {5c9e0b1f-e54c-446e-81ad-40891c1333f0}, !- Shading Control Name + , !- Frame and Divider Name + , !- Multiplier + , !- Number of Vertices + 0, 0, 0, !- X,Y,Z Vertex 1 {m} + 0, 1, 0, !- X,Y,Z Vertex 2 {m} + 1, 1, 0, !- X,Y,Z Vertex 3 {m} + 1, 0, 0; !- X,Y,Z Vertex 4 {m} + +OS:Construction, + {8dc9f32d-e3da-4b0d-8061-ade751c81cda}, !- Handle + Construction 1, !- Name + ; !- Surface Rendering Name + +OS:ShadingControl, + {5c9e0b1f-e54c-446e-81ad-40891c1333f0}, !- Handle + ShadingControl, !- Name + SwitchableGlazing, !- Shading Type + {8dc9f32d-e3da-4b0d-8061-ade751c81cda}; !- Construction with Shading Name + diff --git a/src/osversion/test/3_1_0/test_vt_ShadingControl.rb b/src/osversion/test/3_1_0/test_vt_ShadingControl.rb new file mode 100644 index 00000000000..bed719f7319 --- /dev/null +++ b/src/osversion/test/3_1_0/test_vt_ShadingControl.rb @@ -0,0 +1,25 @@ +require '/usr/local/openstudio-3.0.1/Ruby/openstudio' + +include OpenStudio::Model + +m = Model.new + +pts = OpenStudio::Point3dVector.new; + +pts << OpenStudio::Point3d.new(0, 0, 0) +pts << OpenStudio::Point3d.new(0, 1, 0) +pts << OpenStudio::Point3d.new(1, 1, 0) +pts << OpenStudio::Point3d.new(1, 0, 0) + +ss = OpenStudio::Model::SubSurface.new(pts, m) +c = Construction.new(m) +ss.setConstruction(c) +ss.setName("SubSurface") + +sc = ShadingControl.new(c) +sc.setName("ShadingControl") +ss.setShadingControl(sc) +ss.setViewFactortoGround(0.5) + +m.save('test_vt_ShadingControl.osm', true) + diff --git a/src/osversion/test/VersionTranslator_GTest.cpp b/src/osversion/test/VersionTranslator_GTest.cpp index 22907274b4e..9c4b7ac5f38 100644 --- a/src/osversion/test/VersionTranslator_GTest.cpp +++ b/src/osversion/test/VersionTranslator_GTest.cpp @@ -1216,3 +1216,35 @@ TEST_F(OSVersionFixture, update_3_0_1_to_3_1_0_ZoneHVACLowTemp) { ASSERT_TRUE(lowtempradiant.getTarget(8)); // Heating Setpoint Temperature Schedule Name } } + + +TEST_F(OSVersionFixture, update_3_0_1_to_3_1_0_ShadingControl_and_SubSurfaces) { + openstudio::path path = resourcesPath() / toPath("osversion/3_1_0/test_vt_ShadingControl.osm"); + osversion::VersionTranslator vt; + boost::optional model = vt.loadModel(path); + ASSERT_TRUE(model) << "Failed to load " << path;; + openstudio::path outPath = resourcesPath() / toPath("osversion/3_1_0/test_vt_ShadingControl_updated.osm"); + model->save(outPath, true); + + std::vector sss = model->getObjectsByType("OS:SubSurface"); + ASSERT_EQ(1u, sss.size()); + WorkspaceObject ss = sss[0]; + + EXPECT_EQ(0.5, ss.getDouble(6)); + EXPECT_EQ(4u, ss.numExtensibleGroups()); + auto eg = ss.extensibleGroups()[3]; + EXPECT_EQ(1, eg.getInt(0, false).get()); + EXPECT_EQ(0, eg.getInt(1, false).get()); + EXPECT_EQ(0, eg.getInt(2, false).get()); + + std::vector scs = model->getObjectsByType("OS:ShadingControl"); + ASSERT_EQ(1u, scs.size()); + WorkspaceObject sc = scs[0]; + + EXPECT_EQ("Sequential", sc.getString(13, false, true).get()); + ASSERT_EQ(1u, sc.numExtensibleGroups()); + + WorkspaceExtensibleGroup w_eg = extensibleGroups()[0].cast(); + ASSERT_TRUE(w_eg.getTarget(0)); + EXPECT_EQ("OS:SubSurface", w_eg.getTarget(0).get().iddObject().name()); +} From cfdf3eea5b26a4884022b62b3f197c7fe5708b5d Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 11 Sep 2020 13:58:33 +0200 Subject: [PATCH 22/49] typo in VT test --- src/osversion/test/VersionTranslator_GTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osversion/test/VersionTranslator_GTest.cpp b/src/osversion/test/VersionTranslator_GTest.cpp index 9c4b7ac5f38..03ec5dfaa8d 100644 --- a/src/osversion/test/VersionTranslator_GTest.cpp +++ b/src/osversion/test/VersionTranslator_GTest.cpp @@ -1244,7 +1244,7 @@ TEST_F(OSVersionFixture, update_3_0_1_to_3_1_0_ShadingControl_and_SubSurfaces) { EXPECT_EQ("Sequential", sc.getString(13, false, true).get()); ASSERT_EQ(1u, sc.numExtensibleGroups()); - WorkspaceExtensibleGroup w_eg = extensibleGroups()[0].cast(); + WorkspaceExtensibleGroup w_eg = sc.extensibleGroups()[0].cast(); ASSERT_TRUE(w_eg.getTarget(0)); EXPECT_EQ("OS:SubSurface", w_eg.getTarget(0).get().iddObject().name()); } From 257fb6aa8ccdfbd26d4e45d5fdfec97f5d5391eb Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Fri, 11 Sep 2020 13:13:27 -0700 Subject: [PATCH 23/49] Fix, updates to idd. --- resources/model/OpenStudio.idd | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd index dda65fd06b3..cdca44126d8 100644 --- a/resources/model/OpenStudio.idd +++ b/resources/model/OpenStudio.idd @@ -5744,7 +5744,8 @@ OS:SubSurface, \units m OS:ShadingControl, - \min-fields 4 + \extensible:1 + \min-fields 15 A1 , \field Handle \type handle \required-field @@ -5887,7 +5888,8 @@ OS:ShadingControl, \note When Sequential is used the list of fenestration surfaces are controlled individually in the order specified \note When Group is used the entire list is controlled simultaneously and if glare control is needed the entire \note group of window shades are deployed together a the same time - A13; \field Sub Surface Name + A13; \field Sub Surface Name 1 + \required-field \begin-extensible \type object-list \object-list GlazedExtSubSurfNames From 64d54a780afd2987b5a300953c21de3046053f58 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Fri, 11 Sep 2020 15:03:24 -0700 Subject: [PATCH 24/49] Skip adding a subsurface that already exists. --- src/model/ShadingControl.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index a8b1792f498..6600b001c13 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -265,6 +265,13 @@ namespace detail { bool ShadingControl_Impl::addSubSurface(const SubSurface& subSurface) { + // Check if subSurface already exists + boost::optional _existingIndex = subSurfaceIndex(subSurface); + if (_existingIndex) { + LOG(Warn, "For " << briefDescription() << ", SubSurface already exists."); + return true; + } + bool result; WorkspaceExtensibleGroup eg = getObject().pushExtensibleGroup().cast(); @@ -317,8 +324,6 @@ namespace detail { return ok; } - - bool ShadingControl_Impl::removeSubSurface(const SubSurface& subSurface) { boost::optional idx = subSurfaceIndex(subSurface); @@ -346,7 +351,7 @@ namespace detail { for (const SubSurface& subSurface : subSurfaces) { ok &= addSubSurface(subSurface); } - return ok;; + return ok; } void ShadingControl_Impl::removeAllSubSurfaces() From bb37994d6a028de9e153846fc2b6144664ba3ac9 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Fri, 11 Sep 2020 15:03:34 -0700 Subject: [PATCH 25/49] Update and improve tests. --- src/model/test/ShadingControl_GTest.cpp | 8 ++++++++ src/model/test/SubSurface_GTest.cpp | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/model/test/ShadingControl_GTest.cpp b/src/model/test/ShadingControl_GTest.cpp index 3a1a947269a..4af89f6d717 100644 --- a/src/model/test/ShadingControl_GTest.cpp +++ b/src/model/test/ShadingControl_GTest.cpp @@ -151,4 +151,12 @@ TEST_F(ModelFixture, ShadingControl_SubSurfaces) { EXPECT_EQ(2, shadingControl.numberofSubSurfaces()); shadingControl.removeAllSubSurfaces(); EXPECT_EQ(0, shadingControl.numberofSubSurfaces()); + + EXPECT_TRUE(shadingControl.addSubSurfaces(subSurfaces)); + EXPECT_EQ(2, shadingControl.numberofSubSurfaces()); + subSurface2.remove(); + // EXPECT_EQ(1, shadingControl.numberofSubSurfaces()); + + // ShadingControl shadingControlClone = shadingControl.clone(model).cast(); + // EXPECT_EQ(0, shadingControlClone.numberofSubSurfaces()); } diff --git a/src/model/test/SubSurface_GTest.cpp b/src/model/test/SubSurface_GTest.cpp index 62cb33a5793..6dc1a86b897 100644 --- a/src/model/test/SubSurface_GTest.cpp +++ b/src/model/test/SubSurface_GTest.cpp @@ -1228,7 +1228,15 @@ TEST_F(ModelFixture, SubSurface_ShadingControls) EXPECT_EQ(0, subSurface.numberofShadingControls()); EXPECT_TRUE(subSurface.addShadingControl(shadingControl1)); EXPECT_EQ(1, subSurface.numberofShadingControls()); + EXPECT_TRUE(subSurface.addShadingControl(shadingControl1)); + EXPECT_EQ(1, subSurface.numberofShadingControls()); + EXPECT_TRUE(subSurface.addShadingControl(shadingControl2)); + EXPECT_EQ(2, subSurface.numberofShadingControls()); subSurface.removeShadingControl(shadingControl1); + EXPECT_EQ(1, subSurface.numberofShadingControls()); + subSurface.removeShadingControl(shadingControl1); + EXPECT_EQ(1, subSurface.numberofShadingControls()); + subSurface.removeShadingControl(shadingControl2); EXPECT_EQ(0, subSurface.numberofShadingControls()); std::vector shadingControls; @@ -1242,12 +1250,14 @@ TEST_F(ModelFixture, SubSurface_ShadingControls) // Test deprecated methods subSurface.addShadingControls(shadingControls); EXPECT_EQ(2, subSurface.numberofShadingControls()); - EXPECT_FALSE(subSurface.shadingControl()); - EXPECT_TRUE(subSurface.setShadingControl(shadingControl1)); + ASSERT_TRUE(subSurface.shadingControl()); + // EXPECT_EQ(subSurface.shadingControl()->handle(), shadingControl1.handle()); // no guarantee that it's shadingControl1 + EXPECT_TRUE(subSurface.setShadingControl(shadingControl2)); EXPECT_EQ(1, subSurface.numberofShadingControls()); - EXPECT_TRUE(subSurface.shadingControl()); + ASSERT_TRUE(subSurface.shadingControl()); + EXPECT_EQ(subSurface.shadingControl().get(), shadingControl2); EXPECT_TRUE(subSurface.addShadingControl(shadingControl2)); - EXPECT_EQ(2, subSurface.numberofShadingControls()); + EXPECT_EQ(1, subSurface.numberofShadingControls()); subSurface.resetShadingControl(); EXPECT_EQ(0, subSurface.numberofShadingControls()); } From bd530232f0ae1fd3023ddf5ab539d4d9809dcff2 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 14 Sep 2020 12:03:13 +0200 Subject: [PATCH 26/49] Model test for ShadingControl 'Multiple Surface Control Type' field (new) --- src/model/test/ShadingControl_GTest.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/model/test/ShadingControl_GTest.cpp b/src/model/test/ShadingControl_GTest.cpp index 4af89f6d717..306d30f0e2f 100644 --- a/src/model/test/ShadingControl_GTest.cpp +++ b/src/model/test/ShadingControl_GTest.cpp @@ -149,6 +149,13 @@ TEST_F(ModelFixture, ShadingControl_SubSurfaces) { subSurfaces.push_back(subSurface2); EXPECT_TRUE(shadingControl.addSubSurfaces(subSurfaces)); EXPECT_EQ(2, shadingControl.numberofSubSurfaces()); + + EXPECT_EQ("Sequential", shadingControl.multipleSurfaceControlType()); + EXPECT_TRUE(shadingControl.setMultipleSurfaceControlType("Group")); + EXPECT_EQ("Group", shadingControl.multipleSurfaceControlType()); + EXPECT_FALSE(shadingControl.setMultipleSurfaceControlType("BADENUM")); + EXPECT_EQ("Group", shadingControl.multipleSurfaceControlType()); + shadingControl.removeAllSubSurfaces(); EXPECT_EQ(0, shadingControl.numberofSubSurfaces()); From 04e8c6edac3cb81b953476e7c0dd040f1683fc1f Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 14 Sep 2020 14:21:51 +0200 Subject: [PATCH 27/49] Extend Gtest for clone and removeSubSurface --- src/model/test/ShadingControl_GTest.cpp | 73 ++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/src/model/test/ShadingControl_GTest.cpp b/src/model/test/ShadingControl_GTest.cpp index 306d30f0e2f..18920ebfecc 100644 --- a/src/model/test/ShadingControl_GTest.cpp +++ b/src/model/test/ShadingControl_GTest.cpp @@ -32,7 +32,9 @@ #include "ModelFixture.hpp" #include "../ShadingControl.hpp" +#include "../ShadingControl_Impl.hpp" #include "../Construction.hpp" +#include "../Construction_Impl.hpp" #include "../Schedule.hpp" #include "../Blind.hpp" #include "../SimpleGlazing.hpp" @@ -138,17 +140,17 @@ TEST_F(ModelFixture, ShadingControl_SubSurfaces) { vertices2.push_back(Point3d(1,0,1)); SubSurface subSurface2(vertices2, model); - EXPECT_EQ(0, shadingControl.numberofSubSurfaces()); + EXPECT_EQ(0u, shadingControl.numberofSubSurfaces()); EXPECT_TRUE(shadingControl.addSubSurface(subSurface1)); - EXPECT_EQ(1, shadingControl.numberofSubSurfaces()); + EXPECT_EQ(1u, shadingControl.numberofSubSurfaces()); shadingControl.removeSubSurface(subSurface1); - EXPECT_EQ(0, shadingControl.numberofSubSurfaces()); + EXPECT_EQ(0u, shadingControl.numberofSubSurfaces()); std::vector subSurfaces; subSurfaces.push_back(subSurface1); subSurfaces.push_back(subSurface2); EXPECT_TRUE(shadingControl.addSubSurfaces(subSurfaces)); - EXPECT_EQ(2, shadingControl.numberofSubSurfaces()); + EXPECT_EQ(2u, shadingControl.numberofSubSurfaces()); EXPECT_EQ("Sequential", shadingControl.multipleSurfaceControlType()); EXPECT_TRUE(shadingControl.setMultipleSurfaceControlType("Group")); @@ -157,13 +159,66 @@ TEST_F(ModelFixture, ShadingControl_SubSurfaces) { EXPECT_EQ("Group", shadingControl.multipleSurfaceControlType()); shadingControl.removeAllSubSurfaces(); - EXPECT_EQ(0, shadingControl.numberofSubSurfaces()); + EXPECT_EQ(0u, shadingControl.numberofSubSurfaces()); EXPECT_TRUE(shadingControl.addSubSurfaces(subSurfaces)); + EXPECT_EQ(2u, shadingControl.numberofSubSurfaces()); + subSurface1.remove(); + EXPECT_EQ(1u, shadingControl.numberofSubSurfaces()); + EXPECT_EQ(1u, shadingControl.numExtensibleGroups()); + ASSERT_TRUE(shadingControl.subSurfaceIndex(subSurface2)); + EXPECT_EQ(1u, shadingControl.subSurfaceIndex(subSurface2).get()); +} + +TEST_F(ModelFixture, ShadingControl_Clone) { + Model model; + + Blind blind(model); + ShadingControl shadingControl(blind); + + std::vector vertices1; + vertices1.push_back(Point3d(0,0,1)); + vertices1.push_back(Point3d(0,0,0)); + vertices1.push_back(Point3d(1,0,0)); + vertices1.push_back(Point3d(1,0,1)); + SubSurface subSurface1(vertices1, model); + + std::vector vertices2; + vertices2.push_back(Point3d(0,0,1)); + vertices2.push_back(Point3d(0,0,0)); + vertices2.push_back(Point3d(1,0,0)); + vertices2.push_back(Point3d(1,0,1)); + SubSurface subSurface2(vertices2, model); + + shadingControl.setSubSurfaces({subSurface1, subSurface2}); EXPECT_EQ(2, shadingControl.numberofSubSurfaces()); - subSurface2.remove(); - // EXPECT_EQ(1, shadingControl.numberofSubSurfaces()); - // ShadingControl shadingControlClone = shadingControl.clone(model).cast(); - // EXPECT_EQ(0, shadingControlClone.numberofSubSurfaces()); + // Clone same model + { + // TODO: what is the expected behavior here? Should the clone reference the same subSurfaces as the original? + ShadingControl shadingControlClone = shadingControl.clone(model).cast(); + ASSERT_TRUE(shadingControlClone.construction()); + EXPECT_EQ(shadingControl.construction()->handle(), shadingControlClone.construction()->handle()); + EXPECT_EQ(2u, shadingControl.numberofSubSurfaces()); + EXPECT_EQ(2u, shadingControl.numExtensibleGroups()); + EXPECT_EQ(2u, shadingControlClone.numberofSubSurfaces()); + EXPECT_EQ(2u, shadingControlClone.numExtensibleGroups()); + EXPECT_EQ(shadingControl.subSurfaces(), shadingControlClone.subSurfaces()); + + } + + // Clone other model + { + Model model2; + + // TODO: what is the expected behavior here? It will clone the Construction (ResourceObject...) referenced here, but not the subSurfaces + ShadingControl shadingControlClone = shadingControl.clone(model2).cast(); + EXPECT_EQ(2u, shadingControl.numberofSubSurfaces()); + EXPECT_EQ(2u, shadingControl.numExtensibleGroups()); + EXPECT_EQ(0u, shadingControlClone.numberofSubSurfaces()); + EXPECT_EQ(0u, shadingControlClone.numExtensibleGroups()); + EXPECT_EQ(1u, model2.getConcreteModelObjects().size()); + EXPECT_TRUE(shadingControlClone.construction()); + EXPECT_NE(shadingControl.construction().get(), shadingControlClone.construction().get()); + } } From c858e5f73d2341ed6121837a2a3f7db3af3f3b92 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 14 Sep 2020 14:22:27 +0200 Subject: [PATCH 28/49] Proposed implementation of ShadingControl::clone & if remove subSurface => remove from ShadingControls --- src/model/ShadingControl.cpp | 10 ++++++++++ src/model/ShadingControl_Impl.hpp | 4 ++++ src/model/SubSurface.cpp | 5 +++++ 3 files changed, 19 insertions(+) diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index 6600b001c13..072aced2e85 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -96,6 +96,16 @@ namespace detail { return ShadingControl::iddObjectType(); } + ModelObject ShadingControl_Impl::clone(Model model) const { + ShadingControl scClone = ResourceObject_Impl::clone(model).cast(); + + if (model != this->model()) { + scClone.removeAllSubSurfaces(); + } + + return scClone; + } + boost::optional ShadingControl_Impl::construction() const { return getObject().getModelObjectTarget(OS_ShadingControlFields::ConstructionwithShadingName); diff --git a/src/model/ShadingControl_Impl.hpp b/src/model/ShadingControl_Impl.hpp index 061137ea488..7acc5b1b670 100644 --- a/src/model/ShadingControl_Impl.hpp +++ b/src/model/ShadingControl_Impl.hpp @@ -72,6 +72,10 @@ namespace detail { virtual IddObjectType iddObjectType() const override; + // If cloning in the same model, will keep on referencing the same SubSurfaces as the original + // If cloning in another model, will clear out its extensible Sub Surface Name group + virtual ModelObject clone(Model model) const; + //@} /** @name Getters */ //@{ diff --git a/src/model/SubSurface.cpp b/src/model/SubSurface.cpp index 73b0b6f37a4..b613e16b39c 100644 --- a/src/model/SubSurface.cpp +++ b/src/model/SubSurface.cpp @@ -147,6 +147,11 @@ namespace detail { this->resetAdjacentSubSurface(); } + // Remove it from the extensible groups in ShadingControl(s) + for (auto& sc: shadingControls()) { + sc.removeSubSurface(this->getObject()); + } + return ParentObject_Impl::remove(); } From 4859e45096e788584568390dcbb1cbf664d08cb8 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 14 Sep 2020 14:31:54 +0200 Subject: [PATCH 29/49] typo in test: wasn't testing the right property. --- src/model/test/ShadingControl_GTest.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/model/test/ShadingControl_GTest.cpp b/src/model/test/ShadingControl_GTest.cpp index 18920ebfecc..4df014a465b 100644 --- a/src/model/test/ShadingControl_GTest.cpp +++ b/src/model/test/ShadingControl_GTest.cpp @@ -197,8 +197,8 @@ TEST_F(ModelFixture, ShadingControl_Clone) { { // TODO: what is the expected behavior here? Should the clone reference the same subSurfaces as the original? ShadingControl shadingControlClone = shadingControl.clone(model).cast(); - ASSERT_TRUE(shadingControlClone.construction()); - EXPECT_EQ(shadingControl.construction()->handle(), shadingControlClone.construction()->handle()); + ASSERT_TRUE(shadingControlClone.shadingMaterial()); + EXPECT_EQ(shadingControl.shadingMaterial()->handle(), shadingControlClone.shadingMaterial()->handle()); EXPECT_EQ(2u, shadingControl.numberofSubSurfaces()); EXPECT_EQ(2u, shadingControl.numExtensibleGroups()); EXPECT_EQ(2u, shadingControlClone.numberofSubSurfaces()); @@ -211,14 +211,14 @@ TEST_F(ModelFixture, ShadingControl_Clone) { { Model model2; - // TODO: what is the expected behavior here? It will clone the Construction (ResourceObject...) referenced here, but not the subSurfaces + // TODO: what is the expected behavior here? It will clone the Construction and ShadingMaterial (ResourceObject...) referenced here, but not the subSurfaces ShadingControl shadingControlClone = shadingControl.clone(model2).cast(); EXPECT_EQ(2u, shadingControl.numberofSubSurfaces()); EXPECT_EQ(2u, shadingControl.numExtensibleGroups()); EXPECT_EQ(0u, shadingControlClone.numberofSubSurfaces()); EXPECT_EQ(0u, shadingControlClone.numExtensibleGroups()); EXPECT_EQ(1u, model2.getConcreteModelObjects().size()); - EXPECT_TRUE(shadingControlClone.construction()); - EXPECT_NE(shadingControl.construction().get(), shadingControlClone.construction().get()); + EXPECT_TRUE(shadingControlClone.shadingMaterial()); + EXPECT_NE(shadingControl.shadingMaterial().get(), shadingControlClone.shadingMaterial().get()); } } From cb6ceb01c3ea8ed1a7f3c67ef3283ce95964ea31 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 14 Sep 2020 14:32:48 +0200 Subject: [PATCH 30/49] Partial classes for C#: reimpling ShadingControl methods that use SubSurface in ModelGeometry.i(untested yet) --- src/model/ModelGeometry.i | 56 +++++++++++++++++++++++++ src/model/ModelResources.i | 8 ++++ src/model/test/ShadingControl_GTest.cpp | 4 +- 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/model/ModelGeometry.i b/src/model/ModelGeometry.i index 05ec1fe3d31..ec7ff03bf66 100644 --- a/src/model/ModelGeometry.i +++ b/src/model/ModelGeometry.i @@ -267,6 +267,34 @@ SWIG_MODELOBJECT(ExteriorWaterEquipment, 1); return sc.subSurfaces(); } + boost::optional getSubSurfaceIndexForShadingControl(const openstudio::model::ShadingControl& sc, const openstudio::model::SubSurface& subSurface) { + return sc.subSurfaceIndex(subSurface); + } + + bool addSubSurfaceForShadingControl(openstudio::model::ShadingControl sc, const openstudio::model::SubSurface& subSurface) { + return sc.addSubSurface(subSurface); + } + + bool addSubSurfaceForShadingControlWithIndex(openstudio::model::ShadingControl sc, const openstudio::model::SubSurface& subSurface, unsigned index) { + return sc.addSubSurface(subSurface, index); + } + + bool setSubSurfaceIndexForShadingControl(openstudio::model::ShadingControl sc, const openstudio::model::SubSurface& subSurface, unsigned index) { + return sc.setSubSurfaceIndex(subSurface, index); + } + + bool removeSubSurfaceForShadingControl(openstudio::model::ShadingControl sc, const openstudio::model::SubSurface& subSurface) { + return sc.removeSubSurface(subSurface); + } + + bool addSubSurfacesForShadingControl(openstudio::model::ShadingControl sc, const std::vector& subSurfaces) { + return sc.addSubSurfaces(subSurfaces); + } + + bool setSubSurfacesForShadingControl(openstudio::model::ShadingControl sc, const std::vector& subSurfaces) { + return sc.setSubSurfaces(subSurfaces); + } + // EMS Actuator setter for Space (reimplemented from ModelCore.i) bool setSpaceForEMSActuator(openstudio::model::EnergyManagementSystemActuator actuator, openstudio::model::Space space) { return actuator.setSpace(space); @@ -315,6 +343,34 @@ SWIG_MODELOBJECT(ExteriorWaterEquipment, 1); public SubSurfaceVector subSurfaces() { return OpenStudio.OpenStudioModelGeometry.getSubSurfaces(this); } + + public OptionalUnsigned subSurfaceIndex(OpenStudio.SubSurface subSurface) { + return OpenStudio.OpenStudioModelGeometry.getSubSurfaceIndexForShadingControl(this, subSurface); + } + + public bool addSubSurface(OpenStudio.SubSurface subSurface) { + return OpenStudio.OpenStudioModelGeometry.addSubSurfaceForShadingControl(this, subSurface); + } + + public bool addSubSurface(OpenStudio.SubSurface subSurface, uint index) { + return OpenStudio.OpenStudioModelGeometry.addSubSurfaceForShadingControlWithIndex(this, subSurface, index); + } + + public bool setSubSurfaceIndex(OpenStudio.SubSurface subSurface, uint index) { + return OpenStudio.OpenStudioModelGeometry.setSubSurfaceIndexForShadingControl(this, subSurface, index); + } + + public bool removeSubSurface(OpenStudio.SubSurface subSurface) { + return OpenStudio.OpenStudioModelGeometry.removeSubSurfaceForShadingControl(this, subSurface); + } + + public bool addSubSurfaces(SubSurfaceVector subSurfaces) { + return OpenStudio.OpenStudioModelHVAC.addSubSurfacesForShadingControl(this, subSurfaces); + } + + public bool setSubSurfaces(SubSurfaceVector subSurfaces) { + return OpenStudio.OpenStudioModelHVAC.setSubSurfacesForShadingControl(this, subSurfaces); + } } public partial class EnergyManagementSystemActuator : ModelObject { diff --git a/src/model/ModelResources.i b/src/model/ModelResources.i index 362ea6ab964..85b29d225c5 100644 --- a/src/model/ModelResources.i +++ b/src/model/ModelResources.i @@ -26,6 +26,12 @@ %ignore openstudio::model::SpaceLoadDefinition::instances; %ignore openstudio::model::ExteriorLoadDefinition::instances; %ignore openstudio::model::ShadingControl::subSurfaces; + %ignore openstudio::model::ShadingControl::subSurfaceIndex; + %ignore openstudio::model::ShadingControl::addSubSurface; + %ignore openstudio::model::ShadingControl::setSubSurfaceIndex; + %ignore openstudio::model::ShadingControl::removeSubSurface(const SubSurface& subSurface); // The unsigned index overload is fine + %ignore openstudio::model::ShadingControl::addSubSurfaces; + %ignore openstudio::model::ShadingControl::setSubSurfaces; // TODO: why? // ignore schedule type @@ -47,6 +53,8 @@ namespace model { // forward declarations class ShadingControl; +%feature("valuewrapper") SubSurface; +class SubSurface; } } diff --git a/src/model/test/ShadingControl_GTest.cpp b/src/model/test/ShadingControl_GTest.cpp index 4df014a465b..7aed746ab16 100644 --- a/src/model/test/ShadingControl_GTest.cpp +++ b/src/model/test/ShadingControl_GTest.cpp @@ -34,9 +34,9 @@ #include "../ShadingControl.hpp" #include "../ShadingControl_Impl.hpp" #include "../Construction.hpp" -#include "../Construction_Impl.hpp" #include "../Schedule.hpp" #include "../Blind.hpp" +#include "../Blind_Impl.hpp" #include "../SimpleGlazing.hpp" #include "../SubSurface.hpp" @@ -217,7 +217,7 @@ TEST_F(ModelFixture, ShadingControl_Clone) { EXPECT_EQ(2u, shadingControl.numExtensibleGroups()); EXPECT_EQ(0u, shadingControlClone.numberofSubSurfaces()); EXPECT_EQ(0u, shadingControlClone.numExtensibleGroups()); - EXPECT_EQ(1u, model2.getConcreteModelObjects().size()); + EXPECT_EQ(1u, model2.getConcreteModelObjects().size()); EXPECT_TRUE(shadingControlClone.shadingMaterial()); EXPECT_NE(shadingControl.shadingMaterial().get(), shadingControlClone.shadingMaterial().get()); } From c5c99f2f5c47d42378a412af794779c1a151436b Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 14 Sep 2020 14:47:00 +0200 Subject: [PATCH 31/49] Add a TODO --- src/model/test/ShadingControl_GTest.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/model/test/ShadingControl_GTest.cpp b/src/model/test/ShadingControl_GTest.cpp index 7aed746ab16..ad079c01b70 100644 --- a/src/model/test/ShadingControl_GTest.cpp +++ b/src/model/test/ShadingControl_GTest.cpp @@ -222,3 +222,21 @@ TEST_F(ModelFixture, ShadingControl_Clone) { EXPECT_NE(shadingControl.shadingMaterial().get(), shadingControlClone.shadingMaterial().get()); } } + +TEST_F(ModelFixture, ShadingControl_RemoveRequiredObject) { + Model model; + + Blind blind(model); + ShadingControl shadingControl(blind); + + blind.remove(); + + EXPECT_FALSE(shadingControl.shadingMaterial()); + EXPECT_FALSE(shadingControl.construction()); + + // TODO: You're now in a broken, and unfixable state: you neither have a Construction nor a ShadingMaterial, + // and the model API has no setters to help you fix the state (setShadingMaterial / setConstruction) + // This WILL get forward translated anyways. We need to determine whether we want to add setters in the Model API or have the FT do a check and not + // translate the object if it doesn't have either. Throwing here so we do not forget to do it + ASSERT_TRUE(false); +} From 48aab8621eefb74291e13d313a4adfdea73b4b5d Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 14 Sep 2020 12:57:54 -0700 Subject: [PATCH 32/49] Add rt and more tests. --- src/energyplus/CMakeLists.txt | 2 + .../ForwardTranslateShadingControl.cpp | 2 - src/energyplus/ReverseTranslator.cpp | 5 + src/energyplus/ReverseTranslator.hpp | 2 + ...seTranslateFenestrationSurfaceDetailed.cpp | 8 - .../ReverseTranslateWindowShadingControl.cpp | 148 +++++++++++++ src/energyplus/Test/ShadingControl_GTest.cpp | 204 ++++++++++++++++++ src/energyplus/Test/SubSurface_GTest.cpp | 2 - 8 files changed, 361 insertions(+), 12 deletions(-) create mode 100644 src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp create mode 100644 src/energyplus/Test/ShadingControl_GTest.cpp diff --git a/src/energyplus/CMakeLists.txt b/src/energyplus/CMakeLists.txt index b6d696531d4..897178c95c1 100644 --- a/src/energyplus/CMakeLists.txt +++ b/src/energyplus/CMakeLists.txt @@ -542,6 +542,7 @@ set(${target_name}_src ReverseTranslator/ReverseTranslateWindowMaterialGlazing.cpp ReverseTranslator/ReverseTranslateWindowMaterialSimpleGlazingSystem.cpp ReverseTranslator/ReverseTranslateWindowPropertyFrameAndDivider.cpp + ReverseTranslator/ReverseTranslateWindowShadingControl.cpp ReverseTranslator/ReverseTranslateZoneAirHeatBalanceAlgorithm.cpp ReverseTranslator/ReverseTranslateZoneAirMassFlowConservation.cpp ReverseTranslator/ReverseTranslateZone.cpp @@ -649,6 +650,7 @@ set(${target_name}_test_src Test/ScheduleInterval_GTest.cpp Test/ScheduleRuleset_GTest.cpp Test/SetpointManagerFollowGroundTemperature_GTest.cpp + Test/ShadingControl_GTest.cpp Test/ShadingSurface_GTest.cpp Test/ShadowCalculation_GTest.cpp Test/SimulationControl_GTest.cpp diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp index 479bfbed6d0..73125a08770 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp @@ -118,8 +118,6 @@ boost::optional ForwardTranslator::translateShadingControl(model::Sha LOG(Error, modelObject.briefDescription() << " has unknown Shading Control Sequence Number"); } - idfObject.setString(WindowShadingControlFields::MultipleSurfaceControlType, "Group"); - std::string shadingType = modelObject.shadingType(); if (istringEqual("InteriorDaylightRedirectionDevice", shadingType)) { idfObject.setString(WindowShadingControlFields::ShadingType, "InteriorBlind"); diff --git a/src/energyplus/ReverseTranslator.cpp b/src/energyplus/ReverseTranslator.cpp index cfe35c1321f..593467d5c5b 100644 --- a/src/energyplus/ReverseTranslator.cpp +++ b/src/energyplus/ReverseTranslator.cpp @@ -1069,6 +1069,11 @@ boost::optional ReverseTranslator::translateAndMapWorkspaceObject(c modelObject = translateWindowPropertyFrameAndDivider(workspaceObject); break; } + case openstudio::IddObjectType::WindowShadingControl: + { + modelObject = translateWindowShadingControl(workspaceObject); + break; + } case openstudio::IddObjectType::Zone: { modelObject = translateZone(workspaceObject); diff --git a/src/energyplus/ReverseTranslator.hpp b/src/energyplus/ReverseTranslator.hpp index f957118c524..dab0de65444 100644 --- a/src/energyplus/ReverseTranslator.hpp +++ b/src/energyplus/ReverseTranslator.hpp @@ -347,6 +347,8 @@ class ENERGYPLUS_API ReverseTranslator { boost::optional translateWindowPropertyFrameAndDivider(const WorkspaceObject & workspaceObject); + boost::optional translateWindowShadingControl(const WorkspaceObject & workspaceObject); + boost::optional translateZone(const WorkspaceObject & workspaceObject); boost::optional translateZoneAirHeatBalanceAlgorithm(const WorkspaceObject & workspaceObject); diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateFenestrationSurfaceDetailed.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateFenestrationSurfaceDetailed.cpp index 1f7bff86c72..1dc526392cb 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateFenestrationSurfaceDetailed.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateFenestrationSurfaceDetailed.cpp @@ -169,14 +169,6 @@ OptionalModelObject ReverseTranslator::translateFenestrationSurfaceDetailed( con subSurface->setViewFactortoGround(*d); } - //target = workspaceObject.getTarget(openstudio::FenestrationSurface_DetailedFields::ShadingControlName); - //if (target){ - // OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); - // if (modelObject && modelObject->optionalCast()){ - // subSurface->setShadingControl(modelObject->cast()); - // } - //} - target = workspaceObject.getTarget(openstudio::FenestrationSurface_DetailedFields::FrameandDividerName); if (target){ OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp new file mode 100644 index 00000000000..0d3c9e3d9cc --- /dev/null +++ b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp @@ -0,0 +1,148 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +* following conditions are met: +* +* (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following +* disclaimer. +* +* (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the distribution. +* +* (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission from the respective party. +* +* (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other derivative works +* may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar designation without specific prior +* written permission from Alliance for Sustainable Energy, LLC. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED +* STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************************************************************/ + +#include "../ReverseTranslator.hpp" + +#include "../../model/ShadingControl.hpp" +#include "../../model/ShadingControl_Impl.hpp" +#include "../../model/Construction.hpp" +#include "../../model/Construction_Impl.hpp" +#include "../../model/Schedule.hpp" +#include "../../model/Schedule_Impl.hpp" +#include "../../model/ShadingMaterial.hpp" +#include "../../model/ShadingMaterial_Impl.hpp" +#include "../../model/SubSurface.hpp" +#include "../../model/SubSurface_Impl.hpp" + +#include "../../utilities/idf/WorkspaceExtensibleGroup.hpp" + +#include +#include "../../utilities/idd/IddEnums.hpp" +#include + +#include "../../utilities/core/Assert.hpp" + +using namespace openstudio::model; + +namespace openstudio { +namespace energyplus { + +boost::optional ReverseTranslator::translateWindowShadingControl( const WorkspaceObject& workspaceObject ) +{ + if( workspaceObject.iddObject().type() != IddObjectType::WindowShadingControl ){ + LOG(Error, "WorkspaceObject is not IddObjectType: WindowShadingControl"); + return boost::none; + } + + OptionalWorkspaceObject target; + + boost::optional construction; + if (target = workspaceObject.getTarget(WindowShadingControlFields::ConstructionwithShadingName)){ + OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); + if (modelObject){ + if (modelObject->optionalCast()){ + construction = modelObject->cast(); + } + } + } + + boost::optional shadingMaterial; + if (target = workspaceObject.getTarget(WindowShadingControlFields::ShadingDeviceMaterialName)){ + OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); + if (modelObject){ + if (modelObject->optionalCast()){ + shadingMaterial = modelObject->cast(); + } + } + } + + boost::optional shadingControl; + if (construction){ + openstudio::model::ShadingControl shadingControl(*construction); + } else if (shadingMaterial){ + openstudio::model::ShadingControl shadingControl(*shadingMaterial); + } + + OptionalString s; + OptionalDouble d; + + s = workspaceObject.name(); + if(s){ + shadingControl->setName(*s); + } + + s = workspaceObject.getString(WindowShadingControlFields::ShadingType); + if(s){ + if(istringEqual("InteriorBlind", *s)){ + shadingControl->setShadingType("InteriorDaylightRedirectionDevice"); + } else { + shadingControl->setShadingType(*s); + } + } + + s = workspaceObject.getString(WindowShadingControlFields::ShadingControlType); + if(s){ + shadingControl->setShadingControlType(*s); + } + + d = workspaceObject.getDouble(WindowShadingControlFields::Setpoint); + if(s){ + shadingControl->setSetpoint(*d); + } + + target = workspaceObject.getTarget(WindowShadingControlFields::ScheduleName); + if (target){ + OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); + if (modelObject){ + if (modelObject->optionalCast()){ + shadingControl->setSchedule(modelObject->cast()); + } + } + } + + s = workspaceObject.getString(WindowShadingControlFields::MultipleSurfaceControlType); + if(s){ + shadingControl->setMultipleSurfaceControlType(*s); + } + + // get extensible groups for sub surfaces + for (const IdfExtensibleGroup& idfGroup : workspaceObject.extensibleGroups()){ + WorkspaceExtensibleGroup workspaceGroup = idfGroup.cast(); + OptionalWorkspaceObject target = workspaceGroup.getTarget(WindowShadingControlExtensibleFields::FenestrationSurfaceName); + OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); + + // add the sub surface + shadingControl->addSubSurface(modelObject->cast()); + } + + return shadingControl.get(); +} + +} // energyplus +} // openstudio diff --git a/src/energyplus/Test/ShadingControl_GTest.cpp b/src/energyplus/Test/ShadingControl_GTest.cpp new file mode 100644 index 00000000000..d382ab4dc17 --- /dev/null +++ b/src/energyplus/Test/ShadingControl_GTest.cpp @@ -0,0 +1,204 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +* following conditions are met: +* +* (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following +* disclaimer. +* +* (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the distribution. +* +* (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission from the respective party. +* +* (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other derivative works +* may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar designation without specific prior +* written permission from Alliance for Sustainable Energy, LLC. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED +* STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************************************************************/ + +#include +#include "EnergyPlusFixture.hpp" + +#include "../ErrorFile.hpp" +#include "../ForwardTranslator.hpp" +#include "../ReverseTranslator.hpp" + +#include "../../model/Model.hpp" +#include "../../model/SubSurface.hpp" +#include "../../model/SubSurface_Impl.hpp" +#include "../../model/Surface.hpp" +#include "../../model/Surface_Impl.hpp" +#include "../../model/Space.hpp" +#include "../../model/Space_Impl.hpp" +#include "../../model/ThermalZone.hpp" +#include "../../model/ThermalZone_Impl.hpp" +#include "../../model/ShadingControl.hpp" +#include "../../model/ShadingControl_Impl.hpp" +#include "../../model/Blind.hpp" +#include "../../model/Blind_Impl.hpp" + +#include "../../utilities/core/Optional.hpp" +#include "../../utilities/core/Checksum.hpp" +#include "../../utilities/core/Logger.hpp" +#include "../../utilities/geometry/Point3d.hpp" +#include "../../utilities/geometry/Vector3d.hpp" +#include "../../utilities/sql/SqlFile.hpp" +#include "../../utilities/idd/IddEnums.hpp" +#include "../../utilities/idd/IddFile.hpp" +#include "../../utilities/idf/IdfFile.hpp" + +#include +#include +#include +#include + +#include "../../utilities/idf/IdfExtensibleGroup.hpp" +#include "../../utilities/idf/WorkspaceExtensibleGroup.hpp" + +#include + +#include + +using namespace openstudio; +using namespace openstudio::energyplus; +using namespace openstudio::model; + +TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) +{ + Model model; + + ThermalZone thermalZone(model); + + Space space(model); + space.setThermalZone(thermalZone); + + std::vector vertices; + vertices.push_back(Point3d(0, 2, 0)); + vertices.push_back(Point3d(0, 0, 0)); + vertices.push_back(Point3d(2, 0, 0)); + vertices.push_back(Point3d(2, 2, 0)); + Surface surface(vertices, model); + surface.setSpace(space); + + vertices.clear(); + vertices.push_back(Point3d(0, 1, 0)); + vertices.push_back(Point3d(0, 0, 0)); + vertices.push_back(Point3d(1, 0, 0)); + vertices.push_back(Point3d(1, 1, 0)); + + SubSurface subSurface(vertices, model); + subSurface.setSurface(surface); + subSurface.assignDefaultSubSurfaceType(); + + Blind blind1(model); + ShadingControl shadingControl1(blind1); + subSurface.addShadingControl(shadingControl1); + + Blind blind2(model); + ShadingControl shadingControl2(blind2); + shadingControl2.setMultipleSurfaceControlType("Group"); + subSurface.addShadingControl(shadingControl2); + + ForwardTranslator forwardTranslator; + Workspace workspace = forwardTranslator.translateModel(model); + + EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::FenestrationSurface_Detailed).size()); + + std::vector objVector(workspace.getObjectsByType(IddObjectType::WindowShadingControl).size()); + ASSERT_EQ(2u, objVector.size()); + WorkspaceObject wo1(objVector.at(0)); + WorkspaceObject wo2(objVector.at(1)); + + EXPECT_EQ("Sequential", wo1.getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); + EXPECT_EQ("Group", wo2.getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); + + ASSERT_EQ(1u, wo1.extensibleGroups().size()); + ASSERT_EQ(1u, wo2.extensibleGroups().size()); +} + +TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) +{ + openstudio::Workspace workspace(openstudio::StrictnessLevel::None, openstudio::IddFileType::EnergyPlus); + + openstudio::IdfObject idfObject1(openstudio::IddObjectType::BuildingSurface_Detailed); + idfObject1.setString(BuildingSurface_DetailedFields::Name, "Surface 1"); + idfObject1.setString(BuildingSurface_DetailedFields::SurfaceType, "Wall"); + idfObject1.setString(BuildingSurface_DetailedFields::ConstructionName, ""); + idfObject1.setString(BuildingSurface_DetailedFields::ZoneName, ""); + idfObject1.setString(BuildingSurface_DetailedFields::OutsideBoundaryCondition, "Outdoors"); + idfObject1.setString(BuildingSurface_DetailedFields::OutsideBoundaryConditionObject, ""); + idfObject1.setString(BuildingSurface_DetailedFields::SunExposure, "SunExposed"); + idfObject1.setString(BuildingSurface_DetailedFields::WindExposure, "WindExposed"); + idfObject1.setString(BuildingSurface_DetailedFields::ViewFactortoGround, ""); + idfObject1.setString(BuildingSurface_DetailedFields::NumberofVertices, ""); + IdfExtensibleGroup group1 = idfObject1.pushExtensibleGroup(); // vertex 1 + group1.setDouble(0, 0); + group1.setDouble(1, 2); + group1.setDouble(2, 0); + IdfExtensibleGroup group2 = idfObject1.pushExtensibleGroup(); // vertex 2 + group2.setDouble(0, 0); + group2.setDouble(1, 0); + group2.setDouble(2, 0); + IdfExtensibleGroup group3 = idfObject1.pushExtensibleGroup(); // vertex 3 + group3.setDouble(0, 2); + group3.setDouble(1, 0); + group3.setDouble(2, 0); + IdfExtensibleGroup group4 = idfObject1.pushExtensibleGroup(); // vertex 4 + group4.setDouble(0, 2); + group4.setDouble(1, 2); + group4.setDouble(2, 0); + + openstudio::WorkspaceObject epSurface = workspace.addObject(idfObject1).get(); + + openstudio::IdfObject idfObject2(openstudio::IddObjectType::FenestrationSurface_Detailed); + idfObject2.setString(FenestrationSurface_DetailedFields::Name, "Sub Surface 1"); + idfObject2.setString(FenestrationSurface_DetailedFields::SurfaceType, "Window"); + idfObject2.setString(FenestrationSurface_DetailedFields::ConstructionName, ""); + idfObject2.setString(FenestrationSurface_DetailedFields::BuildingSurfaceName, "Surface 1"); + idfObject2.setString(FenestrationSurface_DetailedFields::OutsideBoundaryConditionObject, ""); + idfObject2.setString(FenestrationSurface_DetailedFields::ViewFactortoGround, "Autocalculate"); + idfObject2.setString(FenestrationSurface_DetailedFields::FrameandDividerName, ""); + idfObject2.setString(FenestrationSurface_DetailedFields::Multiplier, "1.0"); + idfObject2.setString(FenestrationSurface_DetailedFields::NumberofVertices, ""); + IdfExtensibleGroup group5 = idfObject2.pushExtensibleGroup(); // vertex 1 + group5.setDouble(0, 0); + group5.setDouble(1, 1); + group5.setDouble(2, 0); + IdfExtensibleGroup group6 = idfObject2.pushExtensibleGroup(); // vertex 2 + group6.setDouble(0, 0); + group6.setDouble(1, 0); + group6.setDouble(2, 0); + IdfExtensibleGroup group7 = idfObject2.pushExtensibleGroup(); // vertex 3 + group7.setDouble(0, 1); + group7.setDouble(1, 0); + group7.setDouble(2, 0); + IdfExtensibleGroup group8 = idfObject2.pushExtensibleGroup(); // vertex 4 + group8.setDouble(0, 1); + group8.setDouble(1, 1); + group8.setDouble(2, 0); + + openstudio::WorkspaceObject epSubSurface = workspace.addObject(idfObject2).get(); + + // TODO + + ReverseTranslator trans; + ASSERT_NO_THROW(trans.translateWorkspace(workspace)); + Model model = trans.translateWorkspace(workspace); + + EXPECT_EQ(1u, model.getModelObjects().size()); + EXPECT_EQ(1u, model.getModelObjects().size()); + EXPECT_EQ(1u, model.getModelObjects().size()); + + // TODO +} diff --git a/src/energyplus/Test/SubSurface_GTest.cpp b/src/energyplus/Test/SubSurface_GTest.cpp index 7383909f6d7..0996f55a7b5 100644 --- a/src/energyplus/Test/SubSurface_GTest.cpp +++ b/src/energyplus/Test/SubSurface_GTest.cpp @@ -128,5 +128,3 @@ TEST_F(EnergyPlusFixture,ForwardTranslator_SubSurface) ASSERT_TRUE(subSurfaceObject.getTarget(FenestrationSurface_DetailedFields::FrameandDividerName)); EXPECT_EQ(frameObject.handle(), subSurfaceObject.getTarget(FenestrationSurface_DetailedFields::FrameandDividerName)->handle()); } - - From 8ea432e1df5607cbf39a5e2f2189ffb7a909032a Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 14 Sep 2020 15:40:11 -0700 Subject: [PATCH 33/49] Fix rt and update rt tests. --- .../ReverseTranslateWindowShadingControl.cpp | 7 ++-- src/energyplus/Test/ShadingControl_GTest.cpp | 37 +++++++++++++++++-- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp index 0d3c9e3d9cc..4b8d7fb48ec 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp @@ -63,7 +63,7 @@ boost::optional ReverseTranslator::translateWindowShadingControl( c OptionalWorkspaceObject target; boost::optional construction; - if (target = workspaceObject.getTarget(WindowShadingControlFields::ConstructionwithShadingName)){ + if ((target = workspaceObject.getTarget(WindowShadingControlFields::ConstructionwithShadingName))){ OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); if (modelObject){ if (modelObject->optionalCast()){ @@ -73,7 +73,7 @@ boost::optional ReverseTranslator::translateWindowShadingControl( c } boost::optional shadingMaterial; - if (target = workspaceObject.getTarget(WindowShadingControlFields::ShadingDeviceMaterialName)){ + if ((target = workspaceObject.getTarget(WindowShadingControlFields::ShadingDeviceMaterialName))){ OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); if (modelObject){ if (modelObject->optionalCast()){ @@ -116,8 +116,7 @@ boost::optional ReverseTranslator::translateWindowShadingControl( c shadingControl->setSetpoint(*d); } - target = workspaceObject.getTarget(WindowShadingControlFields::ScheduleName); - if (target){ + if ((target = workspaceObject.getTarget(WindowShadingControlFields::ScheduleName))){ OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); if (modelObject){ if (modelObject->optionalCast()){ diff --git a/src/energyplus/Test/ShadingControl_GTest.cpp b/src/energyplus/Test/ShadingControl_GTest.cpp index d382ab4dc17..72a08184f0d 100644 --- a/src/energyplus/Test/ShadingControl_GTest.cpp +++ b/src/energyplus/Test/ShadingControl_GTest.cpp @@ -115,7 +115,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::FenestrationSurface_Detailed).size()); - std::vector objVector(workspace.getObjectsByType(IddObjectType::WindowShadingControl).size()); + std::vector objVector(workspace.getObjectsByType(IddObjectType::WindowShadingControl)); ASSERT_EQ(2u, objVector.size()); WorkspaceObject wo1(objVector.at(0)); WorkspaceObject wo2(objVector.at(1)); @@ -190,7 +190,23 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) openstudio::WorkspaceObject epSubSurface = workspace.addObject(idfObject2).get(); - // TODO + openstudio::IdfObject idfObject3(openstudio::IddObjectType::WindowMaterial_Shade); + idfObject3.setString(WindowMaterial_ShadeFields::Name, "Shade 1"); + + openstudio::IdfObject idfObject4(openstudio::IddObjectType::WindowShadingControl); + idfObject4.setString(WindowShadingControlFields::Name, "Shading Control 1"); + idfObject4.setString(WindowShadingControlFields::ZoneName, ""); + idfObject4.setString(WindowShadingControlFields::ShadingControlType, "AlwaysOn"); + idfObject4.setInt(WindowShadingControlFields::ShadingControlSequenceNumber, 1); + idfObject4.setString(WindowShadingControlFields::ShadingType, "InteriorShade"); + idfObject4.setString(WindowShadingControlFields::ShadingDeviceMaterialName, "Shade 1"); + idfObject4.setDouble(WindowShadingControlFields::Setpoint, 100); + idfObject4.setString(WindowShadingControlFields::GlareControlIsActive, "No"); + idfObject4.setString(WindowShadingControlFields::MultipleSurfaceControlType, "Sequential"); + IdfExtensibleGroup group9 = idfObject4.pushExtensibleGroup(); // sub surface + group9.setString(0, "Sub Surface 1"); + + openstudio::WorkspaceObject epWindowShadingControl = workspace.addObject(idfObject4).get(); ReverseTranslator trans; ASSERT_NO_THROW(trans.translateWorkspace(workspace)); @@ -198,7 +214,20 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) EXPECT_EQ(1u, model.getModelObjects().size()); EXPECT_EQ(1u, model.getModelObjects().size()); - EXPECT_EQ(1u, model.getModelObjects().size()); - // TODO + std::vector shadingControls = model.getModelObjects(); + ASSERT_EQ(1u, shadingControls.size()); + ShadingControl shadingControl = shadingControls[0]; + EXPECT_EQ(1, shadingControl.numberofSubSurfaces()); + EXPECT_EQ("Sequential", shadingControl.multipleSurfaceControlType()); + + std::vector subSurfaces = model.getModelObjects(); + ASSERT_EQ(1u, subSurfaces.size()); + SubSurface subSurface = subSurfaces[0]; + EXPECT_EQ("Sub Surface 1", subSurface.name().get()); + + ASSERT_EQ(1, subSurface.numberofShadingControls()); + ASSERT_TRUE(subSurface.shadingControl()); + ShadingControl shadingControl2 = subSurface.shadingControl().get(); + EXPECT_EQ(shadingControl, shadingControl2); } From fbfd1dba32194397cab28464f56138bf975a06bd Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 14 Sep 2020 21:58:28 -0700 Subject: [PATCH 34/49] Improve shading control rt and tests. --- .../ReverseTranslateWindowShadingControl.cpp | 89 ++++++++++--------- src/energyplus/Test/ShadingControl_GTest.cpp | 64 +++++++++---- 2 files changed, 95 insertions(+), 58 deletions(-) diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp index 4b8d7fb48ec..9404708b488 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp @@ -89,58 +89,65 @@ boost::optional ReverseTranslator::translateWindowShadingControl( c openstudio::model::ShadingControl shadingControl(*shadingMaterial); } - OptionalString s; - OptionalDouble d; + if (shadingControl) { - s = workspaceObject.name(); - if(s){ - shadingControl->setName(*s); - } + OptionalString s; + OptionalDouble d; - s = workspaceObject.getString(WindowShadingControlFields::ShadingType); - if(s){ - if(istringEqual("InteriorBlind", *s)){ - shadingControl->setShadingType("InteriorDaylightRedirectionDevice"); - } else { - shadingControl->setShadingType(*s); + s = workspaceObject.name(); + if(s){ + shadingControl->setName(*s); } - } - s = workspaceObject.getString(WindowShadingControlFields::ShadingControlType); - if(s){ - shadingControl->setShadingControlType(*s); - } + s = workspaceObject.getString(WindowShadingControlFields::ShadingType); + if(s){ + if(istringEqual("InteriorBlind", *s)){ + shadingControl->setShadingType("InteriorDaylightRedirectionDevice"); + } else { + shadingControl->setShadingType(*s); + } + } - d = workspaceObject.getDouble(WindowShadingControlFields::Setpoint); - if(s){ - shadingControl->setSetpoint(*d); - } + s = workspaceObject.getString(WindowShadingControlFields::ShadingControlType); + if(s){ + shadingControl->setShadingControlType(*s); + } - if ((target = workspaceObject.getTarget(WindowShadingControlFields::ScheduleName))){ - OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); - if (modelObject){ - if (modelObject->optionalCast()){ - shadingControl->setSchedule(modelObject->cast()); + if ((target = workspaceObject.getTarget(WindowShadingControlFields::ScheduleName))){ + OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); + if (modelObject){ + if (modelObject->optionalCast()){ + shadingControl->setSchedule(modelObject->cast()); + } } } - } - s = workspaceObject.getString(WindowShadingControlFields::MultipleSurfaceControlType); - if(s){ - shadingControl->setMultipleSurfaceControlType(*s); - } + d = workspaceObject.getDouble(WindowShadingControlFields::Setpoint); + if(s){ + shadingControl->setSetpoint(*d); + } - // get extensible groups for sub surfaces - for (const IdfExtensibleGroup& idfGroup : workspaceObject.extensibleGroups()){ - WorkspaceExtensibleGroup workspaceGroup = idfGroup.cast(); - OptionalWorkspaceObject target = workspaceGroup.getTarget(WindowShadingControlExtensibleFields::FenestrationSurfaceName); - OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); - - // add the sub surface - shadingControl->addSubSurface(modelObject->cast()); - } + s = workspaceObject.getString(WindowShadingControlFields::MultipleSurfaceControlType); + if(s){ + shadingControl->setMultipleSurfaceControlType(*s); + } + + // get extensible groups for sub surfaces + for (const IdfExtensibleGroup& idfGroup : workspaceObject.extensibleGroups()){ + WorkspaceExtensibleGroup workspaceGroup = idfGroup.cast(); + OptionalWorkspaceObject target = workspaceGroup.getTarget(WindowShadingControlExtensibleFields::FenestrationSurfaceName); + OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); - return shadingControl.get(); + // add the sub surface + shadingControl->addSubSurface(modelObject->cast()); + } + + return shadingControl.get(); + } else { + LOG(Error, "Unknown error translating " << workspaceObject.briefDescription()); + + return boost::none; + } } } // energyplus diff --git a/src/energyplus/Test/ShadingControl_GTest.cpp b/src/energyplus/Test/ShadingControl_GTest.cpp index 72a08184f0d..ad85c1d0fea 100644 --- a/src/energyplus/Test/ShadingControl_GTest.cpp +++ b/src/energyplus/Test/ShadingControl_GTest.cpp @@ -47,6 +47,8 @@ #include "../../model/ShadingControl_Impl.hpp" #include "../../model/Blind.hpp" #include "../../model/Blind_Impl.hpp" +#include "../../model/ScheduleConstant.hpp" +#include "../../model/ScheduleConstant_Impl.hpp" #include "../../utilities/core/Optional.hpp" #include "../../utilities/core/Checksum.hpp" @@ -61,6 +63,7 @@ #include #include #include +#include #include #include "../../utilities/idf/IdfExtensibleGroup.hpp" @@ -103,6 +106,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) Blind blind1(model); ShadingControl shadingControl1(blind1); + shadingControl1.setMultipleSurfaceControlType("Group"); subSurface.addShadingControl(shadingControl1); Blind blind2(model); @@ -120,7 +124,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) WorkspaceObject wo1(objVector.at(0)); WorkspaceObject wo2(objVector.at(1)); - EXPECT_EQ("Sequential", wo1.getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); + EXPECT_EQ("Group", wo1.getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); EXPECT_EQ("Group", wo2.getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); ASSERT_EQ(1u, wo1.extensibleGroups().size()); @@ -131,11 +135,16 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) { openstudio::Workspace workspace(openstudio::StrictnessLevel::None, openstudio::IddFileType::EnergyPlus); + openstudio::IdfObject idf_zone(openstudio::IddObjectType::Zone); + idf_zone.setName("Thermal Zone 1"); + + openstudio::WorkspaceObject epZone = workspace.addObject(idf_zone).get(); + openstudio::IdfObject idfObject1(openstudio::IddObjectType::BuildingSurface_Detailed); idfObject1.setString(BuildingSurface_DetailedFields::Name, "Surface 1"); idfObject1.setString(BuildingSurface_DetailedFields::SurfaceType, "Wall"); idfObject1.setString(BuildingSurface_DetailedFields::ConstructionName, ""); - idfObject1.setString(BuildingSurface_DetailedFields::ZoneName, ""); + idfObject1.setString(BuildingSurface_DetailedFields::ZoneName, "Thermal Zone 1"); idfObject1.setString(BuildingSurface_DetailedFields::OutsideBoundaryCondition, "Outdoors"); idfObject1.setString(BuildingSurface_DetailedFields::OutsideBoundaryConditionObject, ""); idfObject1.setString(BuildingSurface_DetailedFields::SunExposure, "SunExposed"); @@ -190,23 +199,43 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) openstudio::WorkspaceObject epSubSurface = workspace.addObject(idfObject2).get(); - openstudio::IdfObject idfObject3(openstudio::IddObjectType::WindowMaterial_Shade); - idfObject3.setString(WindowMaterial_ShadeFields::Name, "Shade 1"); - - openstudio::IdfObject idfObject4(openstudio::IddObjectType::WindowShadingControl); - idfObject4.setString(WindowShadingControlFields::Name, "Shading Control 1"); - idfObject4.setString(WindowShadingControlFields::ZoneName, ""); - idfObject4.setString(WindowShadingControlFields::ShadingControlType, "AlwaysOn"); - idfObject4.setInt(WindowShadingControlFields::ShadingControlSequenceNumber, 1); - idfObject4.setString(WindowShadingControlFields::ShadingType, "InteriorShade"); - idfObject4.setString(WindowShadingControlFields::ShadingDeviceMaterialName, "Shade 1"); - idfObject4.setDouble(WindowShadingControlFields::Setpoint, 100); - idfObject4.setString(WindowShadingControlFields::GlareControlIsActive, "No"); - idfObject4.setString(WindowShadingControlFields::MultipleSurfaceControlType, "Sequential"); - IdfExtensibleGroup group9 = idfObject4.pushExtensibleGroup(); // sub surface + openstudio::IdfObject idfObject3(openstudio::IddObjectType::WindowMaterial_Blind); + idfObject3.setString(WindowMaterial_BlindFields::Name, "Shade 1"); + + openstudio::WorkspaceObject epBlind = workspace.addObject(idfObject3).get(); + + openstudio::IdfObject idfObject4(openstudio::IddObjectType::Schedule_Constant); + idfObject4.setString(0, "Schedule 1"); + idfObject4.setString(1, "0.5"); + + openstudio::WorkspaceObject epSchedule = workspace.addObject(idfObject4).get(); + + openstudio::IdfObject idfObject5(openstudio::IddObjectType::WindowShadingControl); + idfObject5.setString(WindowShadingControlFields::Name, "Shading Control 1"); + idfObject5.setString(WindowShadingControlFields::ZoneName, ""); + idfObject5.setString(WindowShadingControlFields::ShadingControlSequenceNumber, "1"); + idfObject5.setString(WindowShadingControlFields::ShadingType, "InteriorBlind"); + idfObject5.setString(WindowShadingControlFields::ConstructionwithShadingName, ""); + idfObject5.setString(WindowShadingControlFields::ShadingControlType, "OnIfScheduleAllows"); + idfObject5.setString(WindowShadingControlFields::ScheduleName, "Schedule 1"); + idfObject5.setString(WindowShadingControlFields::Setpoint, "100"); + idfObject5.setString(WindowShadingControlFields::ShadingControlIsScheduled, "Yes"); + idfObject5.setString(WindowShadingControlFields::GlareControlIsActive, "No"); + idfObject5.setString(WindowShadingControlFields::ShadingDeviceMaterialName, "Shade 1"); + idfObject5.setString(WindowShadingControlFields::TypeofSlatAngleControlforBlinds, ""); + idfObject5.setString(WindowShadingControlFields::SlatAngleScheduleName, ""); + idfObject5.setString(WindowShadingControlFields::Setpoint2, ""); + idfObject5.setString(WindowShadingControlFields::MultipleSurfaceControlType, "Sequential"); + IdfExtensibleGroup group9 = idfObject5.pushExtensibleGroup(); // sub surface group9.setString(0, "Sub Surface 1"); - openstudio::WorkspaceObject epWindowShadingControl = workspace.addObject(idfObject4).get(); + openstudio::WorkspaceObject epWindowShadingControl = workspace.addObject(idfObject5).get(); + + std::vector objVector(workspace.getObjectsByType(IddObjectType::WindowShadingControl)); + ASSERT_EQ(1u, objVector.size()); + WorkspaceObject wo1(objVector.at(0)); + EXPECT_EQ("Sequential", wo1.getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); + ASSERT_EQ(1u, wo1.extensibleGroups().size()); ReverseTranslator trans; ASSERT_NO_THROW(trans.translateWorkspace(workspace)); @@ -214,6 +243,7 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) EXPECT_EQ(1u, model.getModelObjects().size()); EXPECT_EQ(1u, model.getModelObjects().size()); + EXPECT_EQ(1u, model.getModelObjects().size()); std::vector shadingControls = model.getModelObjects(); ASSERT_EQ(1u, shadingControls.size()); From 80ffb2f0316d6349014873db65096ad7c2688326 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 15 Sep 2020 12:53:40 +0200 Subject: [PATCH 35/49] Catch the case where neither Shading Material nor Construction are assigned in the FT --- .../ForwardTranslateShadingControl.cpp | 6 +++++- src/model/test/ShadingControl_GTest.cpp | 18 ------------------ 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp index 73125a08770..b46f981906d 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp @@ -58,7 +58,11 @@ boost::optional ForwardTranslator::translateShadingControl(model::Sha std::vector subSurfaces = modelObject.subSurfaces(); if (subSurfaces.empty()) { - LOG(Warn, modelObject.briefDescription() << " does not control any SubSurfaces, will not be translated"); + LOG(Warn, modelObject.briefDescription() << " does not control any SubSurfaces, it will not be translated"); + return boost::none; + } + if (!modelObject.shadingMaterial() && !modelObject.construction()) { + LOG(Error, modelObject.briefDescription() << " does not have either a Shading Material or a Construction assigned, it will not be translated"); return boost::none; } diff --git a/src/model/test/ShadingControl_GTest.cpp b/src/model/test/ShadingControl_GTest.cpp index ad079c01b70..7aed746ab16 100644 --- a/src/model/test/ShadingControl_GTest.cpp +++ b/src/model/test/ShadingControl_GTest.cpp @@ -222,21 +222,3 @@ TEST_F(ModelFixture, ShadingControl_Clone) { EXPECT_NE(shadingControl.shadingMaterial().get(), shadingControlClone.shadingMaterial().get()); } } - -TEST_F(ModelFixture, ShadingControl_RemoveRequiredObject) { - Model model; - - Blind blind(model); - ShadingControl shadingControl(blind); - - blind.remove(); - - EXPECT_FALSE(shadingControl.shadingMaterial()); - EXPECT_FALSE(shadingControl.construction()); - - // TODO: You're now in a broken, and unfixable state: you neither have a Construction nor a ShadingMaterial, - // and the model API has no setters to help you fix the state (setShadingMaterial / setConstruction) - // This WILL get forward translated anyways. We need to determine whether we want to add setters in the Model API or have the FT do a check and not - // translate the object if it doesn't have either. Throwing here so we do not forget to do it - ASSERT_TRUE(false); -} From 7ee6d21d2dfa10bdb2534725b8ab6fe7cf3168a1 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 15 Sep 2020 12:54:03 +0200 Subject: [PATCH 36/49] Extend the ShadingControl FT test to check all fields currently available in depth --- src/energyplus/Test/ShadingControl_GTest.cpp | 164 ++++++++++++++++--- 1 file changed, 141 insertions(+), 23 deletions(-) diff --git a/src/energyplus/Test/ShadingControl_GTest.cpp b/src/energyplus/Test/ShadingControl_GTest.cpp index ad85c1d0fea..ffff01ea595 100644 --- a/src/energyplus/Test/ShadingControl_GTest.cpp +++ b/src/energyplus/Test/ShadingControl_GTest.cpp @@ -49,6 +49,7 @@ #include "../../model/Blind_Impl.hpp" #include "../../model/ScheduleConstant.hpp" #include "../../model/ScheduleConstant_Impl.hpp" +#include "../../model/Construction.hpp" #include "../../utilities/core/Optional.hpp" #include "../../utilities/core/Checksum.hpp" @@ -79,6 +80,9 @@ using namespace openstudio::model; TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) { + + ForwardTranslator forwardTranslator; + Model model; ThermalZone thermalZone(model); @@ -94,41 +98,155 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) Surface surface(vertices, model); surface.setSpace(space); + // Here's the position of the two subSurfaces onto the base Surface + // 2 _____________ + // | | B | + // 1 |_____|_____| + // | A | | + // |_____|_____| + // 0 1 2 + + // A vertices.clear(); vertices.push_back(Point3d(0, 1, 0)); vertices.push_back(Point3d(0, 0, 0)); vertices.push_back(Point3d(1, 0, 0)); vertices.push_back(Point3d(1, 1, 0)); - SubSurface subSurface(vertices, model); - subSurface.setSurface(surface); - subSurface.assignDefaultSubSurfaceType(); + SubSurface subSurfaceA(vertices, model); + subSurfaceA.setName("SubSurface A"); + subSurfaceA.setSurface(surface); + subSurfaceA.assignDefaultSubSurfaceType(); + + // B + vertices.clear(); + vertices.push_back(Point3d(1, 2, 0)); + vertices.push_back(Point3d(1, 1, 0)); + vertices.push_back(Point3d(2, 1, 0)); + vertices.push_back(Point3d(2, 2, 0)); + + SubSurface subSurfaceB(vertices, model); + subSurfaceB.setName("SubSurface B"); + subSurfaceB.setSurface(surface); + subSurfaceB.assignDefaultSubSurfaceType(); + Blind blind1(model); ShadingControl shadingControl1(blind1); - shadingControl1.setMultipleSurfaceControlType("Group"); - subSurface.addShadingControl(shadingControl1); + EXPECT_TRUE(shadingControl1.setShadingType("ExteriorBlind")); + + EXPECT_TRUE(shadingControl1.setShadingControlType("OnNightIfLowOutdoorTempAndOffDay")); + EXPECT_TRUE(shadingControl1.isControlTypeValueAllowingSchedule()); + EXPECT_TRUE(shadingControl1.isControlTypeValueNeedingSetpoint1()); + + ScheduleConstant shadingControl1Schedule(model); + EXPECT_TRUE(shadingControl1.setSchedule(shadingControl1Schedule)); + EXPECT_TRUE(shadingControl1.setSetpoint(3.0)); + EXPECT_TRUE(shadingControl1.setMultipleSurfaceControlType("Sequential")); + EXPECT_TRUE(shadingControl1.addSubSurface(subSurfaceA)); + // Convenience method that calls ShadingControl::addSubSurface() + EXPECT_TRUE(subSurfaceB.addShadingControl(shadingControl1)); + ASSERT_EQ(2u, shadingControl1.subSurfaces().size()); + EXPECT_EQ(1u, shadingControl1.subSurfaceIndex(subSurfaceA).get()); + EXPECT_EQ(2u, shadingControl1.subSurfaceIndex(subSurfaceB).get()); Blind blind2(model); ShadingControl shadingControl2(blind2); - shadingControl2.setMultipleSurfaceControlType("Group"); - subSurface.addShadingControl(shadingControl2); - - ForwardTranslator forwardTranslator; - Workspace workspace = forwardTranslator.translateModel(model); - - EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::FenestrationSurface_Detailed).size()); - - std::vector objVector(workspace.getObjectsByType(IddObjectType::WindowShadingControl)); - ASSERT_EQ(2u, objVector.size()); - WorkspaceObject wo1(objVector.at(0)); - WorkspaceObject wo2(objVector.at(1)); - - EXPECT_EQ("Group", wo1.getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); - EXPECT_EQ("Group", wo2.getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); - - ASSERT_EQ(1u, wo1.extensibleGroups().size()); - ASSERT_EQ(1u, wo2.extensibleGroups().size()); + EXPECT_TRUE(shadingControl2.setMultipleSurfaceControlType("Group")); + EXPECT_TRUE(subSurfaceA.addShadingControl(shadingControl2)); + ASSERT_EQ(1u, shadingControl2.subSurfaces().size()); + EXPECT_EQ(1u, shadingControl2.subSurfaceIndex(subSurfaceA).get()); + + + EXPECT_EQ(2u, subSurfaceA.shadingControls().size()); + EXPECT_EQ(1u, subSurfaceB.shadingControls().size()); + + { + Workspace workspace = forwardTranslator.translateModel(model); + + EXPECT_EQ(2u, workspace.getObjectsByType(IddObjectType::FenestrationSurface_Detailed).size()); + ASSERT_EQ(2u, workspace.getObjectsByType(IddObjectType::WindowShadingControl).size()); + + // Test ShadingControl1: it has all the fields set. We also check that it's control sequence number is 1. + { + boost::optional _wo = workspace.getObjectByTypeAndName(IddObjectType::WindowShadingControl, shadingControl1.nameString()); + ASSERT_TRUE(_wo); + + EXPECT_EQ(thermalZone.nameString(), _wo->getString(WindowShadingControlFields::ZoneName, false, true).get()); + EXPECT_EQ(1, _wo->getInt(WindowShadingControlFields::ShadingControlSequenceNumber, false).get()); + EXPECT_EQ("ExteriorBlind", _wo->getString(WindowShadingControlFields::ShadingType, false, true).get()); + EXPECT_FALSE(_wo->getString(WindowShadingControlFields::ConstructionwithShadingName, false, true)); + EXPECT_EQ("OnNightIfLowOutdoorTempAndOffDay", _wo->getString(WindowShadingControlFields::ShadingControlType, false, true).get()); + EXPECT_EQ(3.0, _wo->getDouble(WindowShadingControlFields::Setpoint, false).get()); + + EXPECT_EQ(shadingControl1Schedule.nameString(), _wo->getString(WindowShadingControlFields::ScheduleName, false, true).get()); + EXPECT_EQ("Yes", _wo->getString(WindowShadingControlFields::ShadingControlIsScheduled, false, true).get()); + + EXPECT_EQ("No", _wo->getString(WindowShadingControlFields::GlareControlIsActive, false, true).get()); + EXPECT_EQ(blind1.nameString(), _wo->getString(WindowShadingControlFields::ShadingDeviceMaterialName, false, true).get()); + EXPECT_FALSE(_wo->getString(WindowShadingControlFields::SlatAngleScheduleName, false, true)); + EXPECT_FALSE(_wo->getString(WindowShadingControlFields::Setpoint2, false, true)); + EXPECT_FALSE(_wo->getString(WindowShadingControlFields::DaylightingControlObjectName, false, true)); + EXPECT_EQ("Sequential", _wo->getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); + ASSERT_EQ(2u, _wo->extensibleGroups().size()); + { + WorkspaceExtensibleGroup w_eg = _wo->extensibleGroups()[0].cast(); + EXPECT_EQ(subSurfaceA.nameString(), w_eg.getString(WindowShadingControlExtensibleFields::FenestrationSurfaceName, false).get()); + } + { + WorkspaceExtensibleGroup w_eg = _wo->extensibleGroups()[1].cast(); + EXPECT_EQ(subSurfaceB.nameString(), w_eg.getString(WindowShadingControlExtensibleFields::FenestrationSurfaceName, false).get()); + } + } + + { + boost::optional _wo = workspace.getObjectByTypeAndName(IddObjectType::WindowShadingControl, shadingControl2.nameString()); + ASSERT_TRUE(_wo); + + EXPECT_EQ(thermalZone.nameString(), _wo->getString(WindowShadingControlFields::ZoneName, false, true).get()); + // Number 2 this time + EXPECT_EQ(2, _wo->getInt(WindowShadingControlFields::ShadingControlSequenceNumber, false).get()); + EXPECT_EQ("InteriorBlind", _wo->getString(WindowShadingControlFields::ShadingType, false, true).get()); + EXPECT_FALSE(_wo->getString(WindowShadingControlFields::ConstructionwithShadingName, false, true)); + EXPECT_EQ("OnIfHighSolarOnWindow", _wo->getString(WindowShadingControlFields::ShadingControlType, false, true).get()); + EXPECT_EQ(shadingControl2.setpoint().get(), _wo->getDouble(WindowShadingControlFields::Setpoint, false).get()); // Model setpoint at 27 W/m2 for some reason + + EXPECT_FALSE(_wo->getString(WindowShadingControlFields::ScheduleName, false, true)); + EXPECT_EQ("No", _wo->getString(WindowShadingControlFields::ShadingControlIsScheduled, false, true).get()); + + EXPECT_EQ("No", _wo->getString(WindowShadingControlFields::GlareControlIsActive, false, true).get()); + EXPECT_EQ(blind2.nameString(), _wo->getString(WindowShadingControlFields::ShadingDeviceMaterialName, false, true).get()); + EXPECT_FALSE(_wo->getString(WindowShadingControlFields::SlatAngleScheduleName, false, true)); + EXPECT_FALSE(_wo->getString(WindowShadingControlFields::Setpoint2, false, true)); + EXPECT_FALSE(_wo->getString(WindowShadingControlFields::DaylightingControlObjectName, false, true)); + EXPECT_EQ("Group", _wo->getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); + ASSERT_EQ(1u, _wo->extensibleGroups().size()); + { + WorkspaceExtensibleGroup w_eg = _wo->extensibleGroups()[0].cast(); + EXPECT_EQ(subSurfaceA.nameString(), w_eg.getString(WindowShadingControlExtensibleFields::FenestrationSurfaceName, false).get()); + } + } + + } + + { + blind1.remove(); + + EXPECT_FALSE(shadingControl1.shadingMaterial()); + EXPECT_FALSE(shadingControl1.construction()); + + // You're now in a broken, and unfixable state: you neither have a Construction nor a ShadingMaterial, + // and the model API has no setters to help you fix the state (setShadingMaterial / setConstruction) + // We test that the FT catches this and does not translate the ShadingControl + + Workspace workspace = forwardTranslator.translateModel(model); + + EXPECT_EQ(2u, workspace.getObjectsByType(IddObjectType::FenestrationSurface_Detailed).size()); + + std::vector objVector(workspace.getObjectsByType(IddObjectType::WindowShadingControl)); + EXPECT_EQ(1u, objVector.size()); + EXPECT_EQ(shadingControl2.nameString(), objVector[0].nameString()); + } } TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) From d6041d8385aecb280360e84f47338276ae5132cd Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 15 Sep 2020 13:15:01 +0200 Subject: [PATCH 37/49] Fix #4074 - Implement Setpoint2 and support all Shading Control Type & improve model logic --- .../ForwardTranslateShadingControl.cpp | 50 +++- src/energyplus/Test/ShadingControl_GTest.cpp | 12 +- src/model/ShadingControl.cpp | 259 +++++++++++++++--- src/model/ShadingControl.hpp | 19 +- src/model/ShadingControl_Impl.hpp | 18 ++ 5 files changed, 298 insertions(+), 60 deletions(-) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp index b46f981906d..ef86c3390eb 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp @@ -66,6 +66,27 @@ boost::optional ForwardTranslator::translateShadingControl(model::Sha return boost::none; } + // Read this now, since we'll use it to test if a Warn is needed + std::string shadingControlType = modelObject.shadingControlType(); + + if (modelObject.isControlTypeValueNeedingSetpoint1() && !modelObject.setpoint()) { + LOG(Error, modelObject.briefDescription() << " is using Shading Control Type '" << shadingControlType + << "' which requires a Setpoint which is missing, it will not be translated"); + return boost::none; + } + + if (modelObject.isControlTypeValueNeedingSetpoint2() && !modelObject.setpoint2()) { + LOG(Error, modelObject.briefDescription() << " is using Shading Control Type '" << shadingControlType + << "' which requires a Setpoint2 which is missing, it will not be translated"); + return boost::none; + } + + if (modelObject.isControlTypeValueRequiringSchedule() && !modelObject.schedule()) { + LOG(Error, modelObject.briefDescription() << " is using Shading Control Type '" << shadingControlType + << "' which requires a Schedule which is missing, it will not be translated"); + return boost::none; + } + IdfObject idfObject(openstudio::IddObjectType::WindowShadingControl); m_idfObjects.push_back(idfObject); @@ -94,8 +115,6 @@ boost::optional ForwardTranslator::translateShadingControl(model::Sha } idfObject.setString(WindowShadingControlFields::ZoneName, zoneName); - // Read this now, since we'll use it to test if a Warn is needed - std::string shadingControlType = modelObject.shadingControlType(); idfObject.setString(WindowShadingControlFields::ShadingControlType, shadingControlType); if (zone) { @@ -137,21 +156,24 @@ boost::optional ForwardTranslator::translateShadingControl(model::Sha idfObject.setString(WindowShadingControlFields::ShadingDeviceMaterialName, shadingMaterial->name().get()); } - boost::optional schedule = modelObject.schedule(); - if (schedule) { - idfObject.setString(WindowShadingControlFields::ScheduleName, schedule->name().get()); - idfObject.setString(WindowShadingControlFields::ShadingControlIsScheduled, "Yes"); + if (modelObject.isControlTypeValueAllowingSchedule()) { + boost::optional schedule = modelObject.schedule(); + if (schedule) { + idfObject.setString(WindowShadingControlFields::ScheduleName, schedule->name().get()); + idfObject.setString(WindowShadingControlFields::ShadingControlIsScheduled, "Yes"); + } else { + idfObject.setString(WindowShadingControlFields::ShadingControlIsScheduled, "No"); + } } else { idfObject.setString(WindowShadingControlFields::ShadingControlIsScheduled, "No"); } - boost::optional setpoint = modelObject.setpoint(); - if (istringEqual("OnIfHighSolarOnWindow", shadingControlType)) { - if (!setpoint) { - setpoint = 100; // W/m2 - } - OS_ASSERT(setpoint); - idfObject.setDouble(WindowShadingControlFields::Setpoint, *setpoint); + if (modelObject.isControlTypeValueNeedingSetpoint1()) { + idfObject.setDouble(WindowShadingControlFields::Setpoint, modelObject.setpoint().get()); + } + + if (modelObject.isControlTypeValueNeedingSetpoint2()) { + idfObject.setDouble(WindowShadingControlFields::Setpoint2, modelObject.setpoint2().get()); } idfObject.setString(WindowShadingControlFields::GlareControlIsActive, "No"); @@ -160,8 +182,6 @@ boost::optional ForwardTranslator::translateShadingControl(model::Sha //idfObject.setString(WindowShadingControlFields::SlatAngleScheduleName, ""); - //idfObject.setDouble(WindowShadingControlFields::Setpoint2, 0.0); - idfObject.setString(WindowShadingControlFields::MultipleSurfaceControlType, modelObject.multipleSurfaceControlType()); idfObject.clearExtensibleGroups(); diff --git a/src/energyplus/Test/ShadingControl_GTest.cpp b/src/energyplus/Test/ShadingControl_GTest.cpp index ffff01ea595..1c4f84bd1b2 100644 --- a/src/energyplus/Test/ShadingControl_GTest.cpp +++ b/src/energyplus/Test/ShadingControl_GTest.cpp @@ -135,13 +135,15 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) ShadingControl shadingControl1(blind1); EXPECT_TRUE(shadingControl1.setShadingType("ExteriorBlind")); - EXPECT_TRUE(shadingControl1.setShadingControlType("OnNightIfLowOutdoorTempAndOffDay")); + EXPECT_TRUE(shadingControl1.setShadingControlType("OnIfHighZoneAirTempAndHighSolarOnWindow")); EXPECT_TRUE(shadingControl1.isControlTypeValueAllowingSchedule()); EXPECT_TRUE(shadingControl1.isControlTypeValueNeedingSetpoint1()); + EXPECT_TRUE(shadingControl1.isControlTypeValueNeedingSetpoint2()); ScheduleConstant shadingControl1Schedule(model); EXPECT_TRUE(shadingControl1.setSchedule(shadingControl1Schedule)); - EXPECT_TRUE(shadingControl1.setSetpoint(3.0)); + EXPECT_TRUE(shadingControl1.setSetpoint(25.0)); + EXPECT_TRUE(shadingControl1.setSetpoint2(500.0)); EXPECT_TRUE(shadingControl1.setMultipleSurfaceControlType("Sequential")); EXPECT_TRUE(shadingControl1.addSubSurface(subSurfaceA)); // Convenience method that calls ShadingControl::addSubSurface() @@ -176,8 +178,9 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) EXPECT_EQ(1, _wo->getInt(WindowShadingControlFields::ShadingControlSequenceNumber, false).get()); EXPECT_EQ("ExteriorBlind", _wo->getString(WindowShadingControlFields::ShadingType, false, true).get()); EXPECT_FALSE(_wo->getString(WindowShadingControlFields::ConstructionwithShadingName, false, true)); - EXPECT_EQ("OnNightIfLowOutdoorTempAndOffDay", _wo->getString(WindowShadingControlFields::ShadingControlType, false, true).get()); - EXPECT_EQ(3.0, _wo->getDouble(WindowShadingControlFields::Setpoint, false).get()); + EXPECT_EQ("OnIfHighZoneAirTempAndHighSolarOnWindow", _wo->getString(WindowShadingControlFields::ShadingControlType, false, true).get()); + EXPECT_EQ(25.0, _wo->getDouble(WindowShadingControlFields::Setpoint, false).get()); + EXPECT_EQ(500.0, _wo->getDouble(WindowShadingControlFields::Setpoint2, false).get()); EXPECT_EQ(shadingControl1Schedule.nameString(), _wo->getString(WindowShadingControlFields::ScheduleName, false, true).get()); EXPECT_EQ("Yes", _wo->getString(WindowShadingControlFields::ShadingControlIsScheduled, false, true).get()); @@ -185,7 +188,6 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) EXPECT_EQ("No", _wo->getString(WindowShadingControlFields::GlareControlIsActive, false, true).get()); EXPECT_EQ(blind1.nameString(), _wo->getString(WindowShadingControlFields::ShadingDeviceMaterialName, false, true).get()); EXPECT_FALSE(_wo->getString(WindowShadingControlFields::SlatAngleScheduleName, false, true)); - EXPECT_FALSE(_wo->getString(WindowShadingControlFields::Setpoint2, false, true)); EXPECT_FALSE(_wo->getString(WindowShadingControlFields::DaylightingControlObjectName, false, true)); EXPECT_EQ("Sequential", _wo->getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); ASSERT_EQ(2u, _wo->extensibleGroups().size()); diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index 072aced2e85..a9e91e1bfc4 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -57,6 +57,11 @@ #include #include "../utilities/core/Assert.hpp" +#include "utilities/core/Compare.hpp" + +#include +#include +#include namespace openstudio { namespace model { @@ -91,6 +96,84 @@ namespace detail { return result; } + bool ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(const std::string& controlType) { + static constexpr std::array data{ + //"AlwaysOn", + //"AlwaysOff", + //"OnIfScheduleAllows", + "OnIfHighSolarOnWindow", + "OnIfHighHorizontalSolar", + "OnIfHighOutdoorAirTemperature", + "OnIfHighZoneAirTemperature", + "OnIfHighZoneCooling", + "OnIfHighGlare", + //"MeetDaylightIlluminanceSetpoint", + "OnNightIfLowOutdoorTempAndOffDay", + "OnNightIfLowInsideTempAndOffDay", + "OnNightIfHeatingAndOffDay", + "OnNightIfLowOutdoorTempAndOnDayIfCooling", + "OnNightIfHeatingAndOnDayIfCooling", + "OffNightAndOnDayIfCoolingAndHighSolarOnWindow", + "OnNightAndOnDayIfCoolingAndHighSolarOnWindow", + "OnIfHighOutdoorAirTempAndHighSolarOnWindow", + "OnIfHighOutdoorAirTempAndHighHorizontalSolar", + "OnIfHighZoneAirTempAndHighSolarOnWindow", + "OnIfHighZoneAirTempAndHighHorizontalSolar" + }; + return std::find_if(data.begin(), + data.end(), + [&controlType](auto c){ + return openstudio::istringEqual(controlType, c); + }) != data.end(); + } + + bool ShadingControl_Impl::isControlTypeValueNeedingSetpoint2(const std::string& controlType) { + static constexpr std::array data{ + "OnIfHighZoneAirTempAndHighSolarOnWindow", + "OnIfHighZoneAirTempAndHighHorizontalSolar" + }; + return std::find_if(data.begin(), + data.end(), + [&controlType](auto c){ + return openstudio::istringEqual(controlType, c); + }) != data.end(); + } + + bool ShadingControl_Impl::isControlTypeValueAllowingSchedule(const std::string& controlType) { + static constexpr std::array data{ + //"AlwaysOn", + //"AlwaysOff", + "OnIfScheduleAllows", + "OnIfHighSolarOnWindow", + "OnIfHighHorizontalSolar", + "OnIfHighOutdoorAirTemperature", + "OnIfHighZoneAirTemperature", + "OnIfHighZoneCooling", + //"OnIfHighGlare", + //"MeetDaylightIlluminanceSetpoint", + "OnNightIfLowOutdoorTempAndOffDay", + "OnNightIfLowInsideTempAndOffDay", + "OnNightIfHeatingAndOffDay", + "OnNightIfLowOutdoorTempAndOnDayIfCooling", + "OnNightIfHeatingAndOnDayIfCooling", + "OffNightAndOnDayIfCoolingAndHighSolarOnWindow", + "OnNightAndOnDayIfCoolingAndHighSolarOnWindow", + "OnIfHighOutdoorAirTempAndHighSolarOnWindow", + "OnIfHighOutdoorAirTempAndHighHorizontalSolar", + "OnIfHighZoneAirTempAndHighSolarOnWindow", + "OnIfHighZoneAirTempAndHighHorizontalSolar" + }; + return std::find_if(data.begin(), + data.end(), + [&controlType](auto c){ + return openstudio::istringEqual(controlType, c); + }) != data.end(); + } + + bool ShadingControl_Impl::isControlTypeValueRequiringSchedule(const std::string& controlType) { + return openstudio::istringEqual("OnIfScheduleAllows", controlType); + } + IddObjectType ShadingControl_Impl::iddObjectType() const { return ShadingControl::iddObjectType(); @@ -157,6 +240,67 @@ namespace detail { return isEmpty(OS_ShadingControlFields::Setpoint); } + bool ShadingControl_Impl::setSetpoint(double setpoint) + { + bool result = false; + std::string shadingControlType = this->shadingControlType(); + if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType)) { + result = setDouble(OS_ShadingControlFields::Setpoint, setpoint); + } else { + LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does not require a Setpoint"); + } + return result; + } + + void ShadingControl_Impl::resetSetpoint() + { + std::string shadingControlType = this->shadingControlType(); + if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType) && + !openstudio::istringEqual("OnIfHighSolarOnWindow", shadingControlType)) + { + LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does require a Setpoint, not resetting it"); + } else { + bool test = setString(OS_ShadingControlFields::Setpoint, ""); + OS_ASSERT(test); + } + } + + + boost::optional ShadingControl_Impl::setpoint2() const + { + boost::optional result = getDouble(OS_ShadingControlFields::Setpoint2); + if (!result){ + std::string shadingControlType = this->shadingControlType(); + if (istringEqual("OnIfHighSolarOnWindow", shadingControlType)){ + result = 27; // w/m^2 + } + } + return result; + } + + bool ShadingControl_Impl::setSetpoint2(double setpoint2) + { + bool result = false; + std::string shadingControlType = this->shadingControlType(); + if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint2(shadingControlType)) { + result = setDouble(OS_ShadingControlFields::Setpoint2, setpoint2); + } else { + LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does not require a Setpoint2"); + } + return result; + } + + void ShadingControl_Impl::resetSetpoint2() + { + std::string shadingControlType = this->shadingControlType(); + if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType)) { + LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does require a Setpoint2, not resetting it"); + } else { + bool test = setString(OS_ShadingControlFields::Setpoint2, ""); + OS_ASSERT(test); + } + } + bool ShadingControl_Impl::setShadingType(const std::string& shadingType) { return setString(OS_ShadingControlFields::ShadingType, shadingType); @@ -167,12 +311,30 @@ namespace detail { std::string oldControlType = this->shadingControlType(); bool result = setString(OS_ShadingControlFields::ShadingControlType, shadingControlType); if (result){ - if (oldControlType != shadingControlType){ - resetSetpoint(); - } else if (istringEqual("AlwaysOn", shadingControlType) || - istringEqual("AlwaysOff", shadingControlType) || - istringEqual("OnIfScheduleAllows", shadingControlType)){ + if (!openstudio::istringEqual(oldControlType, shadingControlType)) { resetSetpoint(); + } else { + if (!ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType)) { + // Not calling reset to avoid double check on whether it's required + // resetSetpoint(); + LOG(Info, briefDescription() << " Shading Control Type was changed to '" << shadingControlType << " which does not require a Setpoint, reseting"); + bool test = setString(OS_ShadingControlFields::Setpoint, ""); + OS_ASSERT(test); + } + if (!ShadingControl_Impl::isControlTypeValueNeedingSetpoint2(shadingControlType)) { + // Not calling reset to avoid double check on whether it's required + // resetSetpoint2(); + LOG(Info, briefDescription() << " Shading Control Type was changed to '" << shadingControlType << " which does not require a Setpoint2, reseting"); + bool test = setString(OS_ShadingControlFields::Setpoint2, ""); + OS_ASSERT(test); + } + if (!ShadingControl_Impl::isControlTypeValueAllowingSchedule(shadingControlType)) { + LOG(Info, briefDescription() << " Shading Control Type was changed to '" << shadingControlType << " which does not allow a Schedule, reseting"); + bool test = setString(OS_ShadingControlFields::ScheduleName, ""); + OS_ASSERT(test); + test = setString(OS_ShadingControlFields::ShadingControlIsScheduled, "No"); + OS_ASSERT(test); + } } } return result; @@ -180,45 +342,42 @@ namespace detail { void ShadingControl_Impl::resetShadingControlType() { + std::string oldControlType = this->shadingControlType(); bool test = setString(OS_ShadingControlFields::ShadingControlType, ""); OS_ASSERT(test); - - resetSetpoint(); + if (!openstudio::istringEqual("OnIfHighSolarOnWindow", oldControlType)) { + resetSetpoint(); + } } bool ShadingControl_Impl::setSchedule(const Schedule& schedule) { - bool result = setPointer(OS_ShadingControlFields::ScheduleName, schedule.handle()); - if (result){ - bool test = setString(OS_ShadingControlFields::ShadingControlIsScheduled, "Yes"); - OS_ASSERT(test); + bool result = false; + std::string shadingControlType = this->shadingControlType(); + if (ShadingControl_Impl::isControlTypeValueAllowingSchedule(shadingControlType)) { + result = setPointer(OS_ShadingControlFields::ScheduleName, schedule.handle()); + if (result){ + bool test = setString(OS_ShadingControlFields::ShadingControlIsScheduled, "Yes"); + OS_ASSERT(test); + } + } else { + LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does not allow a Schedule"); } return result; } void ShadingControl_Impl::resetSchedule() { - bool test = setString(OS_ShadingControlFields::ScheduleName, ""); - OS_ASSERT(test); - - test = setString(OS_ShadingControlFields::ShadingControlIsScheduled, "No"); - OS_ASSERT(test); - } - - bool ShadingControl_Impl::setSetpoint(double setpoint) - { - bool result = false; std::string shadingControlType = this->shadingControlType(); - if (istringEqual("OnIfHighSolarOnWindow", shadingControlType)){ - result = setDouble(OS_ShadingControlFields::Setpoint, setpoint); - } - return result; - } + if (ShadingControl_Impl::isControlTypeValueRequiringSchedule(shadingControlType)) { + LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does require a Schedule, not resetting it"); + } else { + bool test = setString(OS_ShadingControlFields::ScheduleName, ""); + OS_ASSERT(test); - void ShadingControl_Impl::resetSetpoint() - { - bool test = setString(OS_ShadingControlFields::Setpoint, ""); - OS_ASSERT(test); + test = setString(OS_ShadingControlFields::ShadingControlIsScheduled, "No"); + OS_ASSERT(test); + } } std::string ShadingControl_Impl::multipleSurfaceControlType() const @@ -493,6 +652,22 @@ std::vector ShadingControl::multipleSurfaceControlTypeValues() { OS_ShadingControlFields::MultipleSurfaceControlType); } +bool ShadingControl::isControlTypeValueNeedingSetpoint1() { + return getImpl()->isControlTypeValueNeedingSetpoint1(this->shadingControlType()); +} + +bool ShadingControl::isControlTypeValueNeedingSetpoint2() { + return getImpl()->isControlTypeValueNeedingSetpoint2(this->shadingControlType()); +} + +bool ShadingControl::isControlTypeValueAllowingSchedule() { + return getImpl()->isControlTypeValueAllowingSchedule(this->shadingControlType()); +} + +bool ShadingControl::isControlTypeValueRequiringSchedule() { + return getImpl()->isControlTypeValueRequiringSchedule(this->shadingControlType()); +} + boost::optional ShadingControl::construction() const { return getImpl()->construction(); } @@ -525,6 +700,22 @@ bool ShadingControl::isSetpointDefaulted() const{ return getImpl()->isSetpointDefaulted(); } +bool ShadingControl::setSetpoint(double setpoint){ + return getImpl()->setSetpoint(setpoint); +} + +void ShadingControl::resetSetpoint(){ + getImpl()->resetSetpoint(); +} + +boost::optional ShadingControl::setpoint2() const { + return getImpl()->setpoint2(); +} + +bool ShadingControl::setSetpoint2(double setpoint2){ + return getImpl()->setSetpoint2(setpoint2); +} + bool ShadingControl::setShadingType(const std::string& shadingType){ return getImpl()->setShadingType(shadingType); } @@ -545,14 +736,6 @@ void ShadingControl::resetSchedule(){ getImpl()->resetSchedule(); } -bool ShadingControl::setSetpoint(double setpoint){ - return getImpl()->setSetpoint(setpoint); -} - -void ShadingControl::resetSetpoint(){ - getImpl()->resetSetpoint(); -} - std::string ShadingControl::multipleSurfaceControlType() const { return getImpl()->multipleSurfaceControlType(); } diff --git a/src/model/ShadingControl.hpp b/src/model/ShadingControl.hpp index d278e8121ae..6da984f15bc 100644 --- a/src/model/ShadingControl.hpp +++ b/src/model/ShadingControl.hpp @@ -94,7 +94,9 @@ class MODEL_API ShadingControl : public ResourceObject { boost::optional setpoint() const; - bool isSetpointDefaulted() const; + bool isSetpointDefaulted() const; // TODO: This makes little sense. Based on the shadingControlType, it's basically required. There's a default harcoded only for OnIfHighSolarOnWindow + + boost::optional setpoint2() const; std::string multipleSurfaceControlType() const; @@ -117,7 +119,9 @@ class MODEL_API ShadingControl : public ResourceObject { bool setSetpoint(double setpoint); - void resetSetpoint(); + void resetSetpoint(); // TODO: makes little sense like isSetpointDefaulted + + bool setSetpoint2(double setpoint2); bool setMultipleSurfaceControlType(const std::string& multipleSurfaceControlType); @@ -125,6 +129,17 @@ class MODEL_API ShadingControl : public ResourceObject { /** @name Other */ //@{ + + // Check if the current ShadingControlType requires Setpoint(1) + bool isControlTypeValueNeedingSetpoint1(); + // Check if the current ShadingControlType requires Setpoint(2) + bool isControlTypeValueNeedingSetpoint2(); + + // Check if the current ShadingControlType allows a Schedule + bool isControlTypeValueAllowingSchedule(); + // Check if the current ShadingControlType requires a Schedule + bool isControlTypeValueRequiringSchedule(); + // Extensible: Surfaces std::vector subSurfaces() const; unsigned int numberofSubSurfaces() const; diff --git a/src/model/ShadingControl_Impl.hpp b/src/model/ShadingControl_Impl.hpp index 7acc5b1b670..edd48a8af18 100644 --- a/src/model/ShadingControl_Impl.hpp +++ b/src/model/ShadingControl_Impl.hpp @@ -63,6 +63,7 @@ namespace detail { virtual ~ShadingControl_Impl() {} + //@} /** @name Virtual Methods */ @@ -77,6 +78,15 @@ namespace detail { virtual ModelObject clone(Model model) const; //@} + + static bool isControlTypeValueNeedingSetpoint1(const std::string& controlType); + static bool isControlTypeValueNeedingSetpoint2(const std::string& controlType); + + // **Allows** a schedule + static bool isControlTypeValueAllowingSchedule(const std::string& controlType); + // **Requires** a Schedule + static bool isControlTypeValueRequiringSchedule(const std::string& controlType); + /** @name Getters */ //@{ @@ -96,6 +106,8 @@ namespace detail { bool isSetpointDefaulted() const; + boost::optional setpoint2() const; + std::string multipleSurfaceControlType() const; //@} @@ -116,6 +128,11 @@ namespace detail { void resetSetpoint(); + bool setSetpoint2(double setpoint2); + + // Impl only + void resetSetpoint2(); + bool setMultipleSurfaceControlType(const std::string& multipleSurfaceControlType); //@} @@ -138,6 +155,7 @@ namespace detail { bool setSubSurfaces(const std::vector &subSurfaces); void removeAllSubSurfaces(); + //@} protected: From 1a92506a3c2d6fa6d3559f6b06b9ea36322224b2 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 15 Sep 2020 14:02:24 +0200 Subject: [PATCH 38/49] Exit RT for ShadingControl if neither the shadingMaterial nor Construction are valid --- .../ReverseTranslateWindowShadingControl.cpp | 7 +++++-- src/energyplus/Test/ShadingControl_GTest.cpp | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp index 9404708b488..43b8d41dbd2 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp @@ -84,9 +84,12 @@ boost::optional ReverseTranslator::translateWindowShadingControl( c boost::optional shadingControl; if (construction){ - openstudio::model::ShadingControl shadingControl(*construction); + shadingControl = openstudio::model::ShadingControl(*construction); } else if (shadingMaterial){ - openstudio::model::ShadingControl shadingControl(*shadingMaterial); + shadingControl = openstudio::model::ShadingControl(*shadingMaterial); + } else { + LOG(Error, workspaceObject.briefDescription() << " does not appear to have a valid Construction or Shading Material Name attached to it"); + return boost::none; } if (shadingControl) { diff --git a/src/energyplus/Test/ShadingControl_GTest.cpp b/src/energyplus/Test/ShadingControl_GTest.cpp index 1c4f84bd1b2..be12ac00f38 100644 --- a/src/energyplus/Test/ShadingControl_GTest.cpp +++ b/src/energyplus/Test/ShadingControl_GTest.cpp @@ -357,6 +357,8 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) EXPECT_EQ("Sequential", wo1.getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); ASSERT_EQ(1u, wo1.extensibleGroups().size()); + workspace.save(toPath("./ReverseTranslator_ShadingControls.idf"), true); + ReverseTranslator trans; ASSERT_NO_THROW(trans.translateWorkspace(workspace)); Model model = trans.translateWorkspace(workspace); From f95045fa7ad38d6832148e2d135bbb0f49ecf83c Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 15 Sep 2020 14:14:23 +0200 Subject: [PATCH 39/49] Fix RT by using a Construction instead of the not RT'ed WindowMaterial:Blind and test a few more fields --- .../ReverseTranslateWindowShadingControl.cpp | 5 ++ src/energyplus/Test/ShadingControl_GTest.cpp | 48 ++++++++++++++----- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp index 43b8d41dbd2..390e21e7262 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp @@ -130,6 +130,11 @@ boost::optional ReverseTranslator::translateWindowShadingControl( c shadingControl->setSetpoint(*d); } + d = workspaceObject.getDouble(WindowShadingControlFields::Setpoint2); + if(s){ + shadingControl->setSetpoint2(*d); + } + s = workspaceObject.getString(WindowShadingControlFields::MultipleSurfaceControlType); if(s){ shadingControl->setMultipleSurfaceControlType(*s); diff --git a/src/energyplus/Test/ShadingControl_GTest.cpp b/src/energyplus/Test/ShadingControl_GTest.cpp index be12ac00f38..964889a57d3 100644 --- a/src/energyplus/Test/ShadingControl_GTest.cpp +++ b/src/energyplus/Test/ShadingControl_GTest.cpp @@ -319,10 +319,28 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) openstudio::WorkspaceObject epSubSurface = workspace.addObject(idfObject2).get(); - openstudio::IdfObject idfObject3(openstudio::IddObjectType::WindowMaterial_Blind); - idfObject3.setString(WindowMaterial_BlindFields::Name, "Shade 1"); - - openstudio::WorkspaceObject epBlind = workspace.addObject(idfObject3).get(); + // Currently WindowMaterial:Blind is not ReverseTranslated... So we'll fake something using a Construction (and not a Shading Material Name) that + // has no blind on it... + // openstudio::IdfObject idfObject3(openstudio::IddObjectType::WindowMaterial_Blind); + // idfObject3.setString(WindowMaterial_BlindFields::Name, "Shade 1"); + + // openstudio::WorkspaceObject epBlind = workspace.addObject(idfObject3).get(); + + IdfObject glazing(IddObjectType::WindowMaterial_Glazing); + IdfObject gas(IddObjectType::WindowMaterial_Gas); + glazing.setName("Glazing Material"); + gas.setName("Gas Material"); + IdfObject construction(IddObjectType::Construction); + construction.setName("Construction A"); + ASSERT_EQ(0u,construction.numExtensibleGroups()); + EXPECT_FALSE(construction.pushExtensibleGroup(StringVector(1u,glazing.name().get())).empty()); + EXPECT_FALSE(construction.pushExtensibleGroup(StringVector(1u,gas.name().get())).empty()); + EXPECT_FALSE(construction.pushExtensibleGroup(StringVector(1u,glazing.name().get())).empty()); + IdfObjectVector objects; + objects.push_back(glazing); + objects.push_back(gas); + objects.push_back(construction); + EXPECT_EQ(3u,workspace.addObjects(objects).size()); openstudio::IdfObject idfObject4(openstudio::IddObjectType::Schedule_Constant); idfObject4.setString(0, "Schedule 1"); @@ -335,16 +353,17 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) idfObject5.setString(WindowShadingControlFields::ZoneName, ""); idfObject5.setString(WindowShadingControlFields::ShadingControlSequenceNumber, "1"); idfObject5.setString(WindowShadingControlFields::ShadingType, "InteriorBlind"); - idfObject5.setString(WindowShadingControlFields::ConstructionwithShadingName, ""); - idfObject5.setString(WindowShadingControlFields::ShadingControlType, "OnIfScheduleAllows"); + idfObject5.setString(WindowShadingControlFields::ConstructionwithShadingName, construction.nameString()); + // This Shading Control Type accepts 2 setpoints and a Schedule + idfObject5.setString(WindowShadingControlFields::ShadingControlType, "OnIfHighZoneAirTempAndHighSolarOnWindow"); idfObject5.setString(WindowShadingControlFields::ScheduleName, "Schedule 1"); - idfObject5.setString(WindowShadingControlFields::Setpoint, "100"); + idfObject5.setString(WindowShadingControlFields::Setpoint, "30"); idfObject5.setString(WindowShadingControlFields::ShadingControlIsScheduled, "Yes"); idfObject5.setString(WindowShadingControlFields::GlareControlIsActive, "No"); - idfObject5.setString(WindowShadingControlFields::ShadingDeviceMaterialName, "Shade 1"); + // idfObject5.setString(WindowShadingControlFields::ShadingDeviceMaterialName, "Shade 1"); idfObject5.setString(WindowShadingControlFields::TypeofSlatAngleControlforBlinds, ""); idfObject5.setString(WindowShadingControlFields::SlatAngleScheduleName, ""); - idfObject5.setString(WindowShadingControlFields::Setpoint2, ""); + idfObject5.setString(WindowShadingControlFields::Setpoint2, "500.0"); idfObject5.setString(WindowShadingControlFields::MultipleSurfaceControlType, "Sequential"); IdfExtensibleGroup group9 = idfObject5.pushExtensibleGroup(); // sub surface group9.setString(0, "Sub Surface 1"); @@ -357,8 +376,6 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) EXPECT_EQ("Sequential", wo1.getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); ASSERT_EQ(1u, wo1.extensibleGroups().size()); - workspace.save(toPath("./ReverseTranslator_ShadingControls.idf"), true); - ReverseTranslator trans; ASSERT_NO_THROW(trans.translateWorkspace(workspace)); Model model = trans.translateWorkspace(workspace); @@ -370,8 +387,15 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) std::vector shadingControls = model.getModelObjects(); ASSERT_EQ(1u, shadingControls.size()); ShadingControl shadingControl = shadingControls[0]; - EXPECT_EQ(1, shadingControl.numberofSubSurfaces()); + EXPECT_EQ("InteriorDaylightRedirectionDevice", shadingControl.shadingType()); // InteriorBlind maps to InteriorDaylightRedirectionDevice for some reason + EXPECT_EQ("OnIfHighZoneAirTempAndHighSolarOnWindow", shadingControl.shadingControlType()); + EXPECT_TRUE(shadingControl.schedule()); + ASSERT_TRUE(shadingControl.setpoint()); + EXPECT_EQ(30.0, shadingControl.setpoint().get()); + ASSERT_TRUE(shadingControl.setpoint2()); + EXPECT_EQ(500.0, shadingControl.setpoint2().get()); EXPECT_EQ("Sequential", shadingControl.multipleSurfaceControlType()); + EXPECT_EQ(1, shadingControl.numberofSubSurfaces()); std::vector subSurfaces = model.getModelObjects(); ASSERT_EQ(1u, subSurfaces.size()); From b06fd15fb8d88e2555169624ec49f5d3c9a0dda6 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 15 Sep 2020 14:40:37 +0200 Subject: [PATCH 40/49] Add some release notes for this PR --- .../doc/ReleaseNotes/OpenStudio_Release_Notes_3_1_0.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_1_0.md b/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_1_0.md index aadec392eee..7ab0bf09a50 100644 --- a/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_1_0.md +++ b/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_1_0.md @@ -66,7 +66,14 @@ A number of API-breaking changes have been implemented in OpenStudio 3.1.0: * [#3960](https://github.com/NREL/OpenStudio/pull/3960) - Added support for building the C# bindings via `dotnet` CLI, including on Unix platforms. * [#3959](https://github.com/NREL/OpenStudio/pull/3959) - Also included some improvements in the generated C# bindings by reducing build warnings and properly exposing some types via SWIG * `ScheduleTypeKey` (which is normally only use by OpenStudio internals in ScheduleTypeRegistry checks) previously mapped to a `std::pair` which was SWIGed in ruby as an Array of strings of size two, but improperly exposed in C#. It now uses a dedicated helper class with two methods `ScheduleTypeKey::className()` and `ScheduleTypeKey::scheduleDisplayName()` - +* [#4066](https://github.com/NREL/OpenStudio/pull/4066) - Multiple shading controls referenced by a single subsurface + * `SubSurface` was historically the one referencing the `ShadingControl` object. Now it's a many-to-many relationship where `ShadingControl` has an extensible 'Surface Name' field, and multiple `ShadingControl` can reference the same `SubSurface`. This is trickling down from a change introduced in EnergyPlus version 9.4, and specifically in PR [NREL/EnergyPlus#8196](https://github.com/NREL/EnergyPlus/pull/8196) + * Methods in `SubSurface` have been deprecated but keep for backward compatibility. They will be removed in a future version of OpenStudio: + * `shadingControl()`: prefer `shadingControls()` + * `setShadingControl(ShadingControl&)`: use `addShadingControl(SubSurface&)`, `addShadingControls(std::vector&)` or `setShadingControls(std::vector&)` + * `resetShadingControl()`: use `removeAllShadingControls()` instead + * All Shading Control Type values should now be supported. Refer to issue [#4074](https://github.com/NREL/OpenStudio/issues/4074) for more information + * Fields `Setpoint2` and 'Multiple Surface Control Type' are now implemented as well ## Minor changes: From 9d5b2ac04b28dedf37c4d9bccbce5a9868b706ad Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 15 Sep 2020 14:42:43 +0200 Subject: [PATCH 41/49] Missing an override keyword --- src/model/ShadingControl_Impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/ShadingControl_Impl.hpp b/src/model/ShadingControl_Impl.hpp index edd48a8af18..35b1791c513 100644 --- a/src/model/ShadingControl_Impl.hpp +++ b/src/model/ShadingControl_Impl.hpp @@ -75,7 +75,7 @@ namespace detail { // If cloning in the same model, will keep on referencing the same SubSurfaces as the original // If cloning in another model, will clear out its extensible Sub Surface Name group - virtual ModelObject clone(Model model) const; + virtual ModelObject clone(Model model) const override; //@} From 361e509cfe2a13e4d32a903203de3bd3d6312cae Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 15 Sep 2020 15:05:29 +0200 Subject: [PATCH 42/49] #4074 Followup: add test for logic, and avoid clearing Setpoint2/Schedule all the time. Left A TODO --- src/model/ShadingControl.cpp | 52 ++++++++++--------- src/model/test/ShadingControl_GTest.cpp | 68 +++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 23 deletions(-) diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index a9e91e1bfc4..dd248f3d72f 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -311,31 +311,37 @@ namespace detail { std::string oldControlType = this->shadingControlType(); bool result = setString(OS_ShadingControlFields::ShadingControlType, shadingControlType); if (result){ + if (!ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType)) { + // Not calling reset to avoid double check on whether it's required + // resetSetpoint(); + LOG(Info, briefDescription() << " Shading Control Type was changed to '" << shadingControlType << " which does not require a Setpoint, reseting"); + bool test = setString(OS_ShadingControlFields::Setpoint, ""); + OS_ASSERT(test); + } + if (!ShadingControl_Impl::isControlTypeValueNeedingSetpoint2(shadingControlType)) { + // Not calling reset to avoid double check on whether it's required + // resetSetpoint2(); + LOG(Info, briefDescription() << " Shading Control Type was changed to '" << shadingControlType << " which does not require a Setpoint2, reseting"); + bool test = setString(OS_ShadingControlFields::Setpoint2, ""); + OS_ASSERT(test); + } + if (!ShadingControl_Impl::isControlTypeValueAllowingSchedule(shadingControlType)) { + LOG(Info, briefDescription() << " Shading Control Type was changed to '" << shadingControlType << " which does not allow a Schedule, reseting"); + bool test = setString(OS_ShadingControlFields::ScheduleName, ""); + OS_ASSERT(test); + test = setString(OS_ShadingControlFields::ShadingControlIsScheduled, "No"); + OS_ASSERT(test); + } + + // TODO: do we want to force remove this stuff like it did resetSetpoint before? Units/quantity might be oranges and apples when switching + // types, but they could be compatible, and it may be very confusing at least for interface users that are playing with a dropdown to see + // schedulesand setpoints disapear if (!openstudio::istringEqual(oldControlType, shadingControlType)) { - resetSetpoint(); - } else { - if (!ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType)) { - // Not calling reset to avoid double check on whether it's required - // resetSetpoint(); - LOG(Info, briefDescription() << " Shading Control Type was changed to '" << shadingControlType << " which does not require a Setpoint, reseting"); - bool test = setString(OS_ShadingControlFields::Setpoint, ""); - OS_ASSERT(test); - } - if (!ShadingControl_Impl::isControlTypeValueNeedingSetpoint2(shadingControlType)) { - // Not calling reset to avoid double check on whether it's required - // resetSetpoint2(); - LOG(Info, briefDescription() << " Shading Control Type was changed to '" << shadingControlType << " which does not require a Setpoint2, reseting"); - bool test = setString(OS_ShadingControlFields::Setpoint2, ""); - OS_ASSERT(test); - } - if (!ShadingControl_Impl::isControlTypeValueAllowingSchedule(shadingControlType)) { - LOG(Info, briefDescription() << " Shading Control Type was changed to '" << shadingControlType << " which does not allow a Schedule, reseting"); - bool test = setString(OS_ShadingControlFields::ScheduleName, ""); - OS_ASSERT(test); - test = setString(OS_ShadingControlFields::ShadingControlIsScheduled, "No"); - OS_ASSERT(test); - } + resetSetpoint(); // For backward compatibility + // resetSetpoint2(); + // resetSchedule(); } + } return result; } diff --git a/src/model/test/ShadingControl_GTest.cpp b/src/model/test/ShadingControl_GTest.cpp index 7aed746ab16..756fa035e7e 100644 --- a/src/model/test/ShadingControl_GTest.cpp +++ b/src/model/test/ShadingControl_GTest.cpp @@ -35,6 +35,7 @@ #include "../ShadingControl_Impl.hpp" #include "../Construction.hpp" #include "../Schedule.hpp" +#include "../ScheduleConstant.hpp" #include "../Blind.hpp" #include "../Blind_Impl.hpp" #include "../SimpleGlazing.hpp" @@ -222,3 +223,70 @@ TEST_F(ModelFixture, ShadingControl_Clone) { EXPECT_NE(shadingControl.shadingMaterial().get(), shadingControlClone.shadingMaterial().get()); } } + +TEST_F(ModelFixture, ShadingControl_ShadingControlTypeLogic) { + + Model m; + + Blind b(m); + ShadingControl sc(b); + + EXPECT_TRUE(sc.setSetpoint(32.0)); + ASSERT_TRUE(sc.setpoint()); + EXPECT_EQ(32.0, sc.setpoint().get()); + + ScheduleConstant sch(m); + + // Allows nothing + EXPECT_TRUE(sc.setShadingControlType("AlwaysOn")); + EXPECT_FALSE(sc.isControlTypeValueNeedingSetpoint1()); + EXPECT_FALSE(sc.isControlTypeValueNeedingSetpoint2()); + EXPECT_FALSE(sc.isControlTypeValueAllowingSchedule()); + EXPECT_FALSE(sc.setSetpoint(30.0)); + EXPECT_FALSE(sc.setSetpoint2(500.0)); + EXPECT_FALSE(sc.setSchedule(sch)); + EXPECT_FALSE(sc.setpoint()); + EXPECT_FALSE(sc.setpoint2()); + EXPECT_FALSE(sc.schedule()); + + // Allows schedules, required two setpoints + EXPECT_TRUE(sc.setShadingControlType("OnIfHighZoneAirTempAndHighSolarOnWindow")); + EXPECT_TRUE(sc.isControlTypeValueNeedingSetpoint1()); + EXPECT_TRUE(sc.isControlTypeValueNeedingSetpoint2()); + EXPECT_TRUE(sc.isControlTypeValueAllowingSchedule()); + EXPECT_TRUE(sc.setSetpoint(30.0)); + EXPECT_TRUE(sc.setSetpoint2(500.0)); + EXPECT_TRUE(sc.setSchedule(sch)); + ASSERT_TRUE(sc.setpoint()); + EXPECT_EQ(30.0, sc.setpoint().get()); + ASSERT_TRUE(sc.setpoint2()); + EXPECT_EQ(500.0, sc.setpoint2().get()); + ASSERT_TRUE(sc.schedule()); + EXPECT_EQ(sch, sc.schedule().get()); + + // Shouldn't allow reseting setpoints since required + sc.resetSetpoint(); + ASSERT_TRUE(sc.setpoint()); + EXPECT_EQ(30.0, sc.setpoint().get()); + ASSERT_TRUE(sc.setpoint2()); + EXPECT_EQ(500.0, sc.setpoint2().get()); + // Note: I'm not providing resetSetpoint2 on purpose + + sc.resetSchedule(); + EXPECT_FALSE(sc.schedule()); + EXPECT_TRUE(sc.setSchedule(sch)); + + // OnIfHighGlare: needs setpoint1 only and not Setpoint2, allows schedule + EXPECT_TRUE(sc.setShadingControlType("OnIfHighZoneCooling")); + EXPECT_TRUE(sc.isControlTypeValueNeedingSetpoint1()); + EXPECT_FALSE(sc.isControlTypeValueNeedingSetpoint2()); + EXPECT_TRUE(sc.isControlTypeValueAllowingSchedule()); + + // Setpoint 1 has been cleared because we're switching Shading Control Type and that was the historical behavior + EXPECT_FALSE(sc.setpoint2()); + // Setpoint2 is cleared because the new Shading Control Type does not support Setpoint 2 + EXPECT_FALSE(sc.setpoint2()); + // Schedule is kept, user should be responsible to ensure the Schedule still makes sense, instead of always clearing it + EXPECT_TRUE(sc.schedule()); + +} From 33df5782779f6b4362e021740c83101156be13d3 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 15 Sep 2020 16:24:41 +0200 Subject: [PATCH 43/49] Typo in C# partial class --- src/model/ModelGeometry.i | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/model/ModelGeometry.i b/src/model/ModelGeometry.i index ec7ff03bf66..e4fa06ea9cb 100644 --- a/src/model/ModelGeometry.i +++ b/src/model/ModelGeometry.i @@ -365,11 +365,11 @@ SWIG_MODELOBJECT(ExteriorWaterEquipment, 1); } public bool addSubSurfaces(SubSurfaceVector subSurfaces) { - return OpenStudio.OpenStudioModelHVAC.addSubSurfacesForShadingControl(this, subSurfaces); + return OpenStudio.OpenStudioModelGeometry.addSubSurfacesForShadingControl(this, subSurfaces); } public bool setSubSurfaces(SubSurfaceVector subSurfaces) { - return OpenStudio.OpenStudioModelHVAC.setSubSurfacesForShadingControl(this, subSurfaces); + return OpenStudio.OpenStudioModelGeometry.setSubSurfacesForShadingControl(this, subSurfaces); } } From b751a345a0c54bfe9ca7575bdd4fd98b0cd9ea84 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 15 Sep 2020 17:21:35 +0200 Subject: [PATCH 44/49] Unrelated C# fixed while I'm at it. --- src/model/ModelCore.i | 4 +++- src/model/ModelResources.i | 4 ++++ src/model/ModelSimulation.i | 30 ++++++++++++++++++++++++++++++ src/model/ModelStraightComponent.i | 11 +++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/model/ModelCore.i b/src/model/ModelCore.i index 6efb5cf0428..98dcf192647 100644 --- a/src/model/ModelCore.i +++ b/src/model/ModelCore.i @@ -25,7 +25,7 @@ // Ignore AccessPolicyStore which is used by GUIs only %ignore openstudio::model::AccessPolicyStore; - // ignore simulation objects for now, add back in with partial classes in ModelSimulation.i + // ignore simulation objects for now, add back in with partial classes in ModelSimulation.i (TODO) %ignore openstudio::model::Model::foundationKivaSettings; %ignore openstudio::model::Model::outputTableSummaryReports; %ignore openstudio::model::Model::runPeriod; @@ -33,6 +33,8 @@ %ignore openstudio::model::Model::yearDescription; %ignore openstudio::model::Model::performancePrecisionTradeoffs; + %ignore openstudio::model::Model::outputControlFiles; + // ignore geometry objects for now, add back in with partial classes in ModelGeometry.i %ignore openstudio::model::Model::building; %ignore openstudio::model::Model::plenumSpaceType; diff --git a/src/model/ModelResources.i b/src/model/ModelResources.i index 85b29d225c5..7a25e4f9045 100644 --- a/src/model/ModelResources.i +++ b/src/model/ModelResources.i @@ -33,6 +33,8 @@ %ignore openstudio::model::ShadingControl::addSubSurfaces; %ignore openstudio::model::ShadingControl::setSubSurfaces; + // CoilCoolingDX is defined in StraightComponent.i + %ignore openstudio::model::CoilCoolingDXCurveFitPerformance::coilCoolingDXs; // TODO: why? // ignore schedule type // %ignore openstudio::model::ScheduleType; @@ -55,6 +57,8 @@ namespace model { class ShadingControl; %feature("valuewrapper") SubSurface; class SubSurface; +%feature("valuewrapper") CoilCoolingDX; +class CoilCoolingDX; } } diff --git a/src/model/ModelSimulation.i b/src/model/ModelSimulation.i index c6de559f106..e729a370a9d 100644 --- a/src/model/ModelSimulation.i +++ b/src/model/ModelSimulation.i @@ -139,4 +139,34 @@ SWIG_UNIQUEMODELOBJECT(FoundationKivaSettings); SWIG_UNIQUEMODELOBJECT(OutputTableSummaryReports); SWIG_UNIQUEMODELOBJECT(PerformancePrecisionTradeoffs); +#if defined SWIGCSHARP || defined(SWIGJAVA) + + %inline { + namespace openstudio { + namespace model { + boost::optional outputControlFiles(const openstudio::model::Model& model){ + return model.outputControlFiles(); + } + } + } + } + +#endif + +#if defined(SWIGCSHARP) + //%pragma(csharp) imclassimports=%{ + %pragma(csharp) moduleimports=%{ + + using System; + using System.Runtime.InteropServices; + + public partial class Model : Workspace { + public OptionalOutputControlFiles outputControlFiles() + { + return OpenStudio.OpenStudioModelSimulation.outputControlFiles(this); + } + } + %} #endif + +#endif // MODEL_GEOMETRY_I diff --git a/src/model/ModelStraightComponent.i b/src/model/ModelStraightComponent.i index ddaaa31369a..e97654b3e4e 100644 --- a/src/model/ModelStraightComponent.i +++ b/src/model/ModelStraightComponent.i @@ -273,6 +273,10 @@ SWIG_MODELOBJECT(WaterUseConnections,1); OptionalCoilCoolingDXMultiSpeed parentCoil(const openstudio::model::CoilCoolingDXMultiSpeedStageData& stage){ return stage.parentCoil(); } + + CoilCoolingDXVector coilCoolingDXs(const openstudio::model::CoilCoolingDXCurveFitPerformance& perf) { + return perf.coilCoolingDXs(); + } } } } @@ -299,6 +303,13 @@ SWIG_MODELOBJECT(WaterUseConnections,1); } } + public partial class CoilCoolingDXCurveFitPerformance : ResourceObject + { + public CoilCoolingDXVector coilCoolingDXs() { + return OpenStudio.OpenStudioModelStraightComponent.coilCoolingDXs(this); + } + } + %} #endif #endif From bec2af2577106f24e5867f66aca0b5bf490ade61 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 15 Sep 2020 17:21:59 +0200 Subject: [PATCH 45/49] Unrelated issue in ModelObject::getAutosizedValue Found it while investigating #4062 --- src/model/ModelObject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/ModelObject.cpp b/src/model/ModelObject.cpp index ab5585ce08e..1e14964b41c 100644 --- a/src/model/ModelObject.cpp +++ b/src/model/ModelObject.cpp @@ -255,7 +255,7 @@ namespace detail { boost::replace_all(sqlObjectType, "OS:", ""); // Special logic to deal with EnergyPlus inconsistencies - if (sqlObjectType == "Coil:Heating:NaturalGas") { + if (sqlObjectType == "Coil:Heating:Gas") { sqlObjectType = "Coil:Heating:Fuel"; } From 64f1a6df8e9bf38494c639e791e2bbba1a552b91 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 15 Sep 2020 13:46:16 -0700 Subject: [PATCH 46/49] Include glare and slat angle control in api. --- .../ForwardTranslateShadingControl.cpp | 22 +- .../ReverseTranslateWindowShadingControl.cpp | 23 ++ src/energyplus/Test/ShadingControl_GTest.cpp | 11 +- src/model/ShadingControl.cpp | 279 +++++++++++++----- src/model/ShadingControl.hpp | 28 +- src/model/ShadingControl_Impl.hpp | 29 +- src/model/test/ShadingControl_GTest.cpp | 23 ++ 7 files changed, 331 insertions(+), 84 deletions(-) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp index ef86c3390eb..76d269cab4d 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp @@ -172,15 +172,25 @@ boost::optional ForwardTranslator::translateShadingControl(model::Sha idfObject.setDouble(WindowShadingControlFields::Setpoint, modelObject.setpoint().get()); } - if (modelObject.isControlTypeValueNeedingSetpoint2()) { - idfObject.setDouble(WindowShadingControlFields::Setpoint2, modelObject.setpoint2().get()); + if (modelObject.glareControlIsActive() || istringEqual("OnIfHighGlare", shadingControlType)) { + idfObject.setString(WindowShadingControlFields::GlareControlIsActive, "Yes"); + } else { + idfObject.setString(WindowShadingControlFields::GlareControlIsActive, "No"); } - idfObject.setString(WindowShadingControlFields::GlareControlIsActive, "No"); - - //idfObject.setString(WindowShadingControlFields::TypeofSlatAngleControlforBlinds, "FixedSlatAngle"); + boost::optional slatAngleSchedule = modelObject.slatAngleSchedule(); + if (slatAngleSchedule) { + idfObject.setString(WindowShadingControlFields::SlatAngleScheduleName, slatAngleSchedule->name().get()); + idfObject.setString(WindowShadingControlFields::TypeofSlatAngleControlforBlinds, "ScheduledSlatAngle"); + } else { + if (!istringEqual("ScheduledSlatAngle", modelObject.typeofSlatAngleControlforBlinds())) { + idfObject.setString(WindowShadingControlFields::TypeofSlatAngleControlforBlinds, modelObject.typeofSlatAngleControlforBlinds()); + } + } - //idfObject.setString(WindowShadingControlFields::SlatAngleScheduleName, ""); + if (modelObject.isControlTypeValueNeedingSetpoint2()) { + idfObject.setDouble(WindowShadingControlFields::Setpoint2, modelObject.setpoint2().get()); + } idfObject.setString(WindowShadingControlFields::MultipleSurfaceControlType, modelObject.multipleSurfaceControlType()); diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp index 390e21e7262..a535aaa8620 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateWindowShadingControl.cpp @@ -130,6 +130,29 @@ boost::optional ReverseTranslator::translateWindowShadingControl( c shadingControl->setSetpoint(*d); } + s = workspaceObject.getString(WindowShadingControlFields::GlareControlIsActive); + if(s){ + if (istringEqual(*s, "Yes")) { + shadingControl->setGlareControlIsActive(true); + } else if (istringEqual(*s, "No")) { + shadingControl->setGlareControlIsActive(false); + } + } + + s = workspaceObject.getString(WindowShadingControlFields::TypeofSlatAngleControlforBlinds); + if(s){ + shadingControl->setTypeofSlatAngleControlforBlinds(*s); + } + + if ((target = workspaceObject.getTarget(WindowShadingControlFields::SlatAngleScheduleName))){ + OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target); + if (modelObject){ + if (modelObject->optionalCast()){ + shadingControl->setSlatAngleSchedule(modelObject->cast()); + } + } + } + d = workspaceObject.getDouble(WindowShadingControlFields::Setpoint2); if(s){ shadingControl->setSetpoint2(*d); diff --git a/src/energyplus/Test/ShadingControl_GTest.cpp b/src/energyplus/Test/ShadingControl_GTest.cpp index 964889a57d3..e9f470bc2d4 100644 --- a/src/energyplus/Test/ShadingControl_GTest.cpp +++ b/src/energyplus/Test/ShadingControl_GTest.cpp @@ -130,7 +130,6 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) subSurfaceB.setSurface(surface); subSurfaceB.assignDefaultSubSurfaceType(); - Blind blind1(model); ShadingControl shadingControl1(blind1); EXPECT_TRUE(shadingControl1.setShadingType("ExteriorBlind")); @@ -139,11 +138,13 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) EXPECT_TRUE(shadingControl1.isControlTypeValueAllowingSchedule()); EXPECT_TRUE(shadingControl1.isControlTypeValueNeedingSetpoint1()); EXPECT_TRUE(shadingControl1.isControlTypeValueNeedingSetpoint2()); + EXPECT_TRUE(shadingControl1.isTypeValueAllowingSlatAngleControl()); ScheduleConstant shadingControl1Schedule(model); EXPECT_TRUE(shadingControl1.setSchedule(shadingControl1Schedule)); EXPECT_TRUE(shadingControl1.setSetpoint(25.0)); EXPECT_TRUE(shadingControl1.setSetpoint2(500.0)); + EXPECT_TRUE(shadingControl1.setGlareControlIsActive(true)); EXPECT_TRUE(shadingControl1.setMultipleSurfaceControlType("Sequential")); EXPECT_TRUE(shadingControl1.addSubSurface(subSurfaceA)); // Convenience method that calls ShadingControl::addSubSurface() @@ -154,12 +155,12 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) Blind blind2(model); ShadingControl shadingControl2(blind2); + EXPECT_TRUE(shadingControl2.setTypeofSlatAngleControlforBlinds("BlockBeamSolar")); EXPECT_TRUE(shadingControl2.setMultipleSurfaceControlType("Group")); EXPECT_TRUE(subSurfaceA.addShadingControl(shadingControl2)); ASSERT_EQ(1u, shadingControl2.subSurfaces().size()); EXPECT_EQ(1u, shadingControl2.subSurfaceIndex(subSurfaceA).get()); - EXPECT_EQ(2u, subSurfaceA.shadingControls().size()); EXPECT_EQ(1u, subSurfaceB.shadingControls().size()); @@ -185,9 +186,10 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) EXPECT_EQ(shadingControl1Schedule.nameString(), _wo->getString(WindowShadingControlFields::ScheduleName, false, true).get()); EXPECT_EQ("Yes", _wo->getString(WindowShadingControlFields::ShadingControlIsScheduled, false, true).get()); - EXPECT_EQ("No", _wo->getString(WindowShadingControlFields::GlareControlIsActive, false, true).get()); + EXPECT_EQ("Yes", _wo->getString(WindowShadingControlFields::GlareControlIsActive, false, true).get()); EXPECT_EQ(blind1.nameString(), _wo->getString(WindowShadingControlFields::ShadingDeviceMaterialName, false, true).get()); EXPECT_FALSE(_wo->getString(WindowShadingControlFields::SlatAngleScheduleName, false, true)); + EXPECT_EQ("FixedSlatAngle", _wo->getString(WindowShadingControlFields::TypeofSlatAngleControlforBlinds, false, true).get()); EXPECT_FALSE(_wo->getString(WindowShadingControlFields::DaylightingControlObjectName, false, true)); EXPECT_EQ("Sequential", _wo->getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); ASSERT_EQ(2u, _wo->extensibleGroups().size()); @@ -219,6 +221,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ShadingControls) EXPECT_EQ("No", _wo->getString(WindowShadingControlFields::GlareControlIsActive, false, true).get()); EXPECT_EQ(blind2.nameString(), _wo->getString(WindowShadingControlFields::ShadingDeviceMaterialName, false, true).get()); EXPECT_FALSE(_wo->getString(WindowShadingControlFields::SlatAngleScheduleName, false, true)); + EXPECT_EQ("BlockBeamSolar", _wo->getString(WindowShadingControlFields::TypeofSlatAngleControlforBlinds, false, true).get()); EXPECT_FALSE(_wo->getString(WindowShadingControlFields::Setpoint2, false, true)); EXPECT_FALSE(_wo->getString(WindowShadingControlFields::DaylightingControlObjectName, false, true)); EXPECT_EQ("Group", _wo->getString(WindowShadingControlFields::MultipleSurfaceControlType, false).get()); @@ -396,6 +399,8 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ShadingControls) EXPECT_EQ(500.0, shadingControl.setpoint2().get()); EXPECT_EQ("Sequential", shadingControl.multipleSurfaceControlType()); EXPECT_EQ(1, shadingControl.numberofSubSurfaces()); + EXPECT_FALSE(shadingControl.slatAngleSchedule()); + EXPECT_TRUE(shadingControl.isTypeofSlatAngleControlforBlindsDefaulted()); std::vector subSurfaces = model.getModelObjects(); ASSERT_EQ(1u, subSurfaces.size()); diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index dd248f3d72f..41c3afca2a6 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -106,7 +106,7 @@ namespace detail { "OnIfHighOutdoorAirTemperature", "OnIfHighZoneAirTemperature", "OnIfHighZoneCooling", - "OnIfHighGlare", + //"OnIfHighGlare", //"MeetDaylightIlluminanceSetpoint", "OnNightIfLowOutdoorTempAndOffDay", "OnNightIfLowInsideTempAndOffDay", @@ -129,6 +129,8 @@ namespace detail { bool ShadingControl_Impl::isControlTypeValueNeedingSetpoint2(const std::string& controlType) { static constexpr std::array data{ + "OnIfHighOutdoorAirTempAndHighSolarOnWindow", + "OnIfHighOutdoorAirTempAndHighHorizontalSolar", "OnIfHighZoneAirTempAndHighSolarOnWindow", "OnIfHighZoneAirTempAndHighHorizontalSolar" }; @@ -174,6 +176,25 @@ namespace detail { return openstudio::istringEqual("OnIfScheduleAllows", controlType); } + bool ShadingControl_Impl::isTypeValueAllowingSlatAngleControl(const std::string& type) { + static constexpr std::array data{ + //"InteriorShade", + //"ExteriorShade", + //"ExteriorScreen", + "InteriorBlind", + "ExteriorBlind", + //"BetweenGlassShade", + "BetweenGlassBlind", + //"SwitchableGlazing", + //"InteriorDaylightRedirectionDevice" + }; + return std::find_if(data.begin(), + data.end(), + [&type](auto c){ + return openstudio::istringEqual(type, c); + }) != data.end(); + } + IddObjectType ShadingControl_Impl::iddObjectType() const { return ShadingControl::iddObjectType(); @@ -189,6 +210,13 @@ namespace detail { return scClone; } + std::string ShadingControl_Impl::shadingType() const + { + boost::optional result = getString(OS_ShadingControlFields::ShadingType, true); + OS_ASSERT(result); + return result.get(); + } + boost::optional ShadingControl_Impl::construction() const { return getObject().getModelObjectTarget(OS_ShadingControlFields::ConstructionwithShadingName); @@ -199,13 +227,6 @@ namespace detail { return getObject().getModelObjectTarget(OS_ShadingControlFields::ShadingDeviceMaterialName); } - std::string ShadingControl_Impl::shadingType() const - { - boost::optional result = getString(OS_ShadingControlFields::ShadingType, true); - OS_ASSERT(result); - return result.get(); - } - std::string ShadingControl_Impl::shadingControlType() const { boost::optional result = getString(OS_ShadingControlFields::ShadingControlType, true); @@ -240,31 +261,29 @@ namespace detail { return isEmpty(OS_ShadingControlFields::Setpoint); } - bool ShadingControl_Impl::setSetpoint(double setpoint) + bool ShadingControl_Impl::glareControlIsActive() const { - bool result = false; - std::string shadingControlType = this->shadingControlType(); - if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType)) { - result = setDouble(OS_ShadingControlFields::Setpoint, setpoint); - } else { - LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does not require a Setpoint"); - } - return result; + boost::optional value = getString(OS_ShadingControlFields::GlareControlIsActive, true); + OS_ASSERT(value); + return openstudio::istringEqual(value.get(), "Yes"); } - void ShadingControl_Impl::resetSetpoint() + std::string ShadingControl_Impl::typeofSlatAngleControlforBlinds() const { - std::string shadingControlType = this->shadingControlType(); - if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType) && - !openstudio::istringEqual("OnIfHighSolarOnWindow", shadingControlType)) - { - LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does require a Setpoint, not resetting it"); - } else { - bool test = setString(OS_ShadingControlFields::Setpoint, ""); - OS_ASSERT(test); - } + boost::optional result = getString(OS_ShadingControlFields::TypeofSlatAngleControlforBlinds, true); + OS_ASSERT(result); + return result.get(); } + bool ShadingControl_Impl::isTypeofSlatAngleControlforBlindsDefaulted() const + { + return isEmpty(OS_ShadingControlFields::TypeofSlatAngleControlforBlinds); + } + + boost::optional ShadingControl_Impl::slatAngleSchedule() const + { + return getObject().getModelObjectTarget(OS_ShadingControlFields::SlatAngleScheduleName); + } boost::optional ShadingControl_Impl::setpoint2() const { @@ -278,27 +297,11 @@ namespace detail { return result; } - bool ShadingControl_Impl::setSetpoint2(double setpoint2) - { - bool result = false; - std::string shadingControlType = this->shadingControlType(); - if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint2(shadingControlType)) { - result = setDouble(OS_ShadingControlFields::Setpoint2, setpoint2); - } else { - LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does not require a Setpoint2"); - } - return result; - } - - void ShadingControl_Impl::resetSetpoint2() + std::string ShadingControl_Impl::multipleSurfaceControlType() const { - std::string shadingControlType = this->shadingControlType(); - if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType)) { - LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does require a Setpoint2, not resetting it"); - } else { - bool test = setString(OS_ShadingControlFields::Setpoint2, ""); - OS_ASSERT(test); - } + boost::optional result = getString(OS_ShadingControlFields::MultipleSurfaceControlType, true); + OS_ASSERT(result); + return result.get(); } bool ShadingControl_Impl::setShadingType(const std::string& shadingType) @@ -386,11 +389,113 @@ namespace detail { } } - std::string ShadingControl_Impl::multipleSurfaceControlType() const + bool ShadingControl_Impl::setSetpoint(double setpoint) { - boost::optional result = getString(OS_ShadingControlFields::MultipleSurfaceControlType, true); + bool result = false; + std::string shadingControlType = this->shadingControlType(); + if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType)) { + result = setDouble(OS_ShadingControlFields::Setpoint, setpoint); + } else { + LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does not require a Setpoint"); + } + return result; + } + + void ShadingControl_Impl::resetSetpoint() + { + std::string shadingControlType = this->shadingControlType(); + if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType) && + !openstudio::istringEqual("OnIfHighSolarOnWindow", shadingControlType)) + { + LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does require a Setpoint, not resetting it"); + } else { + bool test = setString(OS_ShadingControlFields::Setpoint, ""); + OS_ASSERT(test); + } + } + + bool ShadingControl_Impl::setGlareControlIsActive(bool glareControlIsActive) + { + bool result = false; + if (glareControlIsActive) { + result = setString(OS_ShadingControlFields::GlareControlIsActive, "Yes"); + } else { + result = setString(OS_ShadingControlFields::GlareControlIsActive, "No"); + } OS_ASSERT(result); - return result.get(); + return result; + } + + void ShadingControl_Impl::resetGlareControlIsActive() + { + bool result = setString(OS_ShadingControlFields::GlareControlIsActive, ""); + OS_ASSERT(result); + } + + bool ShadingControl_Impl::setTypeofSlatAngleControlforBlinds(const std::string& typeofSlatAngleControlforBlinds) + { + bool result = false; + std::string shadingType = this->shadingType(); + if (ShadingControl_Impl::isTypeValueAllowingSlatAngleControl(shadingType)) { + result = setString(OS_ShadingControlFields::TypeofSlatAngleControlforBlinds, typeofSlatAngleControlforBlinds); + } + return result; + } + + void ShadingControl_Impl::resetTypeofSlatAngleControlforBlinds() + { + bool result = setString(OS_ShadingControlFields::TypeofSlatAngleControlforBlinds, ""); + OS_ASSERT(result); + } + + bool ShadingControl_Impl::setSlatAngleSchedule(const Schedule& slatAngleSchedule) + { + bool result = false; + std::string shadingType = this->shadingType(); + if (ShadingControl_Impl::isTypeValueAllowingSlatAngleControl(shadingType)) { + result = setPointer(OS_ShadingControlFields::SlatAngleScheduleName, slatAngleSchedule.handle()); + if (result){ + bool test = setString(OS_ShadingControlFields::TypeofSlatAngleControlforBlinds, "ScheduledSlatAngle"); + OS_ASSERT(test); + } + } else { + LOG(Warn, briefDescription() << " has a Shading Type '" << shadingType << "' which does not allow a Slat Angle Schedule"); + } + return result; + } + + void ShadingControl_Impl::resetSlatAngleSchedule() + { + bool result = false; + + result = setString(OS_ShadingControlFields::SlatAngleScheduleName, ""); + OS_ASSERT(result); + + result = setString(OS_ShadingControlFields::TypeofSlatAngleControlforBlinds, ""); + OS_ASSERT(result); + } + + bool ShadingControl_Impl::setSetpoint2(double setpoint2) + { + bool result = false; + std::string shadingControlType = this->shadingControlType(); + if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint2(shadingControlType)) { + result = setDouble(OS_ShadingControlFields::Setpoint2, setpoint2); + } else { + LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does not require a Setpoint2"); + } + return result; + } + + void ShadingControl_Impl::resetSetpoint2() + { + std::string shadingControlType = this->shadingControlType(); + if (ShadingControl_Impl::isControlTypeValueNeedingSetpoint1(shadingControlType)) { + LOG(Warn, briefDescription() << " has a Shading Control Type '" << shadingControlType << "' which does require a Setpoint2, not resetting it"); + } else { + bool test = setString(OS_ShadingControlFields::Setpoint2, ""); + OS_ASSERT(test); + } } bool ShadingControl_Impl::setMultipleSurfaceControlType(const std::string& multipleSurfaceControlType) @@ -437,7 +542,6 @@ namespace detail { return result; } - bool ShadingControl_Impl::addSubSurface(const SubSurface& subSurface) { // Check if subSurface already exists @@ -462,7 +566,6 @@ namespace detail { return result; } - bool ShadingControl_Impl::setSubSurfaceIndex(const SubSurface& subSurface, unsigned index) { boost::optional idx = subSurfaceIndex(subSurface); @@ -543,7 +646,6 @@ namespace detail { } // detail - ShadingControl::ShadingControl(const Construction& construction) : ResourceObject(ShadingControl::iddObjectType(),construction.model()) { @@ -674,6 +776,14 @@ bool ShadingControl::isControlTypeValueRequiringSchedule() { return getImpl()->isControlTypeValueRequiringSchedule(this->shadingControlType()); } +bool ShadingControl::isTypeValueAllowingSlatAngleControl() { + return getImpl()->isTypeValueAllowingSlatAngleControl(this->shadingType()); +} + +std::string ShadingControl::shadingType() const { + return getImpl()->shadingType(); +} + boost::optional ShadingControl::construction() const { return getImpl()->construction(); } @@ -682,10 +792,6 @@ boost::optional ShadingControl::shadingMaterial() const { return getImpl()->shadingMaterial(); } -std::string ShadingControl::shadingType() const { - return getImpl()->shadingType(); -} - std::string ShadingControl::shadingControlType() const { return getImpl()->shadingControlType(); } @@ -702,24 +808,32 @@ boost::optional ShadingControl::setpoint() const { return getImpl()->setpoint(); } -bool ShadingControl::isSetpointDefaulted() const{ +bool ShadingControl::isSetpointDefaulted() const { return getImpl()->isSetpointDefaulted(); } -bool ShadingControl::setSetpoint(double setpoint){ - return getImpl()->setSetpoint(setpoint); +bool ShadingControl::glareControlIsActive() const { + return getImpl()->glareControlIsActive(); } -void ShadingControl::resetSetpoint(){ - getImpl()->resetSetpoint(); +std::string ShadingControl::typeofSlatAngleControlforBlinds() const { + return getImpl()->typeofSlatAngleControlforBlinds(); +} + +bool ShadingControl::isTypeofSlatAngleControlforBlindsDefaulted() const { + return getImpl()->isTypeofSlatAngleControlforBlindsDefaulted(); +} + +boost::optional ShadingControl::slatAngleSchedule() const { + return getImpl()->slatAngleSchedule(); } boost::optional ShadingControl::setpoint2() const { return getImpl()->setpoint2(); } -bool ShadingControl::setSetpoint2(double setpoint2){ - return getImpl()->setSetpoint2(setpoint2); +std::string ShadingControl::multipleSurfaceControlType() const { + return getImpl()->multipleSurfaceControlType(); } bool ShadingControl::setShadingType(const std::string& shadingType){ @@ -742,16 +856,45 @@ void ShadingControl::resetSchedule(){ getImpl()->resetSchedule(); } -std::string ShadingControl::multipleSurfaceControlType() const { - return getImpl()->multipleSurfaceControlType(); +bool ShadingControl::setSetpoint(double setpoint){ + return getImpl()->setSetpoint(setpoint); } +void ShadingControl::resetSetpoint(){ + getImpl()->resetSetpoint(); +} -bool ShadingControl::setMultipleSurfaceControlType(const std::string& multipleSurfaceControlType){ - return getImpl()->setMultipleSurfaceControlType(multipleSurfaceControlType); +bool ShadingControl::setGlareControlIsActive(bool glareControlIsActive){ + return getImpl()->setGlareControlIsActive(glareControlIsActive); +} + +void ShadingControl::resetGlareControlIsActive(){ + getImpl()->resetGlareControlIsActive(); +} + +bool ShadingControl::setTypeofSlatAngleControlforBlinds(const std::string& typeofSlatAngleControlforBlinds){ + return getImpl()->setTypeofSlatAngleControlforBlinds(typeofSlatAngleControlforBlinds); +} + +void ShadingControl::resetTypeofSlatAngleControlforBlinds(){ + getImpl()->resetTypeofSlatAngleControlforBlinds(); } +bool ShadingControl::setSlatAngleSchedule(const Schedule& slatAngleSchedule){ + return getImpl()->setSlatAngleSchedule(slatAngleSchedule); +} +void ShadingControl::resetSlatAngleSchedule(){ + getImpl()->resetSlatAngleSchedule(); +} + +bool ShadingControl::setSetpoint2(double setpoint2){ + return getImpl()->setSetpoint2(setpoint2); +} + +bool ShadingControl::setMultipleSurfaceControlType(const std::string& multipleSurfaceControlType){ + return getImpl()->setMultipleSurfaceControlType(multipleSurfaceControlType); +} // Extensible Fields diff --git a/src/model/ShadingControl.hpp b/src/model/ShadingControl.hpp index 6da984f15bc..1abb9a2514a 100644 --- a/src/model/ShadingControl.hpp +++ b/src/model/ShadingControl.hpp @@ -80,12 +80,12 @@ class MODEL_API ShadingControl : public ResourceObject { /** @name Getters */ //@{ + std::string shadingType() const; + boost::optional construction() const; boost::optional shadingMaterial() const; - std::string shadingType() const; - std::string shadingControlType() const; bool isShadingControlTypeDefaulted() const; @@ -96,6 +96,14 @@ class MODEL_API ShadingControl : public ResourceObject { bool isSetpointDefaulted() const; // TODO: This makes little sense. Based on the shadingControlType, it's basically required. There's a default harcoded only for OnIfHighSolarOnWindow + bool glareControlIsActive() const; + + std::string typeofSlatAngleControlforBlinds() const; + + bool isTypeofSlatAngleControlforBlindsDefaulted() const; + + boost::optional slatAngleSchedule() const; + boost::optional setpoint2() const; std::string multipleSurfaceControlType() const; @@ -121,6 +129,18 @@ class MODEL_API ShadingControl : public ResourceObject { void resetSetpoint(); // TODO: makes little sense like isSetpointDefaulted + bool setGlareControlIsActive(bool glareControlIsActive); + + void resetGlareControlIsActive(); + + bool setTypeofSlatAngleControlforBlinds(const std::string& typeofSlatAngleControlforBlinds); + + void resetTypeofSlatAngleControlforBlinds(); + + bool setSlatAngleSchedule(const Schedule& slatAngleSchedule); + + void resetSlatAngleSchedule(); + bool setSetpoint2(double setpoint2); bool setMultipleSurfaceControlType(const std::string& multipleSurfaceControlType); @@ -129,7 +149,6 @@ class MODEL_API ShadingControl : public ResourceObject { /** @name Other */ //@{ - // Check if the current ShadingControlType requires Setpoint(1) bool isControlTypeValueNeedingSetpoint1(); // Check if the current ShadingControlType requires Setpoint(2) @@ -140,6 +159,9 @@ class MODEL_API ShadingControl : public ResourceObject { // Check if the current ShadingControlType requires a Schedule bool isControlTypeValueRequiringSchedule(); + // Check if the current ShadingType allows a Slat Angle Control + bool isTypeValueAllowingSlatAngleControl(); + // Extensible: Surfaces std::vector subSurfaces() const; unsigned int numberofSubSurfaces() const; diff --git a/src/model/ShadingControl_Impl.hpp b/src/model/ShadingControl_Impl.hpp index 35b1791c513..1280e935646 100644 --- a/src/model/ShadingControl_Impl.hpp +++ b/src/model/ShadingControl_Impl.hpp @@ -63,7 +63,6 @@ namespace detail { virtual ~ShadingControl_Impl() {} - //@} /** @name Virtual Methods */ @@ -87,15 +86,18 @@ namespace detail { // **Requires** a Schedule static bool isControlTypeValueRequiringSchedule(const std::string& controlType); + // **Allows** a slat angle control + static bool isTypeValueAllowingSlatAngleControl(const std::string& type); + /** @name Getters */ //@{ + std::string shadingType() const; + boost::optional construction() const; boost::optional shadingMaterial() const; - std::string shadingType() const; - std::string shadingControlType() const; bool isShadingControlTypeDefaulted() const; @@ -106,6 +108,14 @@ namespace detail { bool isSetpointDefaulted() const; + bool glareControlIsActive() const; + + std::string typeofSlatAngleControlforBlinds() const; + + bool isTypeofSlatAngleControlforBlindsDefaulted() const; + + boost::optional slatAngleSchedule() const; + boost::optional setpoint2() const; std::string multipleSurfaceControlType() const; @@ -128,6 +138,18 @@ namespace detail { void resetSetpoint(); + bool setGlareControlIsActive(bool glareControlIsActive); + + void resetGlareControlIsActive(); + + bool setTypeofSlatAngleControlforBlinds(const std::string& typeofSlatAngleControlforBlinds); + + void resetTypeofSlatAngleControlforBlinds(); + + bool setSlatAngleSchedule(const Schedule& slatAngleSchedule); + + void resetSlatAngleSchedule(); + bool setSetpoint2(double setpoint2); // Impl only @@ -155,7 +177,6 @@ namespace detail { bool setSubSurfaces(const std::vector &subSurfaces); void removeAllSubSurfaces(); - //@} protected: diff --git a/src/model/test/ShadingControl_GTest.cpp b/src/model/test/ShadingControl_GTest.cpp index 756fa035e7e..0f291e7597e 100644 --- a/src/model/test/ShadingControl_GTest.cpp +++ b/src/model/test/ShadingControl_GTest.cpp @@ -63,6 +63,7 @@ TEST_F(ModelFixture, ShadingControl_Construction) { EXPECT_EQ(construction.handle(), shadingControl.construction()->handle()); EXPECT_FALSE(shadingControl.shadingMaterial()); EXPECT_EQ("InteriorBlind", shadingControl.shadingType()); + EXPECT_TRUE(shadingControl.isTypeValueAllowingSlatAngleControl()); EXPECT_EQ("OnIfHighSolarOnWindow", shadingControl.shadingControlType()); EXPECT_FALSE(shadingControl.schedule()); @@ -91,6 +92,7 @@ TEST_F(ModelFixture,ShadingControl_Material) { ASSERT_TRUE(shadingControl.shadingMaterial()); EXPECT_EQ(blind.handle(), shadingControl.shadingMaterial()->handle()); EXPECT_EQ("InteriorBlind", shadingControl.shadingType()); + EXPECT_TRUE(shadingControl.isTypeValueAllowingSlatAngleControl()); EXPECT_EQ("OnIfHighSolarOnWindow", shadingControl.shadingControlType()); EXPECT_FALSE(shadingControl.schedule()); @@ -242,6 +244,7 @@ TEST_F(ModelFixture, ShadingControl_ShadingControlTypeLogic) { EXPECT_FALSE(sc.isControlTypeValueNeedingSetpoint1()); EXPECT_FALSE(sc.isControlTypeValueNeedingSetpoint2()); EXPECT_FALSE(sc.isControlTypeValueAllowingSchedule()); + EXPECT_TRUE(sc.isTypeValueAllowingSlatAngleControl()); EXPECT_FALSE(sc.setSetpoint(30.0)); EXPECT_FALSE(sc.setSetpoint2(500.0)); EXPECT_FALSE(sc.setSchedule(sch)); @@ -254,6 +257,7 @@ TEST_F(ModelFixture, ShadingControl_ShadingControlTypeLogic) { EXPECT_TRUE(sc.isControlTypeValueNeedingSetpoint1()); EXPECT_TRUE(sc.isControlTypeValueNeedingSetpoint2()); EXPECT_TRUE(sc.isControlTypeValueAllowingSchedule()); + EXPECT_TRUE(sc.isTypeValueAllowingSlatAngleControl()); EXPECT_TRUE(sc.setSetpoint(30.0)); EXPECT_TRUE(sc.setSetpoint2(500.0)); EXPECT_TRUE(sc.setSchedule(sch)); @@ -281,6 +285,7 @@ TEST_F(ModelFixture, ShadingControl_ShadingControlTypeLogic) { EXPECT_TRUE(sc.isControlTypeValueNeedingSetpoint1()); EXPECT_FALSE(sc.isControlTypeValueNeedingSetpoint2()); EXPECT_TRUE(sc.isControlTypeValueAllowingSchedule()); + EXPECT_TRUE(sc.isTypeValueAllowingSlatAngleControl()); // Setpoint 1 has been cleared because we're switching Shading Control Type and that was the historical behavior EXPECT_FALSE(sc.setpoint2()); @@ -289,4 +294,22 @@ TEST_F(ModelFixture, ShadingControl_ShadingControlTypeLogic) { // Schedule is kept, user should be responsible to ensure the Schedule still makes sense, instead of always clearing it EXPECT_TRUE(sc.schedule()); + EXPECT_TRUE(sc.isTypeofSlatAngleControlforBlindsDefaulted()); + EXPECT_TRUE(sc.setSlatAngleSchedule(sch)); + EXPECT_TRUE(sc.slatAngleSchedule()); + EXPECT_FALSE(sc.isTypeofSlatAngleControlforBlindsDefaulted()); + EXPECT_EQ("ScheduledSlatAngle", sc.typeofSlatAngleControlforBlinds()); + sc.resetSlatAngleSchedule(); + EXPECT_FALSE(sc.slatAngleSchedule()); + EXPECT_TRUE(sc.isTypeofSlatAngleControlforBlindsDefaulted()); + EXPECT_TRUE(sc.setTypeofSlatAngleControlforBlinds("BlockBeamSolar")); + EXPECT_FALSE(sc.isTypeofSlatAngleControlforBlindsDefaulted()); + EXPECT_EQ("BlockBeamSolar", sc.typeofSlatAngleControlforBlinds()); + sc.resetTypeofSlatAngleControlforBlinds(); + EXPECT_TRUE(sc.isTypeofSlatAngleControlforBlindsDefaulted()); + EXPECT_FALSE(sc.glareControlIsActive()); + EXPECT_TRUE(sc.setGlareControlIsActive(true)); + EXPECT_TRUE(sc.glareControlIsActive()); + sc.resetGlareControlIsActive(); + EXPECT_FALSE(sc.glareControlIsActive()); } From 7bea01bebb4e49428cba3d2f26e4a23fdb828ee3 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Wed, 16 Sep 2020 11:18:47 +0200 Subject: [PATCH 47/49] Another typo in getAutosizedValue --- src/model/ModelObject.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/model/ModelObject.cpp b/src/model/ModelObject.cpp index 1e14964b41c..0cf457d936b 100644 --- a/src/model/ModelObject.cpp +++ b/src/model/ModelObject.cpp @@ -326,7 +326,7 @@ namespace detail { AND Value = ?;)"; boost::optional> rowNames = model().sqlFile().get().execAndReturnVectorOfString(rowsQuery, - // Bind args + // bindArgs sqlName); // Warn if the query failed @@ -346,7 +346,7 @@ namespace detail { for (std::string rowName : rowNames.get()) { std::string rowCheckQuery = R"( - SELECT RowName FROM TabularDataWithStrings + SELECT Value FROM TabularDataWithStrings WHERE ReportName = 'Initialization Summary' AND ReportForString = 'Entire Facility' AND TableName = 'Component Sizing Information' @@ -366,9 +366,10 @@ namespace detail { AND ReportForString = 'Entire Facility' AND TableName = 'Component Sizing Information' AND ColumnName='Value' - AND RowName = ? - AND Value = ?;)"; - boost::optional val = model().sqlFile().get().execAndReturnFirstDouble(valQuery, rowName); + AND RowName = ?;)"; + boost::optional val = model().sqlFile().get().execAndReturnFirstDouble(valQuery, + // bindArgs + rowName); // Check if the query succeeded if (val) { result = val.get(); From 81be659bd2c23cdba2278576432ff20a69f56868 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Wed, 16 Sep 2020 08:05:55 -0700 Subject: [PATCH 48/49] Updates to release notes draft. --- .../doc/ReleaseNotes/OpenStudio_Release_Notes_3_1_0.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_1_0.md b/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_1_0.md index 7ab0bf09a50..131ed0514d7 100644 --- a/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_1_0.md +++ b/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_1_0.md @@ -9,7 +9,6 @@ These release notes describe version 3.1.0 of the OpenStudio SDK developed by th - Installation Notes - OpenStudio SDK: Changelog - # Overview Following an important announcement related to future development of the OpenStudio Application released in September 2019 ([A Shift in BTO’s BEM Strategy: A New Future for the OpenStudio Application](https://www.openstudio.net/new-future-for-openstudio-application)), **this release marks the first installment of the separated OpenStudio SDK from the Application.** @@ -45,6 +44,7 @@ OpenStudio 3.x now uses **Ruby 2.5.5** as the supported version (2.2.4 previousl As usual, you can refer to the **[OpenStudio Compatibility Matrix](https://github.com/NREL/OpenStudio/wiki/OpenStudio-Version-Compatibility-Matrix)** for more information. + ## Installation Steps - Download and install OpenStudio SDK and/or [OpenStudioApplication]( depending on your needs. Select components for installation. Note that OpenStudio Application is a standalone app and does not require you to install OpenStudio SDK. @@ -67,13 +67,13 @@ A number of API-breaking changes have been implemented in OpenStudio 3.1.0: * [#3959](https://github.com/NREL/OpenStudio/pull/3959) - Also included some improvements in the generated C# bindings by reducing build warnings and properly exposing some types via SWIG * `ScheduleTypeKey` (which is normally only use by OpenStudio internals in ScheduleTypeRegistry checks) previously mapped to a `std::pair` which was SWIGed in ruby as an Array of strings of size two, but improperly exposed in C#. It now uses a dedicated helper class with two methods `ScheduleTypeKey::className()` and `ScheduleTypeKey::scheduleDisplayName()` * [#4066](https://github.com/NREL/OpenStudio/pull/4066) - Multiple shading controls referenced by a single subsurface - * `SubSurface` was historically the one referencing the `ShadingControl` object. Now it's a many-to-many relationship where `ShadingControl` has an extensible 'Surface Name' field, and multiple `ShadingControl` can reference the same `SubSurface`. This is trickling down from a change introduced in EnergyPlus version 9.4, and specifically in PR [NREL/EnergyPlus#8196](https://github.com/NREL/EnergyPlus/pull/8196) - * Methods in `SubSurface` have been deprecated but keep for backward compatibility. They will be removed in a future version of OpenStudio: + * `SubSurface` was historically the one referencing the `ShadingControl` object. Now it's a many-to-many relationship where `ShadingControl` has an extensible 'Sub Surface Name' field, and multiple `ShadingControl` objects can reference the same `SubSurface`. This is trickling down from a change introduced in EnergyPlus version 9.4, and specifically in PR [NREL/EnergyPlus#8196](https://github.com/NREL/EnergyPlus/pull/8196) + * Methods in `SubSurface` have been deprecated but are kept for backward compatibility. They will be removed in a future version of OpenStudio: * `shadingControl()`: prefer `shadingControls()` * `setShadingControl(ShadingControl&)`: use `addShadingControl(SubSurface&)`, `addShadingControls(std::vector&)` or `setShadingControls(std::vector&)` * `resetShadingControl()`: use `removeAllShadingControls()` instead * All Shading Control Type values should now be supported. Refer to issue [#4074](https://github.com/NREL/OpenStudio/issues/4074) for more information - * Fields `Setpoint2` and 'Multiple Surface Control Type' are now implemented as well + * Fields 'Glare Control Is Active', 'Type of Slat Angle Control for Blinds', 'Slat Angle Schedule Name', 'Setpoint2', and 'Multiple Surface Control Type' are now implemented as well ## Minor changes: From 142330d93c0f7725fee69f1f63f08e85342bdc57 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 17 Sep 2020 14:47:41 +0200 Subject: [PATCH 49/49] Add static typeofSlatAngleControlforBlindsValues --- src/model/ShadingControl.cpp | 5 +++++ src/model/ShadingControl.hpp | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/model/ShadingControl.cpp b/src/model/ShadingControl.cpp index 41c3afca2a6..89153697a19 100644 --- a/src/model/ShadingControl.cpp +++ b/src/model/ShadingControl.cpp @@ -755,6 +755,11 @@ std::vector ShadingControl::shadingControlTypeValues() { OS_ShadingControlFields::ShadingControlType); } +std::vector ShadingControl::typeofSlatAngleControlforBlindsValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), + OS_ShadingControlFields::TypeofSlatAngleControlforBlinds); +} + std::vector ShadingControl::multipleSurfaceControlTypeValues() { return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), OS_ShadingControlFields::MultipleSurfaceControlType); diff --git a/src/model/ShadingControl.hpp b/src/model/ShadingControl.hpp index 1abb9a2514a..e62f90cfe4e 100644 --- a/src/model/ShadingControl.hpp +++ b/src/model/ShadingControl.hpp @@ -75,6 +75,8 @@ class MODEL_API ShadingControl : public ResourceObject { static std::vector shadingControlTypeValues(); + static std::vector typeofSlatAngleControlforBlindsValues(); + static std::vector multipleSurfaceControlTypeValues(); /** @name Getters */ @@ -96,7 +98,7 @@ class MODEL_API ShadingControl : public ResourceObject { bool isSetpointDefaulted() const; // TODO: This makes little sense. Based on the shadingControlType, it's basically required. There's a default harcoded only for OnIfHighSolarOnWindow - bool glareControlIsActive() const; + bool glareControlIsActive() const; std::string typeofSlatAngleControlforBlinds() const;