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
Adding geometry-based methods #13
Conversation
Tests against Ruby v278 (locally).
# calculations (and avoid OpenStudio stdout errors/warnings), append the | ||
# last vertex of the original surface: each EnergyPlus edge must be | ||
# referenced (at least) twice (i.e. the 'leader line' between each of the | ||
# 3x original surfaces and each of the 'mini' holes must be doubled). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a first test, the US DOE SmallOffice Prototype core floor and ceiling (as well as its adjacent attic floor) are cut out to each receive a 2m x 2m mini surface insert. The 3x original (larger) surfaces must have their vertices extended to accommodate their smaller mini counterparts, i.e. holes:
Vertex winding for both the (larger) core and attic floors: a clockwise sequence for the outer edges (as seen from a bird's eye view), followed by a counterclockwise delineation of the mini hole (in the actual model, the opening is square and centred).
mini_attic_vtx << OpenStudio::Point3d.new(mini_w, mini_s, 3.05) | ||
mini_attic_vtx << OpenStudio::Point3d.new(mini_w, mini_n, 3.05) | ||
mini_attic = OpenStudio::Model::Surface.new(mini_attic_vtx, model) | ||
mini_attic.setName("Mini attic") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 2m x 2m mini surface centred in the attic floor. Here, the original floor (as well as its adjacent core ceiling) vertices are not yet extended (as described here). Although subsequent OpenStudio/EnergyPlus tests support this vertex extension operation, it does seem to prevent SketchUp from rendering such modified OpenStudio models. The OpenStudio Application renders the model just fine, yet this remains a challenge for SketchUp OpenStudio plugin users. Hopefully there's a workaround for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, SketchUp will detect this as an inner loop of the larger polygon, there is code that then runs to turn inner loops into subsurfaces (auto-classified as door, window, or skylight). Is that what you are seeing when you open this in SketchUp? It will be turned into a skylight? The way around that would be to add vertices to the outer polygon (like you did here #13 (comment)) so the smaller surface is technically adjacent and not "inside" the larger one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, SketchUp (2021) has difficulty with the vertex sequencing I illustrate in #13 (comment). SketchUp is unable to render the OSM geometry altogether. If one runs these OSut Rake tests (geo branch), 3x OSM files of interest are generated under spec/files/osms/out:
- mini.osm
- mini2.osm
- mini3.osm
None of these will render. Yet they render just fine with the OpenStudio Application (Geometry tab).
@@ -2708,8 +2712,9 @@ module M | |||
expect(core.floorArea).to be_within(TOL).of(149.66) | |||
core_volume = core.floorArea * 3.05 | |||
expect(core_volume).to be_within(TOL).of(core.volume) | |||
expect(attic.volume).to be_within(TOL).of(720.19) | |||
expect(attic.floorArea).to be_within(TOL).of(567.98) | |||
expect(attic.volume).to be_within(TOL).of(720.19) unless v < 350 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calculations of core and attic floor/ceiling surface areas (m2), as well as core and attic volumes (m3), remain consistent even with mini surfaces inserted in the centre of each. Reiterating that this requires sequencing vertices of the larger (original) surfaces, as described here. Simulation results remain consistent, regardless of Solar Distribution modes, as summarized here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should check the surface areas and zone volumes in the E+ results too. The reporting measure has an example here: https://github.com/NREL/openstudio-common-measures-gem/blob/develop/lib/measures/example_report/resources/os_lib_reporting_example.rb#L221 that shows how to query data out of the E+ tabular results. The eplusout.sql file has a table named tabulardatawithstrings
which follows the tables in the eplustbl.htm file. If you adjust the ReportName
, ReportForString
, TableName
, RowName
, ColumnName
, and Units
in the query you can get any of the other data in the eplustbl.htm file like the "Envelope Summary" or "Zone Summary"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the pointer, @macumber. Reported areas/volumes in the eplusout.htm do match these first 3x test results. Once I'm done, I'll look into automating an SQL test.
# office.osm FullInteriorAndExterior 247 GJ 3.8 UMH cool | ||
# mini.osm A FullInteriorAndExterior 247 GJ 4.0 UMH cool | ||
# mini.osm B FullExteriorWithReflections 248 GJ 3.8 UMH cool | ||
# mini.osm C FullInteriorAndExteriorWithReflections 247 GJ 3.8 UMH cool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consistent results using E+ v22.2, no warnings or errors.
# Mini as an interior courtyard: | ||
# - 4x new outdoor-facing walls (core) | ||
# - remove mini floor @Z0 and mini ceiling @Z3.05 | ||
# - attic mini floor facing outdoors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2nd test: This transforms the core space into a donut (i.e. a toroidal polytope), something considered problematic for OpenStudio. Not sure if this is strictly a v350 fix, but both area and volume calculations correctly reflect the intended changes - so do the E+ 22.2 simulation results.
# @param ratio [Double] internal mass surface / floor areas | ||
# | ||
# @return [Bool] true if successful | ||
# @return [Bool] false if invalid input (see logs) | ||
def genMass(model = nil, sps = [], ratio = 2.0) | ||
# This is largely adapted from OpenStudio-Standards | ||
def genMass(sps = OpenStudio::Model::SpaceVector.new, ratio = 2.0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Switch from input Arrays to ObjectVectors, whenever possible. Lightens argument validation.
# poly method (convex = true, uniqueness = true, collinearity = false). | ||
expect(vtx.size).to eq(3) | ||
expect(mod1.poly(vtx, true, true, false).size).to eq(3) | ||
expect(mod1.status.zero?).to be(true) | ||
triads = mod1.getTriads(vtx) | ||
expect(mod1.status.zero?).to be(true) | ||
expect(triads.size).to eq(3) | ||
|
||
# TO DO ... in progress. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the geometry methods are in flux, and so are their tests.
Gemfile
Outdated
@@ -1,3 +1,5 @@ | |||
source "https://rubygems.org" | |||
|
|||
gem "oslg", git: "https://github.com/rd2/oslg", branch: "yard" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests OSlg release candidate (passed).
door: 1.800, # insulated, unglazed steel door (single layer) | ||
window: 2.800, # e.g. patio doors (simple glazing) | ||
skylight: 3.500 # all skylight technologies | ||
}.freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatted this way is great for Yard.
|
||
log(ERR, "Invalid '#{id}' MIN/MAX (#{mth})") unless res[:min] && res[:max] | ||
res[:min] = values.min.is_a?(Numeric) ? values.min : nil | ||
res[:max] = values.max.is_a?(Numeric) ? values.max : nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few instances of refactoring code (more compact, easier).
|
||
stpts = M.setpoints(entry) | ||
expect(stpts[:heating].nil?).to be(false) | ||
expect(stpts[:heating]).to be_within(TOL).of(22.78) # radiant heating |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a zone equipment temperature setpoint test (independent of zone thermostat temperature setpoint).
@@ -2880,6 +2881,9 @@ def overlaps?(p1 = nil, p2 = nil, flat = true) | |||
return false if p1.empty? | |||
return false if p2.empty? | |||
|
|||
return true if fits?(p1, p2) | |||
return true if fits?(p2, p1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simpler to catch fit cases sooner.
return true if delta > TOL | ||
end | ||
|
||
false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revised logic. Catches unexpected (and unfortunately yet untested) cases where Boost-based join returns either polygon area for 2 side-by-side polygons.
# warning if aligned points aren't @Z =0, before 'flattening'. | ||
# | ||
# invalid("points (non-aligned)", mth, 1, WRN) unless xyz?(a, :z, 0) | ||
a = flatten(a).to_a unless xyz?(a, :z, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe better as a DEBUG log, but muting this for now. Upcoming methods will frequently need to project polygons unto each other (without sharing same 3D plane).
expect(surface.is_a?(OpenStudio::Model::LayeredConstruction)).to be(true) | ||
expect(surface).to_not be_nil | ||
expect(cls1.status).to be_zero | ||
expect(surface).to be_a(OpenStudio::Model::LayeredConstruction) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General revision, making better use of RSpec methods. Easier to consult.
|
||
# --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- # | ||
# CASE 2: None of the occupied spaces have outdoor-facing roofs, yet the | ||
# plenum above has 4x outdoor-facing roofs (each matches 1x space ceiling). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getRoofs fetches both outdoor-facing RoofCeiling surfaces, as well as those of a plenum/attic directly above.
end | ||
next unless overlaps?(ceiling, ruf) | ||
|
||
roofs << ruf unless roofs.include?(ruf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overlaps?
calls fits?
- redundant.
This builds upon the previous geometry PR towards automating sub surface generation (e.g. skylights). As a follow-up, this PR deals with automated well (or shaft) generation for skylights (or dormers, or roof monitors) designed to daylight occupied zones more than one floor below (e.g. wells completely spanning unoccupied plenums or attics, and/or multiple floors). For a single array of skylights, this involves inter alia:
The Figure illustrates a simplified version of the US DOE SmallOffice Prototype model (overhangs are left out), with an added skylights/well combo. The suggested implementation would raise a number of red flags for many experienced OpenStudio/EnergyPlus users/devs, notably concerning:
... affecting several key OpenStudio/EnergyPlus calculations:
By the end of this PR, it is hoped (!) that most of these challenges will be addressed/documented (if not solved). For instance, PixelCounting solves a large number of solar-related challenges (yet at a cost).