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

Adding array(s) of (varied-size) sub surfaces #11

Merged
merged 12 commits into from
May 15, 2023
Merged

Adding array(s) of (varied-size) sub surfaces #11

merged 12 commits into from
May 15, 2023

Conversation

brgix
Copy link
Member

@brgix brgix commented Apr 22, 2023

No description provided.

@brgix brgix self-assigned this Apr 22, 2023
# @param surface [OpenStudio::Model::PlanarSurface] a surface
#
# @return [Bool] true if valid surface
def valid(surface = nil)
Copy link
Member Author

Choose a reason for hiding this comment

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

A clone of TBD's validate - to be deprecated within TBD (in favour of OSut's valid? ... note: add question mark).

sub[:multiplier] = 1 unless sub.key?(:multiplier)
sub[:centerline] = 1.0 unless sub.key?(:centerline)
sub[:offset ] = 3.0 unless sub.key?(:offset )
sub[:ratio ] = 40 unless sub.key?(:ratio )
Copy link
Member Author

Choose a reason for hiding this comment

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

The intention is to support multiple options when inserting sub surfaces, e.g. simple a 40% FWR band, arrays of regularly-spaced windows, totally customized insertions (e.g. multiple, custom-sized windows & doors, with unique anchor points).

it "checks subsurface insertions on tilted surfaces" do
# Examples of how to harness OpenStudio's Boost geometry methods to safely
# insert subsurfaces along rotated/tilted/slanted host/parent/base
# surfaces. First step, modify SEB.osm model.
Copy link
Member Author

Choose a reason for hiding this comment

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

The end result of the basic tests:
seb_fen
The intention is to support sub surface additions, regardless of surface azimuth or tilt, and independently of host surface polygon attributes (e.g. concave vs convex, regular vs irregular).

# At this point, "head", "sill" and/or "height" have been tentatively
# validated (and/or have been corrected) independently from one another.
# Log/reset "head" & "sill" heights if conflicting.
if sub.key?(:head) && sub.key?(:sill) && sub[:head] < sub[:sill] + glass
Copy link
Member Author

Choose a reason for hiding this comment

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

An example of one of many validation checks of user-set arguments. There are several options offered to users, e.g. sub surface (ww) ratio, height, width, head, sill, spacing (if an array of sub surfaces), and hence many possible conflicts. Most of the code in addSubs is a (longish), sequential series of validation checks. In many cases, the method resets conflicting input (while logging warnings). In other instances, it skips over an invalid combo of user arguments (while logging errors). This may be broken down into more than one method in the future ... maybe.

@@ -1545,5 +1545,13 @@ module M
expect(mod1.reset(DBG)).to eq(DBG)
expect(mod1.level).to eq(DBG)
expect(mod1.clean!).to eq(DBG)

subs = []
subs << {height: 0.2, width: 0.2}
Copy link
Member Author

Choose a reason for hiding this comment

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

The most basic (minimal) call to addSubs (all other arguments are defaulted). This generates the tiny, illustrated 8" x 8" side window. All EnergyPlus checks pass. Simulation runs are good.

seb_right

The method also allows users to request a WWR-calculated sub surface addition, or instead an array of equally-sized sub surfaces. The method can be run on the same base surface over and over, without deleting previously-added sub surfaces, e.g. adding a corner door AFTER adding a WWR-calculated horizontal window band, adding a transom window above a door (or vice versa). A LOT more testing needs to be completed before merging ...

expect(mod1.addSubs(model, roof, [sub], false)).to be(true)
expect(mod1.warn?).to be(true)
expect(mod1.logs.size).to eq(1)
message = "' sill height to 0.005 m (OSut::addSubs)"
Copy link
Member Author

Choose a reason for hiding this comment

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

A warning is logged if any user-set argument (here, sill height of 0mm) needs to be reset to a safer value. In the end, the same outcome is generated using addSubs.

seb_final

expect(sub.key?(:head)).to be(false)
sub[:sill] = 0.0 # will be reset to 5mm
sub[:type] = "Skylight"
expect(mod1.addSubs(model, roof, [sub], false)).to be(true)
Copy link
Member Author

Choose a reason for hiding this comment

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

General approach to using the method:

  • same sub surface Hash may be reused from one base surface to another (ensuring consistency)
  • Hash key:value pairs may be deleted or added, as needed
  • some key:value pairs are safe to default

