Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple shading controls referenced by a single subsurface #4066

Merged
merged 52 commits into from
Sep 18, 2020
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
691f6a7
Store subsurface on shading control instead of shading control on sub…
joseph-robertson Sep 4, 2020
71318ce
Stub new methods for subsurface and shading control.
joseph-robertson Sep 4, 2020
f9df752
Start filling out methods for shading control.
joseph-robertson Sep 8, 2020
4c453f5
Start filling out methods for sub surface.
joseph-robertson Sep 8, 2020
92fdd7b
Continue to fill out sub surface methods.
joseph-robertson Sep 8, 2020
f84e710
Add new model test for sub surface.
joseph-robertson Sep 8, 2020
b282d03
Add new model test for shading control.
joseph-robertson Sep 8, 2020
b14c8f7
Clean up some model and test files.
joseph-robertson Sep 8, 2020
afda1a1
Start a vt for sub surface and shading control.
joseph-robertson Sep 8, 2020
4ab9318
Updates to source files after review.
joseph-robertson Sep 10, 2020
8b1664b
Make some changes to ShadingControl.
jmarrec Sep 11, 2020
3e236f1
Remove the deprecated functions from the Impl API to fix compiler error
jmarrec Sep 11, 2020
2f008b3
const-correctness; ,no ABI break: cannot pass cosnt ShadingCOntrol& w…
jmarrec Sep 11, 2020
ff629b3
ABI break of now-deprecated function
jmarrec Sep 11, 2020
373d248
Update description
jmarrec Sep 11, 2020
87820ee
Update FT to avoid error using deprecated. is this still needed? @jos…
jmarrec Sep 11, 2020
5dd85a1
Implement new MultipleSurfaceControlType field in Shading Control
jmarrec Sep 11, 2020
6619cbf
The Radiance Forward Translator also needs to be update. I'm just mak…
jmarrec Sep 11, 2020
3c610c1
VT & FT for MultipleSurfaceControlType
jmarrec Sep 11, 2020
b682148
There's a problem with the extensibles
jmarrec Sep 11, 2020
85fdf12
Write a VT test and adjust VT: Always deal with OS:SubSurface, and pr…
jmarrec Sep 11, 2020
cfdf3ee
typo in VT test
jmarrec Sep 11, 2020
257fb6a
Fix, updates to idd.
joseph-robertson Sep 11, 2020
64d54a7
Skip adding a subsurface that already exists.
joseph-robertson Sep 11, 2020
bb37994
Update and improve tests.
joseph-robertson Sep 11, 2020
bd53023
Model test for ShadingControl 'Multiple Surface Control Type' field (…
jmarrec Sep 14, 2020
04e8c6e
Extend Gtest for clone and removeSubSurface
jmarrec Sep 14, 2020
c858e5f
Proposed implementation of ShadingControl::clone & if remove subSurfa…
jmarrec Sep 14, 2020
4859e45
typo in test: wasn't testing the right property.
jmarrec Sep 14, 2020
cb6ceb0
Partial classes for C#: reimpling ShadingControl methods that use Sub…
jmarrec Sep 14, 2020
c5c99f2
Add a TODO
jmarrec Sep 14, 2020
48aab86
Add rt and more tests.
joseph-robertson Sep 14, 2020
8ea432e
Fix rt and update rt tests.
joseph-robertson Sep 14, 2020
fbfd1db
Improve shading control rt and tests.
joseph-robertson Sep 15, 2020
005f0a4
Merge branch 'develop' into multiple-shading-controls
joseph-robertson Sep 15, 2020
80ffb2f
Catch the case where neither Shading Material nor Construction are as…
jmarrec Sep 15, 2020
7ee6d21
Extend the ShadingControl FT test to check all fields currently avail…
jmarrec Sep 15, 2020
d6041d8
Fix #4074 - Implement Setpoint2 and support all Shading Control Type…
jmarrec Sep 15, 2020
1a92506
Exit RT for ShadingControl if neither the shadingMaterial nor Constru…
jmarrec Sep 15, 2020
f95045f
Fix RT by using a Construction instead of the not RT'ed WindowMateria…
jmarrec Sep 15, 2020
b06fd15
Add some release notes for this PR
jmarrec Sep 15, 2020
9d5b2ac
Missing an override keyword
jmarrec Sep 15, 2020
361e509
#4074 Followup: add test for logic, and avoid clearing Setpoint2/Sche…
jmarrec Sep 15, 2020
33df578
Typo in C# partial class
jmarrec Sep 15, 2020
b751a34
Unrelated C# fixed while I'm at it.
jmarrec Sep 15, 2020
bec2af2
Unrelated issue in ModelObject::getAutosizedValue
jmarrec Sep 15, 2020
64f1a6d
Include glare and slat angle control in api.
joseph-robertson Sep 15, 2020
abe551f
Merge branch 'multiple-shading-controls' of github.com:NREL/OpenStudi…
joseph-robertson Sep 15, 2020
7bea01b
Another typo in getAutosizedValue
jmarrec Sep 16, 2020
81be659
Updates to release notes draft.
joseph-robertson Sep 16, 2020
142330d
Add static typeofSlatAngleControlforBlindsValues
jmarrec Sep 17, 2020
e454bfa
Merge remote-tracking branch 'origin/develop' into multiple-shading-c…
jmarrec Sep 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_1_0.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string, std::string>` 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<SubSurface>&)` or `setShadingControls(std::vector<SubSurface>&)`
* `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
jmarrec marked this conversation as resolved.
Show resolved Hide resolved

## Minor changes:

Expand Down
28 changes: 19 additions & 9 deletions resources/model/OpenStudio.idd
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -5750,7 +5744,8 @@ OS:SubSurface,
\units m

OS:ShadingControl,
\min-fields 4
\extensible:1
\min-fields 15
A1 , \field Handle
\type handle
\required-field
Expand Down Expand Up @@ -5878,13 +5873,28 @@ 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 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 1
\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.
Expand Down
2 changes: 2 additions & 0 deletions src/energyplus/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -650,6 +651,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
Expand Down
3 changes: 2 additions & 1 deletion src/energyplus/ForwardTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,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<ShadingControl> shadingControls = model.getConcreteModelObjects<ShadingControl>();
Comment on lines +448 to 451
Copy link
Collaborator

Choose a reason for hiding this comment

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

  • TODO

Expand Down Expand Up @@ -477,7 +478,7 @@ Workspace ForwardTranslator::translateModelPrivate( model::Model & model, bool f
thisZoneHandleSet.insert(zoneHandle);
ShadingControl clone = shadingControl.clone(model).cast<ShadingControl>();
// 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<ShadingControl>()));
Expand Down
74 changes: 54 additions & 20 deletions src/energyplus/ForwardTranslator/ForwardTranslateShadingControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,32 @@ boost::optional<IdfObject> ForwardTranslator::translateShadingControl(model::Sha
std::vector<SubSurface> 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;
}

// 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;
}

Expand Down Expand Up @@ -90,8 +115,6 @@ boost::optional<IdfObject> 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) {
Expand All @@ -118,8 +141,6 @@ boost::optional<IdfObject> 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");
Expand All @@ -135,30 +156,43 @@ boost::optional<IdfObject> ForwardTranslator::translateShadingControl(model::Sha
idfObject.setString(WindowShadingControlFields::ShadingDeviceMaterialName, shadingMaterial->name().get());
}

boost::optional<Schedule> schedule = modelObject.schedule();
if (schedule) {
idfObject.setString(WindowShadingControlFields::ScheduleName, schedule->name().get());
idfObject.setString(WindowShadingControlFields::ShadingControlIsScheduled, "Yes");
if (modelObject.isControlTypeValueAllowingSchedule()) {
boost::optional<Schedule> 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<double> 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());
}

idfObject.setString(WindowShadingControlFields::GlareControlIsActive, "No");
if (modelObject.glareControlIsActive() || istringEqual("OnIfHighGlare", shadingControlType)) {
idfObject.setString(WindowShadingControlFields::GlareControlIsActive, "Yes");
} else {
idfObject.setString(WindowShadingControlFields::GlareControlIsActive, "No");
}

//idfObject.setString(WindowShadingControlFields::TypeofSlatAngleControlforBlinds, "FixedSlatAngle");
boost::optional<Schedule> 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.setDouble(WindowShadingControlFields::Setpoint2, 0.0);
idfObject.setString(WindowShadingControlFields::MultipleSurfaceControlType, modelObject.multipleSurfaceControlType());

idfObject.clearExtensibleGroups();
for (const SubSurface& subSurface : subSurfaces) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 5 additions & 0 deletions src/energyplus/ReverseTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,11 @@ boost::optional<ModelObject> ReverseTranslator::translateAndMapWorkspaceObject(c
modelObject = translateWindowPropertyFrameAndDivider(workspaceObject);
break;
}
case openstudio::IddObjectType::WindowShadingControl:
{
modelObject = translateWindowShadingControl(workspaceObject);
break;
}
case openstudio::IddObjectType::Zone:
{
modelObject = translateZone(workspaceObject);
Expand Down
2 changes: 2 additions & 0 deletions src/energyplus/ReverseTranslator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,8 @@ class ENERGYPLUS_API ReverseTranslator {

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

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

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

boost::optional<model::ModelObject> translateZoneAirHeatBalanceAlgorithm(const WorkspaceObject & workspaceObject);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<model::ShadingControl>()){
// subSurface->setShadingControl(modelObject->cast<model::ShadingControl>());
// }
//}

target = workspaceObject.getTarget(openstudio::FenestrationSurface_DetailedFields::FrameandDividerName);
if (target){
OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
Expand Down
Loading