Skip to content
New issue

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

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

Already on GitHub? # to your account

Addresses #3216, wrong OS:Daylighting:Control rotation angle translated #3858

Merged
merged 6 commits into from
Feb 14, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -467,12 +467,12 @@ boost::optional<IdfObject> ForwardTranslator::translateThermalZone( ThermalZone
LOG(Warn, "Rotation of " << primaryDaylightingControl->psiRotationAroundXAxis() << " degrees about X axis not mapped for OS:Daylighting:Control " << primaryDaylightingControl->name().get());
}

if (primaryDaylightingControl->phiRotationAroundZAxis() != 0.0){
LOG(Warn, "Rotation of " << primaryDaylightingControl->phiRotationAroundZAxis() << " degrees about Z axis not mapped for OS:Daylighting:Control " << primaryDaylightingControl->name().get());
if (primaryDaylightingControl->thetaRotationAroundYAxis() != 0.0){
LOG(Warn, "Rotation of " << primaryDaylightingControl->thetaRotationAroundYAxis() << " degrees about Y axis not mapped for OS:Daylighting:Control " << primaryDaylightingControl->name().get());
}

// glare
double glareAngle = -openstudio::radToDeg(primaryDaylightingControl->thetaRotationAroundYAxis());
double glareAngle = primaryDaylightingControl->phiRotationAroundZAxis();
Copy link
Collaborator

Choose a reason for hiding this comment

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

The radToDeg shouldn't be there, great catch. Everything stored as deg. OpenStudio uses euler angles internally only

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the "-" was needed actually. @eringold has a file that is throwing in 3.2.1 but worked as 2.9.0, and I tracked it down to here.

   ** Severe  ** <root>[Daylighting:Controls][TZ_L6_BKS_Corridor/Toilets DaylightingControls][glare_calculation_azimuth_angle_of_view_direction_clockwise_from_zone_y_axis] - "-0.000000" - Expected number greater than or equal to 0.000000

Copy link
Contributor

Choose a reason for hiding this comment

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

Agree that the negative sign should stay. If E+ requires rotation angle to be positive you could also do a:

if (angle < 0){
  angle += 360;
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

By "also" you mean "in addition" right?

If I follow correctly, openstudio's convention for phi is counterclockwise, which is the opposite of the convention for phi in E+ (clockwise)?

https://bigladdersoftware.com/epx/docs/9-5/input-output-reference/group-daylighting.html#field-glare-calculation-azimuth-angle-of-view-direction-clockwise-from-zone-y-axis

do you recall if it's documented somewhere (at least in code comments somewhere)?

Only thing I could find is this:

// rotate negative amount around the z axis, EnergyPlus defines rotation opposite to OpenStudio

Copy link
Contributor

Choose a reason for hiding this comment

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

@jmarrec yes I meant in addition, if after applying the negative sign the result for E+ is still negative you can add 360. The angle mod 360 might also work, you could try it with a unit test. If you use the right hand rule, https://en.wikipedia.org/wiki/Right-hand_rule, with y pointing North and x pointing East, then a positive rotation around the z-axis (pointing up) is counter-clockwise when viewed from above. The E+ convention of positive rotation in the clockwise direction is backwards to most conventions.

daylightingControlObject.setDouble(
Daylighting_ControlsFields::GlareCalculationAzimuthAngleofViewDirectionClockwisefromZoneyAxis,
glareAngle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ OptionalModelObject ReverseTranslator::translateDaylightingControls( const Works

d = workspaceObject.getDouble(Daylighting_ControlsFields::GlareCalculationAzimuthAngleofViewDirectionClockwisefromZoneyAxis);
if (d){
daylightingControl.setThetaRotationAroundYAxis(-degToRad(*d));
daylightingControl.setPhiRotationAroundZAxis(*d);
}

d = workspaceObject.getDouble(Daylighting_ControlsFields::MaximumAllowableDiscomfortGlareIndex);
Expand Down
24 changes: 24 additions & 0 deletions src/energyplus/Test/DaylightingControl_GTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,27 @@ TEST_F(EnergyPlusFixture,ForwardTranslator_DaylightingControl_TwoControl)

EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Daylighting_Controls).size());
}

TEST_F(EnergyPlusFixture,ForwardTranslator_DaylightingControl_3216)
{
Model model;

ThermalZone thermalZone(model);
Space space(model);
space.setThermalZone(thermalZone);

DaylightingControl daylightingControl(model);
daylightingControl.setThetaRotationAroundYAxis(90.0);
daylightingControl.setPhiRotationAroundZAxis(180.0);

EXPECT_TRUE(thermalZone.setPrimaryDaylightingControl(daylightingControl));

ForwardTranslator ft;
Workspace w = ft.translateModel(model);

WorkspaceObjectVector idfObjs = w.getObjectsByType(IddObjectType::Daylighting_Controls);
ASSERT_EQ(1u, idfObjs.size());
WorkspaceObject idf_d(idfObjs[0]);

EXPECT_EQ(daylightingControl.phiRotationAroundZAxis(), idf_d.getDouble(Daylighting_ControlsFields::GlareCalculationAzimuthAngleofViewDirectionClockwisefromZoneyAxis).get());
}
42 changes: 42 additions & 0 deletions src/energyplus/Test/ReverseTranslator_GTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
#include "../../model/PerformancePrecisionTradeoffs_Impl.hpp"
#include "../../model/ZonePropertyUserViewFactorsBySurfaceName.hpp"
#include "../../model/ZonePropertyUserViewFactorsBySurfaceName_Impl.hpp"
#include "../../model/DaylightingControl.hpp"
#include "../../model/DaylightingControl_Impl.hpp"

#include "../../utilities/core/Optional.hpp"
#include "../../utilities/core/Checksum.hpp"
Expand All @@ -99,6 +101,8 @@
#include <utilities/idd/PerformancePrecisionTradeoffs_FieldEnums.hxx>
#include <utilities/idd/ZoneList_FieldEnums.hxx>
#include <utilities/idd/GlobalGeometryRules_FieldEnums.hxx>
#include <utilities/idd/Daylighting_Controls_FieldEnums.hxx>
#include <utilities/idd/Daylighting_ReferencePoint_FieldEnums.hxx>

#include "../../utilities/time/Time.hpp"

Expand Down Expand Up @@ -968,3 +972,41 @@ TEST_F(EnergyPlusFixture, ReverseTranslator_ZoneList)

}
}

