tbd 3.2.1 → 3.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/measures/tbd/measure.xml +20 -20
- data/lib/measures/tbd/resources/geo.rb +10 -42
- data/lib/measures/tbd/resources/ua.rb +154 -145
- data/lib/measures/tbd/resources/utils.rb +590 -2
- data/lib/tbd/geo.rb +10 -42
- data/lib/tbd/ua.rb +154 -145
- data/lib/tbd/version.rb +1 -1
- data/tbd.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15442c735a4591e22e609b8b2f73733a583a5f6b304c3c479866d98afcf63251
|
4
|
+
data.tar.gz: c4d53db567cc419b2e0eb5b4b48f85f19e6c12745bab19ee257566c0c1b38bea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e314e00796a8d0e6e44c6ccd23d0e9accaa45be119589da431d00f45354c622bbedd964b94053fd9823c33914713b07984e0f0df44f714d4311ac16f382c0407
|
7
|
+
data.tar.gz: 7344be85007deed2d9a22d83c0cb20d4860d4e048c1bf281e7f2c8024439696b75ba6d232c9f8985253003c1295d2e537fc29a9fb9322ea6d756bcd08ec0dcf9
|
@@ -3,8 +3,8 @@
|
|
3
3
|
<schema_version>3.0</schema_version>
|
4
4
|
<name>tbd_measure</name>
|
5
5
|
<uid>8890787b-8c25-4dc8-8641-b6be1b6c2357</uid>
|
6
|
-
<version_id>
|
7
|
-
<version_modified>
|
6
|
+
<version_id>30d7ee3a-8327-4a32-92fd-5cc0b9ab24b0</version_id>
|
7
|
+
<version_modified>20230516T180637Z</version_modified>
|
8
8
|
<xml_checksum>99772807</xml_checksum>
|
9
9
|
<class_name>TBDMeasure</class_name>
|
10
10
|
<display_name>Thermal Bridging and Derating - TBD</display_name>
|
@@ -406,12 +406,6 @@
|
|
406
406
|
<usage_type>resource</usage_type>
|
407
407
|
<checksum>A4E8433C</checksum>
|
408
408
|
</file>
|
409
|
-
<file>
|
410
|
-
<filename>utils.rb</filename>
|
411
|
-
<filetype>rb</filetype>
|
412
|
-
<usage_type>resource</usage_type>
|
413
|
-
<checksum>283C976C</checksum>
|
414
|
-
</file>
|
415
409
|
<file>
|
416
410
|
<version>
|
417
411
|
<software_program>OpenStudio</software_program>
|
@@ -429,24 +423,12 @@
|
|
429
423
|
<usage_type>test</usage_type>
|
430
424
|
<checksum>58ED6635</checksum>
|
431
425
|
</file>
|
432
|
-
<file>
|
433
|
-
<filename>geo.rb</filename>
|
434
|
-
<filetype>rb</filetype>
|
435
|
-
<usage_type>resource</usage_type>
|
436
|
-
<checksum>F447D8CE</checksum>
|
437
|
-
</file>
|
438
426
|
<file>
|
439
427
|
<filename>README.md</filename>
|
440
428
|
<filetype>md</filetype>
|
441
429
|
<usage_type>readme</usage_type>
|
442
430
|
<checksum>B836C43A</checksum>
|
443
431
|
</file>
|
444
|
-
<file>
|
445
|
-
<filename>ua.rb</filename>
|
446
|
-
<filetype>rb</filetype>
|
447
|
-
<usage_type>resource</usage_type>
|
448
|
-
<checksum>19193778</checksum>
|
449
|
-
</file>
|
450
432
|
<file>
|
451
433
|
<filename>psi.rb</filename>
|
452
434
|
<filetype>rb</filetype>
|
@@ -465,5 +447,23 @@
|
|
465
447
|
<usage_type>resource</usage_type>
|
466
448
|
<checksum>A3BB982A</checksum>
|
467
449
|
</file>
|
450
|
+
<file>
|
451
|
+
<filename>ua.rb</filename>
|
452
|
+
<filetype>rb</filetype>
|
453
|
+
<usage_type>resource</usage_type>
|
454
|
+
<checksum>EEFCA7DA</checksum>
|
455
|
+
</file>
|
456
|
+
<file>
|
457
|
+
<filename>utils.rb</filename>
|
458
|
+
<filetype>rb</filetype>
|
459
|
+
<usage_type>resource</usage_type>
|
460
|
+
<checksum>C03764A5</checksum>
|
461
|
+
</file>
|
462
|
+
<file>
|
463
|
+
<filename>geo.rb</filename>
|
464
|
+
<filetype>rb</filetype>
|
465
|
+
<usage_type>resource</usage_type>
|
466
|
+
<checksum>5F84399F</checksum>
|
467
|
+
</file>
|
468
468
|
</files>
|
469
469
|
</measure>
|
@@ -218,42 +218,6 @@ module TBD
|
|
218
218
|
true
|
219
219
|
end
|
220
220
|
|
221
|
-
##
|
222
|
-
# Validate whether an OpenStudio planar surface is safe for TBD to process.
|
223
|
-
#
|
224
|
-
# @param s [OpenStudio::Model::PlanarSurface] a surface
|
225
|
-
#
|
226
|
-
# @return [Bool] true if valid surface
|
227
|
-
def validate(s = nil)
|
228
|
-
mth = "TBD::#{__callee__}"
|
229
|
-
cl = OpenStudio::Model::PlanarSurface
|
230
|
-
|
231
|
-
return mismatch("surface", s, cl, mth, DBG, false) unless s.is_a?(cl)
|
232
|
-
|
233
|
-
id = s.nameString
|
234
|
-
size = s.vertices.size
|
235
|
-
last = size - 1
|
236
|
-
|
237
|
-
log(ERR, "#{id} #{size} vertices? need +3 (#{mth})") unless size > 2
|
238
|
-
return false unless size > 2
|
239
|
-
|
240
|
-
[0, last].each do |i|
|
241
|
-
v1 = s.vertices[i]
|
242
|
-
v2 = s.vertices[i + 1] unless i == last
|
243
|
-
v2 = s.vertices.first if i == last
|
244
|
-
vector = v2 - v1
|
245
|
-
bad = vector.length < TOL
|
246
|
-
|
247
|
-
# As is, this comparison also catches collinear vertices (< 10mm apart)
|
248
|
-
# along an edge. Should avoid red-flagging such cases. TO DO.
|
249
|
-
log(ERR, "#{id}: < #{TOL}m (#{mth})") if bad
|
250
|
-
return false if bad
|
251
|
-
end
|
252
|
-
|
253
|
-
# Add as many extra tests as needed ...
|
254
|
-
true
|
255
|
-
end
|
256
|
-
|
257
221
|
##
|
258
222
|
# Return site-specific (or true) Topolys normal vector of OpenStudio surface.
|
259
223
|
#
|
@@ -290,30 +254,33 @@ module TBD
|
|
290
254
|
cl2 = OpenStudio::Model::Surface
|
291
255
|
cl3 = OpenStudio::Model::LayeredConstruction
|
292
256
|
|
293
|
-
return mismatch("model", model, cl1, mth)
|
294
|
-
return mismatch("surface", surface, cl2, mth)
|
295
|
-
|
296
|
-
return nil unless validate(surface)
|
257
|
+
return mismatch("model", model, cl1, mth) unless model.is_a?(cl1)
|
258
|
+
return mismatch("surface", surface, cl2, mth) unless surface.is_a?(cl2)
|
259
|
+
return nil unless surface_valid?(surface)
|
297
260
|
|
298
261
|
nom = surface.nameString
|
299
262
|
surf = {}
|
300
263
|
subs = {}
|
301
264
|
fd = false
|
302
265
|
return empty("'#{nom}' space", mth, ERR) if surface.space.empty?
|
266
|
+
|
303
267
|
space = surface.space.get
|
304
268
|
stype = space.spaceType
|
305
269
|
story = space.buildingStory
|
306
270
|
tr = transforms(model, space)
|
307
271
|
return invalid("'#{nom}' transform", mth, 0, FTL) unless tr[:t] && tr[:r]
|
272
|
+
|
308
273
|
t = tr[:t]
|
309
274
|
n = trueNormal(surface, tr[:r])
|
310
275
|
return invalid("'#{nom}' normal", mth, 0, FTL) unless n
|
276
|
+
|
311
277
|
type = surface.surfaceType.downcase
|
312
278
|
facing = surface.outsideBoundaryCondition
|
313
279
|
|
314
280
|
if facing.downcase == "surface"
|
315
281
|
empty = surface.adjacentSurface.empty?
|
316
|
-
return invalid("'#{nom}': adjacent surface", mth, 0, ERR)
|
282
|
+
return invalid("'#{nom}': adjacent surface", mth, 0, ERR) if empty
|
283
|
+
|
317
284
|
facing = surface.adjacentSurface.get.nameString
|
318
285
|
end
|
319
286
|
|
@@ -350,9 +317,10 @@ module TBD
|
|
350
317
|
surf[:story ] = story.get unless story.empty?
|
351
318
|
surf[:n ] = n
|
352
319
|
surf[:gross ] = surface.grossArea
|
320
|
+
surf[:filmRSI ] = surface.filmResistance
|
353
321
|
|
354
322
|
surface.subSurfaces.sort_by { |s| s.nameString }.each do |s|
|
355
|
-
next unless
|
323
|
+
next unless surface_valid?(s)
|
356
324
|
|
357
325
|
id = s.nameString
|
358
326
|
valid = s.vertices.size == 3 || s.vertices.size == 4
|
@@ -39,13 +39,14 @@ module TBD
|
|
39
39
|
cl1 = OpenStudio::Model::Model
|
40
40
|
cl2 = OpenStudio::Model::LayeredConstruction
|
41
41
|
cl3 = Numeric
|
42
|
+
cl4 = String
|
42
43
|
|
43
|
-
return mismatch("model", model, cl1, mth, DBG, res)
|
44
|
-
return mismatch("id",
|
45
|
-
return mismatch("lc",
|
46
|
-
return mismatch("hloss", hloss, cl3, mth, DBG, res)
|
47
|
-
return mismatch("film",
|
48
|
-
return mismatch("Ut",
|
44
|
+
return mismatch("model", model, cl1, mth, DBG, res) unless model.is_a?(cl1)
|
45
|
+
return mismatch("id" , id, cl4, mth, DBG, res) unless id.is_a?(cl4)
|
46
|
+
return mismatch("lc" , lc, cl2, mth, DBG, res) unless lc.is_a?(cl2)
|
47
|
+
return mismatch("hloss", hloss, cl3, mth, DBG, res) unless hloss.is_a?(cl3)
|
48
|
+
return mismatch("film" , film, cl3, mth, DBG, res) unless film.is_a?(cl3)
|
49
|
+
return mismatch("Ut" , ut, cl3, mth, DBG, res) unless ut.is_a?(cl3)
|
49
50
|
|
50
51
|
loss = 0.0 # residual heatloss (not assigned) [W/K]
|
51
52
|
area = lc.getNetArea
|
@@ -54,12 +55,12 @@ module TBD
|
|
54
55
|
lyr[:index] = nil unless lyr[:index] >= 0
|
55
56
|
lyr[:index] = nil unless lyr[:index] < lc.layers.size
|
56
57
|
|
57
|
-
return invalid("'#{id}' layer index", mth, 0, ERR, res)
|
58
|
-
return zero("'#{id}': heatloss", mth,
|
59
|
-
return zero("'#{id}': films", mth,
|
60
|
-
return zero("'#{id}': Ut", mth,
|
61
|
-
return invalid("'#{id}': Ut", mth, 0, WRN, res)
|
62
|
-
return zero("'#{id}': net area (m2)", mth,
|
58
|
+
return invalid("'#{id}' layer index", mth, 0, ERR, res) unless lyr[:index]
|
59
|
+
return zero("'#{id}': heatloss" , mth, WRN, res) unless hloss > TOL
|
60
|
+
return zero("'#{id}': films" , mth, WRN, res) unless film > TOL
|
61
|
+
return zero("'#{id}': Ut" , mth, WRN, res) unless ut > TOL
|
62
|
+
return invalid("'#{id}': Ut" , mth, 0, WRN, res) unless ut < 5.678
|
63
|
+
return zero("'#{id}': net area (m2)", mth, ERR, res) unless area > TOL
|
63
64
|
|
64
65
|
# First, calculate initial layer RSi to initially meet Ut target.
|
65
66
|
rt = 1 / ut # target construction Rt
|
@@ -76,7 +77,7 @@ module TBD
|
|
76
77
|
|
77
78
|
if lyr[:type] == :massless
|
78
79
|
m = lc.getLayer(lyr[:index]).to_MasslessOpaqueMaterial
|
79
|
-
return invalid("'#{id}' massless layer?", mth, 0)
|
80
|
+
return invalid("'#{id}' massless layer?", mth, 0, DBG, res) if m.empty?
|
80
81
|
|
81
82
|
m = m.get.clone(model).to_MasslessOpaqueMaterial.get
|
82
83
|
m.setName("#{id} uprated")
|
@@ -85,7 +86,7 @@ module TBD
|
|
85
86
|
m.setThermalResistance(new_r)
|
86
87
|
else # type == :standard
|
87
88
|
m = lc.getLayer(lyr[:index]).to_StandardOpaqueMaterial
|
88
|
-
return invalid("'#{id}' standard layer?", mth, 0)
|
89
|
+
return invalid("'#{id}' standard layer?", mth, 0, DBG, res) if m.empty?
|
89
90
|
|
90
91
|
m = m.get.clone(model).to_StandardOpaqueMaterial.get
|
91
92
|
m.setName("#{id} uprated")
|
@@ -141,11 +142,12 @@ module TBD
|
|
141
142
|
mth = "TBD::#{__callee__}"
|
142
143
|
cl1 = OpenStudio::Model::Model
|
143
144
|
cl2 = Hash
|
145
|
+
cl3 = OpenStudio::Model::LayeredConstruction
|
144
146
|
a = false
|
145
147
|
|
146
|
-
return mismatch("model", model, cl1, mth, DBG, a)
|
147
|
-
return mismatch("surfaces",
|
148
|
-
return mismatch("argh", model, cl1, mth, DBG, a)
|
148
|
+
return mismatch("model" , model, cl1, mth, DBG, a) unless model.is_a?(cl1)
|
149
|
+
return mismatch("surfaces", s, cl2, mth, DBG, a) unless s.is_a?(cl2)
|
150
|
+
return mismatch("argh" , model, cl1, mth, DBG, a) unless argh.is_a?(cl2)
|
149
151
|
|
150
152
|
argh[:uprate_walls ] = false unless argh.key?(:uprate_walls )
|
151
153
|
argh[:uprate_roofs ] = false unless argh.key?(:uprate_roofs )
|
@@ -168,11 +170,13 @@ module TBD
|
|
168
170
|
groups[:roof ][:op] = argh[:roof_option ]
|
169
171
|
groups[:floor][:op] = argh[:floor_option ]
|
170
172
|
|
171
|
-
groups.each do |
|
173
|
+
groups.each do |type, g|
|
172
174
|
next unless g[:up]
|
173
175
|
next unless g[:ut].is_a?(Numeric)
|
174
176
|
next unless g[:ut] < 5.678
|
175
177
|
|
178
|
+
typ = type
|
179
|
+
typ = :ceiling if typ == :roof # fix in future revision. TO-DO.
|
176
180
|
coll = {}
|
177
181
|
area = 0
|
178
182
|
film = 100000000000000
|
@@ -183,86 +187,81 @@ module TBD
|
|
183
187
|
g[:op].downcase == "all floor constructions"
|
184
188
|
|
185
189
|
if g[:op].empty?
|
186
|
-
log(ERR, "Construction to uprate? (#{mth})")
|
190
|
+
log(ERR, "Construction (#{type}) to uprate? (#{mth})")
|
187
191
|
elsif all
|
188
|
-
|
189
|
-
next unless
|
190
|
-
next unless
|
191
|
-
next
|
192
|
-
next
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
192
|
+
s.each do |nom, surface|
|
193
|
+
next unless surface.key?(:deratable )
|
194
|
+
next unless surface.key?(:type )
|
195
|
+
next unless surface.key?(:construction)
|
196
|
+
next unless surface.key?(:filmRSI )
|
197
|
+
next unless surface.key?(:index )
|
198
|
+
next unless surface.key?(:ltype )
|
199
|
+
next unless surface.key?(:r )
|
200
|
+
next unless surface[:deratable ]
|
201
|
+
next unless surface[:type ] == typ
|
202
|
+
next unless surface[:construction].is_a?(cl3)
|
203
|
+
next if surface[:index ].nil?
|
204
|
+
|
205
|
+
# Retain lowest surface film resistance (e.g. tilted surfaces).
|
206
|
+
c = surface[:construction]
|
207
|
+
i = c.nameString
|
208
|
+
aire = c.getNetArea
|
209
|
+
film = surface[:filmRSI] if surface[:filmRSI] < film
|
210
|
+
|
211
|
+
# Retain construction covering largest area. The following conditional
|
212
|
+
# is reliable UNLESS linked to other deratable surface types e.g. both
|
213
|
+
# floors AND walls (see "elsif lc" corrections below).
|
214
|
+
if aire > area
|
200
215
|
lc = c
|
216
|
+
area = aire
|
201
217
|
id = i
|
202
218
|
end
|
203
219
|
|
204
|
-
|
205
|
-
nom
|
206
|
-
coll[i] = { area: c.getNetArea, lc: c, s: {} } unless coll.key?(i)
|
207
|
-
coll[i][:s][nom] = { a: sss.netArea } unless coll[i][:s].key?(nom)
|
220
|
+
coll[i] = { area: aire, lc: c, s: {} } unless coll.key?(i)
|
221
|
+
coll[i][:s][nom] = { a: surface[:net] } unless coll[i][:s].key?(nom)
|
208
222
|
end
|
209
223
|
else
|
210
224
|
id = g[:op]
|
211
|
-
|
212
|
-
|
213
|
-
if
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
225
|
+
lc = model.getConstructionByName(id)
|
226
|
+
log(ERR, "Construction '#{id}'? (#{mth})") if lc.empty?
|
227
|
+
next if lc.empty?
|
228
|
+
|
229
|
+
lc = lc.get.to_LayeredConstruction
|
230
|
+
log(ERR, "'#{id}' layered construction? (#{mth})") if lc.empty?
|
231
|
+
next if lc.empty?
|
232
|
+
|
233
|
+
lc = lc.get
|
234
|
+
area = lc.getNetArea
|
235
|
+
coll[id] = { area: area, lc: lc, s: {} }
|
236
|
+
|
237
|
+
s.each do |nom, surface|
|
238
|
+
next unless surface.key?(:deratable )
|
239
|
+
next unless surface.key?(:type )
|
240
|
+
next unless surface.key?(:construction)
|
241
|
+
next unless surface.key?(:filmRSI )
|
242
|
+
next unless surface.key?(:index )
|
243
|
+
next unless surface.key?(:ltype )
|
244
|
+
next unless surface.key?(:r )
|
245
|
+
next unless surface[:deratable ]
|
246
|
+
next unless surface[:type ] == typ
|
247
|
+
next unless surface[:construction].is_a?(cl3)
|
248
|
+
next if surface[:index ].nil?
|
249
|
+
|
250
|
+
i = surface[:construction].nameString
|
251
|
+
next unless i == id
|
252
|
+
|
253
|
+
# Retain lowest surface film resistance (e.g. tilted surfaces).
|
254
|
+
film = surface[:filmRSI] if surface[:filmRSI] < film
|
255
|
+
|
256
|
+
coll[i][:s][nom] = { a: surface[:net] } unless coll[i][:s].key?(nom)
|
238
257
|
end
|
239
258
|
end
|
240
259
|
|
241
260
|
if coll.empty?
|
242
|
-
log(ERR, "No #{
|
261
|
+
log(ERR, "No #{type} construction to uprate - skipping (#{mth})")
|
243
262
|
next
|
244
|
-
elsif lc
|
245
|
-
#
|
246
|
-
model.getSurfaces.each do |sss|
|
247
|
-
next if sss.construction.empty?
|
248
|
-
next if sss.construction.get.to_LayeredConstruction.empty?
|
249
|
-
c = sss.construction.get.to_LayeredConstruction.get
|
250
|
-
i = c.nameString
|
251
|
-
next unless coll.key?(i)
|
252
|
-
|
253
|
-
unless sss.surfaceType.downcase.include?(label.to_s)
|
254
|
-
log(ERR, "Uprating #{label.to_s}, not '#{sss.nameString}' (#{mth})")
|
255
|
-
cloned = c.clone(model).to_LayeredConstruction.get
|
256
|
-
cloned.setName("'#{i}' cloned")
|
257
|
-
sss.setConstruction(cloned)
|
258
|
-
ok = s.key?(sss.nameString)
|
259
|
-
s[sss.nameString][:construction] = cloned if ok
|
260
|
-
coll[i][:s].delete(sss.nameString)
|
261
|
-
coll[i][:area] = c.getNetArea
|
262
|
-
next
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
263
|
+
elsif lc
|
264
|
+
# Valid layered construction - good to uprate!
|
266
265
|
lyr = insulatingLayer(lc)
|
267
266
|
lyr[:index] = nil unless lyr[:index].is_a?(Numeric)
|
268
267
|
lyr[:index] = nil unless lyr[:index] >= 0
|
@@ -270,64 +269,81 @@ module TBD
|
|
270
269
|
|
271
270
|
log(ERR, "Insulation index for '#{id}'? (#{mth})") unless lyr[:index]
|
272
271
|
next unless lyr[:index]
|
273
|
-
hloss = 0 # sum of applicable psi & khi effects [W/K]
|
274
272
|
|
275
|
-
|
276
|
-
|
277
|
-
|
273
|
+
# Ensure lc is exclusively linked to deratable surfaces of right type.
|
274
|
+
# If not, assign new lc clone to non-targeted surfaces.
|
275
|
+
s.each do |nom, surface|
|
276
|
+
next unless surface.key?(:type )
|
277
|
+
next unless surface.key?(:deratable )
|
278
|
+
next unless surface.key?(:construction)
|
279
|
+
next unless surface[:construction].is_a?(cl3)
|
280
|
+
next unless surface[:construction] == lc
|
281
|
+
|
282
|
+
ok = true
|
283
|
+
ok = false unless surface[:type ] == typ
|
284
|
+
ok = false unless surface[:deratable]
|
285
|
+
ok = false unless coll.key?(id)
|
286
|
+
ok = false unless coll[id][:s].key?(nom)
|
287
|
+
|
288
|
+
unless ok
|
289
|
+
log(WRN, "Cloning '#{nom}' construction - not '#{id}' (#{mth})")
|
290
|
+
sss = model.getSurfaceByName(nom)
|
291
|
+
next if sss.empty?
|
292
|
+
|
293
|
+
sss = sss.get
|
294
|
+
cloned = lc.clone(model).to_LayeredConstruction.get
|
295
|
+
cloned.setName("#{nom} - cloned")
|
296
|
+
sss.setConstruction(cloned)
|
297
|
+
surface[:construction] = cloned
|
298
|
+
coll[id][:s].delete(nom)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
hloss = 0 # sum of applicable psi & khi effects [W/K]
|
278
303
|
|
304
|
+
# Tally applicable psi + khi losses. Possible construction reassignment.
|
305
|
+
coll.each do |i, col|
|
279
306
|
col[:s].keys.each do |nom|
|
280
307
|
next unless s.key?(nom)
|
281
|
-
next unless s[nom].key?(:deratable )
|
282
308
|
next unless s[nom].key?(:construction)
|
283
309
|
next unless s[nom].key?(:index )
|
284
310
|
next unless s[nom].key?(:ltype )
|
285
311
|
next unless s[nom].key?(:r )
|
286
|
-
next unless s[nom].key?(:type )
|
287
|
-
|
288
|
-
next unless s[nom][:deratable]
|
289
|
-
type = s[nom][:type].to_s.downcase
|
290
|
-
type = "roof" if type == "ceiling"
|
291
|
-
next unless type.include?(label.to_s)
|
292
312
|
|
293
313
|
# Tally applicable psi + khi.
|
294
|
-
hloss += s[nom][:heatloss] if s[nom].key?(:heatloss)
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
sss = sss.get
|
301
|
-
|
302
|
-
if sss.isConstructionDefaulted
|
303
|
-
set = defaultConstructionSet(model, sss)
|
304
|
-
constructions = set.defaultExteriorSurfaceConstructions.get
|
305
|
-
|
306
|
-
case sss.surfaceType.downcase
|
307
|
-
when "roofceiling"
|
308
|
-
constructions.setRoofCeilingConstruction(lc)
|
309
|
-
when "floor"
|
310
|
-
constructions.setFloorConstruction(lc)
|
311
|
-
else
|
312
|
-
constructions.setWallConstruction(lc)
|
313
|
-
end
|
314
|
-
else
|
315
|
-
sss.setConstruction(lc)
|
316
|
-
end
|
314
|
+
hloss += s[nom][:heatloss ] if s[nom].key?(:heatloss)
|
315
|
+
next if s[nom][:construction] == lc
|
316
|
+
|
317
|
+
# Reassign construction unless referencing lc.
|
318
|
+
sss = model.getSurfaceByName(nom)
|
319
|
+
next if sss.empty?
|
317
320
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
321
|
+
sss = sss.get
|
322
|
+
|
323
|
+
if sss.isConstructionDefaulted
|
324
|
+
set = defaultConstructionSet(model, sss) # building? story?
|
325
|
+
constructions = set.defaultExteriorSurfaceConstructions
|
326
|
+
|
327
|
+
unless constructions.empty?
|
328
|
+
constructions = constructions.get
|
329
|
+
constructions.setWallConstruction(lc) if typ == :wall
|
330
|
+
constructions.setFloorConstruction(lc) if typ == :floor
|
331
|
+
constructions.setRoofCeilingConstruction(lc) if typ == :ceiling
|
332
|
+
end
|
333
|
+
else
|
334
|
+
sss.setConstruction(lc)
|
322
335
|
end
|
336
|
+
|
337
|
+
s[nom][:construction] = lc # reset TBD attributes
|
338
|
+
s[nom][:index ] = lyr[:index]
|
339
|
+
s[nom][:ltype ] = lyr[:type ]
|
340
|
+
s[nom][:r ] = lyr[:r ] # temporary
|
323
341
|
end
|
324
342
|
end
|
325
343
|
|
326
344
|
# Merge to ensure a single entry for coll Hash.
|
327
345
|
coll.each do |i, col|
|
328
346
|
next if i == id
|
329
|
-
next unless coll.key?(id)
|
330
|
-
coll[id][:area] += col[:area]
|
331
347
|
|
332
348
|
col[:s].each do |nom, sss|
|
333
349
|
coll[id][:s][nom] = sss unless coll[id][:s].key?(nom)
|
@@ -338,6 +354,8 @@ module TBD
|
|
338
354
|
log(DBG, "Collection == 1? for '#{id}' (#{mth})") unless coll.size == 1
|
339
355
|
next unless coll.size == 1
|
340
356
|
|
357
|
+
area = lc.getNetArea
|
358
|
+
coll[id][:area] = area
|
341
359
|
res = uo(model, lc, id, hloss, film, g[:ut])
|
342
360
|
log(ERR, "Unable to uprate '#{id}' (#{mth})") unless res[:uo] && res[:m]
|
343
361
|
next unless res[:uo] && res[:m]
|
@@ -347,27 +365,18 @@ module TBD
|
|
347
365
|
# Loop through coll :s, and reset :r - likely modified by uo().
|
348
366
|
coll.values.first[:s].keys.each do |nom|
|
349
367
|
next unless s.key?(nom)
|
350
|
-
next unless s[nom].key?(:
|
351
|
-
next unless s[nom].key?(:
|
352
|
-
next unless s[nom].key?(:
|
353
|
-
next unless s[nom]
|
354
|
-
next unless s[nom]
|
355
|
-
|
356
|
-
|
357
|
-
next unless s[nom][:construction] == lc
|
358
|
-
next unless s[nom][:index ] == lyr[:index]
|
359
|
-
next unless s[nom][:ltype ] == lyr[:type]
|
360
|
-
|
361
|
-
type = s[nom][:type].to_s.downcase
|
362
|
-
type = "roof" if type == "ceiling"
|
363
|
-
next unless type.include?(label.to_s)
|
364
|
-
next unless s[nom].key?(:r)
|
365
|
-
s[nom][:r] = lyr[:r] # final
|
368
|
+
next unless s[nom].key?(:index)
|
369
|
+
next unless s[nom].key?(:ltype)
|
370
|
+
next unless s[nom].key?(:r )
|
371
|
+
next unless s[nom][:index] == lyr[:index]
|
372
|
+
next unless s[nom][:ltype] == lyr[:type ]
|
373
|
+
|
374
|
+
s[nom][:r] = lyr[:r] # uprated insulating RSi factor, before derating
|
366
375
|
end
|
367
376
|
|
368
|
-
argh[:wall_uo ] = res[:uo] if
|
369
|
-
argh[:roof_uo ] = res[:uo] if
|
370
|
-
argh[:floor_uo] = res[:uo] if
|
377
|
+
argh[:wall_uo ] = res[:uo] if typ == :wall
|
378
|
+
argh[:roof_uo ] = res[:uo] if typ == :ceiling
|
379
|
+
argh[:floor_uo] = res[:uo] if typ == :floor
|
371
380
|
else
|
372
381
|
log(ERR, "Nilled construction to uprate - (#{mth})")
|
373
382
|
return false
|
@@ -920,7 +929,7 @@ module TBD
|
|
920
929
|
model = "* modèle : #{ua[:file]}" if ua.key?(:file) && lang == :fr
|
921
930
|
model += " (v#{ua[:version]})" if ua.key?(:version)
|
922
931
|
report << model unless model.empty?
|
923
|
-
report << "* TBD : v3.2.
|
932
|
+
report << "* TBD : v3.2.3"
|
924
933
|
report << "* date : #{ua[:date]}"
|
925
934
|
|
926
935
|
if lang == :en
|