# meaning 100mm between w1, w2, t1 vs t2 vertices. In addition, all 4x
# openings (grouped together) should align towards the left of wall4,
# leaving a 200mm gap between the left vertical wall edge and the left
# frame jamb edge of w1 & t1. First initialize Frame & Divider object.
Copy link
Member Author

Choose a reason for hiding this comment

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

Tests/demos:

  • head/sill alignment of new sub surface with those of an existing one (e.g. bottom wwr% strip)
  • recovery of OSut default head/sill (if missing), e.g. top wwr% strip
  • left/right offset of 4x grouped sub surfaces (from base surface centreline)
  • frame & divider enabled (4x grouped sub surfaces)
  • E+ simulations (no related warnings or errors)

seb_offset

Copy link
Member

Choose a reason for hiding this comment

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

This looks pretty cool!

@brgix brgix mentioned this pull request May 6, 2023
#
# @return [Bool] true if successful (check for logged messages if failures)
def addSubs(model = nil, s = nil, subs = [], clear = false)
def addSubs(model = nil, s = nil, subs = [], clear = false, bfr = 0.005)
Copy link
Member Author

Choose a reason for hiding this comment

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

Now an option (i.e. not hardwired).

@@ -1449,6 +1449,9 @@ def overlaps?(p1 = nil, p2 = nil, id1 = "", id2 = "")
area = area.get
return false if area < TOL

delta = (area - area1 - area2).abs
return false if delta < TOL
Copy link
Member Author

Choose a reason for hiding this comment

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

Big oversight: overlaps? previously returned true if a successful union of both polygons had a valid area ... without checking if the area simply equaled the sum of both individual polygon areas (i.e. 2x side-by-side polygons). This oversight should have been caught in this TBD test: a more detailed look revealed that both tested polygons were a fraction of a mm from aligning, which failed to trigger a false positive. This is only an issue for users aligning subsurfaces (with or without frame&dividers).

fr = 0 if fd.empty?
fr = fd.get.frameWidth unless fd.empty?
vk = sb.vertices
vk = offset(vk, fr, 300) if fr > 0
Copy link
Member Author

Choose a reason for hiding this comment

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

Forgot to offset subsurface vertices if frame&divider-enabled. Mea culpa.

@brgix brgix linked an issue May 15, 2023 that may be closed by this pull request
# sub[:offset ] # if array (+ m)
# sub[:centreline] # left or right of base surface centreline (+/- m)
# sub[:r_buffer ] # buffer between sub/array and right-side corner (+ m)
# sub[:l_buffer ] # buffer between sub/array and left-side corner (+ m)
Copy link
Member Author

@brgix brgix May 15, 2023

Choose a reason for hiding this comment

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

2x new options, in response to this desired feature. Left/right buffers are distances (in m, always positive numbers) from either left or right edges of the base surface (e.g. wall corners). Also frame&divider-enabled; the buffers are between e.g. a glazing jamb and either wall corner, not between rough opening jambs and wall corner.

w = area / h
width = w - frames
x0 = centre - w/2
xf = centre + w/2

if sub.key?(:l_buffer)
if sub.key?(:centreline)
log(WRN, "Skip #{id} left buffer (vs centreline) (#{mth})")
Copy link
Member Author

Choose a reason for hiding this comment

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

Attribute :centreline has precedence over either left or right buffer attributes. If both left and right buffers are requested by the user, left is favoured over right.

a7[:sill ] = sub6_min
a7[:width ] = a7[:head ] - a7[:sill]
a7[:offset ] = a7[:width] + gap
a7[:r_buffer ] = gap
Copy link
Member Author

Choose a reason for hiding this comment

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

Tests left/right buffer-alignment (instead of centred or off-centred) of 5x ~square-shaped windows, in the 2x (fairly narrow) walls in the centre of the Figure:

  1. 1x array of 2x windows added to the left wall ("right-aligned")
  2. 1x array of 3x windows added to the right wall ("left-aligned)
leftright

A "gap" (200mm or 8") separates the glazing areas between each other, and between the left (or right) wall corner and the nearest window glazing edge. EnergyPlus simulations run fine (no related warnings/errors).

@brgix brgix merged commit 29a2541 into main May 15, 2023
@brgix brgix deleted the fenestration branch May 16, 2023 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

addSubs : provide (safe) left-edge & right-edge alignments
2 participants