TEST_F(EnergyPlusFixture, ReverseTranslator_DaylightingControl_3216) {
openstudio::Workspace workspace(openstudio::StrictnessLevel::None, openstudio::IddFileType::EnergyPlus);

openstudio::IdfObject idfObject3(openstudio::IddObjectType::Daylighting_ReferencePoint);
idfObject3.setName("Reference Point 1");
idfObject3.setDouble(Daylighting_ReferencePointFields::XCoordinateofReferencePoint, 15);
idfObject3.setDouble(Daylighting_ReferencePointFields::YCoordinateofReferencePoint, 16.05);
idfObject3.setDouble(Daylighting_ReferencePointFields::ZCoordinateofReferencePoint, 0);

openstudio::WorkspaceObject epDaylightingReferencePoint1 = workspace.addObject(idfObject3).get();

openstudio::IdfObject idfObject1(openstudio::IddObjectType::Daylighting_Controls);
idfObject1.setDouble(Daylighting_ControlsFields::GlareCalculationAzimuthAngleofViewDirectionClockwisefromZoneyAxis, 180.0);
IdfExtensibleGroup group1 = idfObject1.pushExtensibleGroup();
group1.setString(0, "Reference Point 1");
group1.setDouble(1, 1);
group1.setDouble(2, 500);

openstudio::WorkspaceObject epDaylightingControls = workspace.addObject(idfObject1).get();

openstudio::IdfObject idfObject2(openstudio::IddObjectType::Zone);

openstudio::WorkspaceObject epZone = workspace.addObject(idfObject2).get();

EXPECT_TRUE(epDaylightingControls.setPointer(Daylighting_ControlsFields::ZoneName, epZone.handle()));
EXPECT_TRUE(epDaylightingReferencePoint1.setPointer(Daylighting_ReferencePointFields::ZoneName, epZone.handle()));

ReverseTranslator trans;
ASSERT_NO_THROW(trans.translateWorkspace(workspace));
Model model = trans.translateWorkspace(workspace);

std::vector<DaylightingControl> daylightingControls = model.getModelObjects<DaylightingControl>();
ASSERT_EQ(1u, daylightingControls.size());
DaylightingControl daylightingControl = daylightingControls[0];
EXPECT_EQ(daylightingControl.name().get(), "Reference Point 1");
EXPECT_EQ(daylightingControl.phiRotationAroundZAxis(), 180.0);
}
1 change: 0 additions & 1 deletion src/energyplus/Test/ThermalZone_GTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,6 @@ TEST_F(EnergyPlusFixture,ForwardTranslator_ThermalZone_Daylighting)
Space space1(m);
space1.setThermalZone(z);


Point3dVector points;
points.push_back(Point3d(0, 0, 0));
points.push_back(Point3d(0, 1, 0));
Expand Down